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<