CqOctree.cpp
上传用户:gzboli
上传日期:2013-04-10
资源大小:471k
文件大小:5k
源码类别:

图片显示

开发平台:

Visual C++

  1. // CqOctree.cpp: implementation of the CCqOctree class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "QuickImage.h"
  6. #include "CqOctree.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. // local function to add a color to octree
  16. void AddColor (NODE** ppNode, BYTE r, BYTE g, BYTE b, UINT nColorBits,
  17.     UINT nLevel, UINT* pLeafCount, NODE** pReducibleNodes)
  18. {
  19.     int nIndex, shift;
  20.     static BYTE mask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  21.     // If the node doesn't exist, create it
  22.     if (*ppNode == NULL)
  23.         *ppNode = CreateNode (nLevel, nColorBits, pLeafCount,
  24.                               pReducibleNodes);
  25.     // Update color information if it's a leaf node
  26.     if ((*ppNode)->bIsLeaf) {
  27.         (*ppNode)->nPixelCount++;
  28.         (*ppNode)->nRedSum += r;
  29.         (*ppNode)->nGreenSum += g;
  30.         (*ppNode)->nBlueSum += b;
  31.     }
  32.     // Recurse a level deeper if the node is not a leaf
  33.     else {
  34.         shift = 7 - nLevel;
  35.         nIndex = (((r & mask[nLevel]) >> shift) << 2) |
  36.             (((g & mask[nLevel]) >> shift) << 1) |
  37.             ((b & mask[nLevel]) >> shift);
  38.         AddColor (&((*ppNode)->pChild[nIndex]), r, g, b, nColorBits,
  39.                   nLevel + 1, pLeafCount, pReducibleNodes);
  40.     }
  41. }
  42. // local function to create a new node in octree
  43. NODE* CreateNode (UINT nLevel, UINT nColorBits, UINT* pLeafCount,
  44.                   NODE** pReducibleNodes)
  45. {
  46.     NODE* pNode;
  47.     if ((pNode = (NODE*) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
  48.         sizeof (NODE))) == NULL)
  49.         return NULL;
  50.     pNode->bIsLeaf = (nLevel == nColorBits) ? TRUE : FALSE;
  51.     if (pNode->bIsLeaf)
  52.         (*pLeafCount)++;
  53.     else { // Add the node to the reducible list for this level
  54.         pNode->pNext = pReducibleNodes[nLevel];
  55.         pReducibleNodes[nLevel] = pNode;
  56.     }
  57.     return pNode;
  58. }
  59. // local function to reduce the nodes of octree
  60. void ReduceTree (UINT nColorBits, UINT* pLeafCount, NODE** pReducibleNodes)
  61. {
  62.     int i;
  63.     NODE* pNode;
  64.     UINT nRedSum, nGreenSum, nBlueSum, nChildren;
  65.     // Find the deepest level containing at least one reducible node
  66.     for (i=nColorBits - 1; (i>0) && (pReducibleNodes[i] == NULL); i--);
  67.     // Reduce the node most recently added to the list at level i
  68.     pNode = pReducibleNodes[i];
  69.     pReducibleNodes[i] = pNode->pNext;
  70.     nRedSum = nGreenSum = nBlueSum = nChildren = 0;
  71.     for (i=0; i<8; i++) {
  72.         if (pNode->pChild[i] != NULL) {
  73.             nRedSum += pNode->pChild[i]->nRedSum;
  74.             nGreenSum += pNode->pChild[i]->nGreenSum;
  75.             nBlueSum += pNode->pChild[i]->nBlueSum;
  76.             pNode->nPixelCount += pNode->pChild[i]->nPixelCount;
  77.             HeapFree (GetProcessHeap (), 0, pNode->pChild[i]);
  78.             pNode->pChild[i] = NULL;
  79.             nChildren++;
  80.         }
  81.     }
  82.     pNode->bIsLeaf = TRUE;
  83.     pNode->nRedSum = nRedSum;
  84.     pNode->nGreenSum = nGreenSum;
  85.     pNode->nBlueSum = nBlueSum;
  86.     *pLeafCount -= (nChildren - 1);
  87. }
  88. // local function to delete a node of octree
  89. void DeleteTree (NODE** ppNode)
  90. {
  91.     int i;
  92.     for (i=0; i<8; i++) {
  93.         if ((*ppNode)->pChild[i] != NULL)
  94.             DeleteTree (&((*ppNode)->pChild[i]));
  95.     }
  96.     HeapFree (GetProcessHeap (), 0, *ppNode);
  97.     *ppNode = NULL;
  98. }
  99. // local function to get color entry from a palette
  100. void GetPaletteColors (NODE* pTree, PALETTEENTRY* pPalEntries, UINT* pIndex)
  101. {
  102.     int i;
  103.     if (pTree->bIsLeaf) {
  104.         pPalEntries[*pIndex].peRed =
  105.             (BYTE) ((pTree->nRedSum) / (pTree->nPixelCount));
  106.         pPalEntries[*pIndex].peGreen =
  107.             (BYTE) ((pTree->nGreenSum) / (pTree->nPixelCount));
  108.         pPalEntries[*pIndex].peBlue =
  109.             (BYTE) ((pTree->nBlueSum) / (pTree->nPixelCount));
  110.         (*pIndex)++;
  111.     }
  112.     else {
  113.         for (i=0; i<8; i++) {
  114.             if (pTree->pChild[i] != NULL)
  115.                 GetPaletteColors (pTree->pChild[i], pPalEntries, pIndex);
  116.         }
  117.     }
  118. }
  119. // local function to get pixel count
  120. int GetRightShiftCount (DWORD dwVal)
  121. {
  122.     int i;
  123.     for (i=0; i<sizeof (DWORD) * 8; i++) {
  124.         if (dwVal & 1)
  125.             return i;
  126.         dwVal >>= 1;
  127.     }
  128.     return -1;
  129. }
  130. // local function to get pixel count
  131. int GetLeftShiftCount (DWORD dwVal)
  132. {
  133.     int nCount, i;
  134.     nCount = 0;
  135.     for (i=0; i<sizeof (DWORD) * 8; i++) {
  136.         if (dwVal & 1)
  137.             nCount++;
  138.         dwVal >>= 1;
  139.     }
  140.     return (8 - nCount);
  141. }