/*   YCrCbの調整 2000/ 2/ 7 宍戸 輝光 */ #include #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL readBMP(LPCTSTR); VOID YuvToDib(void); void changeYUV(int,int,int); HINSTANCE hInst; HWND hwMain; LPBYTE lpDIB,lpPixel,lpYUV1,lpYUV2; LPBITMAPINFO lpbiInfo; BOOL loaded; DWORD dwWidth,dwHeight,dwLength; LPTSTR lpszYv,lpszUv,lpszVv; int iDY,iDU,iDV; HWND hwTBY,hwTBU,hwTBV; 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_CREATE: hwTBY=CreateWindow(TRACKBAR_CLASS,NULL,WS_CHILD|WS_VISIBLE, 8,24,144,32,hwnd,NULL,hInst,NULL); hwTBU=CreateWindow(TRACKBAR_CLASS,NULL,WS_CHILD|WS_VISIBLE, 160,24,144,32,hwnd,NULL,hInst,NULL); hwTBV=CreateWindow(TRACKBAR_CLASS,NULL,WS_CHILD|WS_VISIBLE, 312,24,144,32,hwnd,NULL,hInst,NULL); SendMessage(hwTBY,TBM_SETRANGEMIN,1,0); SendMessage(hwTBY,TBM_SETRANGEMAX,1,96); SendMessage(hwTBY,TBM_SETPOS,1,48); SendMessage(hwTBU,TBM_SETRANGEMIN,1,0); SendMessage(hwTBU,TBM_SETRANGEMAX,1,96); SendMessage(hwTBU,TBM_SETPOS,1,48); SendMessage(hwTBV,TBM_SETRANGEMIN,1,0); SendMessage(hwTBV,TBM_SETRANGEMAX,1,96); SendMessage(hwTBV,TBM_SETPOS,1,48); EnableWindow(hwTBY,FALSE); EnableWindow(hwTBU,FALSE); EnableWindow(hwTBV,FALSE); lpszYv=(LPTSTR)GlobalAlloc(GPTR,32); lpszUv=(LPTSTR)GlobalAlloc(GPTR,32); lpszVv=(LPTSTR)GlobalAlloc(GPTR,32); break; case WM_HSCROLL: iDY=SendMessage(hwTBY,TBM_GETPOS,0,0)-48; iDU=SendMessage(hwTBU,TBM_GETPOS,0,0)-48; iDV=SendMessage(hwTBV,TBM_GETPOS,0,0)-48; changeYUV(iDY,iDU,iDV); break; case WM_DROPFILES: /* ファイルがドロップされた時の処理 */ hDrop=(HDROP)wParam; /* HDROPを取得 */ DragQueryFile(hDrop,0,lpszFn,256); /* ファイル名を取得 */ if (lstrcmpi(lpszFn+lstrlen(lpszFn)-4,".bmp")==0) /* BMP */ loaded=readBMP(lpszFn); DragFinish(hDrop); /* 終了処理 */ InvalidateRgn(hwnd,NULL,TRUE); UpdateWindow (hwnd); /* 再描画 */ break; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); wsprintf(lpszYv,"%s(%d)","明度Y",iDY); wsprintf(lpszUv,"%s(%d)","色差Cr",iDU); wsprintf(lpszVv,"%s(%d)","色差Cb",iDV); TextOut(hdc,8,4,lpszYv,strlen(lpszYv)); TextOut(hdc,160,4,lpszUv,strlen(lpszUv)); TextOut(hdc,312,4,lpszVv,strlen(lpszVv)); if (loaded) /* ビットマップが読み込まれていれば */ StretchDIBits(hdc,4,64,dwWidth,dwHeight, 0,0,dwWidth,dwHeight,lpPixel,lpbiInfo, DIB_RGB_COLORS,SRCCOPY); /* DIBを画面に描画 */ EndPaint(hwnd,&ps); break; case WM_DESTROY : if (loaded) { /* DIBと作業用メモリ解放 */ GlobalFree(lpDIB); GlobalFree(lpYUV1); GlobalFree(lpYUV2); } GlobalFree(lpszYv); GlobalFree(lpszUv); GlobalFree(lpszVv); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(LPCTSTR lpszFn) { /* ビットマップ読み込み */ DWORD offset,dummy,i,j; double y,u,v,r,g,b; HANDLE fh; if (loaded) { /* 以前確保したバッファを解放 */ GlobalFree(lpDIB); GlobalFree(lpYUV1); GlobalFree(lpYUV2); } fh=CreateFile(lpszFn,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ lpDIB=(LPBYTE)GlobalAlloc (GPTR,GetFileSize(fh,NULL)); /* DIBバッファ確保 */ 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); GlobalFree(lpYUV1); GlobalFree(lpYUV2); 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); /* YCrCbバッファ(最初の状態) */ lpYUV1=GlobalAlloc(GPTR,dwWidth*dwHeight*3); /* YCrCbバッファ(表示用) */ lpYUV2=GlobalAlloc(GPTR,dwWidth*dwHeight*3); for (i=0;i255) y=255; if (u<0) u=0; if (u>255) u=255; if (v<0) v=0; if (v>255) v=255; /* バッファに保存 */ lpYUV1[j*3+i*dwWidth*3]=(BYTE)y; lpYUV1[j*3+i*dwWidth*3+1]=(BYTE)u; lpYUV1[j*3+i*dwWidth*3+2]=(BYTE)v; } /* YCrCbを表示用バッファにコピー */ CopyMemory(lpYUV2,lpYUV1,dwWidth*dwHeight*3); YuvToDib(); /* 表示用DIB作成 */ /* トラックバーの位置初期化 */ SendMessage(hwTBY,TBM_SETPOS,1,48); SendMessage(hwTBU,TBM_SETPOS,1,48); SendMessage(hwTBV,TBM_SETPOS,1,48); EnableWindow(hwTBY,TRUE); EnableWindow(hwTBU,TRUE); EnableWindow(hwTBV,TRUE); iDY=0; iDU=0; iDV=0; return TRUE; } VOID YuvToDib(void) { /* 表示用DIB作成 */ DWORD i,j; double y,u,v,r,g,b; 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; } } void changeYUV(int iDY,int iDU,int iDV) { /* YCrCb変更 */ DWORD i,j; int y,u,v; for (i=0;i255) y=255; if (u<0) u=0; if (u>255) u=255; if (v<0) v=0; if (v>255) v=255; lpYUV2[j*3+i*dwWidth*3]=y; lpYUV2[j*3+i*dwWidth*3+1]=u; lpYUV2[j*3+i*dwWidth*3+2]=v; } YuvToDib(); /* 表示用DIBピクセル列作成 */ InvalidateRgn(hwMain,NULL,FALSE); UpdateWindow (hwMain); /* 再描画 */ }