CqOctree.cpp
上传用户:gzboli
上传日期:2013-04-10
资源大小:471k
文件大小:5k
- // 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);
- }