亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? octree.cpp

?? Windows 圖形編程 書籍
?? CPP
字號:
//-----------------------------------------------------------------------------------//
//              Windows Graphics Programming: Win32 GDI and DirectDraw               //
//                             ISBN  0-13-086985-6                                   //
//                                                                                   //
//  Written            by  Yuan, Feng                             www.fengyuan.com   //
//  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
//  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
//                                                                                   //
//  FileName   : octree.cpp						                                     //
//  Description: Octree color quantilization, color reduction                        //
//  Version    : 1.00.000, May 31, 2000                                              //
//-----------------------------------------------------------------------------------//

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <assert.h>

#include "DIB.h"
#include "Image.h"
#include "Octree.h"

/////////////////////////////////////////////////
//											   //
//	O C T R E E  Q U A N T I L I Z A T I O N   //
//										       //	
/////////////////////////////////////////////////

void KNode::RemoveAll(void)
{
	for (int i=0; i<8; i++)
		if ( Child[i] )
		{	
			Child[i]->RemoveAll();
			Child[i] = NULL;
		}
	
	delete this;
}


int KNode::PickLeaves(RGBQUAD * pEntry, int * pFreq, int size)
{
	if ( size==0 )
		return 0;

	if ( IsLeaf )
	{
		* pFreq             = Pixels;

		pEntry->rgbRed      = ( SigmaRed   + Pixels/2 ) / Pixels;
		pEntry->rgbGreen    = ( SigmaGreen + Pixels/2 ) / Pixels;
		pEntry->rgbBlue     = ( SigmaBlue  + Pixels/2 ) / Pixels;
		pEntry->rgbReserved = 0;

		return 1;
	}
	else
	{
		int sum = 0;
	
		for (int i=0; i<8; i++)
			if ( Child[i] )
				sum += Child[i]->PickLeaves(pEntry+sum, pFreq+sum, size-sum);

		return sum;
	}
}


void KOctree::AddColor (BYTE r, BYTE g, BYTE b)
{
	KNode * pNode = pRoot;

	for (BYTE mask=0x80; mask!=0; mask>>=1) // follow the path until leaf node
	{
		// add pixel to it
		pNode->Pixels ++;
		pNode->SigmaRed   += r;
		pNode->SigmaGreen += g;
		pNode->SigmaBlue  += b;

		if ( pNode->IsLeaf )
			break;

		// take one bit each of RGB to form an index
		int index = ( (r & mask) ? 4 : 0 ) + ( (g & mask) ? 2 : 0 ) + ( (b & mask) ? 1 : 0 );
		
		// create a new node if it's a new branch
		if ( pNode->Child[index]==NULL )
		{
			pNode->Child[index] = new KNode(mask==2);
			TotalNode ++;

			if ( mask==2 )
				TotalLeaf ++;
		}

		// follow the path
		pNode = pNode->Child[index];
	}

	for (int threshold=1; TotalNode>MAXMODE; threshold++ )
		Reduce(pRoot, threshold);
}


// Combine node with leaf only child nodes, and no more than threshold pixels
// Combine leaf node with no more than threshold pixels, into closest sibling
void KOctree::Reduce(KNode * pTree, unsigned threshold)
{
	if ( pTree==NULL )
		return;

	bool childallleaf = true;

	// recursively call all non-leaf child nodes
	for (int i=0; i<8; i++)
		if ( pTree->Child[i] && ! pTree->Child[i]->IsLeaf )
		{
			Reduce(pTree->Child[i], threshold);

			if ( ! pTree->Child[i]->IsLeaf )
				childallleaf = false;
		}

	// if all children are leaves, combined is not big enough, combine them
	if ( childallleaf & (pTree->Pixels<=threshold) )
	{
		for (int i=0; i<8; i++)
			if ( pTree->Child[i] )
			{
				delete pTree->Child[i];
				pTree->Child[i] = NULL;
				TotalNode --;
				TotalLeaf --;
			}
	
		pTree->IsLeaf = true;
		TotalLeaf ++;

		return;
	}

	// merge small child leaf nodes
	int i; 
	for (i=0; i<8; i++)
		if ( pTree->Child[i] && pTree->Child[i]->IsLeaf && (pTree->Child[i]->Pixels<=threshold) )
		{
			KNode temp = * pTree->Child[i];

			delete pTree->Child[i];
			pTree->Child[i] = NULL;
			TotalNode --;
			TotalLeaf --;
		
			for (int j=0; j<8; j++)
				if ( pTree->Child[j] )
				{
					Merge(pTree->Child[j], temp);
					break;
				}
		}
}


