www.pudn.com > QRAPPuie.rar > FG_DIB.cpp


// FG_DIB.cpp: implementation of the CFG_DIB class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "FG_DIB.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
 
CFG_DIB::CFG_DIB() 
{ 
	m_hFile = NULL; 
	m_hMap = NULL; 
	m_lpvFile = NULL; 
	m_hBitmap = NULL; 
	m_hPalette = NULL; 
	m_lpDIBits = NULL; 
	m_lpvColorTable = 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; 
	m_nMode = 0; 
	InitDestroy(); 
} 
 
CFG_DIB::CFG_DIB(int width, int height, int nBitCounts) 
{ 
	m_nMode = 0; 
	m_hBitmap = NULL; 
	m_hPalette = NULL; 
	m_lpDIBits = 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(); 
	ComputePaletteSize(nBitCounts);					//为BITMAPINFOHEADER结构申请空间。 
	m_lpBMPHdr = (LPBITMAPINFOHEADER)new  
		char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorEntries]; 
	m_lpBMPHdr->biSize = sizeof(BITMAPINFOHEADER);	//以下是为BITMAPINFOHEADER结构赋值 
	m_lpBMPHdr->biWidth = width; 
	m_lpBMPHdr->biHeight = height; 
	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;   
} 
 
CFG_DIB::~CFG_DIB() 
{ 
	InitDestroy(); 
} 
 
void CFG_DIB::InitDestroy() 
{ 
	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; 
	if(m_hPalette != NULL) ::DeleteObject(m_hPalette); 
	if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap); 
	if(m_lpBMPHdr != NULL) 
	{ 
		//delete m_lpBMPHdr; 
		m_lpBMPHdr = NULL; 
	} 
	if(m_lpDIBits != NULL) 
	{ 
		if(m_nMode == 0) 
		{ 
			delete []m_lpDIBits; 
			m_lpDIBits = NULL; 
		} 
		else if(m_nMode == 1) 
		{ 
			ReleaseMapFile(); 
		} 
		m_lpDIBits = NULL; 
	} 
	if(m_lpvColorTable != NULL) 
	{ 
		//delete []m_lpvColorTable; 
		m_lpvColorTable = NULL; 
	} 
	m_nColorEntries = 0; 
	m_dwImageSize = 0; 
	m_hBitmap = NULL; 
	m_hPalette = NULL; 
	ReleaseMapFile(); 
} 
 
void CFG_DIB::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 CFG_DIB::ComputeImage() 
{ 
	if(m_lpBMPHdr->biSize != sizeof(BITMAPINFOHEADER)) { 
//	TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n"); 
//	 	throw new CException;                    ///eda 
	} 
	m_dwImageSize = m_lpBMPHdr->biSizeImage; 
	if(m_dwImageSize == 0) { //BI_RGB这种未压缩格式的位图,成员biSizeImage也将被设置为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); 
} 
 
 
BOOL CFG_DIB::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);        //creates a logical color palette. 
	delete pLogPal; 
	pLogPal = NULL; 
	return TRUE; 
} 
 
 
UINT CFG_DIB::UseLogPalette(CDC* pDC) 
{ 
	if(m_hPalette == NULL) return 0; 
	HDC hdc = pDC->GetSafeHdc(); 
	::SelectPalette(hdc, m_hPalette,FALSE);		//Windows作为前台调色板来实现该调色板 
	return ::RealizePalette(hdc); 
} 
 
