#include WORD RGBTree::insertItems(Array &rgbItems) { size_t size((size_t)rgbItems.size()); short indexDescending; short indexAscending; if(!size)return FALSE; indexDescending=middleIndex(rgbItems); indexAscending=indexDescending+1; for(;indexDescending>=0;indexDescending--)insertItem(rgbItems[indexDescending]); for(;indexAscending &rgbItems)const { RGBColor middleItem(CenterColor,CenterColor,CenterColor); size_t size((size_t)rgbItems.size()); LONG minDistance(0xFFFFFFL); LONG tmpDistance; WORD centerIndex; for(short rgbIndex=0;rgbIndex *RGBTree::insertNode(TreeNode *lpRootNode,TreeNode *lpCurrentNode,const RGBIndex &rgbItem) { if(!lpCurrentNode) { lpCurrentNode=new TreeNode(rgbItem); assert(0!=lpCurrentNode); if(!lpRootNode)return lpCurrentNode; mColorKey.prevKey(); if(mColorKey.isLess(rgbItem,lpRootNode->item()))lpRootNode->leftNode(lpCurrentNode); else lpRootNode->rightNode(lpCurrentNode); return lpCurrentNode; } if(!(rgbItem==lpCurrentNode->item())) { if(mColorKey.isLess(rgbItem,lpCurrentNode->item())) { mColorKey.nextKey(); return insertNode(lpCurrentNode,lpCurrentNode->leftNode(),rgbItem); } else { mColorKey.nextKey(); return insertNode(lpCurrentNode,lpCurrentNode->rightNode(),rgbItem); } } return 0; } RGBIndex *RGBTree::searchNodeExact(TreeNode *lpRootNode,const RGBIndex &rgbItem) { while(lpRootNode&&!(rgbItem==lpRootNode->item())) { if(mColorKey.isLess(rgbItem,lpRootNode->item()))lpRootNode=lpRootNode->leftNode(); else lpRootNode=lpRootNode->rightNode(); mColorKey.nextKey(); } if(lpRootNode)return &lpRootNode->item(); return 0; } RGBIndex *RGBTree::searchNodeNearest(TreeNode *lpRootNode,const RGBIndex &rgbItem) { TreeNode *lpLastNode=0; TreeNode *lpTempNode; LONG minDistance(0xFFFFFFL); RGBIndex lowerRGB(rgbItem); RGBIndex upperRGB(rgbItem); RGBIndex *lpBestRGB=0; LONG tmpDistance; ColorKey colorKey; if(!lpRootNode)return 0; rewind(); lowerRGB-=mThreshold; upperRGB+=mThreshold; pushNode(TreeNodeEx(*lpRootNode,colorKey)); while(size()&&minDistance) { popNode(); lpTempNode=¤tNode(); if(lpLastNode==lpRootNode)break; else lpLastNode=lpRootNode; colorKey=currentNode(); while(lpTempNode&&minDistance) { if(colorKey.isLessEqual(lowerRGB,lpTempNode->item())) { if(colorKey.isLessEqual(lpTempNode->item(),upperRGB)) { pushNode(TreeNodeEx(*lpTempNode,colorKey)); tmpDistance=lpTempNode->item()-rgbItem; if(!tmpDistance)return &lpTempNode->item(); if(tmpDistanceitem();} } } if(colorKey.isLess(rgbItem,lpTempNode->item()))lpTempNode=lpTempNode->leftNode(); else lpTempNode=lpTempNode->rightNode(); colorKey.nextKey(); } } return lpBestRGB; } WORD RGBTree::insertItem(const RGBIndex &rgbItem) { mColorKey.colorKey(ColorKey::RedKey); if(!rootNode()) { if(!rootNode(insertNode(rootNode(),rootNode(),rgbItem)))return FALSE; leaves(leaves()+1); return TRUE; } else { if(!insertNode(rootNode(),rootNode(),rgbItem))return FALSE; leaves(leaves()+1); return TRUE; } } BOOL RGBTree::searchItem(RGBColor &rgbColor,SearchType searchType) { RGBIndex rgbIndex(rgbColor); if(!searchItem(rgbIndex,searchType))return FALSE; rgbColor=(RGBColor&)rgbIndex; return TRUE; } BOOL RGBTree::searchItem(RGBIndex &rgbItem,SearchType searchType) { RGBIndex *lpItem; WORD currentThreshold(mThreshold); if(!rootNode())return FALSE; mColorKey.colorKey(ColorKey::RedKey); lpItem=searchNodeExact(rootNode(),rgbItem); if(lpItem){rgbItem=*lpItem;return TRUE;} else if(SearchExact==searchType)return FALSE; setThreshold(MaxThreshold); lpItem=searchNodeNearest(rootNode(),rgbItem); setThreshold(currentThreshold); if(lpItem){rgbItem=*lpItem;return TRUE;} return FALSE; } BOOL RGBTree::searchItem(RGBIndex &rgbItem,SmartPointer &rgbIndex,SearchType searchType) { RGBIndex *lpItem; WORD currentThreshold(mThreshold); if(!rootNode())return FALSE; mColorKey.colorKey(ColorKey::RedKey); lpItem=searchNodeExact(rootNode(),rgbItem); if(lpItem){rgbIndex=lpItem;return TRUE;} else if(SearchExact==searchType)return FALSE; setThreshold(MaxThreshold); lpItem=searchNodeNearest(rootNode(),rgbItem); setThreshold(currentThreshold); if(lpItem){rgbIndex=lpItem;return TRUE;} return FALSE; }