void KOctree::Merge(KNode * pNode, KNode & target)
{
	while ( true )
	{
		pNode->Pixels     += target.Pixels;
		pNode->SigmaRed   += target.SigmaRed;
		pNode->SigmaGreen += target.SigmaGreen;
		pNode->SigmaBlue  += target.SigmaBlue;

		if ( pNode->IsLeaf )
			break;

		KNode * pChild = NULL;

		for (int i=0; i<8; i++)
			if ( pNode->Child[i] )
			{
				pChild = pNode->Child[i];
				break;
			}

		if ( pChild==NULL )
		{
			assert(FALSE);
			return;
		}
		else
			pNode = pChild;
	}
}


void KOctree::ReduceLeaves(int limit)
{
	for (unsigned threshold=1; TotalLeaf>limit; threshold++)
		Reduce(pRoot, threshold);
}


int KOctree::GenPalette(RGBQUAD entry[], int * pFreq, int size)
{
	ReduceLeaves(size);
	
	return pRoot->PickLeaves(entry, pFreq, size);
}


int GenPalette(BITMAPINFO * pDIB, RGBQUAD * pEntry, int * pFreq, int size)
{
	KImage		dib;
	KPaletteGen palgen;

	dib.AttachDIB(pDIB, NULL, 0);

	palgen.AddBitmap(dib);
	
	return palgen.GetPalette(pEntry, pFreq, size);
}


BITMAPINFO * KColorReduction::Convert8bpp(BITMAPINFO * pDIB)
{
	m_nBPS     = (pDIB->bmiHeader.biWidth + 3) / 4 * 4;	// scanline size for 8-bpp DIB
	
	int headsize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);

	BITMAPINFO * pNewDIB = (BITMAPINFO *) new BYTE[headsize + m_nBPS * abs(
		pDIB->bmiHeader.biHeight)];

	memset(pNewDIB, 0, headsize);

	pNewDIB->bmiHeader.biSize		 = sizeof(BITMAPINFOHEADER); 
	pNewDIB->bmiHeader.biWidth		 = pDIB->bmiHeader.biWidth; 
	pNewDIB->bmiHeader.biHeight		 = pDIB->bmiHeader.biHeight;
	pNewDIB->bmiHeader.biPlanes		 = 1; 
	pNewDIB->bmiHeader.biBitCount	 = 8; 
	pNewDIB->bmiHeader.biCompression = BI_RGB; 

	memset(pNewDIB->bmiColors, 0, 256 * sizeof(RGBQUAD));

	int freq[236];

	m_Matcher.Setup(GenPalette(pDIB, pNewDIB->bmiColors, freq, 236), pNewDIB->bmiColors);

	m_pBits  = (BYTE*) & pNewDIB->bmiColors[256];
		
	if ( pNewDIB==NULL )
		return NULL;

	KImage dib;

	dib.AttachDIB(pDIB, NULL, 0);

	DWORD t1 = GetTickCount();

	dib.PixelTransform(* this);
		
	TCHAR temp[32];

	wsprintf(temp, _T("Time %d"), GetTickCount() - t1);
	MessageBox(NULL, temp, _T("Convert8bpp"), MB_OK);

	return pNewDIB;
}


inline void ForwardDistribute(int error, int * curerror, int & nexterror)
{
	if ( (error<-2) || (error>2) ) // -2..2, not big enough
	{
		nexterror    = curerror[1] + error * 7 / 16;
	
		curerror[-1] += error * 3 / 16;		//            X   7/16
		curerror[ 0] += error * 5 / 16;     //    3/16  5/16  1/16
		curerror[ 1] += error     / 16;
	}
	else
		nexterror = curerror[1];
}

inline void BackwardDistribute(int error, int * curerror, int & nexterror)
{
	if ( (error<-2) || (error>2) ) // -2..2, not big enough
	{
		nexterror    = curerror[-1] + error * 7 / 16;
	
		curerror[ 1] += error * 3 / 16;		//    7/16   X  
		curerror[ 0] += error * 5 / 16;     //    1/16  5/16  3/16
		curerror[-1] += error     / 16;
	}
	else
		nexterror = curerror[-1];
}



BITMAPINFO * KErrorDiffusionColorReduction::Convert8bpp(BITMAPINFO * pDIB)
{
	int extwidth = pDIB->bmiHeader.biWidth + 2;

	int * error   = new int[extwidth*3];
	memset(error, 0, sizeof(int) * extwidth * 3);

	red_error   = error + 1;
	green_error = red_error   + extwidth;
	blue_error  = green_error + extwidth;

	BITMAPINFO * pNew = KColorReduction::Convert8bpp(pDIB);

	delete [] error;

	return pNew;
}


void KErrorDiffusionColorReduction::Map24bpp(BYTE * pBuffer, int width)
{
	int next_red, next_green, next_blue;

	if ( m_bForward )
	{
		next_red   =   red_error[0];
		next_green = green_error[0];
		next_blue  =  blue_error[0];

		for (int i=0; i<width; i++)
		{
			int red   = pBuffer[2];
			int green = pBuffer[1];
			int blue  = pBuffer[0];

			BYTE match = m_Matcher.ColorMatch( red+next_red, green+next_green, blue+next_blue );
			
			ForwardDistribute(red   - m_Matcher.m_Colors[match].rgbRed  , red_error  +i, next_red);
			ForwardDistribute(green - m_Matcher.m_Colors[match].rgbGreen, green_error+i, next_green);
			ForwardDistribute(blue  - m_Matcher.m_Colors[match].rgbBlue,  blue_error +i, next_blue);
			
			* m_pPixel ++= match;

			pBuffer += 3;
		}
	}
	else
	{
		next_red   =   red_error[width-1];
		next_green = green_error[width-1];
		next_blue  =  blue_error[width-1];

		pBuffer  += 3 * width - 3;
		m_pPixel += width - 1;

		for (int i=width-1; i>=0; i--)
		{
			int red   = pBuffer[2];
			int green = pBuffer[1];
			int blue  = pBuffer[0];

			BYTE match = m_Matcher.ColorMatch( red+next_red, green+next_green, blue+next_blue );
			
			BackwardDistribute(red   - m_Matcher.m_Colors[match].rgbRed  , red_error  +i, next_red);
			BackwardDistribute(green - m_Matcher.m_Colors[match].rgbGreen, green_error+i, next_green);
			BackwardDistribute(blue  - m_Matcher.m_Colors[match].rgbBlue,  blue_error +i, next_blue);
			
			* m_pPixel --= match;

			pBuffer -= 3;
		}
	}		
}


BITMAPINFO * Convert8bpp(BITMAPINFO * pDIB)
{
	KColorReduction cnv;

	return cnv.Convert8bpp(pDIB);
}

BITMAPINFO * Convert8bpp_ErrorDiffusion(BITMAPINFO * pDIB)
{
	KErrorDiffusionColorReduction cnv;

	return cnv.Convert8bpp(pDIB);
}


// Get to DIB color table
const BYTE * GetColorTable(const BITMAPINFO * pDIB, int & nSize, int & nColor)
{
	const BYTE * pRGB;

	if ( pDIB->bmiHeader.biSize==sizeof(BITMAPCOREHEADER) )	// OS/2 BMP format
	{
		pRGB   = (const BYTE *) pDIB + sizeof(BITMAPCOREHEADER);
		nSize  = sizeof(RGBTRIPLE);
		nColor = 1 << ((BITMAPCOREHEADER *) pDIB)->bcBitCount;
	}
	else 
	{
		nColor = 0;

		if ( pDIB->bmiHeader.biBitCount<=8 )
			nColor = 1 << pDIB->bmiHeader.biBitCount;

		if ( pDIB->bmiHeader.biClrUsed )
			nColor = pDIB->bmiHeader.biClrUsed;

		if ( pDIB->bmiHeader.biClrImportant )
			nColor = pDIB->bmiHeader.biClrImportant;

		pRGB  = (const BYTE *) & pDIB->bmiColors;
		nSize = sizeof(RGBQUAD);
		
		if ( pDIB->bmiHeader.biCompression==BI_BITFIELDS )
			pRGB += 3 * sizeof(RGBQUAD);
	}

	if ( nColor>256 )
		nColor = 256;

	if ( nColor==0 )
		return NULL;

	return pRGB;
}


