モノクロ(C版)
effect.c
// // effect.c // // (c)Copyright Spacesoft corp., 2007 All rights reserved. // Hiro KITAYAMA // #include <windows.h>
//--------------------------------------------------------------------------- // // エフェクト // void effect( LPBYTE pInSrc, LPBYTE pInDst, LONG width, LONG height ) { int x, y ; float mono; LPBYTE pSrc=pInSrc ; LPBYTE pDst=pInDst ;
for( y = 0 ; y < height ; y++ ) for( x = 0 ; x < width ; x++ ) { mono = (float)*pSrc * 0.114478f; // B pSrc++; mono+= (float)*pSrc * 0.586611f; // G pSrc++; mono+= (float)*pSrc * 0.298912f; // R pSrc++; pSrc++;
*pDst = (BYTE)mono; pDst++; *pDst = (BYTE)mono; pDst++; *pDst = (BYTE)mono; pDst++; pDst++;
//*pDst++ = (BYTE)((float)*pSrc++ * 0.114478f // B //+ (float)*pSrc++ * 0.586611f // G // + (float)*pSrc++ * 0.298912f); // R //*pDst++ = *(pDst-1); //*pDst++ = *(pDst-1); //pDst++; //pSrc++; } } |
pgm.c
// // pgm.c // // (c)Copyright Spacesoft corp., 2007 All rights reserved. // Hiro KITAYAMA // #include <stdio.h> #include <conio.h> // kbhit(), getch() #include <stdlib.h> // _splitpath() #include <windows.h>
#define SAFE_FREE( p ) if( p ) { free( p ) ; p=NULL ; } #define SZCLASSNAME "TEST"
// グローバル変数 PBITMAPINFOHEADER pDib ; // tolal LPBYTE pBitmap ; // data
void effect( LPBYTE pSrc, LPBYTE pDst, LONG width, LONG height );
//--------------------------------------------------------------------------- // // ファイル名の取得 // BOOL getFname( char* inFname ) { OPENFILENAME fName ; char fileName[256] ; const char filefilter[] = "BMPファイル(*.bmp)\0*.bmp\0\0" ;
fileName[0] = '\0' ;
memset( &fName, 0, sizeof(OPENFILENAME) ) ; fName.lStructSize = sizeof(OPENFILENAME) ; fName.lpstrFilter = filefilter ; fName.nFilterIndex = 1 ; fName.lpstrFile = fileName ; fName.nMaxFile = sizeof(fileName) ; fName.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY ;
// 「ファイルを開く」ダイアログ if( GetOpenFileName( &fName ) == 0 ) return FALSE ;
strcpy( inFname, fileName ) ;
return TRUE ; }
//--------------------------------------------------------------------------- // // ビットッマプヘッダの読み込み // BOOL readHeader( FILE* fp, PBITMAPFILEHEADER bmHdr ) { // ビットッマプヘッダの読み込み if( fread( bmHdr, sizeof(BITMAPFILEHEADER), 1, fp ) != 1 ) { fprintf( stderr, "エラー:ファイル読み込み.\n" ) ; return FALSE ; }
// ビットッマプファイルかチェック if ( bmHdr -> bfType != 'M'*256+'B' ) { fprintf( stderr, "エラー:BMPフォーマットでは無い.\n" ); return FALSE ; } return TRUE ; }
//--------------------------------------------------------------------------- // // ビットッマプ本体の読み込み // BOOL readBody( FILE* fp, PBITMAPFILEHEADER bmHdr, PBITMAPINFOHEADER pDib ) { int bitmapSize ;
bitmapSize = bmHdr -> bfSize - sizeof(BITMAPFILEHEADER) ; // 画像の大きさ
// ビットッマプ本体の読み込み if( fread( pDib , bitmapSize, 1, fp ) != 1 ) { fprintf( stderr, "エラー:ファイル読み込み.\n" ) ; return FALSE ; } if( pDib -> biBitCount != 32 ) { fprintf( stderr, "エラー:32ビット ビットッマプではない.\n"); return FALSE ; } return TRUE ; }
//--------------------------------------------------------------------------- // // window procedure // LRESULT CALLBACK WindProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam ) { PAINTSTRUCT ps ;
switch( uMessage ) { case WM_PAINT: BeginPaint( hWnd, &ps ) ; SetDIBitsToDevice( ps.hdc, 0, 0, // copy BMP pDib -> biWidth, pDib -> biHeight, 0, 0, 0, pDib -> biHeight, pBitmap, (BITMAPINFO*)pDib, DIB_RGB_COLORS ) ; EndPaint( hWnd, &ps ) ; break ;
case WM_DESTROY: PostQuitMessage( 0 ) ; break ;
default: return DefWindowProc( hWnd, uMessage, wParam, lParam ) ; } return 0 ; }
//--------------------------------------------------------------------------- // // create window // HWND createWindow( PBITMAPINFOHEADER pDib ) { HINSTANCE hInstanse ; WNDCLASSEX wcx ; HWND hWnd = NULL ; int ttlHeight, frameWidth, frameHeight ; int windowWidth, windowHeight ;
hInstanse = (HINSTANCE)GetWindowLong( NULL, GWL_HINSTANCE ) ;
memset( &wcx, 0, sizeof(WNDCLASSEX) ) ; wcx.cbSize = sizeof(WNDCLASSEX) ; wcx.lpfnWndProc = WindProc ; // ウィンドウプロシージャ wcx.hInstance = hInstanse ; wcx.hCursor = LoadCursor( NULL, IDC_ARROW ) ; wcx.lpszClassName = SZCLASSNAME ; // ウィンドウクラス名 if( !RegisterClassEx( &wcx ) ) // ウィンドウクラスの登録 return NULL ; // 失敗
ttlHeight = GetSystemMetrics( SM_CYCAPTION ) ; // ウィンドウタイトルの高さ frameWidth = GetSystemMetrics( SM_CXFIXEDFRAME ) ; // ウィンドウフレームの幅 frameHeight = GetSystemMetrics( SM_CYFIXEDFRAME ) ; // ウィンドウフレームの高さ
windowWidth = pDib -> biWidth + (frameWidth * 2), // ウィンドウの幅 windowHeight= pDib -> biHeight + ttlHeight + (frameHeight * 2) ; // ウィンドウの高さ
hWnd = CreateWindow( SZCLASSNAME, // ウィンドウクラス名 "表示ウィンドウ", // ウィンドウタイトル WS_OVERLAPPED | WS_SYSMENU | WS_VISIBLE,// ウィンドウスタイル CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウ位置 windowWidth,windowHeight, // ウィンドウサイズ HWND_DESKTOP, NULL, hInstanse, NULL ) ;
return hWnd ; }
//--------------------------------------------------------------------------- // // main // int main( int argc, char* argv[] ) { char fName[_MAX_PATH], dfFile[_MAX_PATH], dfName[_MAX_FNAME], dfExt[_MAX_EXT ] ; BITMAPFILEHEADER bmHdr ; FILE* fp ; HWND hWnd ; MSG msg ; int bitmapSize, loop, imgSize ; LPBYTE pSrc, pDst ; // SIMD用バッファ UINT64 begin, finish, elapsed ; // 性能表示
if( argc < 2 ) getFname( fName ) ; // 引数なし else strcpy( fName, argv[1] ) ; // 引数あり
// ビットマップファイルのオープン if( (fp = fopen( fName, "rb" )) == NULL ) { fprintf( stderr, "エラー:ファイルのオープンに失敗.\n" ) ; return -1; }
// ファイル名の表示 _splitpath( fName, NULL, NULL, dfName, dfExt ) ; strcpy( dfFile, dfName ) ; strcat( dfFile, dfExt ) ; fprintf( stdout, "ファイル名 = [%s]\n", dfFile ) ;
// ヘッダの読み込み if( !readHeader( fp, &bmHdr ) ) { fclose( fp ) ; // ファイルクローズ return -1; }
// ビットマップ本体のサイズ bitmapSize = bmHdr.bfSize - sizeof(BITMAPFILEHEADER) ;
// メモリ確保 pDib = (BITMAPINFOHEADER *)malloc( bitmapSize ) ;
// 本体読み込み if( !readBody( fp, &bmHdr, pDib ) ) { SAFE_FREE( pDib ) ; // メモリ解放 fclose( fp ) ; // ファイルクローズ return -1; }
fclose( fp ) ; // ファイルクローズ
// 画像サイズの表示 fprintf( stdout, "ビットマップサイズ= %d x %d\n", pDib -> biWidth, pDib -> biHeight ) ;
// ポインタをビットマップ本体位置へ移動 pBitmap = (BYTE *)(pDib) + bmHdr.bfOffBits - sizeof(BITMAPFILEHEADER) ;
imgSize=pDib->biWidth * pDib->biHeight * 4;
// alignされたメモリを確保 pSrc = (LPBYTE)_aligned_malloc(imgSize, 16); pDst = (LPBYTE)_aligned_malloc(imgSize, 16);
// alignされたエリアにコピー memcpy(pSrc, pBitmap, imgSize);
_asm { rdtsc mov dword ptr [begin], eax mov dword ptr [begin+4], edx }
//画像処理 for(loop=0;loop<100;loop++) //キャッシュなどの影響を排除するため100回実行 effect( pSrc, pDst, pDib -> biWidth, pDib -> biHeight ) ;
_asm { rdtsc mov dword ptr [finish], eax mov dword ptr [finish+4], edx } elapsed = finish > begin ? finish - begin : begin - finish ; printf( "counter= %I64u\n", elapsed ) ;
// alignされたエリアからbitmapへコピー memcpy(pBitmap, pDst, imgSize);
hWnd = createWindow( pDib ) ; // ウィンドウ表示
fprintf( stdout, "Enterキーを押せば終わります..." ) ;
// メッセージループ msg.message = WM_CREATE ; // dummy for while while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ) ; DispatchMessage( &msg ) ; }
// Enterキーを押されたらQuit if( kbhit() ) { PostMessage( hWnd, (UINT)WM_DESTROY, (UINT)0, (LONG)0 ) ; getch() ; } }
SAFE_FREE( pDib ) ; // メモリ解放 _aligned_free(pSrc); // メモリ解放 _aligned_free(pDst); // メモリ解放
return 0; } |