www.pudn.com > Gesture[20040824].rar > CBmpFile.cpp


// CBmpFile ver.2 is Copyright Jonathan Nix 
// All Rights Reserved. 
#include "stdafx.h" 
#include "CBmpFile.h" 
#include "NASSERT.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
CBmpFile::CBmpFile() 
{ 
	Init(); 
} 
 
CBmpFile::CBmpFile(LPSTR szFilename) 
{ 
	m_nIsValid = Load(szFilename) ? 1 : 0;  
} 
 
CBmpFile::~CBmpFile() 
{ 
	Destroy(); 
} 
 
bool CBmpFile::Load(LPSTR szFilename) 
{ 
	HANDLE hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL); 
	if(!hFile) return false; 
	Load(hFile); 
	CloseHandle(hFile); 
	return IsValid(); 
} 
 
bool CBmpFile::Load(HANDLE hFile) 
{ 
	Destroy(); 
 
	DWORD dwBytesRead; 
	int bSuccess; 
 
	DWORD &biSizeImage = m_bmInfoHeader.biSizeImage; 
 
	// File header 
	bSuccess = ReadFile(hFile, (LPVOID)&m_bmFileHeader, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL); 
	if(!(bSuccess && m_bmFileHeader.bfType==MAKEWORD('B','M'))) 
	{ ASSERT(false); return false; } 
 
	// Bitmap Info Header 
	bSuccess = ReadFile(hFile, (LPVOID)&m_bmInfoHeader, sizeof(BITMAPINFOHEADER), &dwBytesRead, NULL); 
	if(!(bSuccess && m_bmInfoHeader.biBitCount==24 && m_bmInfoHeader.biCompression==BI_RGB)) 
	{ ASSERT(false); return false; } 
 
	// This member may be zero since biCompression == BI_RGB 
	if(!m_bmInfoHeader.biSizeImage) 
		m_bmInfoHeader.biSizeImage = m_bmInfoHeader.biHeight * m_bmInfoHeader.biWidth * m_bmInfoHeader.biBitCount/8; 
 
	// Image Data 
	m_pRGB = (LPRGB)new BYTE[biSizeImage]; 
	if(!m_pRGB) { ASSERT(false); return false; } 
	bSuccess = ReadFile(hFile, (LPVOID)m_pRGB, biSizeImage, &dwBytesRead, NULL); 
	if(!bSuccess) { ASSERT(false); return false; } 
 
	m_nNumPixels = biSizeImage / 3; 
 
	m_nIsValid = 1; 
	return IsValid(); 
} 
 
bool CBmpFile::Save(LPSTR szFilename) 
{ 
	HANDLE hFile = CreateFile(szFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); 
	if(!hFile) { ASSERT(FALSE); return false; } 
	Save(hFile); 
	CloseHandle(hFile); 
	return IsValid(); 
} 
 
bool CBmpFile::Save(HANDLE hFile) 
{ 
	DWORD dwBytesWrit; 
	int bSuccess; 
 
	DWORD &biSizeImage = m_bmInfoHeader.biSizeImage; 
 
	// File header 
	bSuccess = WriteFile(hFile, (LPVOID)&m_bmFileHeader, sizeof(BITMAPFILEHEADER), &dwBytesWrit, NULL); 
	if(!(bSuccess && m_bmFileHeader.bfType==MAKEWORD('B','M'))) 
	{ ASSERT(false); return false; } 
 
	// This member may be zero since biCompression == BI_RGB 
	if(!m_bmInfoHeader.biSizeImage) 
		m_bmInfoHeader.biSizeImage = m_bmInfoHeader.biHeight * m_bmInfoHeader.biWidth * m_bmInfoHeader.biBitCount/8; 
 
	// Bitmap Info Header 
	bSuccess = WriteFile(hFile, (LPVOID)&m_bmInfoHeader, sizeof(BITMAPINFOHEADER), &dwBytesWrit, NULL); 
	if(!(bSuccess && m_bmInfoHeader.biBitCount==24 && m_bmInfoHeader.biCompression==BI_RGB)) 
	{ ASSERT(false); return false; } 
 
	// Image Data 
	if(!m_pRGB) { ASSERT(false); return false; } 
	bSuccess = WriteFile(hFile, (LPVOID)m_pRGB, biSizeImage, &dwBytesWrit, NULL); 
	if(!bSuccess) { ASSERT(false); return false; } 
 
	m_nIsValid = 1; 
	return IsValid(); 
} 
	 
