A question about dib 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;
}

