www.pudn.com > chap_03.rar > DibObject.cpp


//DibObject.cpp 
 
#include "stdafx.h" 
#include "DibObject.h" 
 
IMPLEMENT_DYNCREATE(CDibObject, CObject) 
 
char *CDibObject::szExtensions[] = { ".BMP", ".GIF", ".PCX", ".TGA", ".JPG", ".TIF", "" }; 
         
//Diagnostics and dump member functions, overridden 
#ifdef _DEBUG 
void CDibObject::Dump(CDumpContext &dc) const 
{ 
	//call base class function first 
	CObject::Dump(dc); 
	//now do the stuff for our specific class 
	dc<<"File Name:"<m_nWidth; 
	m_nHeight = pDibObject->m_nHeight; 
	m_nPlanes = pDibObject->m_nPlanes; 
	m_nBits = pDibObject->m_nBits; 
	m_nColors = pDibObject->m_nColors; 
	m_nImageType = pDibObject->m_nImageType; 
	m_nX = pDibObject->m_nX; 
	m_nY = pDibObject->m_nY; 
	m_nLastError = pDibObject->m_nLastError; 
	m_nScreenPlanes = pDibObject->m_nScreenPlanes; 
	m_nScreenBits = pDibObject->m_nScreenBits; 
	m_nPaletteBytes = pDibObject->m_nPaletteBytes; 
	m_nQuality = pDibObject->m_nQuality; 
	m_nPaletteCreationType = pDibObject->m_nPaletteCreationType; 
	 
	int nNumColors = m_nColors; 
	int nWidthBytes = WidthBytes( m_nBits, m_nWidth ); 
	 
	if( pDibObject->m_hDib != NULL ) 
	{ 
		DWORD dwSize = ::GlobalSize( pDibObject->m_hDib ); 
		char *pData = (char *) ::GlobalLock( pDibObject->m_hDib ); 
		if( pData != NULL ) 
		{ 
			HGLOBAL hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize ); 
			if( hGlobal != NULL ){ 
				 
				char *pDestData = (char *) ::GlobalLock( hGlobal ); 
				if( pDestData != NULL ) 
				{ 
					memcpy( pDestData, pData, dwSize ); 
					::GlobalUnlock( hGlobal ); 
					m_hDib = hGlobal; 
				} 
				else ::GlobalFree( hGlobal ); 
			} 
			::GlobalUnlock( pDibObject->m_hDib ); 
		} 
	} 
} 
 
