bmp.cpp cstdio GL/gl.h bmp.h datatypes.h OpenArena::BITMAP_HEADER OpenArena::BITMAP_INFO OpenArena::BITMAP_QUAD OpenArena BITMAP_MAGIC 19778 // //Module:bmp.cpp //Author:TomHicks //Creation:09-01-2003 //LastEdit:06-20-2005 //Editors:TomHicks // //Purpose: //Toimplementawrapperfunctionthatwillloada24bitwindowsbitmap //fileandreturnapointertoaTextureImageobjectcontainingtheimage. // //SummaryofMethods: //Global //-LoadBMP //Loadsa24bitwindowsbitmapfilespecifiedbyfnandreturnsa //pointertoaTextureImageobjectcontainingthebitmapimage. // #include<cstdio> #ifdefWIN32 #include<windows.h> #endif #include<GL/gl.h> #include"bmp.h" #include"datatypes.h" #ifdefWIN32 #pragmawarning(disable:4996) #endif namespaceOpenArena{ #pragmapack(push,1) structBITMAP_HEADER { uint16type; uint32size; uint16reserved1; uint16reserved2; uint32offset; }; structBITMAP_INFO { uint32size; uint32width; uint32height; uint16planes; uint16bitCount; uint32compression; uint32sizeImage; uint32xPelsPerMeter; uint32yPelsPerMeter; uint32clrUsed; uint32clrImportant; }; structBITMAP_QUAD { uint8blue; uint8green; uint8red; uint8reserved; }; #pragmapack(pop) #defineBITMAP_MAGIC19778 voidPrintBMPHeader(BITMAP_HEADERheader) { printf("Header\n"); printf("Type:%X\nSize:%X\nReserved1:%X\nReserved2:%X\nOffset:%X\n",header.type,header.size,header.reserved1,header.reserved2,header.offset); } voidPrintBMPInfo(BITMAP_INFOinfo) { printf("Info\n"); printf("Size:%X\nWidth:%X\nHeight:%X\n",info.size,info.width,info.height); printf("Planes:%X\nBitCount:%X\nCompression:%X\n",info.planes,info.bitCount,info.compression); printf("SizeImage:%X\nXPelsPerMeter:%X\nYPelsPerMeter:%X\n",info.sizeImage,info.xPelsPerMeter,info.yPelsPerMeter); printf("ClrUsed:%X\nClrImportant:%X\n",info.clrUsed,info.clrImportant); } TextureImage*LoadBMP(constchar*fn) { //IfanythingisnotperfectreturnNULLaftercleaningupourmess FILE*f=NULL;//Apointertoourfilestructure //Ifourfilenameisnull if(!fn) { returnNULL; } //Trytoopenourfileandifsuccessfull... f=fopen(fn,"rb"); if(f) { BITMAP_HEADERbmpHeader; BITMAP_INFObmpInfo; BITMAP_QUAD*bmpPallette=NULL; uint32palletteEntries=0; fread(&bmpHeader,sizeof(bmpHeader),1,f); uint8t[2]={1,0}; if(*((short*)t)!=1) { //Ifbigendianreorderbytes bmpHeader.type=((bmpHeader.type&0xff00)>>8)| ((bmpHeader.type&0x00ff)<<8); bmpHeader.size=(bmpHeader.size&0xff000000)>>24| (bmpHeader.size&0x00ff0000)>>8| (bmpHeader.size&0x0000ff00)<<8| (bmpHeader.size&0x000000ff)<<24; bmpHeader.reserved1=((bmpHeader.reserved1&0xff00)>>8)| ((bmpHeader.reserved1&0x00ff)<<8); bmpHeader.reserved2=((bmpHeader.reserved2&0xff00)>>8)| ((bmpHeader.reserved2&0x00ff)<<8); bmpHeader.offset=(bmpHeader.offset&0xff000000)>>24| (bmpHeader.offset&0x00ff0000)>>8| (bmpHeader.offset&0x0000ff00)<<8| (bmpHeader.offset&0x000000ff)<<24; } fread(&bmpInfo,sizeof(bmpInfo),1,f); if(*((short*)t)!=1) { //Ifbigendianreorderbytes bmpInfo.size=(bmpInfo.size&0xff000000)>>24| (bmpInfo.size&0x00ff0000)>>8| (bmpInfo.size&0x0000ff00)<<8| (bmpInfo.size&0x000000ff)<<24; bmpInfo.width=(bmpInfo.width&0xff000000)>>24| (bmpInfo.width&0x00ff0000)>>8| (bmpInfo.width&0x0000ff00)<<8| (bmpInfo.width&0x000000ff)<<24; bmpInfo.height=(bmpInfo.height&0xff000000)>>24| (bmpInfo.height&0x00ff0000)>>8| (bmpInfo.height&0x0000ff00)<<8| (bmpInfo.height&0x000000ff)<<24; bmpInfo.planes=((bmpInfo.planes&0xff00)>>8)| ((bmpInfo.planes&0x00ff)<<8); bmpInfo.bitCount=((bmpInfo.bitCount&0xff00)>>8)| ((bmpInfo.bitCount&0x00ff)<<8); bmpInfo.compression=(bmpInfo.compression&0xff000000)>>24| (bmpInfo.compression&0x00ff0000)>>8| (bmpInfo.compression&0x0000ff00)<<8| (bmpInfo.compression&0x000000ff)<<24; bmpInfo.sizeImage=(bmpInfo.sizeImage&0xff000000)>>24| (bmpInfo.sizeImage&0x00ff0000)>>8| (bmpInfo.sizeImage&0x0000ff00)<<8| (bmpInfo.sizeImage&0x000000ff)<<24; bmpInfo.xPelsPerMeter=(bmpInfo.xPelsPerMeter&0xff000000)>>24| (bmpInfo.xPelsPerMeter&0x00ff0000)>>8| (bmpInfo.xPelsPerMeter&0x0000ff00)<<8| (bmpInfo.xPelsPerMeter&0x000000ff)<<24; bmpInfo.yPelsPerMeter=(bmpInfo.yPelsPerMeter&0xff000000)>>24| (bmpInfo.yPelsPerMeter&0x00ff0000)>>8| (bmpInfo.yPelsPerMeter&0x0000ff00)<<8| (bmpInfo.yPelsPerMeter&0x000000ff)<<24; bmpInfo.clrUsed=(bmpInfo.clrUsed&0xff000000)>>24| (bmpInfo.clrUsed&0x00ff0000)>>8| (bmpInfo.clrUsed&0x0000ff00)<<8| (bmpInfo.clrUsed&0x000000ff)<<24; bmpInfo.clrImportant=(bmpInfo.clrImportant&0xff000000)>>24| (bmpInfo.clrImportant&0x00ff0000)>>8| (bmpInfo.clrImportant&0x0000ff00)<<8| (bmpInfo.clrImportant&0x000000ff)<<24; } if(bmpInfo.width<0) { //Thisneedstobeabstractedsomehow #ifdefWIN32 MessageBox(NULL,"Imagewidthisnegative","ERROR",MB_OK); #endif fclose(f); returnNULL; } if(bmpInfo.width%4!=0) { //Thisneedstobeabstractedsomehow #ifdefWIN32 MessageBox(NULL,"Imagewidthmustbeamultipleof8","ERROR",MB_OK); #endif fclose(f); returnNULL; } if(bmpInfo.height<0) { //Thisneedstobeabstractedsomehow #ifdefWIN32 MessageBox(NULL,"Imageheightisnegative","ERROR",MB_OK); #endif fclose(f); returnNULL; } if(bmpInfo.height%4!=0) { //Thisneedstobeabstractedsomehow #ifdefWIN32 MessageBox(NULL,"Imageheightmustbeamultipleof8","ERROR",MB_OK); #endif fclose(f); returnNULL; } if((bmpInfo.bitCount!=8&&bmpInfo.bitCount!=24)||bmpInfo.compression!=0) { //Thisneedstobeabstractedsomehow #ifdefWIN32 MessageBox(NULL,"Only8and24bituncompressedwindowsbmpfilesarecurrentlysupported","ERROR",MB_OK); #endif fclose(f); returnNULL; } //AllocatememoryforaTextureImagestructure TextureImage*tex=newTextureImage; tex->sizeX=bmpInfo.width; tex->sizeY=bmpInfo.height; if(bmpInfo.bitCount>=8) { tex->bpp=bmpInfo.bitCount>>3; } tex->type=GL_RGB; uint32pixels=tex->sizeX*tex->sizeY; uint32bytes=pixels*tex->bpp; tex->data=newuint8[bytes]; if(bmpInfo.bitCount==8) { //Loadthepallette palletteEntries=bmpInfo.bitCount<<8; bmpPallette=newBITMAP_QUAD[palletteEntries]; fread(bmpPallette,sizeof(BITMAP_QUAD),palletteEntries,f); } fseek(f,bmpHeader.offset,SEEK_SET); fread(tex->data,bytes,1,f); if(bmpInfo.bitCount==8) { //Applythepallette uint8*image=tex->data; tex->bpp=24; bytes=pixels*tex->bpp; tex->data=newuint8[bytes]; uint32i; uint32i2; for(i=0;i<pixels;i++) { i2=(i<<1)+1; //Shouldmakesureimage[i]<palletteEntries tex->data[i2]=bmpPallette[image[i]].red; tex->data[i2+1]=bmpPallette[image[i]].blue; tex->data[i2+2]=bmpPallette[image[i]].green; } delete[]image; image=NULL; } elseif(bmpInfo.bitCount==24) { uint32i; uint8t; for(i=0;i<bytes;i+=3) { t=tex->data[i]; tex->data[i]=tex->data[i+2]; tex->data[i+2]=t; } } returntex; } returnNULL; } };