void CBmpFile::Init() 
{ 
	m_nIsValid = 0; 
	memset(&m_bmFileHeader, 0, sizeof(BITMAPFILEHEADER)); 
	memset(&m_bmInfoHeader, 0, sizeof(BITMAPINFOHEADER)); 
	m_pRGB = NULL; 
	m_nNumPixels = 0; 
} 
 
void CBmpFile::Destroy() 
{ 
	if(m_pRGB) delete [] m_pRGB; 
	Init(); 
} 
 
/* Set pixels with components < rgbThreshold to rgbSetTo */ 
BOOL CBmpFile::BlueScreen(PIXEL rgbSetTo, PIXEL rgbThreshold) 
{ 
	if(!IsValid()) return FALSE; 
 
	for(int n = 0; n < m_nNumPixels; n++) 
	{ 
		PIXEL &rgb = m_pRGB[n]; 
		if(rgb.red < rgbThreshold.red && 
			rgb.green < rgbThreshold.green && 
			rgb.blue < rgbThreshold.blue) 
		{ 
			rgb.red = rgbSetTo.red; 
			rgb.green = rgbSetTo.green; 
			rgb.blue = rgbSetTo.blue; 
		} 
	} 
	 
	return TRUE; 
} 
 
/* Set pixels at rgbBkgColor to 255,255,255 and set 
   all others to 0,0,0 */ 
BOOL CBmpFile::Maskify(PIXEL rgbBkgColor) 
{ 
	if(!IsValid()) return FALSE; 
 
	for(int n = 0; n < m_nNumPixels; n++) 
	{ 
		PIXEL &rgb = m_pRGB[n]; 
		if(rgb.red == rgbBkgColor.red && 
			rgb.green == rgbBkgColor.green && 
			rgb.blue == rgbBkgColor.blue) 
		{ 
			rgb.red = 255; 
			rgb.green = 255; 
			rgb.blue = 255; 
		} 
		else 
		{ 
			rgb.red = 0; 
			rgb.green = 0; 
			rgb.blue = 0; 
		} 
	} 
 
	return TRUE; 
} 
 
HBITMAP CBmpFile::CreateHandle(HDC hDC) 
{ 
	LPBYTE pBits; 
	HBITMAP hBitmap = 
		CreateDIBSection(hDC, (LPBITMAPINFO)&m_bmInfoHeader, 
		DIB_RGB_COLORS, (LPVOID*)&pBits, NULL, 0); 
 
	if(!hBitmap) return NULL; 
 
	memcpy(pBits, m_pRGB, m_bmInfoHeader.biSizeImage); 
 
	return hBitmap; 
} 
 
 
int CBmpFile::Width() 
{ 
	return m_bmInfoHeader.biWidth; 
} 
 
int CBmpFile::Height() 
{ 
	return m_bmInfoHeader.biHeight; 
} 
 
int CBmpFile::GetBpp() 
{ 
	return m_bmInfoHeader.biBitCount; 
} 
 
int CBmpFile::GetFileSize() 
{ 
	// this is just a guess 
 
	return m_bmFileHeader.bfSize + m_bmInfoHeader.biSize + 
		m_nNumPixels * m_bmInfoHeader.biBitCount/8 + 
		((m_bmInfoHeader.biBitCount==8)?(256*3):(0)); 
} 
 