HPALETTE LUTCreatePalette(const BYTE * pRGB, int nSize, int nColor)
{
	if ( (pRGB==NULL) || (nColor==0) )
		return NULL;

	LOGPALETTE * pLogPal = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * (nColor-1)];
	HPALETTE     hPal;

	if ( pLogPal )
	{
		pLogPal->palVersion    = 0x0300;
		pLogPal->palNumEntries = nColor;

		for (int i=0; i<nColor; i++)
		{
			pLogPal->palPalEntry[i].peBlue  = pRGB[0];
			pLogPal->palPalEntry[i].peGreen = pRGB[1];
			pLogPal->palPalEntry[i].peRed   = pRGB[2]; 
			pLogPal->palPalEntry[i].peFlags = 0; 

			pRGB += nSize;
		}

		hPal = CreatePalette(pLogPal);
	}

	delete [] (BYTE *) pLogPal;
	
	return hPal;
}


// Create palette from Color table in a DIB
HPALETTE CreateDIBPalette(const BITMAPINFO * pDIB)
{
	int	   nSize;
	int    nColor;

	const BYTE * pRGB = GetColorTable(pDIB, nSize, nColor);

	if ( pRGB==NULL )
	{
		RGBQUAD		 RGB[256];
		int			 freq[256];

		nColor = GenPalette((BITMAPINFO *) pDIB, RGB, freq, 236);

#ifdef _DEBUG
		for (int i=0; i<nColor; i++)
		{
			TCHAR temp[64];

			wsprintf(temp, _T("{ %d, %d, %d }, // %3d, %d\n"), RGB[i].rgbRed, RGB[i].rgbGreen, RGB[i].rgbBlue,
				i, freq[i]);
			OutputDebugString(temp);
		}
#endif

		return LUTCreatePalette((BYTE *) RGB, sizeof(RGBQUAD), nColor);
	}
	else
		return LUTCreatePalette(pRGB, nSize, nColor);
}


