www.pudn.com > zhifangtu.rar > ImageObject.cpp


// ImageObject.cpp 
 
#include "stdafx.h" 
#include "ImageObject.h" 
 
IMPLEMENT_DYNCREATE(CImageObject, CObject) 
 
char *CImageObject::szExtensions[] = { ".BMP", ".GIF", ".PCX", ".TGA", ".JPG", ".TIF", "" }; 
         
//Diagnostics and dump member functions, overridden 
#ifdef _DEBUG 
void CImageObject::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 = pImageObject->m_nHeight; 
	m_nPlanes = pImageObject->m_nPlanes; 
	m_nBits = pImageObject->m_nBits; 
	m_nColors = pImageObject->m_nColors; 
	m_nImageType = pImageObject->m_nImageType; 
	m_nX = pImageObject->m_nX; 
	m_nY = pImageObject->m_nY; 
	m_nLastError = pImageObject->m_nLastError; 
	m_nScreenPlanes = pImageObject->m_nScreenPlanes; 
	m_nScreenBits = pImageObject->m_nScreenBits; 
	m_nPaletteBytes = pImageObject->m_nPaletteBytes; 
	m_nQuality = pImageObject->m_nQuality; 
	m_nPaletteCreationType = pImageObject->m_nPaletteCreationType; 
	 
	int nNumColors = m_nColors; 
	int nWidthBytes = WidthBytes( m_nBits, m_nWidth ); 
	 
	if( pImageObject->m_hDib != NULL ) 
	{ 
		DWORD dwSize = ::GlobalSize( pImageObject->m_hDib ); 
		char *pData = (char *) ::GlobalLock( pImageObject->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( pImageObject->m_hDib ); 
		} 
	} 
} 
 
//////////////////////////////////////////////////////////////////////// 
//CImageObject类的构造函数		     
//---------------------------------------------------------------------- 
//基本功能:构造一个CImageObject对象。唯一的要求的一个参数是文件名。如果 
//			给出了CDC参数,图像只要一加载便被绘制。如果给出了nX或nY,这 
//			两个值会被保存起来并且图像显示在该坐标所在的位置。否则,图像 
//			总是显示在坐标为(0,0)的位置。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			CDC *pDC,默认为NULL 
//			int nX,默认为-1 
//			int nY,默认为-1 
//---------------------------------------------------------------------- 
//返 回 值:无 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
CImageObject::CImageObject( const char *pszFilename, 
						   CDC *pDC, int nX, int nY ) 
{ 
 
	InitVars(); 
	Load( pszFilename, pDC, nX, nY ); 
 
} 
 
CImageObject::~CImageObject() 
{ 
 
	if( m_hDib ) ::GlobalFree( m_hDib ); 
	if( m_pszFilename != NULL ) delete [] m_pszFilename; 
	if( m_pLogPal != NULL ) delete [] m_pLogPal; 
 
} 
 
//初始化 
void CImageObject::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()		     
//---------------------------------------------------------------------- 
//基本功能:本函数把一个文件装入CImageObject。必需的一个参数是文件名。如 
//			果给出了CDC参数,图像只要一加载便被绘制。如果给出了nX或nY, 
//			这两个值会被保存起来并且图像显示在该坐标所在的位置。否则,图 
//			像总是显示在坐标为(0,0)的位置。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			CDC *pDC,默认为NULL 
//			int nX,默认为-1 
//			int nY,默认为-1 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::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 ); 
 
	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( const char *pszFilename,int *pnWidth,int *pnHeight, 
//	 int *pnPlanes, int *pnBitsPerPixel, int *pnNumColors )		     
//---------------------------------------------------------------------- 
//基本功能:本函数获取图像信息如图像宽度、高度、位平面数、每个像素点的位 
//			数、以及颜色数。值为NULL的参数将不被传入。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			int *pnWidth,			默认为NULL 
//			int *pnHeight,			默认为NULL 
//			int *pnPlanes,			默认为NULL 
//			int *pnBitsPerPixel,	默认为NULL 
//			int *pnNumColors,		默认为NULL 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::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 ); 
		} 
 
	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()		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回所发生的最后一次CImageObject类错误。详细错误信息见 