//////////////////////////////////////////////////////////////////////// 
//CDibObject类的构造函数		     
//---------------------------------------------------------------------- 
//基本功能:构造一个CDibObject对象。唯一的要求的一个参数是文件名。如果 
//			给出了CDC设备上下文参数,图像加载后会立即在该设备上下文中显示 
//			出来。如果给出了nX或nY参数,图像会显示在该坐标指定的位置,否 
//			则,图像总是显示在坐标为(0, 0)的位置。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			CDC *pDC,默认为NULL 
//			int nX,默认为-1 
//			int nY,默认为-1 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
CDibObject::CDibObject( const char *pszFilename, 
						   CDC *pDC, int nX, int nY ) 
{ 
 
	InitVars(); 
	Load( pszFilename, pDC, nX, nY ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//CDibObject类的析构函数		     
//---------------------------------------------------------------------- 
//基本功能:析构CDibObject对象,删除该对象中的图像及相应的变量 
//---------------------------------------------------------------------- 
//参数说明:无 
//////////////////////////////////////////////////////////////////////// 
CDibObject::~CDibObject() 
{ 
 
	if( m_hDib ) ::GlobalFree( m_hDib ); 
	if( m_pszFilename != NULL ) delete [] m_pszFilename; 
	if( m_pLogPal != NULL ) delete [] m_pLogPal; 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//InitVars()函数		     
//---------------------------------------------------------------------- 
//基本功能:初始化CDibObject类内部变量 
//---------------------------------------------------------------------- 
//参数说明:BOOL bFlag	标记类中是否有图像打开,默认值为FALSE 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::InitVars( BOOL bFlag ) 
{ 
 
	m_nWidth = m_nHeight = m_nBits = m_nColors = m_nImageType = 0; 
	m_nX = m_nY = 0; 
	m_nLastError = 0; 
	m_hDib = NULL; 
	m_nPaletteCreationType = FIXED_PALETTE; 
	if( !bFlag ) 
	{ 
		m_pszFilename = NULL; 
		m_pLogPal = NULL; 
	} 
	m_nQuality = 50; 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL Load()		     
//---------------------------------------------------------------------- 
//基本功能:本函数把一个图像文件载入CDibObject类。必需的一个参数是文件 
//			名。如果给出了CDC设备上下文参数,图像一加载就被绘制。如果给 
//			出了nX或nY参数,图像将显示在该坐标指定的位置。否则,图像总是 
//			显示在坐标为(0,0)的位置。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			CDC *pDC,默认为NULL 
//			int nX,默认为-1 
//			int nY,默认为-1 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::Load( const char *pszFilename,  
						CDC *pDC, int nX, int nY ) 
{ 
 
	//获取图像文件类型 
	m_nImageType = FileType( pszFilename ); 
	if( m_nImageType == 0 ) 
	{ 
		m_nLastError = IMAGELIB_UNSUPPORTED_FILETYPE; 
		return( FALSE ); 
	} 
 
	//删除已存在的图像 
	KillImage(); 
 
	m_pszFilename = new char [strlen(pszFilename)+1]; 
	if( m_pszFilename != NULL ) strcpy( m_pszFilename, pszFilename ); 
 
	//根据文件类型调用ImageLoad.dll动态链接库中的相应函数打开图像文件 
	switch( m_nImageType ) 
	{ 
	case IMAGETYPE_BMP: 
		m_hDib = ::LoadBMP( pszFilename ); 
		if( m_hDib == NULL ){ 
			m_nLastError = ::GetLastPicLibError(); 
			return( FALSE ); 
		} 
		break; 
	case IMAGETYPE_GIF: 
		m_hDib = ::LoadGIF( pszFilename ); 
		if( m_hDib == NULL ){ 
			m_nLastError = ::GetLastPicLibError(); 
			return( FALSE ); 
		} 
		break; 
	case IMAGETYPE_JPG: 
		m_hDib = ::LoadJPG( pszFilename ); 
		if( m_hDib == NULL ){ 
			m_nLastError = ::GetLastPicLibError(); 
			return( FALSE ); 
		} 
		break; 
	case IMAGETYPE_PCX: 
		m_hDib = ::LoadPCX( pszFilename ); 
		if( m_hDib == NULL ){ 
			m_nLastError = ::GetLastPicLibError(); 
			return( FALSE ); 
		} 
		break; 
	case IMAGETYPE_TGA: 
		m_hDib = ::LoadTGA( pszFilename ); 
		if( m_hDib == NULL ){ 
			m_nLastError = ::GetLastPicLibError(); 
			return( FALSE ); 
		} 
		break; 
	case IMAGETYPE_TIF: 
		m_hDib = ::LoadTIF( pszFilename ); 
		if( m_hDib == NULL ){ 
			m_nLastError = ::GetLastPicLibError(); 
			return( FALSE ); 
		} 
		break; 
	} 
 
	//处理图像信息头 
	ProcessImageHeader(); 
	//处理调色板 
	ProcessPalette(); 
 
	//若传入了设备上下文指针,就在指定的设备上下文中绘制图像 
	if( pDC != NULL ) Draw( pDC, nX, nY ); 
 
	return( TRUE ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL GetImageInfo()		     
//---------------------------------------------------------------------- 
//基本功能:本函数获取图像宽度、高度、位平面数、每个像素点的位数、以及颜 
//			色数的信息。值为NULL的参数将不被传入。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			int *pnWidth,			默认为NULL 
//			int *pnHeight,			默认为NULL 
//			int *pnPlanes,			默认为NULL 
//			int *pnBitsPerPixel,	默认为NULL 
//			int *pnNumColors,		默认为NULL 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::GetImageInfo( const char *pszFilename, int *pnWidth, 
	int *pnHeight, int *pnPlanes, int *pnBitsPerPixel, int *pnNumColors ) 
{ 
	int nImageType; 
 
	//获取图像文件类型 
	nImageType = FileType( pszFilename ); 
	if( nImageType == 0 ) 
	{ 
		m_nLastError = IMAGELIB_UNSUPPORTED_FILETYPE; 
		return( FALSE ); 
	} 
	 
	//根据文件类型调用ImageLoad.dll动态链接库中的相应函数获取图像信息 
	switch( nImageType ) 
	{ 
	case IMAGETYPE_BMP: 
		return( ::GetBMPInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) ); 
	case IMAGETYPE_GIF: 
		return( ::GetGIFInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) ); 
	case IMAGETYPE_JPG: 
		return( ::GetJPGInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) ); 
	case IMAGETYPE_PCX: 
		return( ::GetPCXInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) ); 
	case IMAGETYPE_TGA: 
		return( ::GetTGAInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) ); 
	case IMAGETYPE_TIF: 
		return( ::GetTIFInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) ); 
	} 
	 
	return( FALSE ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetLastError()		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回所发生的最后一次CDibObject类错误。详细错误信息见 
//			"ImageErrors.h"头文件。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nErrorNumber 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetLastError( void ) 
{ 
 
	return( m_nLastError ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL Save()		     
//---------------------------------------------------------------------- 
//基本功能:本函数保存驻留于CDibObject对象中的当前图像(图像类型定义见 
//			GetImageType()函数。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			int nType,默认为-1 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::Save( const char *pszFilename, int nType ) 
{ 
 
	//若没有指定文件类型,则根据文件名判断其文件类型 
	if( nType == -1 ) nType = ExtensionIndex( pszFilename ); 
 
	if( nType < IMAGETYPE_FIRSTTYPE || nType > IMAGETYPE_LASTTYPE ) return( FALSE ); 
	m_nImageType = nType; 
	delete [] m_pszFilename; 
	m_pszFilename = new char [strlen(pszFilename)+1]; 
	if( m_pszFilename != NULL ) strcpy( m_pszFilename, pszFilename ); 
 
	//根据文件类型调用ImageLoad.dll动态链接库中的相应函数保存图像 
	switch( m_nImageType ) 
	{ 
	case IMAGETYPE_BMP: 
		return( ::SaveBMP( pszFilename, m_hDib ) ); 
		break; 
	case IMAGETYPE_GIF: 
		return( ::SaveGIF( pszFilename, m_hDib ) ); 
		break; 
	case IMAGETYPE_JPG: 
		return( ::SaveJPG( pszFilename, m_hDib, m_nQuality ) ); 
		break; 
	case IMAGETYPE_PCX: 
		return( ::SavePCX( pszFilename, m_hDib ) ); 
		break; 
	case IMAGETYPE_TGA: 
		return( ::SaveTGA( pszFilename, m_hDib ) ); 
		break; 
	case IMAGETYPE_TIF: 
		return( ::SaveTIF( pszFilename, m_hDib ) ); 
		break; 
	} 
	 
	return( TRUE ); 
	 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int ExtensionIndex() 
//---------------------------------------------------------------------- 
//基本功能:本函数返回文件名指定的图像类型。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nWidth 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::ExtensionIndex( const char *pszFilename ) 
{ 
	int Index = 0; 
	char *pszExtension; 
 
	pszExtension = (char *) &pszFilename[strlen(pszFilename)-4]; 
 
	while( szExtensions[Index][0] ) 
	{ 
		if( !stricmp( pszExtension, szExtensions[Index] ) ) return( Index + 1 ); 
		Index++; 
	} 
 
	return( -1 ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetWidth() 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的像素宽度数。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nWidth 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetWidth( void ) 
{ 
 
	return( m_nWidth ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetHeight( void ) 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的像素高度数。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nHeight 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetHeight( void ) 
{ 
 
	return( m_nHeight ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetNumBits( void ) 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的像素数:1、4、8、16、24、32。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nBits 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetNumBits( void ) 
{ 
 
	return( m_nBits ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetNumColors( void ) 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像调色板中的颜色。图像为16位色或更高时返回值为0。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nColors 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetNumColors( void ) 
{ 
 
	return( m_nColors ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL GetPaletteData()		     
//---------------------------------------------------------------------- 
//基本功能:本函数将当前RGB调色板数据填入到所传入的指针中。如果图像是16 
//			位色或更高时则不进行任何操作。 
//---------------------------------------------------------------------- 
//参数说明:RGBQUAD *pRGBPalette 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::GetPaletteData( RGBQUAD *pRGBPalette ) 
{ 
 
	m_nLastError = IMAGELIB_HDIB_NULL; 
	if( m_hDib == NULL ) return( FALSE ); 
 
	char *pTemp; 
	pTemp = (char *) ::GlobalLock( m_hDib ); 
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR; 
	if( pTemp == NULL ) return( FALSE ); 
 
	memcpy( pRGBPalette, &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)], 
								m_nPaletteBytes ); 
 
	m_nLastError = IMAGELIB_SUCCESS; 
	::GlobalUnlock( m_hDib ); 
 
	return( TRUE ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//RGBQUAD GetPaletteData()		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回一个指向CDibObject调色板数据序列的指针。如果图像 
//			是16位色或更高时则返回NULL。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:返回一个指向CDibObject调色板数据序列的指针 
//////////////////////////////////////////////////////////////////////// 
RGBQUAD *CDibObject::GetPaletteData( void ) 
{ 
	m_nLastError = IMAGELIB_HDIB_NULL; 
	if( m_hDib == NULL ) return( NULL ); 
 
	m_nLastError = IMAGELIB_NO_PALETTE_FOR_HIGH_COLOR; 
	if( m_nColors <= 0 || m_nColors > 256 ) return( NULL ); 
	 
	RGBQUAD *pRGBPalette; 
	pRGBPalette = new RGBQUAD [m_nColors]; 
	if( pRGBPalette == NULL ) 
	{ 
		m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR; 
		return( NULL ); 
	} 
	 
	char *pTemp; 
	pTemp = (char *) ::GlobalLock( m_hDib ); 
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR; 
	if( pTemp == NULL ) 
	{ 
		delete [] pRGBPalette; 
		return( NULL ); 
	} 
	 
	memcpy( pRGBPalette, &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)],  
								m_nColors * sizeof( RGBQUAD ) ); 
	 
	m_nLastError = IMAGELIB_SUCCESS; 
	::GlobalUnlock( m_hDib ); 
	 
	return( pRGBPalette ); 
	 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetImageType()		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的类型。图像类型定义如下: 
//			#define IMAGETYPE_NONE		0 
//			#define IMAGETYPE_BMP		1 
//			#define IMAGETYPE_GIF		2 
//			#define IMAGETYPE_PCX		3 
//			#define IMAGETYPE_TGA		4 
//			#define IMAGETYPE_JPG		5 
//			#define IMAGETYPE_TIF		6 
//---------------------------------------------------------------------- 
//参数说明:const char *pFilename 
//---------------------------------------------------------------------- 
//返 回 值:int nImageType 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetImageType( const char *pFilename ) 
{ 
 
	return( ::FileType( pFilename ) ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetImageType()		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的类型。图像类型定义如下: 
//			#define IMAGETYPE_NONE		0 
//			#define IMAGETYPE_BMP		1 
//			#define IMAGETYPE_GIF		2 
//			#define IMAGETYPE_PCX		3 
//			#define IMAGETYPE_TGA		4 
//			#define IMAGETYPE_JPG		5 
//			#define IMAGETYPE_TIF		6 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nImageType 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetImageType( void ) 
{ 
 
	return( m_nImageType ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL Draw( CDC *pDC, int nX, int nY )		     
//---------------------------------------------------------------------- 
//基本功能:本函数是在设备描述表上绘制图像。如果X和Y坐标没有给出,图像会 
//			被画在(0,0)坐标或上次传入的有效坐标处。 
//---------------------------------------------------------------------- 
//参数说明:CDC *pDC 
//			int nX,默认为-1 
//			int nY,默认为-1 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::Draw( CDC *pDC, int nX, int nY ) 
{ 
	if( nX != -1 ) m_nX = nX; 
	if( nY != -1 ) m_nY = nY; 
 
	m_nLastError = IMAGELIB_HDIB_NULL; 
 
	//没有打开图像 
	if( m_hDib == NULL ) return( FALSE ); 
 
	char *pTemp; 
	//锁定图像对象句柄 
	pTemp = (char *) ::GlobalLock( m_hDib ); 
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR; 
	if( pTemp == NULL ) return( NULL ); 
 
	//图像信息头 
	BITMAPINFOHEADER *pBIH; 
	pBIH = (BITMAPINFOHEADER *) &pTemp[sizeof(BITMAPFILEHEADER)]; 
 
	int nRet = ::StretchDIBits( pDC->m_hDC, m_nX, m_nY, m_nWidth, m_nHeight, 0, 0,  
								m_nWidth, m_nHeight,  
								(const void FAR *) &pTemp[sizeof(BITMAPFILEHEADER)+ 
														  sizeof(BITMAPINFOHEADER)+ 
														  m_nPaletteBytes],  
								(BITMAPINFO *) pBIH, DIB_RGB_COLORS, SRCCOPY ); 
 
	::GlobalUnlock( m_hDib ); 
	m_nLastError = IMAGELIB_STRETCHDIBITS_ERROR; 
	if( nRet != m_nHeight ) return( FALSE ); 
	m_nLastError = IMAGELIB_SUCCESS; 
 
	return( TRUE ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL CreateLogPalette()		     
//---------------------------------------------------------------------- 
//基本功能:本函数根据指定的调色板指针及颜色数创建一个逻辑调色板。 
//---------------------------------------------------------------------- 
//参数说明:CDC *pDC 
//			int nX,默认为-1 
//			int nY,默认为-1 
//---------------------------------------------------------------------- 
//返 回 值:创建的逻辑调色板指针 
//////////////////////////////////////////////////////////////////////// 
LOGPALETTE *CDibObject::CreateLogPalette( RGBQUAD *pPalette,  
										   int nNumColors ) 
{ 
	LOGPALETTE *pLogPal; 
	int i; 
 
	if( pPalette == NULL ) return( NULL ); 
 
	pLogPal = (LOGPALETTE *) new char [sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY)]; 
	if( pLogPal == NULL ) return( NULL ); 
 
	//指定调色板版本号 
	pLogPal->palVersion = 0x300; 
	//指定调色板颜色数 
	pLogPal->palNumEntries = (unsigned short) nNumColors; 
	 
	//复制调色板各颜色项 
	for( i=0; ipalPalEntry[i].peRed = pPalette[i].rgbRed; 
		pLogPal->palPalEntry[i].peGreen = pPalette[i].rgbGreen; 
		pLogPal->palPalEntry[i].peBlue = pPalette[i].rgbBlue; 
		pLogPal->palPalEntry[i].peFlags = 0; 
	} 
 
	return( pLogPal ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//void ProcessImageHeader()		     
//---------------------------------------------------------------------- 
//基本功能:本函数处理图像信息头各项内容。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:无 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::ProcessImageHeader( void ) 
{ 
 
	m_nLastError = IMAGELIB_HDIB_NULL; 
	if( m_hDib == NULL ) return; 
 
	char *pTemp; 
	BITMAPINFOHEADER *pBIH; 
	pTemp = (char *) ::GlobalLock( m_hDib ); 
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR; 
	if( pTemp == NULL ) return; 
	 
	//得到图像信息头指针 
	pBIH = (BITMAPINFOHEADER *) &pTemp[sizeof(BITMAPFILEHEADER)]; 
	m_nWidth = pBIH->biWidth; 
	m_nHeight = pBIH->biHeight; 
	m_nPlanes = pBIH->biPlanes; 
	m_nBits = pBIH->biBitCount; 
	m_nColors = 1 << m_nBits; 
	if( m_nPlanes > 1 ) m_nColors <<= ( m_nPlanes - 1 ); 
	if( m_nBits >= 16 ) m_nColors = 0; 
 
		 
	int nWidthBytes = WidthBytes(m_nBits, m_nWidth); 
	pBIH->biSizeImage = nWidthBytes * m_nHeight; 
 
	::GlobalUnlock( m_hDib ); 
 
	m_nLastError = IMAGELIB_SUCCESS; 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//void ProcessPalette()		     
//---------------------------------------------------------------------- 
//基本功能:处理体调色板。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:无 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::ProcessPalette( void ) 
{ 
 
	m_nLastError = IMAGELIB_HDIB_NULL; 
	if( m_hDib == NULL ) return; 
 
	CWindowDC WindowDC( NULL ); 
	m_nScreenPlanes = WindowDC.GetDeviceCaps( PLANES ); 
	m_nScreenBits = WindowDC.GetDeviceCaps( BITSPIXEL ); 
 
	m_nPaletteBytes = 0; 
	m_Palette.DeleteObject(); 
 
	if( m_nBits <= 8 ) m_nPaletteBytes = m_nColors * sizeof( RGBQUAD ); 
	if( m_nScreenBits >= 16 ) return; 
 
	char *pTemp; 
	pTemp = (char *) ::GlobalLock( m_hDib ); 
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR; 
	if( pTemp == NULL ) return; 
 
	if( m_nBits <= 8 ){ 
		RGBQUAD *pRGBPalette; 
		pRGBPalette = (RGBQUAD *) &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)]; 
		LOGPALETTE *pPalette; 
		pPalette = CreateLogPalette( pRGBPalette, m_nColors ); 
		if( pPalette == NULL ){ 
			m_nLastError = IMAGELIB_LOGICAL_PALETTE_CREATION_ERROR; 
			goto ProcessPaletteExit; 
			} 
		m_Palette.CreatePalette( pPalette ); 
		delete [] pPalette; 
		} 
 
	m_nLastError = IMAGELIB_SUCCESS; 
 
ProcessPaletteExit: 
	::GlobalUnlock( m_hDib ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//void KillImage()		     
//---------------------------------------------------------------------- 
//基本功能:清除当前CDibObject类中的图像对象。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:无 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::KillImage( void ) 
{ 
 
	if( m_hDib ) ::GlobalFree( m_hDib ); 
	m_hDib = NULL; 
 
	if( m_pLogPal != NULL ) delete [] m_pLogPal; 
	m_pLogPal = NULL; 
 
	if( m_pszFilename != NULL ) delete [] m_pszFilename; 
	m_pszFilename = NULL; 
 
	m_Palette.DeleteObject(); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL SetPalette( CDC *pDC )		     
//---------------------------------------------------------------------- 
//基本功能:本函数将该设备描述表的调色板分配给相应的图像。当一个图像被载 
//			入时,它的调色板信息便被存入CDibObject对象中。 
//---------------------------------------------------------------------- 
//参数说明:CDC *pDC 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::SetPalette( CDC *pDC ) 
{ 
 
	m_nLastError = IMAGELIB_HDIB_NULL; 
	if( m_hDib == NULL ) return( FALSE ); 
 
	pDC->SelectPalette( &m_Palette, FALSE ); 
	pDC->RealizePalette(); 
 
	m_nLastError = IMAGELIB_SUCCESS; 
 
	return( TRUE ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL IsLoaded( void )		     
//---------------------------------------------------------------------- 
//基本功能:本函数判断是否已经载入了一幅图像 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::IsLoaded( void ) 
{ 
 
	return( m_hDib != NULL ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//void GetDIBPointer()		     
//---------------------------------------------------------------------- 
//基本功能:得到图像DIB数据指针。 
//---------------------------------------------------------------------- 
//参数说明:int *nWidthBytes	图像的字节宽度 
//			int nNewBits		新设置的图像颜色位数 
//			int *nNewWidthBytes	图像颜色位数改变后的字节宽度 
//			int nNewWidth		新设置的图像宽度(像素) 
//---------------------------------------------------------------------- 
//返 回 值:无 
//////////////////////////////////////////////////////////////////////// 
void *CDibObject::GetDIBPointer( int *nWidthBytes, 
								 int nNewBits,  
								 int *nNewWidthBytes, 
								 int nNewWidth ) 
{ 
 
	m_nLastError = IMAGELIB_HDIB_NULL; 
	if( m_hDib == NULL ) return( NULL ); 
 
	void *pTemp; 
	pTemp = ::GlobalLock( m_hDib ); 
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR; 
	if( pTemp == NULL ) return( NULL ); 
 
	if( nWidthBytes != NULL ) *nWidthBytes = WidthBytes( m_nBits, m_nWidth ); 
 
	if( nNewWidthBytes != NULL ) 
	{ 
		if( nNewWidth == -1 ) nNewWidth = m_nWidth; 
		*nNewWidthBytes = WidthBytes( nNewBits, nNewWidth ); 
	} 
 
	return( pTemp ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int WidthBytes()		     
//---------------------------------------------------------------------- 
//基本功能:本函数根据传入的像素位数及图像宽度(像素)计算其字节宽度。 
//---------------------------------------------------------------------- 
//参数说明:int nBits	每像素位数 
//			int nWidth	图像的宽度 
//---------------------------------------------------------------------- 
//返 回 值:int	图像的字节宽度 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::WidthBytes( int nBits, int nWidth ) 
{ 
	int nWidthBytes; 
 
	nWidthBytes = nWidth; 
	if( nBits == 1 ) nWidthBytes = ( nWidth + 7 ) / 8; 
	else if( nBits == 4 ) nWidthBytes = ( nWidth + 1 ) / 2; 
	else if( nBits == 16 ) nWidthBytes = nWidth * 2; 
	else if( nBits == 24 ) nWidthBytes = nWidth * 3; 
	else if( nBits == 32 ) nWidthBytes = nWidth * 4; 
 
	//一个数的后两位为零,则该数为4的整数倍 
	while( ( nWidthBytes & 3 ) != 0 ) nWidthBytes++; 
 
	return( nWidthBytes ); 
 
} 
 
 
//////////////////////////////////////////////////////////////////////// 
//void NormalizeCoordinates()		     
//---------------------------------------------------------------------- 
//基本功能:规格化处理的图像区域。 
//---------------------------------------------------------------------- 
//参数说明:int *nX1				处理区域左上角X坐标 
//			int *nY1				处理区域左上角Y坐标 
//			int *nX2				处理区域右下角X坐标 
//			int *nY2				处理区域右下角Y坐标 
//			BOOL *bCompleteImage	处理区域是否为全部区域 
//			BOOL *bLessThanHalf		处理区域是否为一半区域 
//---------------------------------------------------------------------- 
//返 回 值:无 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::NormalizeCoordinates( int *nX1, int *nY1, int *nX2, int *nY2,  
									  BOOL *bCompleteImage, BOOL *bLessThanHalf ) 
{ 
 
	if( *nX1 == -1 ) *nX1 = 0; 
	if( *nY1 == -1 ) *nY1 = 0; 
	if( *nX2 == -1 ) *nX2 = m_nWidth - 1; 
	if( *nY2 == -1 ) *nY2 = m_nHeight - 1; 
 
	if( *nX1 > *nX2 ){ 
		int nTemp; 
		nTemp = *nX1; 
		*nX1 = *nX2; 
		*nX2 = nTemp;		 
		} 
 
	if( *nY1 > *nY2 ){ 
		int nTemp; 
		nTemp = *nY1; 
		*nY1 = *nY2; 
		*nY2 = nTemp;		 
		} 
 
	if( *nX1 < 0 ) *nX1 = 0; 
	if( *nX2 > m_nWidth - 1 ) *nX2 = m_nWidth - 1; 
 
	if( *nX2 < 0 ) *nX2 = 0; 
	if( *nX2 > m_nWidth - 1 ) *nX2 = m_nWidth - 1; 
 
	if( *nY1 < 0 ) *nY1 = 0; 
	if( *nY1 > m_nHeight - 1 ) *nY1 = m_nHeight - 1; 
 
	if( *nY2 < 0 ) *nY2 = 0; 
	if( *nY2 > m_nHeight - 1 ) *nY2 = m_nHeight - 1; 
 
	if( bCompleteImage != NULL ) *bCompleteImage = TRUE; 
	if( bLessThanHalf != NULL ) *bLessThanHalf = FALSE; 
	if( *nX1 > 0 || *nY1 > 0 || *nX2 < m_nWidth - 1 || *nY2 < m_nHeight - 1 ){ 
		if( bCompleteImage != NULL ) *bCompleteImage = FALSE; 
		DWORD dwTotalPixels, dwThesePixels; 
		dwTotalPixels = (DWORD) m_nWidth * m_nHeight; 
		dwThesePixels = (DWORD) ( (*nX2) - (*nX1) + 1 ) * (DWORD) ( (*nY2) - (*nY1) + 1 ); 
		if( bLessThanHalf != NULL && dwThesePixels <= dwTotalPixels / 2 ) *bLessThanHalf = TRUE; 
		} 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//void operator=()		     
//---------------------------------------------------------------------- 
//基本功能:“=”操作符重载。 
//---------------------------------------------------------------------- 
//参数说明:CDibObject &DibObject	另一个CDibObject图像对象。 
//---------------------------------------------------------------------- 
//返 回 值:无 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::operator= (const CDibObject &DibObject) 
{ 
 
	KillImage(); 
 
	m_nWidth = DibObject.m_nWidth; 
	m_nHeight = DibObject.m_nHeight; 
	m_nPlanes = DibObject.m_nPlanes; 
	m_nBits = DibObject.m_nBits; 
	m_nColors = DibObject.m_nColors; 
	m_nImageType = DibObject.m_nImageType; 
	m_nX = DibObject.m_nX; 
	m_nY = DibObject.m_nY; 
	m_nLastError = DibObject.m_nLastError; 
	m_nScreenPlanes = DibObject.m_nScreenPlanes; 
	m_nScreenBits = DibObject.m_nScreenBits; 
	m_nPaletteBytes = DibObject.m_nPaletteBytes; 
	m_nQuality = DibObject.m_nQuality; 
	m_nPaletteCreationType = DibObject.m_nPaletteCreationType; 
 
	int nNumColors = m_nColors; 
	int nWidthBytes = WidthBytes( m_nBits, m_nWidth ); 
 
	if( DibObject.m_hDib != NULL ){ 
 
		DWORD dwSize = ::GlobalSize( DibObject.m_hDib ); 
 
		char *pData = (char *) ::GlobalLock( DibObject.m_hDib ); 
		if( pData != NULL ){ 
 
			HGLOBAL hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize ); 
			if( hGlobal != NULL ){ 
 
				char *pDestData = (char *) ::GlobalLock( hGlobal ); 
				if( pDestData != NULL ){ 
 
					memcpy( pDestData, pData, dwSize ); 
 
					if( nNumColors != 0 ) CreatePaletteFromDIB( (RGBQUAD *) &pData[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)], nNumColors ); 
 
					else if( DibObject.m_pLogPal != NULL ){ 
						m_pLogPal = (LOGPALETTE *) new char [sizeof(LOGPALETTE)+DibObject.m_pLogPal->palNumEntries*sizeof(PALETTEENTRY)]; 
						if( m_pLogPal != NULL ){ 
							for( int i=0; ipalNumEntries; i++ ) m_pLogPal[i] = DibObject.m_pLogPal[i]; 
							m_Palette.CreatePalette( m_pLogPal ); 
							} 
						} 
 
					::GlobalUnlock( hGlobal ); 
					m_hDib = hGlobal; 
					} 
				else ::GlobalFree( hGlobal ); 
				} 
			::GlobalUnlock( DibObject.m_hDib ); 
			} 
		} 
 
	if( DibObject.m_pszFilename != NULL ){ 
		m_pszFilename = new char [strlen(DibObject.m_pszFilename)+1]; 
		strcpy( m_pszFilename, DibObject.m_pszFilename ); 
		} 
} 
 
//////////////////////////////////////////////////////////////////////// 
//void CreatePaletteFromDIB()		     
//---------------------------------------------------------------------- 
//基本功能:从当前CDibObject位图对象中创建调色板。 
//---------------------------------------------------------------------- 
//参数说明:RGBQUAD *pRGBPalette	调色板指针 
//			int nNumColors			图像颜色数 
//---------------------------------------------------------------------- 
//返 回 值:无 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::CreatePaletteFromDIB( RGBQUAD *pRGBPalette, int nNumColors ) 
{ 
 
	if( pRGBPalette != NULL ){ 
		LOGPALETTE *pPalette; 
		pPalette = CreateLogPalette( pRGBPalette, nNumColors ); 
		if( pPalette != NULL ){ 
			m_Palette.CreatePalette( pPalette ); 
			delete [] pPalette; 
			} 
		else m_nLastError = IMAGELIB_LOGICAL_PALETTE_CREATION_ERROR; 
		} 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetNearestIndex()		     
//---------------------------------------------------------------------- 
//基本功能:获取相近颜色索引值。 
//---------------------------------------------------------------------- 
//参数说明:unsigned char ucRed		红色分量 
//			unsigned char ucGreen	绿色分量 
//			unsigned char ucBlue	蓝色分量 
//			RGBQUAD *pRGBPalette	调色板指针 
//			int nNumColors			颜色数 
//---------------------------------------------------------------------- 
//返 回 值:int	相近颜色索引值 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetNearestIndex( unsigned char ucRed, 
								 unsigned char ucGreen,  
								 unsigned char ucBlue,  
								 RGBQUAD *pRGBPalette,  
								 int nNumColors ) 
{ 
	int i, Index = 0; 
	DWORD NewDiff, Diff = 100000L; 
	DWORD Red, Green, Blue; 
	 
	for( i=0; i pRGBPalette[i].rgbRed ) Red = (DWORD) ( pRGBPalette[i].rgbRed - ucRed ); 
		else Red = (DWORD) ( ucRed - pRGBPalette[i].rgbRed ); 
		if( ucGreen > pRGBPalette[i].rgbGreen ) Green = (DWORD) ( pRGBPalette[i].rgbGreen - ucGreen ); 
		else Green = (DWORD) ( ucGreen - pRGBPalette[i].rgbGreen ); 
		if( ucBlue > pRGBPalette[i].rgbBlue ) Blue = (DWORD) ( pRGBPalette[i].rgbBlue - ucBlue ); 
		else Blue = (DWORD) ( ucBlue - pRGBPalette[i].rgbBlue ); 
		NewDiff = ( Red * Red ) + ( Green * Green ) + ( Blue * Blue ); 
		if( NewDiff < Diff ) 
		{ 
			if( NewDiff <= 1 ) return( i ); 
			Diff = NewDiff; 
			Index = i; 
		} 
	} 
	 
	return( Index ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL ChangeFormat( int nNewBitsPerPixel )		     
//---------------------------------------------------------------------- 
//基本功能:本函数将图像从当前分辨率转化为指定分辨率。 
//---------------------------------------------------------------------- 
//参数说明:int nNewBitsPerPixel 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//////////////////////////////////////////////////////////////////////// 
BOOL CDibObject::ChangeFormat( int nNewBitsPerPixel ) 
{ 
 
	m_nLastError = IMAGELIB_SUCCESS; 
	if( nNewBitsPerPixel == m_nBits ) return( TRUE ); 
 
	int nOldWidthBytes, nNewWidthBytes; 
	char *pBuffer = (char *) GetDIBPointer( &nOldWidthBytes, nNewBitsPerPixel, &nNewWidthBytes ); 
	if( pBuffer == NULL ) return( FALSE ); 
 
	BITMAPINFOHEADER *pOldBIH, *pNewBIH; 
	BITMAPFILEHEADER *pOldBFH, *pNewBFH; 
	RGBQUAD *pOldRGBPalette, *pNewRGBPalette; 
	unsigned char *pOldBits, *pNewBits; 
	int nNumColors, nNumNewColors; 
 
	pOldBFH = (BITMAPFILEHEADER *) pBuffer; 
	pOldBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)]; 
	pOldRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)]; 
	nNumColors = m_nColors; 
	nNumNewColors = 1 << nNewBitsPerPixel; 
	if( nNewBitsPerPixel > 8 ) nNumNewColors = 0; 
	pOldBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)]; 
 
	if( m_nBits >= 16 && nNewBitsPerPixel < 16 ){ 
		if( m_pLogPal != NULL ) delete [] m_pLogPal; 
		m_pLogPal = CreatePaletteFromBitmap( nNumNewColors, pOldBits, m_nBits, m_nWidth, m_nHeight ); 
		} 
 
	HGLOBAL hGlobal; 
	DWORD dwSize; 
	dwSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD ) + m_nHeight * nNewWidthBytes; 
	hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize ); 
	if( hGlobal == NULL ){ 
		::GlobalUnlock( m_hDib ); 
		return( FALSE ); 
		} 
 
	pBuffer = (char *) ::GlobalLock( hGlobal ); 
	if( pBuffer == NULL ){ 
		::GlobalFree( hGlobal ); 
		::GlobalUnlock( m_hDib ); 
		return( FALSE ); 
		} 
 
	pNewBFH = (BITMAPFILEHEADER *) pBuffer; 
	pNewBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)]; 
	pNewRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)]; 
	*pNewBFH = *pOldBFH; 
	*pNewBIH = *pOldBIH; 
	int i, j = nNumNewColors; 
 
	if( m_nBits < 16 && nNewBitsPerPixel < 16 ){ 
		for( i=0; i= 16 ){ 
 		for( i=0; ipalPalEntry[i].peRed; 
			pNewRGBPalette[i].rgbGreen = m_pLogPal->palPalEntry[i].peGreen; 
			pNewRGBPalette[i].rgbBlue = m_pLogPal->palPalEntry[i].peBlue; 
			} 
		} 
	pNewBIH->biBitCount = nNewBitsPerPixel; 
	pNewBIH->biSizeImage = nNewWidthBytes * m_nHeight; 
	pNewBIH->biClrUsed = nNumNewColors; 
	pNewBFH->bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD ) + pNewBIH->biSizeImage; 
	pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD ); 
	pNewBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumNewColors*sizeof(RGBQUAD)]; 
	m_nPaletteBytes = nNumNewColors * sizeof( RGBQUAD ); 
 
	for( int y=0; y> ( x & 7 ) ) ) 
						ucRed = ucGreen = ucBlue = 0xff; 
					else 
						ucRed = ucGreen = ucBlue = 0x00; 
					break; 
				case 4: 
					if( !( x & 1 ) ){ 
						ucRed = pOldRGBPalette[pSrc[x/2]>>4].rgbRed; 
						ucGreen = pOldRGBPalette[pSrc[x/2]>>4].rgbGreen; 
						ucBlue = pOldRGBPalette[pSrc[x/2]>>4].rgbBlue; 
						} 
					else{ 
						ucRed = pOldRGBPalette[pSrc[x/2]&15].rgbRed; 
						ucGreen = pOldRGBPalette[pSrc[x/2]&15].rgbGreen; 
						ucBlue = pOldRGBPalette[pSrc[x/2]&15].rgbBlue; 
						} 
					break; 
				case 8: 
					ucRed = pOldRGBPalette[pSrc[x]].rgbRed; 
					ucGreen = pOldRGBPalette[pSrc[x]].rgbGreen; 
					ucBlue = pOldRGBPalette[pSrc[x]].rgbBlue; 
					break; 
				case 16: 
					GETRGB555( ucRed, ucGreen, ucBlue, &pSrc[x*2] ); 
					break; 
				case 24: 
					ucRed = pSrc[x*3+2]; 
					ucGreen = pSrc[x*3+1]; 
					ucBlue = pSrc[x*3]; 
					break; 
				case 32: 
					GETRGB888( ucRed, ucGreen, ucBlue, &pSrc[x*4] ); 
					break; 
				} 
 
			switch( nNewBitsPerPixel ){ 
				case 1: 
					if( !( x & 7 ) ) pDest[x/8] = 0; 
					pDest[x/8] |= (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ) << ( x & 7 ); 
					break; 
				case 4: 
					if( !( x & 1 ) ) 
						pDest[x/2] = (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ) << 4; 
					else 
						pDest[x/2] |= (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ); 
					break; 
				case 8: 
					pDest[x] = (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ); 
					break; 
				case 16: 
					PUTRGB555( ucRed, ucGreen, ucBlue, &pDest[x*2] ); 
					break; 
				case 24: 
					pDest[x*3+2] = ucRed; 
					pDest[x*3+1] = ucGreen; 
					pDest[x*3] = ucBlue; 
					break; 
				case 32: 
					PUTRGB888( ucRed, ucGreen, ucBlue, &pDest[x*4] ); 
					break; 
				} 
			} 
		} 
 
	::GlobalUnlock( m_hDib ); 
	::GlobalFree( m_hDib ); 
	::GlobalUnlock( hGlobal ); 
	m_hDib = hGlobal; 
 
	ProcessImageHeader(); 
 
	return( TRUE ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//LOGPALETTE CreatePaletteFromBitmap()		     
//---------------------------------------------------------------------- 
//基本功能:从当前CDibObject位图对象中创建逻辑调色板。 
//---------------------------------------------------------------------- 
//参数说明:int nNumColors			颜色数 
//			unsigned char *pBits	位图数据指针 
//			int nBits				颜色位数 
//			int nWidth				图像宽度 
//			int nHeight				图像高度 
//---------------------------------------------------------------------- 
//返 回 值:LOGPALETTE	逻辑调色板指针 
//////////////////////////////////////////////////////////////////////// 
LOGPALETTE *CDibObject::CreatePaletteFromBitmap(int nNumColors,  
												unsigned char *pBits, int nBits,  
												int nWidth, int nHeight ) 
{ 
 
	RGBQUAD *pRGBPalette; 
	if( nBits != 8 && m_nPaletteCreationType == POPULARITY_PALETTE ) pRGBPalette = MakePopularityPalette( nNumColors, pBits, nBits, nWidth, nHeight ); 
	else if( nBits != 8 && m_nPaletteCreationType == MEDIAN_CUT_PALETTE ) pRGBPalette = MakeMedianCutPalette( nNumColors, pBits, nBits, nWidth, nHeight ); 
	else if( m_nPaletteCreationType == FIXED_PALETTE ) pRGBPalette = MakeFixedPalette( nNumColors ); 
	if( pRGBPalette == NULL ) return( NULL ); 
 
	LOGPALETTE *pLogPal = CreateLogPalette( pRGBPalette, nNumColors ); 
 
	delete [] pRGBPalette; 
 
	return( pLogPal ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//void SetPaletteCreationType( int nType )		     
//---------------------------------------------------------------------- 
//基本功能:当希望通过颜色还原得到一幅具有调色板的图像时,本函数负责设置 
//			调色板的创建类型。可以设置如下: 
//			#define POPULARITY_PALETTE	0 
//			#define MEDIAN_CUT_PALETTE	1 
//			#define FIXED_PALETTE		2 
//---------------------------------------------------------------------- 
//参数说明:int nType 
//---------------------------------------------------------------------- 
//返 回 值:无 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
void CDibObject::SetPaletteCreationType( int nType ) 
{ 
 
	m_nPaletteCreationType = nType; 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetPaletteCreationType( void )		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回用于下一次颜色还原操作的调色板类型。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nPaletteCreationType 
//---------------------------------------------------------------------- 
//////////////////////////////////////////////////////////////////////// 
int CDibObject::GetPaletteCreationType( void ) 
{ 
 
	return( m_nPaletteCreationType ); 
 
} 
 
RGBQUAD *CDibObject::MakePopularityPalette( int nNumColors, unsigned char *pBits, int nBits, int nWidth, int nHeight ) 
{ 
	RGBQUAD *pRGBQuad = new RGBQUAD[nNumColors]; 
	if( pRGBQuad == NULL ) return( MakeFixedPalette( nNumColors ) ); 
	memset( pRGBQuad, 0, nNumColors * sizeof( RGBQUAD ) ); 
 
	BYTE ColMap[256][3]; 
	if( !Popularity( pBits, nBits, nWidth, nHeight, ColMap ) ){ 
		delete [] pRGBQuad; 
		return( MakeFixedPalette( nNumColors ) ); 
		} 
 
	for( int i=0; i