Monday, September 22, 2008

Create DIB section from a BMP file

// Creates a DIB section from a BMP file

//

// lpszFileName : Name of the BMP file

// ppvBits : Receive address of bitmap bits

// hSection : Optional handle to a file mapping object

// dwOffset : Offset to the bitmap bit values within hSection

//

HBITMAP LoadDIBSectionFromFile( LPCTSTR lpszFileName, LPVOID *ppvBits /*= NULL*/, HANDLE hSection /*= NULL*/, DWORD dwOffset /*= 0*/)

{

LPVOID lpBits;

CFile file;

if( !file.Open( lpszFileName, CFile::modeRead) )

return NULL;

BITMAPFILEHEADER bmfHeader;

long nFileLen;

nFileLen = file.GetLength();

// Read file header

if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))

{

return NULL;

}

// File type should be ‘BM’

int ch1 = ‘M’;

int ch2 = 8;

int leftshift = ch1 <<>

int ch = ‘B’;

if ( bmfHeader.bfType != (WORD) (leftshift | ch )

{

return NULL;

}

BITMAPINFO *pbmInfo;

pbmInfo = (BITMAPINFO *)::GlobalAlloc(GMEM_FIXED, sizeof(BITMAPINFO) + sizeof(RGBQUAD)*256 );

if (pbmInfo == NULL)

{

return NULL;

}

// Read the BITMAPINFO

file.Read( pbmInfo, sizeof(BITMAPINFO) + sizeof(RGBQUAD)*256 );

BITMAPINFO &bmInfo = *pbmInfo ;

HBITMAP hBmp = CreateDIBSection( NULL, pbmInfo, DIB_RGB_COLORS, &lpBits, hSection, dwOffset );

LPBYTE lpDIBBits; // Pointer to DIB bits

int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 1 <<>

if( bmInfo.bmiHeader.biBitCount > 8 )

{

lpDIBBits = (LPBYTE)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) + ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));

}

else

{

lpDIBBits = (LPBYTE)(bmInfo.bmiColors + nColors);

}

int nOffset = sizeof(BITMAPFILEHEADER) + (lpDIBBits - (LPBYTE)pbmInfo);

file.Seek( nOffset, CFile::begin);

file.ReadHuge((LPSTR)lpBits, nFileLen - nOffset); //bmInfo.biSizeImage );

::GlobalFree(pbmInfo);

if( ppvBits )

{

*ppvBits = lpBits;

}

return hBmp;

}

No comments: