|
|
//---------------------------------------------------------------------------
// blackrect.cpp - special code for debugging the infamous black rect
// problem. not compiled; keep around until we fix this
// problem.
//---------------------------------------------------------------------------
HRESULT CRenderObj::CreateBitmapFromData(HDC hdc, int iDibOffset, OUT HBITMAP *phBitmap) { RESOURCE HDC hdcTemp = NULL; RESOURCE HBITMAP hBitmap = NULL; HRESULT hr = S_OK;
BYTE *pDibData = (BYTE *)(_pbThemeData + iDibOffset); BITMAPINFOHEADER *pBitmapHdr; pBitmapHdr = (BITMAPINFOHEADER *)pDibData;
BOOL fAlphaChannel; fAlphaChannel = (pBitmapHdr->biBitCount == 32);
if (! hdc) { hdcTemp = GetWindowDC(NULL); if (! hdcTemp) { Log(LOG_ERROR, L"GetWindowDC() failed in CreateBitmapFromData"); hr = MakeErrorLast(); goto exit; }
hdc = hdcTemp; }
//---- create the actual bitmap ----
//---- if using alpha channel, we must use a DIB ----
if (fAlphaChannel) { void *pv; hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)pBitmapHdr, DIB_RGB_COLORS, &pv, NULL, 0);
//Log(LOG_TM, L"CreateDIBSection() returned hBitmap=0x%x, lasterr=0x%x", hBitmap, GetLastError());
} else { hBitmap = CreateCompatibleBitmap(hdc, pBitmapHdr->biWidth, pBitmapHdr->biHeight);
//Log(LOG_TM, L"CreateCompatibleBitmap() returned hBitmap=0x%x, lasterr=0x%x", hBitmap, GetLastError());
}
if (! hBitmap) { hr = MakeErrorLast(); goto exit; }
int iSetVal;
#if 1
//---- SetDIBits() can take unaligned data, right? ----
iSetVal = SetDIBits(hdc, hBitmap, 0, pBitmapHdr->biHeight, DIBDATA(pBitmapHdr), (BITMAPINFO *)pBitmapHdr, DIB_RGB_COLORS); #else
//---- ensure all is DWORD aligned for SetDIBits() call ----
BITMAPINFOHEADER AlignedHdr; int iBytesPerPixel, iRawBytes, iBytesPerRow, iTotalBytes; BYTE *pbAlignedBits;
iBytesPerPixel = pBitmapHdr->biBitCount/8; // bitcount will be 24 or 32
iRawBytes = pBitmapHdr->biWidth * iBytesPerPixel; iBytesPerRow = 4*((iRawBytes+3)/4); iTotalBytes = pBitmapHdr->biHeight * iBytesPerRow;
pbAlignedBits = new BYTE[iTotalBytes]; if (! pbAlignedBits) { hr = E_OUTOFMEMORY; goto exit; }
memcpy(pbAlignedBits, DIBDATA(pBitmapHdr), iTotalBytes);
AlignedHdr = *pBitmapHdr; Log(LOG_TM, L"Calling SetDIBits() with BITMAPINFOHEADER and bits DWORD aligned");
iSetVal = SetDIBits(hdc, hBitmap, 0, AlignedHdr.biHeight, pbAlignedBits, (BITMAPINFO *)&AlignedHdr, DIB_RGB_COLORS);
delete [] pbAlignedBits; #endif
//Log(LOG_TM, L"SetDIBits() returned iSetVal=%d, lasterr=0x%x", iSetVal, GetLastError());
#if 0 // #ifdef LOGGING
if ((pBitmapHdr->biWidth == 16) && (pBitmapHdr->biHeight == 16)) // problem bitmap we are debugging
{ const int len = 3*16*16; DWORD pbNewBits[16*16]; // aligned, quadwords (when we only use 3 bytes) to make GetDIBits() happy
BITMAPINFOHEADER NewHdr = *pBitmapHdr;
int iGetVal; iGetVal = GetDIBits(hdc, hBitmap, 0, pBitmapHdr->biHeight, pbNewBits, (LPBITMAPINFO)&NewHdr, DIB_RGB_COLORS);
Log(LOG_TM, L"GetDIBits() returned iGetVal=%d, lasterr=0x%x", iGetVal, GetLastError()); if (iGetVal) { BYTE *bOrig = DIBDATA(pBitmapHdr); BYTE *bNew = (BYTE *)pbNewBits;
for (int b=0; b < len; b++) { if (*bOrig != *bNew) { Log(LOG_TM, L"old/new bitmap bytes do not match: offset=%d, bOrig=0x%x, bNew=0x%x", b, bOrig, bNew); DEBUG_BREAK; break; } bOrig++; bNew++; } } } #endif
if (! iSetVal) { hr = MakeErrorLast(); goto exit; } *phBitmap = hBitmap;
exit: if (hdcTemp) ReleaseDC(NULL, hdcTemp);
if (FAILED(hr)) { if (hBitmap) DeleteObject(hBitmap); }
return hr; } //---------------------------------------------------------------------------
|