ここでは無圧縮ビットマップの読み方について説明をしたいと思います 読み込みでちょっと面倒臭いところではBITMAPFILEHEADERのあとの情報には BITMAPINFOHEADER または BITMAPCOREHEADER の2種類があるということです これはBITMAPFILEHEADERのすぐ後の先頭アドレスに構造体のサイズがあるので それによってBITMAPINFOHEADERかBITMAPCOREHEADERかを決めます。 またBITMAPINFOHEADER(またはBITMAPCOREHEADER)のあとには色のパレット情報が ありますが24ビットと32ビットの画像にはこの情報が存在しないので気をつけてください 先頭アドレスから順に BITMAPFILEHEADER BITMAPINFOHEADER(またはBITMAPCOREHEADER) RGBテーブル(24bit または 32bitの画像には存在しない) BITDATA といったふうになります 読み込み関数は以下のとおりです そのまま使用すればできると思います(多分) BOOL LoadingBitmap(LPSTR BitmapFileName,LPBITMAPINFO * LoadBitmapInfo,LPSTR * LoadBitmapBitData) //LPSTR BitmapFileName ファイル名 //LPBITMAPINFO * LoadBitmapInfo BITMAPINFOへのポインターのポインタ //LPSTR * LoadBitmapBitData BITMAPのビットデータ { //名前のチェック //ファイルを開く HANDLE LoadBitmapHandle; LPSTR ReadBuffer; LoadBitmapHandle=CreateFile(BitmapFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(LoadBitmapHandle==INVALID_HANDLE_VALUE) return false; //ファイルサイズの確保 DWORD BitmapFileSize=GetFileSize(LoadBitmapHandle,NULL); //Headerよりも大きいかチェック if(BitmapFileSize<=(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER))) { CloseHandle(LoadBitmapHandle); return false; } DWORD CanReadSize; //BITMAPFILEHEADERの読み込み BITMAPFILEHEADER LoadBitmapHeader; ReadBuffer=(LPSTR)(&LoadBitmapHeader); if(!ReadFile(LoadBitmapHandle,ReadBuffer,sizeof(BITMAPFILEHEADER),&CanReadSize,0)) { CloseHandle(LoadBitmapHandle); return false; } DWORD CheckInfoHeaderSize; ReadBuffer=(LPSTR)(&CheckInfoHeaderSize); if(!ReadFile(LoadBitmapHandle,ReadBuffer,sizeof(DWORD),&CanReadSize,0)) { CloseHandle(LoadBitmapHandle); return false; } if(SetFilePointer(LoadBitmapHandle,sizeof(BITMAPFILEHEADER),0,FILE_BEGIN)==0xFFFFFFFF) { CloseHandle(LoadBitmapHandle); return false; } BITMAPINFOHEADER LoadBitmapInfoHeader; BITMAPCOREHEADER LoadBitmapCoreHeader; INT ReadCoreHeaderFlag=0; switch(CheckInfoHeaderSize) { case sizeof(BITMAPINFOHEADER): ReadBuffer=(LPSTR)(&LoadBitmapInfoHeader); if(!ReadFile(LoadBitmapHandle,ReadBuffer,sizeof(BITMAPINFOHEADER),&CanReadSize,0)) { CloseHandle(LoadBitmapHandle); return false; } break; case sizeof(BITMAPCOREHEADER): //BITMAPINFOHEADERの初期化をしておく memset(&LoadBitmapInfoHeader,0,sizeof(BITMAPINFOHEADER)); ReadBuffer=(LPSTR)(&LoadBitmapCoreHeader); if(!ReadFile(LoadBitmapHandle,ReadBuffer,sizeof(BITMAPCOREHEADER),&CanReadSize,0)) { CloseHandle(LoadBitmapHandle); return false; } LoadBitmapInfoHeader.biSize=sizeof(BITMAPINFOHEADER); LoadBitmapInfoHeader.biWidth=LoadBitmapCoreHeader.bcWidth; LoadBitmapInfoHeader.biHeight=LoadBitmapCoreHeader.bcHeight; LoadBitmapInfoHeader.biPlanes=LoadBitmapCoreHeader.bcPlanes; LoadBitmapInfoHeader.biBitCount=LoadBitmapCoreHeader.bcBitCount; LoadBitmapInfoHeader.biCompression=BI_RGB; ReadCoreHeaderFlag=1; break; default: CloseHandle(LoadBitmapHandle); return false; } //BITMAPINFOHEADERの読み込み INT ErrorFlag=0; DWORD RGBColorSize; LONG SumColor; switch(LoadBitmapInfoHeader.biBitCount) { case 1: RGBColorSize=sizeof(RGBQUAD)*2; SumColor=2; break; case 4: RGBColorSize=sizeof(RGBQUAD)*16; SumColor=16; break; case 8: RGBColorSize=sizeof(RGBQUAD)*256; SumColor=256; break; case 16: RGBColorSize=sizeof(RGBQUAD)*65536; SumColor=65536; break; case 24: case 32: RGBColorSize=0; SumColor=0; break; default: ErrorFlag=1; } //BITMAPFILEHEADERの整合性のチェック //FileHeader部分が"BM"になっているかを調べる if(LoadBitmapHeader.bfType!=*(WORD *)"BM") ErrorFlag=1; if(LoadBitmapHeader.bfSize>BitmapFileSize) ErrorFlag=1; if(LoadBitmapHeader.bfOffBits>BitmapFileSize) ErrorFlag=1; if(!ReadCoreHeaderFlag) { if(LoadBitmapHeader.bfOffBits< (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+RGBColorSize)) ErrorFlag=1; } else { if(LoadBitmapHeader.bfOffBits< (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPCOREHEADER)+(RGBColorSize*sizeof(RGBTRIPLE))/sizeof(RGBQUAD))) ErrorFlag=1; } //BITMAPINFOHEADERの整合性のチェック switch(LoadBitmapInfoHeader.biCompression) { case BI_RGB : case BI_RLE8: case BI_RLE4: case BI_BITFIELDS: break; default: ErrorFlag=1; } if(LoadBitmapInfoHeader.biSizeImage>BitmapFileSize) ErrorFlag=1; if(ErrorFlag) { CloseHandle(LoadBitmapHandle); return false; } //ビットマップの情報の確保 if(*LoadBitmapInfo) LocalFreePtr(*LoadBitmapInfo); *LoadBitmapInfo=(BITMAPINFO *)LocalAllocPtr(LMEM_MOVEABLE|LMEM_ZEROINIT,sizeof(BITMAPINFO)+RGBColorSize); if(!(*LoadBitmapInfo)) { CloseHandle(LoadBitmapHandle); return false; } memcpy(&((*LoadBitmapInfo)->bmiHeader),&LoadBitmapInfoHeader,sizeof(BITMAPINFOHEADER)); //Pallet Dataを確保する if(!ReadCoreHeaderFlag) { if(SetFilePointer(LoadBitmapHandle,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),0,FILE_BEGIN)==0xffffffff) { LocalFreePtr(*LoadBitmapInfo); *LoadBitmapInfo=NULL; CloseHandle(LoadBitmapHandle); return false; } } else { if(SetFilePointer(LoadBitmapHandle,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPCOREHEADER),0,FILE_BEGIN)==0xffffffff) { LocalFreePtr(*LoadBitmapInfo); *LoadBitmapInfo=NULL; CloseHandle(LoadBitmapHandle); return false; } } if(RGBColorSize!=0) { if(!ReadCoreHeaderFlag) { //やや強引にデータ領域をとる ReadBuffer=(LPSTR)(*LoadBitmapInfo)->bmiColors; if(!ReadFile(LoadBitmapHandle,ReadBuffer,RGBColorSize,&CanReadSize,0)) { LocalFreePtr(*LoadBitmapInfo); *LoadBitmapInfo=NULL; CloseHandle(LoadBitmapHandle); return false; } } else { //やや強引にデータ領域をとる ReadBuffer=(LPSTR)(*LoadBitmapInfo)->bmiColors; for(LONG Counter=0;CounterbmiColors[0].rgbBlue; (*LoadBitmapInfo)->bmiColors[0].rgbGreen; (*LoadBitmapInfo)->bmiColors[0].rgbRed; (*LoadBitmapInfo)->bmiColors[0].rgbReserved; } //Bit Dataの確保 if(SetFilePointer(LoadBitmapHandle,LoadBitmapHeader.bfOffBits,NULL,FILE_BEGIN)==0xffffffff) { LocalFreePtr(*LoadBitmapInfo); *LoadBitmapInfo=NULL; CloseHandle(LoadBitmapHandle); return false; } if(*LoadBitmapBitData) LocalFreePtr(*LoadBitmapBitData); *LoadBitmapBitData=(LPSTR)LocalAllocPtr(LMEM_MOVEABLE|LMEM_ZEROINIT, BitmapFileSize-LoadBitmapHeader.bfOffBits); if(!(*LoadBitmapBitData)) { LocalFreePtr(*LoadBitmapInfo); *LoadBitmapInfo=NULL; CloseHandle(LoadBitmapHandle); return false; } if(!ReadFile(LoadBitmapHandle,*LoadBitmapBitData,BitmapFileSize-LoadBitmapHeader.bfOffBits,&CanReadSize,0)) { LocalFreePtr(*LoadBitmapInfo); *LoadBitmapInfo=NULL; CloseHandle(LoadBitmapHandle); GlobalFreePtr(*LoadBitmapBitData); *LoadBitmapBitData=NULL; return false; } CloseHandle(LoadBitmapHandle); return true; }