bool
CImage::SetColorTable(const CImageColorTable& clrTbl, bool bRemap)
{
_ASSERT(m_hImage);
_ASSERT(BPP() == 8);
if (bRemap)
{
// go through all pixels and map to new or nearest color
unsigned int numColors = NumColorEntries();
// create palette of new color table, so we can use
// GetNearestPaletteIndex
CImagePalette newPal;
if (!newPal.CreatePalette(clrTbl))
return false;
// get the current color table
CImageColorTable oldClrTbl(numColors);
GetColorTable(oldClrTbl);
unsigned char* pPixel;
UINT newIndex;
// allocate as many structures as there are current colors
// MapIndex are used for quick lookup for color table
// entries that have already been converted to new ones by
// GetNearestPaletteIndex
MapIndexArray mp_array(numColors);
for (int y = 0;y < Height();y++)
{
pPixel =
static_cast<unsigned char*>(GetPixelAddress(0,y));
for (int x = 0;x < Width();x++,pPixel++)
{
_ASSERT(0 <= (*pPixel) && (*pPixel) < numColors);
if (false == mp_array[*pPixel].bMapped)
{
// color not mapped to new color table
mp_array[*pPixel].bMapped = true;
newIndex =
newPal.GetNearestPaletteIndex(
oldClrTbl.color(*pPixel));
if (CLR_INVALID == newIndex)
return false;
mp_array[*pPixel].newIndex =
static_cast<unsigned char>(newIndex);
}
// set pixel to new color
*pPixel = mp_array[*pPixel].newIndex;
}
}
}
// now all pixels are remapped to new colors,
// insert new color table
CImageDC memdc;
if (!memdc.CreateCompatibleDC())
return false;
memdc.SelectBitmap(m_hImage);
UINT result =
::SetDIBColorTable(memdc, 0, clrTbl.size(),
clrTbl.m_prgb);
SetNumColorEntries(clrTbl.size());
return result? true:false;
}
//End of File