From 2b85ce5c1c854012376c6ab7e9e47d3f69f48b07 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 7 Oct 2001 20:10:58 +0000 Subject: [PATCH] Merged Geoff Michel's udpdates to bmp plugin, and fixed a double fclose bug which was causing a seg fault under Linux. --- src/osgPlugins/bmp/ReaderWriterBMP.cpp | 117 +++++++++++++++++-------- 1 file changed, 79 insertions(+), 38 deletions(-) diff --git a/src/osgPlugins/bmp/ReaderWriterBMP.cpp b/src/osgPlugins/bmp/ReaderWriterBMP.cpp index 19b06834f..6aa910cc3 100644 --- a/src/osgPlugins/bmp/ReaderWriterBMP.cpp +++ b/src/osgPlugins/bmp/ReaderWriterBMP.cpp @@ -20,27 +20,29 @@ #include #include -#define ERROR_NO_ERROR 0 -#define ERROR_READING_HEADER 1 -#define ERROR_READING_PALETTE 2 -#define ERROR_MEMORY 3 -#define ERROR_READ_ERROR 4 -#define ERROR_NO_FILE 5 +enum { ERROR_NO_ERROR =0,ERROR_READING_HEADER,ERROR_READING_PALETTE, ERROR_MEMORY, ERROR_READ_ERROR, +ERROR_NO_FILE,ERROR_READING_COLORS}; static int bmperror = ERROR_NO_ERROR; // BMP format bits - at start of file is 512 bytes of pure garbage -enum ftype {MB=19778}; // magic number identifies a bmp file +enum ftype {MB=19778}; // magic number identifies a bmp file; actually chars 'B''M' +// allowed ftypes are 'BM' for windoze; OS2 allows: +//'BA' - Bitmap Array +//'CI' - Color Icon +//'CP' - Color Pointer (mouse cursor) +//'IC' - Icon +//'PT' - Pointer (mouse cursor) + enum ncol { BW=1, IA, RGB, RGBA}; struct bmpheader { short FileType; //always MB - short siz[2]; + short siz[2]; // a dword for whole file size short Reserved1, Reserved2; //reserved for future purposes short offset[2]; //offset to image in bytes }; struct BMPInfo { - long size; //size of BMPinfo in bytes long width; //width of the image in pixels long height; // height of the image in pixels short planes; //:word: number of planes (always 1) @@ -49,8 +51,9 @@ struct BMPInfo { long ImageSize; //image size in bytes long XpixPerMeter; //pixels per meter in X long YpixPerMeter; //pixels per meter in Y - long ColorUsed; //number of the color used żżż??? + long ColorUsed; //number of colors used long Important; //number of "important" colors + long os2stuff[6]; // allows os2.1 with 64 bytes to be read. Dont know what these are yet. }; int @@ -58,6 +61,9 @@ bmp_error(char *buffer, int bufferlen) { switch (bmperror) { + case ERROR_READING_COLORS: + strncpy(buffer, "BMP loader: Error reading colours", bufferlen); + break; case ERROR_READING_HEADER: strncpy(buffer, "BMP loader: Error reading header", bufferlen); break; @@ -75,7 +81,7 @@ bmp_error(char *buffer, int bufferlen) } /* byte order workarounds *sigh* */ -void swapbyte(long &i) +void swapbyte(long *i) { char *vv=(char *)i; char tmp=vv[0]; @@ -85,7 +91,7 @@ void swapbyte(long &i) vv[1]=vv[2]; vv[2]=tmp; } -void swapbyte(unsigned long &i) +void swapbyte(unsigned long *i) { char *vv=(char *)i; char tmp=vv[0]; @@ -105,14 +111,14 @@ void swapbyte(float *i) vv[1]=vv[2]; vv[2]=tmp; } -void swapbyte(unsigned short &i) +void swapbyte(unsigned short *i) { char *vv=(char *)i; char tmp=vv[0]; vv[0]=vv[1]; vv[1]=tmp; } -void swapbyte(short &i) +void swapbyte(short *i) { char *vv=(char *)i; char tmp=vv[0]; @@ -132,7 +138,7 @@ int *numComponents_ret) // It is extremely expensive on disk space - every RGB pixel uses 3 bytes plus a header! // BMP - sponsored by Seagate. // unsigned char palette[256][3]; - unsigned char *buffer, *imbuff; // returned to sender & as read from the disk + unsigned char *buffer; // returned to sender & as read from the disk bmperror = ERROR_NO_FILE; @@ -142,14 +148,17 @@ int *numComponents_ret) int ncolours; int ncomp=0; bool swap=false; // dont need to swap bytes + long infsize; //size of BMPinfo in bytes + // actual size of the bitmap header; 12=os2; 40 = normal; 64=os2.1 struct bmpheader hd; struct BMPInfo inf; bmperror = ERROR_NO_ERROR; fread((char *)&hd, sizeof(bmpheader), 1, fp); - fread((char *)&inf, sizeof(BMPInfo), 1, fp); + fread((char *)&infsize, sizeof(long), 1, fp); + fread((char *)&inf, infsize-sizeof(long), 1, fp); if (hd.FileType != MB) { - swapbyte((hd.FileType)); + swapbyte(&(hd.FileType)); swap=true; if (hd.FileType != MB) { bmperror=ERROR_READING_HEADER; @@ -157,16 +166,22 @@ int *numComponents_ret) } } if (hd.FileType == MB) { + unsigned char *cols=NULL; // dynamic colour palette + unsigned char *imbuff; // returned to sender & as read from the disk if (swap) { // inverse the field of the header which need swapping - swapbyte(hd.siz[0]); - swapbyte(hd.siz[1]); - swapbyte(inf.Colorbits); - swapbyte(inf.width); - swapbyte(inf.height); - swapbyte(inf.ImageSize); + swapbyte(&hd.siz[0]); + swapbyte(&hd.siz[1]); + swapbyte(&inf.Colorbits); + swapbyte(&inf.width); + swapbyte(&inf.height); + swapbyte(&inf.ImageSize); } long size = hd.siz[1]*65536+hd.siz[0]; - size -= sizeof(bmpheader)+sizeof(BMPInfo); + size -= sizeof(bmpheader)+infsize; + if (inf.ImageSize0) buffer = (unsigned char *)malloc( ncomp*inf.width*inf.height*sizeof(unsigned char)); // to be returned + else buffer = (unsigned char *)malloc( 3*inf.width*inf.height*sizeof(unsigned char)); // default full colour to be returned + if (ncomp==BW) { // BW currently error on display osg::notify(osg::NOTICE)<<"BMP file: "<>=inf.Colorbits; + } + } + // osg::notify(osg::NOTICE) << endl; + } off+=doff; if (ncomp>2) { // yes bill, colours are usually BGR aren't they for(int i=0; i0?ncomp:3; return buffer; } @@ -242,16 +287,12 @@ class ReaderWriterBMP : public osgDB::ReaderWriter int r = 1; int internalFormat = numComponents_ret; - unsigned int pixelFormat = numComponents_ret == 1 ? GL_LUMINANCE : - numComponents_ret == 2 ? GL_LUMINANCE_ALPHA : - numComponents_ret == 3 ? GL_RGB : - numComponents_ret == 4 ? GL_RGBA : (GLenum)-1; - - cout << "internalFormat="<