BOOL CFG_DIB::CloseFile() 
{ 
	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(); 
	return TRUE; 
} 
 
 
BOOL CFG_DIB::ReadFile(CFile* pFile) 
{ 
	InitDestroy(); 
	int counts, size;  int testn; 
	BITMAPFILEHEADER bmfh; 
 
	HANDLE hFile; 
	try { 
		testn = sizeof(BITMAPFILEHEADER); 
 
		counts = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); 
	//	::ReadFile((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER),&nBytesRead,NULL); 
 
		if(counts != sizeof(BITMAPFILEHEADER))  
			{ 
			return FALSE;//error 
			} 
		if(bmfh.bfType != 0x4d42) 
			{ 
			return FALSE;//error 
			} 
		 
		size = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); 
		m_lpBMPHdr = (LPBITMAPINFOHEADER) new char[size]; 
		// BITMAPINFOHEADER和颜色表 
		counts = pFile->Read(m_lpBMPHdr, size);  
		ComputeImage();                                           //m_dwImageSize, m_lpvColorTable 
		ComputePaletteSize(m_lpBMPHdr->biBitCount);//biBitCount 每个像素的位数*(1) 
		SetWinPalette(); 
		if(m_nMode == 0) 
		{ 
			m_lpDIBits = (LPBYTE) new char[m_dwImageSize];         //2359296 ?? 
		} 
		counts = pFile->Read(m_lpDIBits, m_dwImageSize);  
	} 
	catch(CException* pe) { 
	AfxMessageBox(_T("Read file error")); 
		pe->Delete(); 
		return FALSE; 
	} 
	return TRUE; 
} 
 
BOOL CFG_DIB::ReadSection(CFile* pFile, CDC* pDC) 
{ 
	InitDestroy(); 
	int counts, size; 
	BITMAPFILEHEADER bmfh; 
	try { 
		counts = pFile->Read((LPVOID) &bmfh,  
					sizeof(BITMAPFILEHEADER)); 
		if(counts != sizeof(BITMAPFILEHEADER)) { 
///            TRACE("counts != sizeof(BITMAPFILEHEADER)\n"); 
		///	throw new CException;  //eda 
		} 
		if(bmfh.bfType != 0x4d42) { 
///			 TRACE("bmfh.bfType != 0x4d42\n"); 
		///	throw new CException;  //eda 
		} 
		size = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); 
		m_lpBMPHdr = (LPBITMAPINFOHEADER) new char[size]; 
		//BITMAPINFOHEADER和颜色表 
		counts = pFile->Read(m_lpBMPHdr, size);  
		if(m_lpBMPHdr->biCompression != BI_RGB) { 
///			TRACE("m_lpBMPHdr->biCompression != BI_RGB\n"); 
		///	throw new CException;  //eda 
		} 
		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(_T("ReadSection error")); 
		pe->Delete(); 
		return FALSE; 
	} 
	return TRUE; 
} 
 
BOOL CFG_DIB::Display(CDC* pDC) 
{ 
	if(m_lpBMPHdr == NULL) return FALSE; 
	if(m_hPalette != NULL) { 
		::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE); 
	} 
 
	::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; 
} 
 
long CFG_DIB::GetLineBit() 
{ 
	long dwBytes = ((long)m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) / 32; 
	if(((long)m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) % 32)  
	{ 
		dwBytes++; 
	} 
	dwBytes *= 4; 
 
	return dwBytes; 
} 
 
void CFG_DIB::SetMode(int mode) 
{ 
	if(mode == 0) 
	{ 
		InitDestroy(); 
		m_nMode = mode; 
		return; 
	} 
	else if(mode == 1) 
	{ 
		InitDestroy(); 
		m_nMode = mode; 
		return; 
	} 
	else 
	{ 
		return; 
	} 
} 
 
void CFG_DIB::ReleaseMapFile() 
{ 
	if(m_hFile == NULL) return; 
	::UnmapViewOfFile(m_lpvFile); 
	::CloseHandle(m_hMap); 
	::CloseHandle(m_hFile); 
	m_hFile = NULL; 
} 
 
///eda 
CString CFG_DIB::GetExeDir() 
{ 
	CString sInstallDir = _T(""); 
	HINSTANCE h = AfxGetInstanceHandle(); 
	TCHAR szModuleName[260]; 
	int nPathLength = GetModuleFileName(h,szModuleName,sizeof(szModuleName)); 
	CString s1 = _T(""); 
	wsprintf(s1.GetBuffer(260),_T("%s"),szModuleName); 
	s1.ReleaseBuffer(); 
	if(nPathLength) 
	{ 
		sInstallDir = s1.Left( s1.ReverseFind('\\')); 
	} 
 
	return sInstallDir; 
}