BITMAPINFO * IndexColorTable(BITMAPINFO * pDIB, HPALETTE hPal)
{
	int nSize;
	int nColor;

	const BYTE * pRGB = GetColorTable(pDIB, nSize, nColor);

	if ( pDIB->bmiHeader.biBitCount>8 )	// no change
		return pDIB;

	// allocate a new BITMAPINFO for modification
	BITMAPINFO * pNew = (BITMAPINFO *) new BYTE[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*nColor];

	pNew->bmiHeader = pDIB->bmiHeader;

	WORD * pIndex = (WORD *) pNew->bmiColors;

	for (int i=0; i<nColor; i++, pRGB+=nSize)
		if ( hPal )
			pIndex[i] = GetNearestPaletteIndex(hPal, RGB(pRGB[2], pRGB[1], pRGB[0]));
		else
			pIndex[i] = i;

	return pNew;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩精品福利| 欧美性三三影院| 视频在线观看一区二区三区| 国产视频一区二区三区在线观看| 在线看不卡av| 一本色道久久加勒比精品| 精品一区二区国语对白| 日韩国产精品久久| 午夜视频一区在线观看| 亚洲一区二区三区四区不卡| 自拍偷拍亚洲激情| 亚洲精品国产a| 亚洲精品伦理在线| 亚洲国产成人av网| 亚洲自拍欧美精品| 午夜欧美大尺度福利影院在线看| 樱花草国产18久久久久| 亚洲男人天堂av| 日韩精品电影一区亚洲| 全国精品久久少妇| 国产精品一卡二卡| 波多野结衣中文一区| av在线一区二区三区| 91美女精品福利| 欧美性极品少妇| 欧美一区二区三区思思人| 久久久影视传媒| 亚洲私人影院在线观看| 日韩精品电影在线| 国产91精品精华液一区二区三区| 不卡视频一二三四| 欧美日韩dvd在线观看| 精品国产免费一区二区三区香蕉| 国产午夜精品在线观看| 亚洲福利一区二区三区| 精彩视频一区二区三区| 91理论电影在线观看| 在线观看91av| 国产iv一区二区三区| 理论电影国产精品| 亚洲1区2区3区视频| 洋洋成人永久网站入口| 中文字幕中文字幕在线一区| 日本一区二区三区高清不卡| 精品国一区二区三区| 日韩一级片在线观看| 欧美精品在线一区二区三区| 在线免费一区三区| 在线成人午夜影院| 欧美一区二区精品久久911| 91精品视频网| 精品欧美一区二区久久| 2020日本不卡一区二区视频| 国产午夜精品理论片a级大结局 | 91在线观看高清| 成人福利视频网站| 欧美怡红院视频| 欧美一级艳片视频免费观看| 精品免费国产一区二区三区四区| 精品蜜桃在线看| 亚洲天堂2014| 美女视频黄 久久| 99精品国产视频| 欧美成人三级在线| 中文字幕在线一区二区三区| 亚洲成人激情综合网| 日韩精品电影在线| 成人av手机在线观看| 欧美专区在线观看一区| 久久毛片高清国产| 一区二区三区国产| 国产一区二区按摩在线观看| 欧美最猛性xxxxx直播| 精品理论电影在线观看| 亚洲一区成人在线| 成人综合在线网站| 精品国产免费一区二区三区香蕉 | 亚洲国产精品ⅴa在线观看| 日韩国产精品久久| 欧美在线不卡一区| 国产精品久久久99| 国产在线精品不卡| 欧美成人bangbros| 丝袜国产日韩另类美女| 色综合久久久久久久久| 国产亚洲1区2区3区| 激情综合色综合久久| 9191久久久久久久久久久| 亚洲国产欧美在线| 欧洲一区二区三区免费视频| 中文字幕在线不卡视频| www.久久精品| 日韩一区在线看| 色丁香久综合在线久综合在线观看| 久久久精品免费免费| 国产精品亚洲人在线观看| 欧美不卡一区二区| 国产福利一区在线| 中文字幕高清一区| 成人av免费网站| 亚洲精品一卡二卡| 欧美挠脚心视频网站| 日韩激情视频网站| 久久婷婷国产综合国色天香| 国产成人亚洲精品青草天美| 欧美午夜宅男影院| 国产女人aaa级久久久级| 日韩精品电影一区亚洲| 欧美精品 日韩| 免费成人深夜小野草| 久久蜜桃av一区精品变态类天堂| 国产成人在线观看免费网站| 国产精品不卡一区二区三区| gogo大胆日本视频一区| 中文字幕亚洲区| 欧美日韩亚洲综合一区| 日韩电影在线免费看| 日韩美女视频在线| 色噜噜久久综合| 日本怡春院一区二区| 国产精品麻豆视频| 欧美日韩成人在线| 国产精品夜夜嗨| 亚洲综合久久av| 国产亚洲一区字幕| 91精品国产欧美日韩| av一二三不卡影片| 国产精品一区二区不卡| 亚洲午夜免费电影| 1000精品久久久久久久久| 日韩一区二区在线看| 欧美日韩一区成人| 91一区二区三区在线观看| 精品午夜一区二区三区在线观看| 亚洲一区二区三区在线播放| 久久综合九色综合久久久精品综合| 色菇凉天天综合网| 91免费观看国产| 成人福利视频网站| 成人免费三级在线| 精品一区二区三区影院在线午夜| 亚洲风情在线资源站| 一区二区三区中文字幕精品精品| 久久久不卡影院| 国产色综合一区| 国产日韩欧美精品一区| 久久久久久久久岛国免费| 精品国产亚洲在线| 久久麻豆一区二区| 久久精品免视看| 国产精品免费aⅴ片在线观看| 中文字幕精品一区| 亚洲色图制服丝袜| 亚洲人一二三区| 亚洲综合视频在线| 亚洲h动漫在线| 青青草国产精品亚洲专区无| 日本不卡的三区四区五区| 免费高清成人在线| 国产99久久久久久免费看农村| 成人三级伦理片| 欧美高清性hdvideosex| 欧美成人女星排行榜| 中文字幕亚洲精品在线观看| 亚洲综合在线视频| 国内偷窥港台综合视频在线播放| 国产精品影视网| 在线视频一区二区三区| 日韩免费电影网站| 国产精品国产三级国产三级人妇 | 欧美亚洲国产一区在线观看网站| 欧美日韩中文字幕一区二区| 欧美mv和日韩mv国产网站| 国产精品丝袜黑色高跟| 免费观看在线综合| 一本大道综合伊人精品热热| 欧美tk—视频vk| 综合激情成人伊人| 国产不卡视频在线观看| 欧美丰满一区二区免费视频| 国产精品国产三级国产aⅴ中文| 亚洲国产日韩a在线播放性色| 国产乱码精品一区二区三区忘忧草| 一本大道久久a久久综合婷婷| www激情久久| 久久99久久精品| 91精品国产品国语在线不卡 | 日韩免费高清av| 亚洲一级在线观看| 91精品91久久久中77777| 国产精品电影一区二区| 国产剧情一区二区| 精品国产91亚洲一区二区三区婷婷 | av一区二区久久| 亚洲三级久久久| 色综合久久综合网97色综合| 国产亚洲成年网址在线观看| 国产精品影视网| 久久蜜桃一区二区| 99久久伊人久久99|