www.pudn.com > jpeglib.rar > Bmpfile.cpp


//	bmpops.cpp : implementation of the BMPFile class 
//	 
//	This handles the reading and writing of BMP files. 
// 
// 
 
#include "stdafx.h" 
#include "bmpfile.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
BMPFile::BMPFile() 
{ 
	m_errorText="OK"; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
//	load a .BMP file - 1,4,8,24 bit 
// 
//	allocates and returns an RGB buffer containing the image. 
//	modifies width and height accordingly - NULL, 0, 0 on error 
 
BYTE * BMPFile::LoadBMP(CString fileName,  
						UINT *width,  
						UINT *height) 
{ 
	BITMAP inBM; 
 
	BYTE m1,m2; 
    long filesize; 
    short res1,res2; 
    long pixoff; 
    long bmisize;                     
    long compression; 
    unsigned long sizeimage; 
    long xscale, yscale; 
    long colors; 
    long impcol; 
     
 
	BYTE *outBuf=NULL; 
	 
	// for safety 
	*width=0; *height=0; 
 
	// init 
	m_errorText="OK"; 
	m_bytesRead=0; 
 
	FILE *fp; 
	 
	fp=fopen(fileName,"rb"); 
	if (fp==NULL) { 
		CString msg;                     
		msg="Can't open file for reading :\n"+fileName; 
		m_errorText=msg; 
		return NULL; 
	} else { 
	    long rc; 
		rc=fread((BYTE  *)&(m1),1,1,fp); m_bytesRead+=1; 
		if (rc==-1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((BYTE  *)&(m2),1,1,fp); m_bytesRead+=1; 
		if (rc==-1) m_errorText="Read Error!"; 
		if ((m1!='B') || (m2!='M')) { 
			m_errorText="Not a valid BMP File"; 
			fclose(fp); 
			return NULL; 
        } 
         
		//////////////////////////////////////////////////////////////////////////// 
		// 
		//	read a ton of header stuff 
 
		rc=fread((long  *)&(filesize),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((int  *)&(res1),2,1,fp); m_bytesRead+=2; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((int  *)&(res2),2,1,fp); m_bytesRead+=2; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(pixoff),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(bmisize),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(inBM.bmWidth),4,1,fp);	 m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(inBM.bmHeight),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((int  *)&(inBM.bmPlanes),2,1,fp); m_bytesRead+=2; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((int  *)&(inBM.bmBitsPixel),2,1,fp); m_bytesRead+=2; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(compression),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(sizeimage),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(xscale),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(yscale),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(colors),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		rc=fread((long  *)&(impcol),4,1,fp); m_bytesRead+=4; 
		if (rc!=1) {m_errorText="Read Error!"; fclose(fp); return NULL;} 
 
		//////////////////////////////////////////////////////////////////////////// 
		//	i don't do RLE files 
 
		if (compression!=BI_RGB) { 
	    	m_errorText="This is a compressed file."; 
	    	fclose(fp); 
	    	return NULL; 
	    } 
 
		if (colors == 0) { 
			colors = 1 << inBM.bmBitsPixel; 
		} 
 
 
		//////////////////////////////////////////////////////////////////////////// 
		// read colormap 
 
		RGBQUAD *colormap = NULL; 
 
		switch (inBM.bmBitsPixel) { 
		case 24: 
			break; 
			// read pallete  
		case 1: 
		case 4: 
		case 8: 
			colormap = new RGBQUAD[colors]; 
			if (colormap==NULL) { 
				fclose(fp); 
				m_errorText="Out of memory"; 
				return NULL; 
			} 
 
			int i; 
			for (i=0;ipixoff) { 
			fclose(fp); 
			m_errorText="Corrupt palette"; 
			delete [] colormap; 
			fclose(fp); 
			return NULL; 
		} 
 
		while ((long)m_bytesRead=0;row--) { 
 
				// which row are we working on? 
				rowOffset=(long unsigned)row*row_size;						       
 
				if (inBM.bmBitsPixel==24) { 
 
					for (int col=0;col> bit_count) & mask; 
 
						// lookup the color from the colormap - stuff it in our buffer 
						// swap red and blue 
						*(outBuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue; 
						*(outBuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen; 
						*(outBuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed; 
					} 
 
					// read DWORD padding 
					while ((m_bytesRead-pixoff)&3) { 
						char dummy; 
						if (fread(&dummy,1,1,fp)!=1) { 
							m_errorText="Read Error"; 
							delete [] outBuf; 
							if (colormap) 
								delete [] colormap; 
							fclose(fp); 
							return NULL; 
						} 
						m_bytesRead++; 
					} 
				} 
			} 
		 
		} 
 
		if (colormap) { 
			delete [] colormap; 
		} 
 
		fclose(fp); 
 
    } 
 
	return outBuf; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
//	write a 24-bit BMP file 
// 
//	image MUST be a packed buffer (not DWORD-aligned) 
//	image MUST be vertically flipped ! 
//	image MUST be BGR, not RGB ! 
// 
 
void BMPFile::SaveBMP(CString fileName,		// output path 
							BYTE * buf,				// BGR buffer 
							UINT width,				// pixels 
							UINT height) 
{ 
	short res1=0; 
    short res2=0; 
    long pixoff=54; 
    long compression=0; 
    long cmpsize=0; 
    long colors=0; 
    long impcol=0; 
	char m1='B'; 
	char m2='M'; 
 
	m_errorText="OK"; 
 
	DWORD widthDW = WIDTHBYTES(width * 24); 
 
	long bmfsize=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
  							widthDW * height;	 
	long byteswritten=0; 
 
	BITMAPINFOHEADER header; 
  	header.biSize=40; 						// header size 
	header.biWidth=width; 
	header.biHeight=height; 
	header.biPlanes=1; 
	header.biBitCount=24;					// RGB encoded, 24 bit 
	header.biCompression=BI_RGB;			// no compression 
	header.biSizeImage=0; 
	header.biXPelsPerMeter=0; 
	header.biYPelsPerMeter=0; 
	header.biClrUsed=0; 
	header.biClrImportant=0; 
 
	FILE *fp;	 
	fp=fopen(fileName,"wb"); 
	if (fp==NULL) { 
		m_errorText="Can't open file for writing"; 
		return; 
	} 
 
	// should probably check for write errors here... 
	 
	fwrite((BYTE  *)&(m1),1,1,fp); byteswritten+=1; 
	fwrite((BYTE  *)&(m2),1,1,fp); byteswritten+=1; 
	fwrite((long  *)&(bmfsize),4,1,fp);	byteswritten+=4; 
	fwrite((int  *)&(res1),2,1,fp); byteswritten+=2; 
	fwrite((int  *)&(res2),2,1,fp); byteswritten+=2; 
	fwrite((long  *)&(pixoff),4,1,fp); byteswritten+=4; 
 
	fwrite((BITMAPINFOHEADER *)&header,sizeof(BITMAPINFOHEADER),1,fp); 
	byteswritten+=sizeof(BITMAPINFOHEADER); 
	 
	long row=0; 
	long rowidx; 
	long row_size; 
	row_size=header.biWidth*3; 
    long rc; 
	for (row=0;row 8) { 
				m_errorText="Error : nBits > 8????"; 
				fclose(fp); 
				return; 
			} 
 
			if (nbits == 8) { 
				putc(pixbuf, fp); 
				pixbuf=0; 
				nbits=0; 
				byteswritten++; 
			} 
		} // cols 
 
		if (nbits > 0) { 
			putc(pixbuf, fp);		// write partially filled byte 
			byteswritten++; 
		} 
 
		// DWORD align 
		while ((byteswritten -pixeloffset) & 3) { 
			putc(0, fp); 
			byteswritten++; 
		} 
 
	}	//rows 
 
	if (byteswritten!=filesize) { 
		m_errorText="byteswritten != filesize"; 
	} 
 
	fclose(fp); 
}