/*   RGBとYCrCbの変換 2001/ 1/25 宍戸 輝光 */ #include LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL readBMP(LPCTSTR); void loadYUV(LPCTSTR); void saveYUV(void); HINSTANCE hInst; HWND hwMain; LPBYTE lpDIB,lpPixel; LPBITMAPINFO lpbiInfo; BOOL loaded; DWORD dwWidth,dwHeight,dwLength; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASS wndclass ; hInst=hInstance; /* プロセスのハンドルを保存 */ wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; RegisterClass(&wndclass); hwMain=CreateWindow ("CWindow","YCrCb",WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,560,480, NULL,NULL,hInstance,NULL); DragAcceptFiles(hwMain,TRUE); /* ドラッグ&ドロップ受入 */ ShowWindow(hwMain,iCmdShow); /* ウインドウを表示 */ UpdateWindow (hwMain); /* 再描画 */ while (GetMessage(&msg,NULL,0,0)) { /* メッセージループ */ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDROP hDrop; HDC hdc; PAINTSTRUCT ps; TCHAR lpszFn[MAX_PATH+1]; switch (iMsg) { case WM_DROPFILES: /* ファイルがドロップされた時の処理 */ hDrop=(HDROP)wParam; /* HDROPを取得 */ DragQueryFile(hDrop,0,lpszFn,256); /* ファイル名を取得 */ if (lstrcmpi(lpszFn+lstrlen(lpszFn)-4,".bmp")==0) { /* BMP */ loaded=readBMP(lpszFn); if (loaded) /* 読みこみ成功ならYCrCb変換・ファイル作成 */ saveYUV(); } else /* YUVファイルとして処理 */ loadYUV(lpszFn); DragFinish(hDrop); /* 終了処理 */ InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); /* 再描画 */ break; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); if (loaded) /* ビットマップが読み込まれていれば */ StretchDIBits(hdc,4,4,dwWidth,dwHeight, 0,0,dwWidth,dwHeight,lpPixel,lpbiInfo, DIB_RGB_COLORS,SRCCOPY); /* DIBを画面に描画 */ EndPaint(hwnd,&ps); return 0; case WM_DESTROY : if (loaded) /* DIBと作業用メモリ解放 */ GlobalFree(lpDIB); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(LPCTSTR lpszFn) { /* ビットマップ読み込み */ DWORD offset,dummy; HANDLE fh; if (loaded) /* 以前確保したバッファを解放 */ GlobalFree(lpDIB); fh=CreateFile(lpszFn,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ lpDIB=(LPBYTE)GlobalAlloc (GPTR,GetFileSize(fh,NULL)); /* バッファ確保 */ ReadFile(fh,lpDIB,GetFileSize(fh,NULL),&dummy,NULL); lpbiInfo=(LPBITMAPINFO)(lpDIB+sizeof(BITMAPFILEHEADER)); offset=*(LPDWORD)(lpDIB+10); lpPixel=lpDIB+offset; /* ビットマップバッファの先頭アドレス */ CloseHandle(fh); /* 24ビットフルカラービットマップでなければ無効 */ if (lpDIB[0]!='B' || lpbiInfo->bmiHeader.biBitCount!=24) { GlobalFree(lpDIB); loaded=FALSE; return FALSE; } /* ビットマップの大きさ保存 */ dwWidth=lpbiInfo->bmiHeader.biWidth; dwHeight=lpbiInfo->bmiHeader.biHeight; if ((dwWidth*3) % 4==0) /* バッファの1ラインの長さを計算 */ dwLength=dwWidth*3; else dwLength=dwWidth*3+(4-(dwWidth*3) % 4); SetWindowText(hwMain,lpszFn); return TRUE; } void saveYUV(void) { /* YCrCb変換とYUVファイル作成 */ DWORD i,j,dwSize; double r,g,b,y,cr,cb; LPBYTE lpWork; HANDLE fh; lpWork=GlobalAlloc(GPTR,dwWidth*dwHeight*3+8); *((LPDWORD)lpWork)=dwWidth; *((LPDWORD)lpWork+1)=dwHeight; for (i=0;i255) y=255; if (cr<0) cr=0; if (cr>255) cr=255; if (cb<0) cb=0; if (cb>255) cb=255; lpWork[j*3+i*dwWidth*3+8]=(BYTE)y; lpWork[j*3+i*dwWidth*3+8+1]=(BYTE)cr; lpWork[j*3+i*dwWidth*3+8+2]=(BYTE)cb; } fh=CreateFile("test.yuv",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); WriteFile(fh,lpWork,dwWidth*dwHeight*3+8,&dwSize,NULL); CloseHandle(fh); GlobalFree(lpWork); } void loadYUV(LPCTSTR lpszFn) { DWORD dummy,i,j; LPBYTE lpWork; double r,g,b,y,cr,cb; HANDLE fh; fh=CreateFile(lpszFn,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ lpWork=(LPBYTE)GlobalAlloc (GPTR,GetFileSize(fh,NULL)); /* バッファ確保 */ ReadFile(fh,lpWork,GetFileSize(fh,NULL),&dummy,NULL); dwWidth=*((LPDWORD)lpWork); dwHeight=*((LPDWORD)lpWork+1); CloseHandle(fh); if ((dwWidth*3) % 4==0) /* バッファの1ラインの長さを計算 */ dwLength=dwWidth*3; else dwLength=dwWidth*3+(4-(dwWidth*3) % 4); if (loaded) GlobalFree(lpDIB); lpDIB=GlobalAlloc(GPTR,sizeof(BITMAPINFO)+dwLength*dwHeight); /* メモリイメージ用ポインタ設定 */ lpbiInfo=(LPBITMAPINFO)lpDIB; lpPixel=(LPBYTE)lpDIB+sizeof(BITMAPINFO); /* ビットマップのヘッダ作成 */ lpbiInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpbiInfo->bmiHeader.biWidth=dwWidth; lpbiInfo->bmiHeader.biHeight=dwHeight; lpbiInfo->bmiHeader.biPlanes=1; lpbiInfo->bmiHeader.biBitCount=24; for (i=0;i255) r=255; if (g<0) g=0; if (g>255) g=255; if (b<0) b=0; if (b>255) b=255; lpPixel[j*3+i*dwLength]=(BYTE)b; lpPixel[j*3+i*dwLength+1]=(BYTE)g; lpPixel[j*3+i*dwLength+2]=(BYTE)r; } loaded=TRUE; GlobalFree(lpWork); SetWindowText(hwMain,lpszFn); InvalidateRgn(hwMain,NULL,FALSE); UpdateWindow (hwMain); /* 再描画 */ }