//			"Errors.h"头文件。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nErrorNumber 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::GetLastError( void ) 
{ 
 
	return( m_nLastError ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL Save( const char *pszFilename, int nType )		     
//---------------------------------------------------------------------- 
//基本功能:本函数保存驻留于CImageObject对象中的当前图像(图像类型定义见 
//			GetImageType()函数。 
//---------------------------------------------------------------------- 
//参数说明:const char *pszFilename 
//			int nType,默认为-1 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::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 ); 
 
	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 CImageObject::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( void ) 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的像素宽度数。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nWidth 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::GetWidth( void ) 
{ 
 
	return( m_nWidth ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetHeight( void ) 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的像素高度数。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nHeight 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::GetHeight( void ) 
{ 
 
	return( m_nHeight ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetNumBits( void ) 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的像素数:1、4、8、16、24、32。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nBits 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::GetNumBits( void ) 
{ 
 
	return( m_nBits ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetNumColors( void ) 
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像调色板中的颜色。图像为16位色或更高时返回值为0。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nColors 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::GetNumColors( void ) 
{ 
 
	return( m_nColors ); 
 
} 
long CImageObject::GetFileSize( void ) 
{ 
	return( m_nFileSize ); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//BOOL GetPaletteData( RGBQUAD *pRGBPalette )		     
//---------------------------------------------------------------------- 
//基本功能:本函数将当前RGB调色板数据填入到所传入的指针中。如果图像是16 
//			位色或更高时则不进行任何操作。 
//---------------------------------------------------------------------- 
//参数说明:RGBQUAD *pRGBPalette 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::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( void )		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回一个指向CImageObject调色板数据序列的指针。如果图像 
//			是16位色或更高时则返回NULL。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:返回一个指向CImageObject调色板数据序列的指针 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
RGBQUAD *CImageObject::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( const char *pFilename )		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的类型。图像类型定义如下: 
//			#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 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::GetImageType( const char *pFilename ) 
{ 
 
	return( ::FileType( pFilename ) ); 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetImageType( void )		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回图像的类型。图像类型定义如下: 
//			#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 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::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 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::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 ); 
 
} 
 
//创建调色板 
LOGPALETTE *CImageObject::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 CImageObject::ProcessImageHeader( void ) 
{ 
 
	m_nLastError = IMAGELIB_HDIB_NULL; 
	if( m_hDib == NULL ) return; 
 
	char *pTemp; 
	BITMAPINFOHEADER *pBIH; 
	BITMAPFILEHEADER *pBFH;//// 
	pTemp = (char *) ::GlobalLock( m_hDib ); 
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR; 
	if( pTemp == NULL ) return; 
 
	pBIH = (BITMAPINFOHEADER *) &pTemp[sizeof(BITMAPFILEHEADER)]; 
	pBFH=(BITMAPFILEHEADER *)pTemp;//偏移至文件头信息 
	m_nWidth = pBIH->biWidth; 
	m_nHeight = pBIH->biHeight; 
	m_nPlanes = pBIH->biPlanes; 
	m_nBits = pBIH->biBitCount; 
	m_nColors = 1 << m_nBits; 
	m_nFileSize=pBFH->bfSize;//// 
	m_nBfOffBits=pBFH->bfOffBits;/// 
	if( m_nPlanes > 1 ) m_nColors <<= ( m_nPlanes - 1 ); 
	if( m_nBits >= 16 ) m_nColors = 0; 
 
	::GlobalUnlock( m_hDib ); 
 
	m_nLastError = IMAGELIB_SUCCESS; 
 
} 
 
//处理体调色板 
void CImageObject::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 CImageObject::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 )		     
//---------------------------------------------------------------------- 
//基本功能:本函数将该设备描述表的调色板分配给相应的图像。当一个图像被载 
//			入时,它的调色板信息便被存入CImageObject对象中。 
//---------------------------------------------------------------------- 
//参数说明:CDC *pDC 
//---------------------------------------------------------------------- 
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::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 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::IsLoaded( void ) 
{ 
 
	return( m_hDib != NULL ); 
 
} 
 
//得到指针 
void *CImageObject::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 CImageObject::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; 
	while( ( nWidthBytes & 3 ) != 0 ) nWidthBytes++; 
 
	return( nWidthBytes ); 
 
} 
 
 
//坐标调整 
void CImageObject::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 CImageObject::operator= (const CImageObject &ImageObject) 
{ 
 
	KillImage(); 
 
	m_nWidth = ImageObject.m_nWidth; 
	m_nHeight = ImageObject.m_nHeight; 
	m_nPlanes = ImageObject.m_nPlanes; 
	m_nBits = ImageObject.m_nBits; 
	m_nColors = ImageObject.m_nColors; 
	m_nImageType = ImageObject.m_nImageType; 
	m_nX = ImageObject.m_nX; 
	m_nY = ImageObject.m_nY; 
	m_nLastError = ImageObject.m_nLastError; 
	m_nScreenPlanes = ImageObject.m_nScreenPlanes; 
	m_nScreenBits = ImageObject.m_nScreenBits; 
	m_nPaletteBytes = ImageObject.m_nPaletteBytes; 
	m_nQuality = ImageObject.m_nQuality; 
	m_nPaletteCreationType = ImageObject.m_nPaletteCreationType; 
 
	int nNumColors = m_nColors; 
	int nWidthBytes = WidthBytes( m_nBits, m_nWidth ); 
 
	if( ImageObject.m_hDib != NULL ){ 
 
		DWORD dwSize = ::GlobalSize( ImageObject.m_hDib ); 
 
		char *pData = (char *) ::GlobalLock( ImageObject.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( ImageObject.m_pLogPal != NULL ){ 
						m_pLogPal = (LOGPALETTE *) new char [sizeof(LOGPALETTE)+ImageObject.m_pLogPal->palNumEntries*sizeof(PALETTEENTRY)]; 
						if( m_pLogPal != NULL ){ 
							for( int i=0; ipalNumEntries; i++ ) m_pLogPal[i] = ImageObject.m_pLogPal[i]; 
							m_Palette.CreatePalette( m_pLogPal ); 
							} 
						} 
 
					::GlobalUnlock( hGlobal ); 
					m_hDib = hGlobal; 
					} 
				else ::GlobalFree( hGlobal ); 
				} 
			::GlobalUnlock( ImageObject.m_hDib ); 
			} 
		} 
 
	if( ImageObject.m_pszFilename != NULL ){ 
		m_pszFilename = new char [strlen(ImageObject.m_pszFilename)+1]; 
		strcpy( m_pszFilename, ImageObject.m_pszFilename ); 
		} 
} 
 
//从位图创建调色板 
void CImageObject::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 CImageObject::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 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
BOOL CImageObject::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 *CImageObject::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 
//---------------------------------------------------------------------- 
//返 回 值:无 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
void CImageObject::SetPaletteCreationType( int nType ) 
{ 
 
	m_nPaletteCreationType = nType; 
 
} 
 
//////////////////////////////////////////////////////////////////////// 
//int GetPaletteCreationType( void )		     
//---------------------------------------------------------------------- 
//基本功能:本函数返回用于下一次颜色还原操作的调色板类型。 
//---------------------------------------------------------------------- 
//参数说明:无 
//---------------------------------------------------------------------- 
//返 回 值:int nPaletteCreationType 
//---------------------------------------------------------------------- 
//编	者:耿	楠 
//最后编改:2001年11月20日 
//////////////////////////////////////////////////////////////////////// 
int CImageObject::GetPaletteCreationType( void ) 
{ 
 
	return( m_nPaletteCreationType ); 
 
} 
 
//普及调色板 
RGBQUAD *CImageObject::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