A question about dib bitmap.

I want to display a 24b bitmap.
The class below work well at debug mode.
But it can not work at release mode. I can't see anything on view.
It can display 256 bitmap, but the result seems too strange(the color).
I think may be something wrong with the palette.
But I can't find it! Can you help me?
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Dib.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDib::CDib()
{
m_hBitmap = NULL;
m_lpBits = NULL;
m_hPalette = NULL;
m_lpColors = NULL;
m_nColorTableEntries = 0;
memset(&m_bi, 0, sizeof(m_bi));
}

CDib::~CDib()
{
Clear();
}

void CDib::Clear()
{
if (m_lpBits)
{
delete []m_lpBits;
m_lpBits = NULL;
}
if (m_lpColors)
{
delete []m_lpColors;
m_lpColors = NULL;
}
if (m_hBitmap)
{
::DeleteObject(m_hBitmap);
m_hBitmap = NULL;
}
if (m_hPalette)
{
::DeleteObject(m_hPalette);
m_hPalette = NULL;
}
memset(&m_bi, 0, sizeof(m_bi));
m_nColorTableEntries = 0;
}

int CDib::NumOfColorEntries(int nBitCount)
{
int nColors = 0;

switch(nBitCount)
{
case 1:
nColors = 2;
break;
case 4:
nColors = 16;
break;
case 8:
nColors = 256;
break;
case 16:
case 24:
case 32:
nColors = 0;
break;
default:
ASSERT(FALSE);
}

return nColors;
}

BOOL CDib::Load(LPCTSTR lpszFileName)
{
Clear();
CFile file;
if (!file.Open(lpszFileName, CFile::modeRead))
{
TRACE0("Failed to open bitmap file!\n");
return FALSE;
}

DWORD dwFileStart = file.GetPosition();

BITMAPFILEHEADER bfh;
int nBytes = file.Read(&bfh, sizeof(bfh));

if (nBytes != sizeof(bfh))
{
TRACE0("Failed to read bitmap file header!\n");
return FALSE;
}

if (bfh.bfType != 0x4d42)
{
TRACE0("It is not a bitmap file!\n");
return FALSE;
}

nBytes = file.Read(&m_bi, sizeof(m_bi));
if (nBytes != sizeof(m_bi))
{
TRACE0("Faile to read bitmap info!\n");
return FALSE;
}

if (m_bi.bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
{
TRACE0("It is not a Windows DIB\n");
return FALSE;
}

m_nColorTableEntries = NumOfColorEntries(m_bi.bmiHeader.biBitCount);
if (m_nColorTableEntries > 0)
{
int nColorTableSize = m_nColorTableEntries * sizeof(RGBQUAD);
m_lpColors = static_cast<LPBYTE>(new unsigned char[nColorTableSize]);
if (!m_lpColors)
{
TRACE0("Failed to allocate memory for color tables!");
return FALSE;
}
nBytes = file.Read(m_lpColors, nColorTableSize);
if (nBytes != nColorTableSize)
{
TRACE0("Failed to read color table\n");
return FALSE;
}
}

int nBitsSize = bfh.bfSize - bfh.bfOffBits;
m_lpBits = static_cast<LPBYTE>(new unsigned char[nBitsSize]);
if (!m_lpBits)
{
TRACE0("Failed to allocate momory for bits!");
return FALSE;
}

file.Seek(dwFileStart + bfh.bfOffBits, CFile::begin);

nBytes = file.Read(m_lpBits, nBitsSize);
if (nBytes != nBitsSize)
{
TRACE0("Failed to read bitmap bits!");
return FALSE;
}

CreatePalette();

return TRUE;
}

BOOL CDib::CreatePalette()
{
if (0 == m_nColorTableEntries)
{
return FALSE;
}
if (m_hPalette) ::DeleteObject(m_hPalette);
LPLOGPALETTE lplgpl;
lplgpl = reinterpret_cast<LPLOGPALETTE>(new char[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*(m_nColorTableEntries)]);
lplgpl->palVersion = 0x300;
lplgpl->palNumEntries = m_nColorTableEntries;
LPRGBQUAD lprq = reinterpret_cast<LPRGBQUAD>(m_lpColors);
for (int i = 0; i < m_nColorTableEntries; i++)
{
lplgpl->palPalEntry[i].peRed = lprq->rgbRed;
lplgpl->palPalEntry[i].peGreen = lprq->rgbGreen;
lplgpl->palPalEntry[i].peBlue = lprq->rgbBlue;
lplgpl->palPalEntry[i].peFlags = 0;
lprq++;
}
m_hPalette = ::CreatePalette(lplgpl);
delete []lplgpl;

return TRUE;
}

BOOL CDib::Draw(CDC *pDC, CPoint ptOrigin, CSize size)
{
if (!m_lpBits) return FALSE;
if (m_hPalette)
{
::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
::RealizePalette(pDC->GetSafeHdc());
}
pDC->SetStretchBltMode(COLORONCOLOR);
::StretchDIBits(pDC->GetSafeHdc(), ptOrigin.x, ptOrigin.y, size.cx, size.cy,
0, 0, m_bi.bmiHeader.biWidth, m_bi.bmiHeader.biHeight,
m_lpBits, &m_bi, DIB_RGB_COLORS, SRCCOPY);
return TRUE;
}
[5342 byte] By [Hydralisk] at [2007-11-18 17:45:31]
# 1 Re: A question about dib bitmap.
Hi,
Try to compile it in a Release mode with the Debug information.
But I think you simply did not release something, which is fine in Debug, but not in Release....

Thank you.
OneEyeMan at 2007-11-11 1:25:45 >
# 2 Re: A question about dib bitmap.
Thank you for your help!

I set the compile option at
"Project setting - C/C++" page to
Optimizations: Disable(Debug)
Debug info: Program Database
But the bitmap still can not display.

And I ouput the value of the parameter of StretchDIBits,
include ptOrgin, size, m_bi's all member. The debug version
and the release version output the same value...
Hydralisk at 2007-11-11 1:26:50 >
# 3 Re: A question about dib bitmap.
Hi, hydralisk,
Did you free all memory and resources you suppose to free?

Thank you.
OneEyeMan at 2007-11-11 1:27:49 >
# 4 Re: A question about dib bitmap.
In member function Clear(), I think I had free all the memory allocate before. And set the member variable to it's initial value.
And I invoke Clear() at the start of the member function Load().
Hydralisk at 2007-11-11 1:28:46 >
# 5 Re: A question about dib bitmap.
Hi, hydralisk,
That's not what I meant. During drawing did you releasing all resources from DC, that supposed to be released? Same goes with memory...

Thank you.
OneEyeMan at 2007-11-11 1:29:45 >
# 6 Re: A question about dib bitmap.
I find the bimap file which I use to do test had a big mistake. It was made by other application. It's bfSize of BITMAPFILEHEADER suggest the size of the bits, not the size of the bitmap file!
Now I use function SizeOfBits to get the actual size of bits.
DWORD CDib2::SizeOfBits()
{
DWORD dwBytes = ((DWORD) m_bi.bmiHeader.biWidth * m_bi.bmiHeader.biBitCount) / 32;
if(((DWORD) m_bi.bmiHeader.biWidth * m_bi.bmiHeader.biBitCount) % 32) {
dwBytes++;
}
dwBytes *= 4;
dwBytes = dwBytes * m_bi.bmiHeader.biHeight; // no compression
return dwBytes;
}

But I was confused by the result: It can display the wrong bitamp file at debug mode,Why @_@?
Hydralisk at 2007-11-11 1:30:44 >