Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
4.3 KiB

  1. //---------------------------------------------------------------------------
  2. // blackrect.cpp - special code for debugging the infamous black rect
  3. // problem. not compiled; keep around until we fix this
  4. // problem.
  5. //---------------------------------------------------------------------------
  6. HRESULT CRenderObj::CreateBitmapFromData(HDC hdc, int iDibOffset, OUT HBITMAP *phBitmap)
  7. {
  8. RESOURCE HDC hdcTemp = NULL;
  9. RESOURCE HBITMAP hBitmap = NULL;
  10. HRESULT hr = S_OK;
  11. BYTE *pDibData = (BYTE *)(_pbThemeData + iDibOffset);
  12. BITMAPINFOHEADER *pBitmapHdr;
  13. pBitmapHdr = (BITMAPINFOHEADER *)pDibData;
  14. BOOL fAlphaChannel;
  15. fAlphaChannel = (pBitmapHdr->biBitCount == 32);
  16. if (! hdc)
  17. {
  18. hdcTemp = GetWindowDC(NULL);
  19. if (! hdcTemp)
  20. {
  21. Log(LOG_ERROR, L"GetWindowDC() failed in CreateBitmapFromData");
  22. hr = MakeErrorLast();
  23. goto exit;
  24. }
  25. hdc = hdcTemp;
  26. }
  27. //---- create the actual bitmap ----
  28. //---- if using alpha channel, we must use a DIB ----
  29. if (fAlphaChannel)
  30. {
  31. void *pv;
  32. hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)pBitmapHdr, DIB_RGB_COLORS,
  33. &pv, NULL, 0);
  34. //Log(LOG_TM, L"CreateDIBSection() returned hBitmap=0x%x, lasterr=0x%x", hBitmap, GetLastError());
  35. }
  36. else
  37. {
  38. hBitmap = CreateCompatibleBitmap(hdc, pBitmapHdr->biWidth, pBitmapHdr->biHeight);
  39. //Log(LOG_TM, L"CreateCompatibleBitmap() returned hBitmap=0x%x, lasterr=0x%x", hBitmap, GetLastError());
  40. }
  41. if (! hBitmap)
  42. {
  43. hr = MakeErrorLast();
  44. goto exit;
  45. }
  46. int iSetVal;
  47. #if 1
  48. //---- SetDIBits() can take unaligned data, right? ----
  49. iSetVal = SetDIBits(hdc, hBitmap, 0, pBitmapHdr->biHeight, DIBDATA(pBitmapHdr), (BITMAPINFO *)pBitmapHdr,
  50. DIB_RGB_COLORS);
  51. #else
  52. //---- ensure all is DWORD aligned for SetDIBits() call ----
  53. BITMAPINFOHEADER AlignedHdr;
  54. int iBytesPerPixel, iRawBytes, iBytesPerRow, iTotalBytes;
  55. BYTE *pbAlignedBits;
  56. iBytesPerPixel = pBitmapHdr->biBitCount/8; // bitcount will be 24 or 32
  57. iRawBytes = pBitmapHdr->biWidth * iBytesPerPixel;
  58. iBytesPerRow = 4*((iRawBytes+3)/4);
  59. iTotalBytes = pBitmapHdr->biHeight * iBytesPerRow;
  60. pbAlignedBits = new BYTE[iTotalBytes];
  61. if (! pbAlignedBits)
  62. {
  63. hr = E_OUTOFMEMORY;
  64. goto exit;
  65. }
  66. memcpy(pbAlignedBits, DIBDATA(pBitmapHdr), iTotalBytes);
  67. AlignedHdr = *pBitmapHdr;
  68. Log(LOG_TM, L"Calling SetDIBits() with BITMAPINFOHEADER and bits DWORD aligned");
  69. iSetVal = SetDIBits(hdc, hBitmap, 0, AlignedHdr.biHeight, pbAlignedBits, (BITMAPINFO *)&AlignedHdr,
  70. DIB_RGB_COLORS);
  71. delete [] pbAlignedBits;
  72. #endif
  73. //Log(LOG_TM, L"SetDIBits() returned iSetVal=%d, lasterr=0x%x", iSetVal, GetLastError());
  74. #if 0 // #ifdef LOGGING
  75. if ((pBitmapHdr->biWidth == 16) && (pBitmapHdr->biHeight == 16)) // problem bitmap we are debugging
  76. {
  77. const int len = 3*16*16;
  78. DWORD pbNewBits[16*16]; // aligned, quadwords (when we only use 3 bytes) to make GetDIBits() happy
  79. BITMAPINFOHEADER NewHdr = *pBitmapHdr;
  80. int iGetVal;
  81. iGetVal = GetDIBits(hdc, hBitmap, 0, pBitmapHdr->biHeight, pbNewBits, (LPBITMAPINFO)&NewHdr, DIB_RGB_COLORS);
  82. Log(LOG_TM, L"GetDIBits() returned iGetVal=%d, lasterr=0x%x", iGetVal, GetLastError());
  83. if (iGetVal)
  84. {
  85. BYTE *bOrig = DIBDATA(pBitmapHdr);
  86. BYTE *bNew = (BYTE *)pbNewBits;
  87. for (int b=0; b < len; b++)
  88. {
  89. if (*bOrig != *bNew)
  90. {
  91. Log(LOG_TM, L"old/new bitmap bytes do not match: offset=%d, bOrig=0x%x, bNew=0x%x",
  92. b, bOrig, bNew);
  93. DEBUG_BREAK;
  94. break;
  95. }
  96. bOrig++;
  97. bNew++;
  98. }
  99. }
  100. }
  101. #endif
  102. if (! iSetVal)
  103. {
  104. hr = MakeErrorLast();
  105. goto exit;
  106. }
  107. *phBitmap = hBitmap;
  108. exit:
  109. if (hdcTemp)
  110. ReleaseDC(NULL, hdcTemp);
  111. if (FAILED(hr))
  112. {
  113. if (hBitmap)
  114. DeleteObject(hBitmap);
  115. }
  116. return hr;
  117. }
  118. //---------------------------------------------------------------------------