📄 cqoctree.cpp
字号:
// CqOctree.cpp: implementation of the CCqOctree class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "QuickImage.h"
#include "CqOctree.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// 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* pNode;
UINT nRedSum, nGreenSum, nBlueSum, nChildren;
// Find the deepest level containing at least one reducible node
for (i=nColorBits - 1; (i>0) && (pReducibleNodes[i] == NULL); i--);
// Reduce the node most recently added to the list at level i
pNode = pReducibleNodes[i];
pReducibleNodes[i] = pNode->pNext;
nRedSum = nGreenSum = nBlueSum = nChildren = 0;
for (i=0; i<8; i++) {
if (pNode->pChild[i] != NULL) {
nRedSum += pNode->pChild[i]->nRedSum;
nGreenSum += pNode->pChild[i]->nGreenSum;
nBlueSum += pNode->pChild[i]->nBlueSum;
pNode->nPixelCount += pNode->pChild[i]->nPixelCount;
HeapFree (GetProcessHeap (), 0, pNode->pChild[i]);
pNode->pChild[i] = NULL;
nChildren++;
}
}
pNode->bIsLeaf = TRUE;
pNode->nRedSum = nRedSum;
pNode->nGreenSum = nGreenSum;
pNode->nBlueSum = nBlueSum;
*pLeafCount -= (nChildren - 1);
}
// local function to delete a node of octree
void DeleteTree (NODE** ppNode)
{
int i;
for (i=0; i<8; i++) {
if ((*ppNode)->pChild[i] != NULL)
DeleteTree (&((*ppNode)->pChild[i]));
}
HeapFree (GetProcessHeap (), 0, *ppNode);
*ppNode = NULL;
}
// local function to get color entry from a palette
void GetPaletteColors (NODE* pTree, PALETTEENTRY* pPalEntries, UINT* pIndex)
{
int i;
if (pTree->bIsLeaf) {
pPalEntries[*pIndex].peRed =
(BYTE) ((pTree->nRedSum) / (pTree->nPixelCount));
pPalEntries[*pIndex].peGreen =
(BYTE) ((pTree->nGreenSum) / (pTree->nPixelCount));
pPalEntries[*pIndex].peBlue =
(BYTE) ((pTree->nBlueSum) / (pTree->nPixelCount));
(*pIndex)++;
}
else {
for (i=0; i<8; i++) {
if (pTree->pChild[i] != NULL)
GetPaletteColors (pTree->pChild[i], pPalEntries, pIndex);
}
}
}
// local function to get pixel count
int GetRightShiftCount (DWORD dwVal)
{
int i;
for (i=0; i<sizeof (DWORD) * 8; i++) {
if (dwVal & 1)
return i;
dwVal >>= 1;
}
return -1;
}
// local function to get pixel count
int GetLeftShiftCount (DWORD dwVal)
{
int nCount, i;
nCount = 0;
for (i=0; i<sizeof (DWORD) * 8; i++) {
if (dwVal & 1)
nCount++;
dwVal >>= 1;
}
return (8 - nCount);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -