www.pudn.com > Gimcrack-v0.0051-Source.zip > bitmap.cpp


#include  
#include  
#include  
#include "bitmap.h" 
using namespace std; 
 
 
/////////////////////////////////////////////////////////////////////////////////// 
 
GcBitmap::GcBitmap(): 
bitmapImage(NULL) 
{ 
	// The bitmap has been constructed 
} 
 
/////////////////////////////////////////////////////////////////////////////////// 
 
GcBitmap::~GcBitmap() 
{ 
	// Free memory 
	Destroy(); 
} 
 
/////////////////////////////////////////////////////////////////////////////////// 
 
bool GcBitmap::Load(char *fileName) 
{ 
	 
	// Open filename in "read binary" mode 
	ifstream file(fileName, ios::in | ios::binary); 
 
	// Check to see if the file has been opened corectly 
	if(!file) { 
		MessageBox(NULL, "Can't find bitmap file", "Error", MB_OK); 
		return false; 
	} 
 
	// Read the bitmap file header 
	file.read((char*)&bitmapFileHeader, sizeof(BITMAPFILEHEADER)); 
 
	// Check to see that this is a bitmap 
	if(bitmapFileHeader.bfType != 0x4D42)  
	{ 
		MessageBox(NULL, "File isn't a bitmap", "Error", MB_OK); 
		file.close(); 
		return false; 
	} 
		       
	// Read the bitmap information header 
	file.read((char*)&bitmapInfoHeader, sizeof(BITMAPINFOHEADER)); 
 
	// Move file pointer to beginning of bitmap data 
	file.seekg(bitmapFileHeader.bfOffBits, ios::beg); 
 
	// Check to make sure that the biSizeImage isn't empty (which it is if it's a Photoshop bitmap) 
	if(bitmapInfoHeader.biSizeImage == 0) { 
		bitmapInfoHeader.biSizeImage = (int)bitmapInfoHeader.biWidth * bitmapInfoHeader.biHeight * (bitmapInfoHeader.biBitCount / 8); 
	} 
 
	// Allocate memmory for the image data 
	bitmapImage = new byte[bitmapInfoHeader.biSizeImage]; 
 
	// Check memmory allocation 
	if(!bitmapImage)  
	{ 
		MessageBox(NULL, "Failed to allocate memmory for the bitmap", "Error", MB_OK); 
		delete [] bitmapImage; 
		bitmapImage = NULL; 
		file.close(); 
		return false; 
	} 
 
	// Read the bitmap image data 
	file.read((char*)bitmapImage, bitmapInfoHeader.biSizeImage); 
 
	// Check to see if this is a BGR bitmap, in that case swap to RGB 
	if(bitmapInfoHeader.biBitCount != 8)  
	{ 
		// Swap the R and B valuse to get RGB from BGR 
		for(int i = 0; i < (int)bitmapInfoHeader.biSizeImage; i += 3) 
		{ 
			tempRGB = bitmapImage[i]; 
			bitmapImage[i] = bitmapImage[i + 2]; 
			bitmapImage[i + 2] = tempRGB; 
		} 
	} 
 
	// Close the file 
	file.close(); 
 
	return true; 
} 
 
/////////////////////////////////////////////////////////////////////////////////// 
 
bool GcBitmap::Write(char *fileName, uint width, uint height, uint screenBpp) 
{ 
	/* WARNING! DO NOT USE THIS IF THE BITMAP ARE TO BE USED FURTHER ON */ 
 
	// Open file for writing binary mode 
	ofstream file(fileName, ios::out | ios::binary); 
 
	// Check if opened 
	if(!file) { 
		return false; 
	} 
 
	// Define the bitmap file header 
	bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER); 
	bitmapFileHeader.bfType = 0x4D42; 
	bitmapFileHeader.bfReserved1 = 0; 
	bitmapFileHeader.bfReserved2 = 0; 
	bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 
 
	// Define the bitmap inforamtion header 
	bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER); 
	bitmapInfoHeader.biPlanes = 1; 
	bitmapInfoHeader.biBitCount = 24; 
	bitmapInfoHeader.biCompression = BI_RGB; 
	bitmapInfoHeader.biSizeImage = width * abs(height) * 3; 
	bitmapInfoHeader.biXPelsPerMeter = 0; 
	bitmapInfoHeader.biYPelsPerMeter = 0; 
	bitmapInfoHeader.biClrUsed = 0; 
	bitmapInfoHeader.biClrImportant = 0; 
	bitmapInfoHeader.biWidth = width; 
	bitmapInfoHeader.biHeight = height; 
 
	// Switch the image data from RGB to BGR 
	for(int i = 0; i < (int)bitmapInfoHeader.biSizeImage; i += 3) 
	{ 
		tempRGB = bitmapImage[i]; 
		bitmapImage[i] = bitmapImage[i + 2]; 
		bitmapImage[i +2] = tempRGB; 
	} 
 
	// Write the bitmap file header 
	file.write((char*)&bitmapFileHeader, sizeof(BITMAPFILEHEADER)); 
 
	// Write the bitmap info header 
	file.write((char*)&bitmapInfoHeader, sizeof(BITMAPINFOHEADER)); 
 
	// Write the image data 
	file.write((char*)bitmapImage, bitmapInfoHeader.biSizeImage); 
 
	// Save the color mode 
	colorMode = bitmapInfoHeader.biBitCount / 8; 
 
	// Close the file 
	file.close(); 
 
	return true; 
} 
 
/////////////////////////////////////////////////////////////////////////////////// 
 
void GcBitmap::Screenshot(char *fileName, uint winWidth, uint winHeight, uint screenBpp) 
{ 
	/* WARNING! DO NOT USE THIS IF THE BITMAP ARE TO BE USED FURTHER ON */ 
 
	// Make sure that there's no memory allocated 
	if(bitmapImage != NULL) { 
		delete [] bitmapImage; 
		bitmapImage = NULL; 
	} 
 
	// Allocate memmory for the screenshot 
	bitmapImage = new byte[winWidth*winHeight*3]; 
 
	// Clear the memmory 
	memset(bitmapImage, 0, winWidth * winHeight * 3); 
 
	// Read the image data from the window 
	glReadPixels(0, 0, winWidth - 1, winHeight - 1, GL_RGB, GL_UNSIGNED_BYTE, bitmapImage); 
 
	// Write the image data to a file 
	Write(fileName, winWidth, winHeight); 
 
	// Free the image memory 
	delete [] bitmapImage; 
	bitmapImage = NULL; 
} 
 
/////////////////////////////////////////////////////////////////////////////////// 
 
void GcBitmap::Draw(uint xPos, uint yPos) 
{ 
	// Bind a null texture to "disable texturing 
	glBindTexture(GL_TEXTURE_2D, NULL); 
 
	// Set the correct drwaings 
	glPixelStorei(GL_UNPACK_ALIGNMENT, colorMode); 
 
	// Set the correct position 
	glRasterPos2i(xPos, yPos); 
 
	// Draw the bitmap to the screen 
	glDrawPixels(bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight,  
				 colorMode, GL_UNSIGNED_BYTE, bitmapImage); 
				  
} 
 
/////////////////////////////////////////////////////////////////////////////////// 
 
void GcBitmap::Destroy() 
{  
	if(bitmapImage != NULL) { 
		delete [] bitmapImage;  
		bitmapImage = NULL;  
	}  
} 
 
///////////////////////////////////////////////////////////////////////////////////