www.pudn.com > 人体步态跟踪识别bate版.rar > Cdib.cpp


// cdib.cpp 
 
#include "stdafx.h" 
#include "cdib.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
IMPLEMENT_SERIAL(CDib, CObject, 0); 
//////////////////////////////////////////// 
//缺省构造函数 
// 
//创建一个空的DIB对象 
///////////////////////////////////////////// 
CDib::CDib() 
{ 
	m_hFile = NULL; 
	m_hBitmap = NULL; 
	m_hPalette = NULL; 
	m_Dest.x = 0; 
	m_Dest.y = 0; 
	m_DestSize.cx = 0; 
	m_DestSize.cy = 0; 
	m_Src.x = 0; 
	m_Src.y = 0; 
	m_SrcSize.cx = 0; 
	m_SrcSize.cy = 0; 
	InitDestroy(); 
} 
//////////////////////////////////////////// 
//通过CreateDIBSection函数创建DIB项时,使用这个函数。 
//它包括DIB的尺寸和颜色数。它对信息头分配内存,而对图 
//像不分配内存。 
//参数 
//size:图像的宽度和高度; 
//nBitCounts:像素的位数(为1、4、8、16、24、32) 
//////////////////////////////////////////// 
CDib::CDib(CSize size, int nBitCounts) 
{ 
	m_hFile = NULL; 
	m_hBitmap = NULL; 
	m_hPalette = NULL; 
	InitDestroy(); 
	ComputePaletteSize(nBitCounts);//为BITMAPINFOHEADER结构申请空间。 
	m_lpBMPHdr = (LPBITMAPINFOHEADER) new  
		char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorEntries]; 
	m_lpBMPHdr->biSize = sizeof(BITMAPINFOHEADER);//以下是为BITMAPINFOHEADER结构赋值 
	m_lpBMPHdr->biWidth = size.cx; 
	m_lpBMPHdr->biHeight = size.cy; 
	m_lpBMPHdr->biPlanes = 1; 
	m_lpBMPHdr->biBitCount = nBitCounts; 
	m_lpBMPHdr->biCompression = BI_RGB; 
	m_lpBMPHdr->biSizeImage = 0; 
	m_lpBMPHdr->biXPelsPerMeter = 0; 
	m_lpBMPHdr->biYPelsPerMeter = 0; 
	m_lpBMPHdr->biClrUsed = m_nColorEntries; 
	m_lpBMPHdr->biClrImportant = m_nColorEntries; 
	ComputeImage(); 
	memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorEntries); 
	m_lpDIBits = NULL;   
} 
//////////////////////////////////////////// 
//析构函数,释放内存 
//////////////////////////////////////////// 
CDib::~CDib() 
{ 
	InitDestroy(); 
} 
//////////////////////////////////////////// 
//返回值:图像的高度 
//////////////////////////////////////////// 
int CDib::GetHeight () 
{ 
	if(m_lpBMPHdr == NULL) return 0; 
	return m_lpBMPHdr->biHeight;//返回图像的高度 
} 
//////////////////////////////////////////// 
//返回值:图像的宽度 
//////////////////////////////////////////// 
int CDib::GetWidth () 
{ 
	if(m_lpBMPHdr == NULL) return 0; 
	return m_lpBMPHdr->biWidth;//返回图像的宽度 
} 
//////////////////////////////////////////// 
//该函数用只读模式打开一个内存映射文件。 
//参数 
//strPathName:映射的文件路径 
//bSharing:TRUE 以共享方式打开;FALSE 缺省值 
//返回值:成功为TRUE 
//////////////////////////////////////////// 
BOOL CDib::SetMapFile(const char* strPathname, BOOL bSharing) // 只读 
{ 
	//如果我们两次打开同一文件,Windows会把它当作两个单独的文件 
	//如果调色板的颜色数大于实际使用的颜色数,则不会工作 
 
	HANDLE hFile =  
		::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ, 
		bSharing ? FILE_SHARE_READ : 0, 
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
	DWORD dwFileSize = ::GetFileSize(hFile, NULL); 
	HANDLE hMap = ::CreateFileMapping(hFile,  
				NULL, PAGE_READWRITE, 0, 0, NULL); 
	DWORD dwErr = ::GetLastError(); 
	if(hMap == NULL) { 
		AfxMessageBox("Empty bitmap file"); 
		return FALSE; 
	} 
	// 映射整个文件 
	LPVOID lpvFile = ::MapViewOfFile(hMap,  
				FILE_MAP_WRITE, 0, 0, 0);  
	ASSERT(lpvFile != NULL); 
	if(((LPBITMAPFILEHEADER) lpvFile)->bfType != 0x4d42) { 
		AfxMessageBox("Invalid bitmap file"); 
		ReleaseMapFile(); 
		return FALSE; 
	} 
	AllotDibMemory((LPBYTE) lpvFile +  
						sizeof(BITMAPFILEHEADER)); 
	m_lpvFile = lpvFile; 
	m_hFile = hFile; 
	m_hMap = hMap; 
	return TRUE; 
} 
//////////////////////////////////////////// 
//这个函数创建一个新的内存映射文件,并把 
//信息拷贝到该文件中,释放内存。 
//strPathName:映射的文件路径 
//返回值:成功为TRUE 
//////////////////////////////////////////// 
BOOL CDib::CopyMapFile(const char* strPathname) 
{ 
	//将DIB拷贝到一个新的文件中,释放先前的指针 
	//如果以前使用过CreateSection函数,则HBITMAP为NULL 
	 
 
	BITMAPFILEHEADER bmfh; 
	bmfh.bfType = 0x4d42;  // 'BM' 
	bmfh.bfSize =  
		m_dwImageSize + sizeof(BITMAPINFOHEADER) +  
		sizeof(RGBQUAD) * m_nColorEntries + sizeof(BITMAPFILEHEADER); 
	// meaning of bfSize open to interpretation 
	bmfh.bfReserved1 = bmfh.bfReserved2 = 0; 
	bmfh.bfOffBits =  
		sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  
		+ sizeof(RGBQUAD) * m_nColorEntries;	 
	HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE |  
					GENERIC_READ, 0, NULL,	CREATE_ALWAYS,  
					FILE_ATTRIBUTE_NORMAL, NULL); 
	int size =   
		sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
		sizeof(RGBQUAD) * m_nColorEntries +  m_dwImageSize; 
	HANDLE hMap = ::CreateFileMapping(hFile, NULL,  
					PAGE_READWRITE, 0, size, NULL); 
	DWORD dwErr = ::GetLastError(); 
	ASSERT(hMap != NULL);  
	// 映射整个文件 
	LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); 
	ASSERT(lpvFile != NULL); 
	LPBYTE lpbCurrent = (LPBYTE) lpvFile; 
	memcpy(lpbCurrent, &bmfh, sizeof(BITMAPFILEHEADER)); // 文件头 
	lpbCurrent += sizeof(BITMAPFILEHEADER); 
	LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpbCurrent; 
	memcpy(lpbCurrent, m_lpBMPHdr, sizeof(BITMAPINFOHEADER) +  
						sizeof(RGBQUAD) * m_nColorEntries);  
	lpbCurrent += sizeof(BITMAPINFOHEADER) +  
					sizeof(RGBQUAD) * m_nColorEntries; 
	memcpy(lpbCurrent, m_lpDIBits, m_dwImageSize); // bit 图像 
	DWORD dwSizeImage = m_dwImageSize; 
	InitDestroy(); 
	m_dwImageSize = dwSizeImage; 
	m_lpBMPHdr = lpBMIH; 
	m_lpDIBits = lpbCurrent; 
	m_hFile = hFile; 
	m_hMap = hMap; 
	m_lpvFile = lpvFile; 
	ComputePaletteSize(m_lpBMPHdr->biBitCount); 
	ComputeImage(); 
	SetWinPalette(); 
	return TRUE; 
} 
//////////////////////////////////////////// 
//将内存和一个DIB对象联系起来。 
//参数 
//lpvMemory:内存地址 
//////////////////////////////////////////// 
BOOL CDib::AllotDibMemory(LPVOID lpvMemory) 
{ 
	//假定一个BITMAPINFOHEADER结构,颜色表,图像 
	//颜色表的长度可以为0 
 
	InitDestroy(); 
	try { 
		m_lpBMPHdr = (LPBITMAPINFOHEADER) lpvMemory; 
		ComputeImage(); 
		ComputePaletteSize(m_lpBMPHdr->biBitCount); 
		m_lpDIBits = (LPBYTE) m_lpvColorTable +  
					sizeof(RGBQUAD) * m_nColorEntries; 
		SetWinPalette(); 
	} 
	catch(CException* pe) { 
		AfxMessageBox("AllotDibMemory error"); 
		pe->Delete(); 
		return FALSE; 
	} 
	return TRUE; 
} 
//////////////////////////////////////////// 
//把DIB对象的逻辑调色板选进设备环境里,然后 
//实现调色板。 
//参数 
//pDC:设备环境指针 
//////////////////////////////////////////// 
UINT CDib::UseLogPalette(CDC* pDC) 
{ 
	if(m_hPalette == NULL) return 0; 
	HDC hdc = pDC->GetSafeHdc(); 
	::SelectPalette(hdc, m_hPalette,FALSE);//Windows作为前台调色板来实现该调色板 
	return ::RealizePalette(hdc); 
} 
///////////////////////////////////////////// 
//这个函数用来显示DIB图像 
//参数 
//pDC:设备环境指针 
//origin:显示DIB的逻辑坐标 
//size:DIB的逻辑宽度和高度 
//////////////////////////////////////////// 
BOOL CDib::Display(CDC* pDC) 
{ 
	if(m_lpBMPHdr == NULL) return FALSE; 
	if(m_hPalette != NULL) { 
		::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE); 
	} 
	pDC->SetStretchBltMode(COLORONCOLOR); 
	//取得图像文件的拷贝文件  
	char name[30] ; 
	GetCurrentDirectory(30, name) ; 
	CString Pathname = CString(name) ; 
	CopyMapFile(Pathname) ; 
 
	::StretchDIBits(pDC->GetSafeHdc(), m_Dest.x, m_Dest.y, 
								m_DestSize.cx, m_DestSize.cy, 
								m_Src.x, m_Src.y, 
								m_SrcSize.cx, m_SrcSize.cy, 
								m_lpDIBits, (LPBITMAPINFO) m_lpBMPHdr,  
								DIB_RGB_COLORS, SRCCOPY); 
	return TRUE; 
} 
///////////////////////////////////////////// 
//调用CreateDIBSection函数来创建DIB项 
//参数 
//pDC:设备环境指针 
//////////////////////////////////////////// 
//调用CreateDIBSection函数来创建DIB项 
HBITMAP CDib::CreateSection(CDC* pDC ) 
{ 
	if(m_lpBMPHdr == NULL) return NULL; 
	if(m_lpDIBits != NULL) return NULL; // 图像不存在 
	m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), 
		(LPBITMAPINFO) m_lpBMPHdr, DIB_RGB_COLORS, 
		(LPVOID*) &m_lpDIBits, NULL, 0); 
	ASSERT(m_lpDIBits != NULL); 
	return m_hBitmap; 
} 
///////////////////////////////////////////// 
//调用CreateDIBSection函数来创建DIB项 
//从DIB颜色表生成逻辑调色板,在显示DIB位图之前, 
//将这个调色板选入设备并实现它 
//////////////////////////////////////////// 
BOOL CDib::SetWinPalette() 
{ 
	if(m_nColorEntries == 0) return FALSE; 
	if(m_hPalette != NULL) ::DeleteObject(m_hPalette); 
	TRACE("CDib::MakePalette --	m_nColorEntries = %d\n", m_nColorEntries); 
	LPLOGPALETTE pLogPal =  
		(LPLOGPALETTE) new char[2 * sizeof(WORD) + 
		m_nColorEntries * sizeof(PALETTEENTRY)]; 
	pLogPal->palVersion = 0x300; 
	pLogPal->palNumEntries = m_nColorEntries; 
	LPRGBQUAD pDibRGBquad = (LPRGBQUAD) m_lpvColorTable; 
	for(int i = 0; i < m_nColorEntries; i++) { 
		pLogPal->palPalEntry[i].peRed =  
				pDibRGBquad->rgbRed; 
		pLogPal->palPalEntry[i].peGreen = 
				pDibRGBquad->rgbGreen; 
		pLogPal->palPalEntry[i].peBlue =  
				pDibRGBquad->rgbBlue; 
		pLogPal->palPalEntry[i].peFlags = 0; 
		pDibRGBquad++; 
	} 
	m_hPalette = ::CreatePalette(pLogPal); 
	delete pLogPal; 
	return TRUE; 
}	 
///////////////////////////////////////////// 
//如果DIB没有颜色表,可以用逻辑调色板。 
//参数 
//pDC:设备环境指针 
//////////////////////////////////////////// 
BOOL CDib::SetLogPalette(CDC* pDC) 
{ 
	//如果DIB没有颜色表,可以用逻辑调色板 
	if(m_nColorEntries != 0) return FALSE; 
	m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc()); 
	return TRUE; 
} 
///////////////////////////////////////////// 
//用DIB创建一个DDB位图。 
//参数 
//pDC:设备环境指针 
//////////////////////////////////////////// 
HBITMAP CDib::CreateBitmap(CDC* pDC) 
{ 
    if (m_dwImageSize == 0) return NULL; 
    HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), 
		m_lpBMPHdr, CBM_INIT, m_lpDIBits,  
		(LPBITMAPINFO) m_lpBMPHdr, DIB_RGB_COLORS); 
    ASSERT(hBitmap != NULL); 
    return hBitmap; 
} 
///////////////////////////////////////////// 
//这个函数产生压缩或非压缩的DIB。 
//参数 
//pDC:设备环境指针 
//BitsCompress:TRUE 表示压缩;FALSE 表示解压缩 
//////////////////////////////////////////// 
BOOL CDib::CompressDib(CDC* pDC, BOOL BitsCompress /* = TRUE */) 
{ 
	//先将DIB转换到一个DDB 
	//从这个DDB来生成一个新的DIB 
	//清除原来的DIB 
	//将新的DIB放到目标中 
	if((m_lpBMPHdr->biBitCount != 4) &&  
				(m_lpBMPHdr->biBitCount != 8))  
		return FALSE; 
		// 压缩只支持4-bpp和8-bpp的方式的DIB 
	if(m_hBitmap) return FALSE; // 不能压缩单个DIB项 
	TRACE("Compress: original palette size = %d\n", 
									m_nColorEntries);  
	HDC hdc = pDC->GetSafeHdc(); 
	HPALETTE hOldPalette =  
				::SelectPalette(hdc, m_hPalette, FALSE); 
	HBITMAP hBitmap;   
	if((hBitmap = CreateBitmap(pDC)) == NULL)  
		return FALSE; 
	int nSize = sizeof(BITMAPINFOHEADER) +  
				sizeof(RGBQUAD) * m_nColorEntries; 
	LPBITMAPINFOHEADER lpBMPHdr =  
				(LPBITMAPINFOHEADER) new char[nSize]; 
	memcpy(lpBMPHdr, m_lpBMPHdr, nSize);   
	if(BitsCompress) { 
		switch (lpBMPHdr->biBitCount) { 
		case 4: 
			lpBMPHdr->biCompression = BI_RLE4; 
			break; 
		case 8: 
			lpBMPHdr->biCompression = BI_RLE8; 
			break; 
		default: 
			ASSERT(FALSE); 
		} 
		//调用GetDIBits函数来获得压缩的DIB的尺寸 
 
		if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0,  
						(UINT) lpBMPHdr->biHeight, 
						NULL, (LPBITMAPINFO) lpBMPHdr, DIB_RGB_COLORS)) { 
			AfxMessageBox("Unable to compress this DIB"); 
			//如果不能压缩则删除相应的内存空间 
			 
			::DeleteObject(hBitmap); 
			delete [] lpBMPHdr; 
			::SelectPalette(hdc, hOldPalette, FALSE); 
			return FALSE;  
		} 
		if (lpBMPHdr->biSizeImage == 0) { 
			AfxMessageBox("Driver can't do compression"); 
	 		::DeleteObject(hBitmap); 
			delete [] lpBMPHdr; 
			::SelectPalette(hdc, hOldPalette, FALSE); 
			return FALSE;  
		} 
		else { 
			m_dwImageSize = lpBMPHdr->biSizeImage; 
		} 
	} 
	else { 
		lpBMPHdr->biCompression = BI_RGB; //解压缩 
		//从bitmap的宽度和高度计算出图像的尺寸 
 
		DWORD dwBytes = ((DWORD) lpBMPHdr->biWidth *  
							lpBMPHdr->biBitCount) / 32; 
		if(((DWORD) lpBMPHdr->biWidth * lpBMPHdr->biBitCount) % 32) { 
			dwBytes++; 
		} 
		dwBytes *= 4; 
		m_dwImageSize = dwBytes * lpBMPHdr->biHeight; // 不解压 
		lpBMPHdr->biSizeImage = m_dwImageSize; 
	}  
	//第二次调用GetDIBits函数来生成DIB项 
	LPBYTE lpImage = (LPBYTE) new char[m_dwImageSize]; 
	VERIFY(::GetDIBits(pDC->GetSafeHdc(), 
			hBitmap, 0, (UINT) lpBMPHdr->biHeight, 
    		lpImage, (LPBITMAPINFO) lpBMPHdr, DIB_RGB_COLORS)); 
    TRACE("dib successfully created - height = %d\n",  
									lpBMPHdr->biHeight); 
	::DeleteObject(hBitmap); 
	InitDestroy(); 
	m_lpBMPHdr = lpBMPHdr; 
	m_lpDIBits = lpImage; 
	ComputeImage(); 
	ComputePaletteSize(m_lpBMPHdr->biBitCount); 
	SetWinPalette(); 
	::SelectPalette(hdc, hOldPalette, FALSE); 
	TRACE("Compress: new palette size = %d\n", m_nColorEntries);  
	return TRUE; 
} 
///////////////////////////////////////////// 
//这个函数从文件中将DIB读进CDib对象中,文件 
//被成功的打开。 
//参数 
//pFile:指向包含DIB文件的指针 
//////////////////////////////////////////// 
BOOL CDib::ReadFile(CFile* pFile) 
{ 
	//读文件头得到BITMAPINFOHEADER和颜色表的大小 
	//读BITMAPINFOHEADER得到图像小、尺寸和颜色表 
	//读取图像信息 
	InitDestroy(); 
	int counts, size; 
	BITMAPFILEHEADER bmfh; 
	try { 
		counts = pFile->Read((LPVOID)&bmfh, sizeof(BITMAPFILEHEADER)); 
		if(counts != sizeof(BITMAPFILEHEADER))  
		{ 
			throw new CException; 
		} 
		if(bmfh.bfType != 0x4d42)  
		{ 
			throw new CException; 
		} 
		size = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); 
		m_lpBMPHdr = (LPBITMAPINFOHEADER) new char[size]; 
		// BITMAPINFOHEADER和颜色表 
		counts = pFile->Read(m_lpBMPHdr, size);  
		ComputeImage(); 
		ComputePaletteSize(m_lpBMPHdr->biBitCount); 
		SetWinPalette(); 
		m_lpDIBits = (LPBYTE) new char[m_dwImageSize]; 
		counts = pFile->Read(m_lpDIBits, m_dwImageSize);  
	} 
	catch(CException* pe) { 
		AfxMessageBox("Read error"); 
		pe->Delete(); 
		return FALSE; 
	} 
	return TRUE; 
} 
///////////////////////////////////////////// 
//读BMP文件得到信息头和颜色表的大小,用这些信息 
//来创建图像,并将其读到用CreateDibSection分配 
//的空间中。 
//参数 
//pFile:指向包含DIB文件的指针 
//pDC:设备环境指针 
//////////////////////////////////////////// 
 
BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */) 
{ 
 
	InitDestroy(); 
	int counts, size; 
	BITMAPFILEHEADER bmfh; 
	try { 
		counts = pFile->Read((LPVOID) &bmfh,  
					sizeof(BITMAPFILEHEADER)); 
		if(counts != sizeof(BITMAPFILEHEADER)) { 
			throw new CException; 
		} 
		if(bmfh.bfType != 0x4d42) { 
			throw new CException; 
		} 
		size = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); 
		m_lpBMPHdr = (LPBITMAPINFOHEADER) new char[size]; 
		//BITMAPINFOHEADER和颜色表 
		counts = pFile->Read(m_lpBMPHdr, size);  
		if(m_lpBMPHdr->biCompression != BI_RGB) { 
			throw new CException; 
		} 
		ComputeImage(); 
		ComputePaletteSize(m_lpBMPHdr->biBitCount); 
		SetWinPalette(); 
		UseLogPalette(pDC); 
		m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(),  
			(LPBITMAPINFO) m_lpBMPHdr, DIB_RGB_COLORS, 
			(LPVOID*) &m_lpDIBits, NULL, 0); 
		ASSERT(m_lpDIBits != NULL); 
		counts = pFile->Read(m_lpDIBits, m_dwImageSize); // 图像 
	} 
	catch(CException* pe) { 
		AfxMessageBox("ReadSection error"); 
		pe->Delete(); 
		return FALSE; 
	} 
	return TRUE; 
} 
/////////////////////////////////////////////// 
//这个函数将DIB从CDib对象中写到文件中,文件 
//被成功的打开。 
//参数 
//pFile:指向包含DIB文件的指针 
/////////////////////////////////////////////// 
BOOL CDib::WriteFile(CFile* pFile) 
{ 
	BITMAPFILEHEADER bmfh; 
	bmfh.bfType = 0x4d42;  // 'BM' 
	int sizeHdr = sizeof(BITMAPINFOHEADER) +  
				sizeof(RGBQUAD) * m_nColorEntries; 
	bmfh.bfSize = 0; 
	bmfh.bfReserved1 = bmfh.bfReserved2 = 0; 
	bmfh.bfOffBits =  
		sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
		sizeof(RGBQUAD) * m_nColorEntries;	 
	try { 
		pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); 
		pFile->Write((LPVOID) m_lpBMPHdr,  sizeHdr); 
		pFile->Write((LPVOID) m_lpDIBits, m_dwImageSize); 
	} 
	catch(CException* pe) { 
		pe->Delete(); 
		AfxMessageBox("write error"); 
		return FALSE; 
	} 
	return TRUE; 
} 
//存储图像 
void CDib::Serialize(CArchive& ar) 
{ 
	DWORD pos; 
	pos = ar.GetFile()->GetPosition(); 
	TRACE("CDib::Serialize -- pos = %d\n", pos); 
	ar.Flush(); 
	pos = ar.GetFile()->GetPosition(); 
	TRACE("CDib::Serialize -- pos = %d\n", pos); 
	if(ar.IsStoring()) { 
		WriteFile(ar.GetFile()); 
	} 
	else { 
		ReadFile(ar.GetFile()); 
	} 
} 
/////////////////////////////////////////////// 
//这个函数计算调色板的大小。 
//参数 
//nBitCounts:像素的位数(为1、4、8、16、24、32) 
/////////////////////////////////////////////// 
void CDib::ComputePaletteSize(int nBitCounts) 
{ 
	if((m_lpBMPHdr == NULL) || (m_lpBMPHdr->biClrUsed == 0)) { 
		switch(nBitCounts) { 
			case 1: 
				m_nColorEntries = 2; 
				break; 
			case 4: 
				m_nColorEntries = 16; 
				break; 
			case 8: 
				m_nColorEntries = 256; 
				break; 
			case 16: 
			case 24: 
			case 32: 
				m_nColorEntries = 0; 
				break; 
			default: 
				ASSERT(FALSE); 
		} 
	} 
	else { 
		m_nColorEntries = m_lpBMPHdr->biClrUsed; 
	} 
	ASSERT((m_nColorEntries >= 0) && (m_nColorEntries <= 256));  
} 
/////////////////////////////////////////////// 
//这个函数计算图像的大小。 
/////////////////////////////////////////////// 
void CDib::ComputeImage() 
{ 
	if(m_lpBMPHdr->biSize != sizeof(BITMAPINFOHEADER)) { 
		TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n"); 
		throw new CException; 
	} 
	m_dwImageSize = m_lpBMPHdr->biSizeImage; 
	if(m_dwImageSize == 0) { 
		DWORD dwBytes = ((DWORD) m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) / 32; 
		if(((DWORD) m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) % 32) { 
			dwBytes++; 
		} 
		dwBytes *= 4; 
		// 没被压缩 
		m_dwImageSize = dwBytes * m_lpBMPHdr->biHeight;  
	} 
	m_lpvColorTable = (LPBYTE) m_lpBMPHdr + sizeof(BITMAPINFOHEADER); 
} 
/////////////////////////////////////////////// 
//这个函数清除所申请到的内存。 
/////////////////////////////////////////////// 
void CDib::InitDestroy() 
{ 
	 
	ReleaseMapFile(); 
	if(m_hPalette != NULL) ::DeleteObject(m_hPalette); 
	if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap); 
	m_hGlobal = NULL; 
	m_lpBMPHdr = NULL; 
	m_lpDIBits = NULL; 
	m_lpvColorTable = NULL; 
	m_nColorEntries = 0; 
	m_dwImageSize = 0; 
	m_lpvFile = NULL; 
	m_hMap = NULL; 
	m_hFile = NULL; 
	m_hBitmap = NULL; 
	m_hPalette = NULL; 
} 
/////////////////////////////////////////////// 
//这个函数释放被映射的文件。 
/////////////////////////////////////////////// 
void CDib::ReleaseMapFile() 
{ 
	if(m_hFile == NULL) return; 
	::UnmapViewOfFile(m_lpvFile); 
	::CloseHandle(m_hMap); 
	::CloseHandle(m_hFile); 
	m_hFile = NULL; 
}