【VC开源代码栏目提醒】:网学会员为广大网友收集整理了,CreatePal.cpp,希望对大家有所帮助!
/******************************************************************
CreatePal.cpp
Performing Color Quantization algorithm
******************************************************************/
#include "stdafx.h"
#ifndef _CREATEPAL_C
#define _CREATEPAL_C
typedef struct _NODE
{
BOOL bIsLeaf; // TRUE if node has no children
UINT nPixelCount; // Number of pixels represented by this leaf
UINT nRedSum; // Sum of red components
UINT nGreenSum; // Sum of green components
UINT nBlueSum; // Sum of blue components
struct _NODE* pChild[8]; // Pointers to child nodes
struct _NODE* pNext; // Pointer to next reducible node
} NODE;
void AddColor (NODE**, BYTE, BYTE, BYTE, UINT, UINT, UINT*, NODE**);
NODE* CreateNode (UINT, UINT, UINT*, NODE**);
void ReduceTree (UINT, UINT*, NODE**);
void DeleteTree (NODE**);
void GetPaletteColors (NODE*, RGBQUAD*, UINT*);
void TrueColorToIndex(CImage *pImg0,CImage *pImg1)
{
struct IMAGEPARAMENT P;
CImage gpImg;
RGBQUAD ColorTab[256];
HDC hMemDC;
GetImageParament(pImg1,&P);
gpImg.Create(P.nWidth,P.nHeight,8,0);
Create8TreePal(pImg1,ColorTab,256,8);
SetAllPalette(&gpImg,ColorTab);
hMemDC = gpImg.GetDC();
pImg1->BitBlt(hMemDC,0,0,P.nWidth,P.nHeight,0,0,SRCCOPY);
gpImg.ReleaseDC();
ImageCopy(pImg0,&gpImg);
gpImg.Destroy();
}
// local function to build optimal palette from CImage
void Create8TreePal(CImage *pImg,RGBQUAD *Pal, UINT nMaxColors, UINT nColorBits)
{
struct IMAGEPARAMENT P;
int i, j;
BYTE *pbBits;
BYTE r, g, b;
NODE *pTree;
UINT nLeafCount,nIndex;
NODE *pReducibleNodes[9];
GetImageParament(pImg,&P);
// Initialize octree variables
pTree = NULL;
nLeafCount = 0;
for (i=0; i<=(int) nColorBits; i++) pReducibleNodes[i] = NULL;
for (i=0; i<P.nHeight; i++) {
pbBits = (BYTE*) pImg->GetPixelAddress(0,i);
for (j=0; j<P.nWidth; j++) {
b = *pbBits++;
g = *pbBits++;
r = *pbBits++;
if (P.nBitCount==32) pbBits++;
AddColor (&pTree, r, g, b, nColorBits, 0, &nLeafCount,
pReducibleNodes);
while (nLeafCount > nMaxColors)
ReduceTree (nColorBits, &nLeafCount, pReducibleNodes);
}
}
nIndex = 0;
GetPaletteColors (pTree, Pal, &nIndex);
DeleteTree (&pTree);
}
// local function to add a color to octree
void AddColor (NODE** ppNode, BYTE r, BYTE g, BYTE b, UINT nColorBits,
UINT nLevel, UINT* pLeafCount, NODE** pReducibleNodes)
{
int nIndex, shift;
static BYTE mask[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
// If the node doesn't exist, create it
if (*ppNode == NULL)
*ppNode = CreateNode (nLevel, nColorBits, pLeafCount,
pReducibleNodes);
// Update color information if it's a leaf node
if ((*ppNode)->bIsLeaf) {
(*ppNode)->nPixelCount++;
(*ppNode)->nRedSum += r;
(*ppNode)->nGreenSum += g;
(*ppNode)->nBlueSum += b;
}
// Recurse a level deeper if the node is not a leaf
else {
shift = 7 - nLevel;
nIndex = (((r & mask[nLevel]) >> shift) << 2) |
(((g & mask[nLevel]) >> shift) << 1) |
((b & mask[nLevel]) >> shift);
AddColor (&((*ppNode)->pChild[nIndex]), r, g, b, nColorBits,
nLevel + 1, pLeafCount, pReducibleNodes);
}
}
// local function to create a new node in octree
NODE* CreateNode (UINT nLevel, UINT nColorBits, UINT* pLeafCount,
NODE** pReducibleNodes)
{
NODE* pNode;
if ((pNode = (NODE*) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
sizeof (NODE))) == NULL)
return NULL;
pNode->bIsLeaf = (nLevel == nColorBits) ? TRUE : FALSE;
if (pNode->bIsLeaf) (*pLeafCount)++;
else { // Add the node to the reducible list for this level
pNode->pNext = pReducibleNodes[nLevel];
pReducibleNodes[nLevel] = pNode;
}
return pNode;
}
// local function to reduce the nodes of octree
void ReduceTree (UINT nColorBits, UINT* pLeafCount, NODE** pReducibleNodes)
{
int i;
NODE* p