generated from bob/template
Initial commit
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "image_proc.h"
|
||||
#include "user_proc.h"
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint16_t bfType;
|
||||
uint32_t bfSize;
|
||||
uint16_t bfReserved1;
|
||||
uint16_t bfReserved2;
|
||||
uint32_t bfOffBits;
|
||||
} BMPFILEHEADER;
|
||||
#pragma pack(pop)
|
||||
|
||||
static uint8_t* g_pixels = NULL;
|
||||
static BITMAPINFO* g_bmi = NULL;
|
||||
static int g_w=0, g_h=0, g_bpp=0;
|
||||
static const char* g_title = "BMP Viewer";
|
||||
|
||||
static void FreeImage() {
|
||||
free(g_pixels); g_pixels = NULL;
|
||||
free(g_bmi); g_bmi = NULL;
|
||||
g_w = g_h = g_bpp = 0;
|
||||
}
|
||||
|
||||
static int LoadBMP(const char* path) {
|
||||
FreeImage();
|
||||
FILE* fp = fopen(path, "rb");
|
||||
if(!fp){ fprintf(stderr,"无法打开: %s\n", path); return 0; }
|
||||
|
||||
BMPFILEHEADER fh;
|
||||
BITMAPINFOHEADER ih;
|
||||
if(fread(&fh,sizeof(fh),1,fp)!=1){ fclose(fp); return 0; }
|
||||
if(fh.bfType != 0x4D42){ fclose(fp); fprintf(stderr,"非BMP\n"); return 0; }
|
||||
if(fread(&ih,sizeof(ih),1,fp)!=1){ fclose(fp); return 0; }
|
||||
if(ih.biCompression != BI_RGB){ fclose(fp); fprintf(stderr,"仅支持未压缩 BI_RGB\n"); return 0; }
|
||||
if(!(ih.biBitCount==8 || ih.biBitCount==24 || ih.biBitCount==32)){
|
||||
fclose(fp); fprintf(stderr,"不支持位数: %u\n", ih.biBitCount); return 0;
|
||||
}
|
||||
|
||||
g_w = ih.biWidth;
|
||||
g_h = ih.biHeight;
|
||||
g_bpp = ih.biBitCount;
|
||||
|
||||
int bytesPerPixel = g_bpp / 8;
|
||||
int stride = ((g_w * bytesPerPixel + 3) / 4) * 4;
|
||||
size_t imgSize = (size_t)stride * g_h;
|
||||
|
||||
uint32_t colors = 0;
|
||||
if(g_bpp == 8){
|
||||
colors = ih.biClrUsed ? ih.biClrUsed : 256;
|
||||
if(colors > 256) colors = 256;
|
||||
}
|
||||
size_t bmiSize = sizeof(BITMAPINFOHEADER) + colors * sizeof(RGBQUAD);
|
||||
g_bmi = (BITMAPINFO*)calloc(1, bmiSize);
|
||||
if(!g_bmi){ fclose(fp); return 0; }
|
||||
g_bmi->bmiHeader = ih;
|
||||
|
||||
if(g_bpp == 8){
|
||||
if(colors){
|
||||
size_t readPaletteBytes = colors * sizeof(RGBQUAD);
|
||||
if(fread(g_bmi->bmiColors, 1, readPaletteBytes, fp) != readPaletteBytes){
|
||||
for(uint32_t i=0;i<colors;i++){
|
||||
g_bmi->bmiColors[i].rgbRed =
|
||||
g_bmi->bmiColors[i].rgbGreen =
|
||||
g_bmi->bmiColors[i].rgbBlue = (BYTE)i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
g_pixels = (uint8_t*)malloc(imgSize);
|
||||
if(!g_pixels){ fclose(fp); FreeImage(); return 0; }
|
||||
|
||||
if(fseek(fp, (long)fh.bfOffBits, SEEK_SET)!=0){
|
||||
fclose(fp); FreeImage(); return 0;
|
||||
}
|
||||
if(fread(g_pixels,1,imgSize,fp)!=imgSize){
|
||||
fclose(fp); FreeImage(); fprintf(stderr,"像素读取失败\n"); return 0;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if(g_bpp == 8){
|
||||
int isGray = 1;
|
||||
for(uint32_t i=0;i<colors;i++){
|
||||
BYTE r=g_bmi->bmiColors[i].rgbRed;
|
||||
BYTE g=g_bmi->bmiColors[i].rgbGreen;
|
||||
BYTE b=g_bmi->bmiColors[i].rgbBlue;
|
||||
if(!(r==g && g==b)){ isGray=0; break; }
|
||||
}
|
||||
if(!isGray){
|
||||
for(uint32_t i=0;i<colors;i++){
|
||||
g_bmi->bmiColors[i].rgbRed =
|
||||
g_bmi->bmiColors[i].rgbGreen =
|
||||
g_bmi->bmiColors[i].rgbBlue = (BYTE)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
|
||||
switch(msg){
|
||||
case WM_ERASEBKGND:
|
||||
return 1;
|
||||
case WM_PAINT:{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hWnd,&ps);
|
||||
if(g_pixels && g_bmi){
|
||||
int dstW = g_w * IMAGE_SCALE;
|
||||
int dstH = g_h * IMAGE_SCALE;
|
||||
SetStretchBltMode(hdc, COLORONCOLOR);
|
||||
StretchDIBits(
|
||||
hdc,
|
||||
0,0,dstW,dstH,
|
||||
0,0,g_w,g_h,
|
||||
g_pixels,
|
||||
g_bmi,
|
||||
DIB_RGB_COLORS,
|
||||
SRCCOPY
|
||||
);
|
||||
} else {
|
||||
TextOutA(hdc,10,10,"未加载BMP",12);
|
||||
}
|
||||
EndPaint(hWnd,&ps);
|
||||
} break;
|
||||
case WM_DESTROY:
|
||||
FreeImage();
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd,msg,wParam,lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APIENTRY WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpCmdLine,int nShow){
|
||||
(void)hPrev; (void)lpCmdLine;
|
||||
if(!LoadBMP(BMP_PATH)){
|
||||
char msg[256];
|
||||
snprintf(msg,sizeof(msg),"加载失败: %s", BMP_PATH);
|
||||
MessageBoxA(NULL,msg,"错误",MB_OK|MB_ICONERROR);
|
||||
} else {
|
||||
g_title = BMP_PATH;
|
||||
|
||||
GrayImage gray = {0};
|
||||
if(ExtractGray(g_pixels, g_w, g_h, g_bpp, &gray)){
|
||||
|
||||
img_proc(&gray);//这里调用了图像处理函数
|
||||
|
||||
BITMAPINFO *newBMI = NULL;
|
||||
uint8_t *newPixels = NULL;
|
||||
if(Build8BitDIB(&gray, &newBMI, &newPixels)){
|
||||
free(g_pixels);
|
||||
free(g_bmi);
|
||||
g_pixels = newPixels;
|
||||
g_bmi = newBMI;
|
||||
g_bpp = 8;
|
||||
}
|
||||
}
|
||||
FreeGray(&gray);
|
||||
}
|
||||
|
||||
const char* cls = "BMP_VIEWER_CLASS";
|
||||
WNDCLASSA wc = (WNDCLASSA){0};
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.hInstance = hInst;
|
||||
wc.lpszClassName = cls;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
if(!RegisterClassA(&wc)) return 0;
|
||||
|
||||
int winW = g_w ? g_w * IMAGE_SCALE : 640;
|
||||
int winH = g_h ? g_h * IMAGE_SCALE : 480;
|
||||
|
||||
RECT rc = {0,0, winW, winH};
|
||||
DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||
AdjustWindowRect(&rc, style, FALSE);
|
||||
|
||||
HWND hWnd = CreateWindowExA(
|
||||
0, cls, g_title,
|
||||
style,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
NULL,NULL,hInst,NULL);
|
||||
if(!hWnd) return 0;
|
||||
|
||||
ShowWindow(hWnd,nShow);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
MSG msg;
|
||||
while(GetMessage(&msg,NULL,0,0)>0){
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
Reference in New Issue
Block a user