ASSERT(bitmap.GetSafeHandle());
// the function has no arg for bitfields
if( dwcompression == BI_BITFIELDS)
return NULL;
// if a palette has not been supplied use defaul palette
hpal = (HPALETTE) ppal->GetSafeHandle();
if (hpal==NULL)
hpal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
// get bitmap information
bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
// compute the size of the infoheader and the color table
int ncolors = (1 << bi.biBitCount);
if( ncolors> 256 )
ncolors = 0;
dwlen = bi.biSize + ncolors * sizeof(RGBQUAD);
// we need a device context to get the dib from
hdc =::GetDC(NULL);
hpal = SelectPalette(hdc,hpal,FALSE);
RealizePalette(hdc);
// allocate enough memory to hold bitmapinfoheader and color table
hdib = GlobalAlloc(GMEM_FIXED,dwlen);
if (!hdib)
{
SelectPalette(hdc,hpal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)hdib;
*lpbi = bi;
// call getdibits with a null lpbits param, so the device driver
// will calculate the bisizeimage field
GetDIBits(hdc, (HBITMAP )bitmap.GetSafeHandle(),0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
// if the driver did not fill in the bisizeimage field, then compute it
// each scan line of the image is aligned on a dword (32bit) boundary
if (bi.biSizeImage == 0)
{
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
// if a compression scheme is used the result may infact be larger
// increase the size to account for this.
if (dwcompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
// realloc the buffer so that it can hold all the bits
dwlen += bi.biSizeImage;
if (handle = GlobalReAlloc(hdib, dwlen, GMEM_MOVEABLE))
hdib = handle;
else
{
GlobalFree(hdib);
// reselect the original palette
SelectPalette(hdc,hpal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
}
// get the bitmap bits
lpbi = (LPBITMAPINFOHEADER)hdib;
// finally get the dib
int bgotbits =GetDIBits( hdc, (HBITMAP )bitmap.GetSafeHandle(),
0L, // start scan line
(DWORD)bi.biHeight, // # of scan lines
(LPBYTE)lpbi // address for bitmap bits
+ (bi.biSize + ncolors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, // address of bitmapinfo
(DWORD)DIB_RGB_COLORS); // use rgb for color table