LPRGB CBmpFile::GetRGB() 
{ 
	return m_pRGB; 
} 
 
BITMAPINFO* CBmpFile::GetBitmapInfo() 
{ 
	return (BITMAPINFO*)&m_bmInfoHeader; 
} 
 
void CBmpFile::Show(HDC dc, int x, int y, int from_x=0, int from_y=0) 
{ 
        int res = SetDIBitsToDevice( 
              dc,                        // handle to DC 
              x,                         // x-coord of destination upper-left corner 
              y,                         // y-coord of destination upper-left corner  
              m_bmInfoHeader.biWidth,                        // source rectangle width 
              m_bmInfoHeader.biHeight,                        // source rectangle height 
              from_x,                    // x-coord of source lower-left corner 
              from_y,                    // y-coord of source lower-left corner 
              from_y,                    // first scan line in array 
              m_bmInfoHeader.biHeight,                        // number of scan lines 
              m_pRGB,    // array of DIB bits 
              (BITMAPINFO*)&m_bmInfoHeader,          // bitmap information 
              DIB_RGB_COLORS );          // RGB or palette indexes 
 
} 
 
void ShowBmp(LPBITMAPINFO pBmpInfo,HDC dc, int x, int y, int from_x=0, int from_y=0) 
{ 
BITMAPINFOHEADER& m_bmInfoHeader=pBmpInfo->bmiHeader; 
LPBYTE pBmpBits = ((LPBYTE)pBmpInfo) + pBmpInfo->bmiHeader.biSize; 
int res = SetDIBitsToDevice( 
              dc,                        // handle to DC 
              x,                         // x-coord of destination upper-left corner 
              y,                         // y-coord of destination upper-left corner  
              m_bmInfoHeader.biWidth,                        // source rectangle width 
              m_bmInfoHeader.biHeight,                        // source rectangle height 
              from_x,                    // x-coord of source lower-left corner 
              from_y,                    // y-coord of source lower-left corner 
              from_y,                    // first scan line in array 
              m_bmInfoHeader.biHeight,                        // number of scan lines 
              pBmpBits,    // array of DIB bits 
              pBmpInfo,          // bitmap information 
              DIB_RGB_COLORS );     
} 
 
HANDLE  MakeDib( HBITMAP hbitmap, UINT bits ) 
{ 
	HANDLE              hdib ; 
	HDC                 hdc ; 
	BITMAP              bitmap ; 
	UINT                wLineLen ; 
	DWORD               dwSize ; 
	DWORD               wColSize ; 
	LPBITMAPINFOHEADER  lpbi ; 
	LPBYTE              lpBits ; 
	 
	GetObject(hbitmap,sizeof(BITMAP),&bitmap) ; 
 
	// 
	// DWORD align the width of the DIB 
	// Figure out the size of the colour table 
	// Calculate the size of the DIB 
	// 
	wLineLen = (bitmap.bmWidth*bits+31)/32 * 4; 
	wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<biSize = sizeof(BITMAPINFOHEADER) ; 
	lpbi->biWidth = bitmap.bmWidth ; 
	lpbi->biHeight = bitmap.bmHeight ; 
	lpbi->biPlanes = 1 ; 
	lpbi->biBitCount = (WORD) bits ; 
	lpbi->biCompression = BI_RGB ; 
	lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ; 
	lpbi->biXPelsPerMeter = 0 ; 
	lpbi->biYPelsPerMeter = 0 ; 
	lpbi->biClrUsed = (bits <= 8) ? 1<biClrImportant = 0 ; 
 
	// 
	// Get the bits from the bitmap and stuff them after the LPBI 
	// 
	lpBits = (LPBYTE)(lpbi+1)+wColSize ; 
 
	hdc = CreateCompatibleDC(NULL) ; 
 
	GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS); 
 
	// Fix this if GetDIBits messed it up.... 
	lpbi->biClrUsed = (bits <= 8) ? 1<