diff --git a/panda/src/pnmimagetypes/bmp.h b/panda/src/pnmimagetypes/bmp.h index 58582f0d78..ecf117d775 100644 --- a/panda/src/pnmimagetypes/bmp.h +++ b/panda/src/pnmimagetypes/bmp.h @@ -32,6 +32,10 @@ static unsigned long BMPoffbits(int classv, unsigned long bitcount); #define C_WIN 1 #define C_OS2 2 +#define C_WINV2 3 +#define C_WINV3 4 +#define C_WINV4 5 +#define C_WINV5 6 static char er_internal[] = "%s: internal error!"; @@ -41,8 +45,12 @@ BMPlenfileheader(int classv) switch (classv) { case C_WIN: - return 14; case C_OS2: + case C_WINV2: + case C_WINV3: + case C_WINV4: + case C_WINV5: + return 14; return 14; default: pm_error(er_internal, "BMPlenfileheader"); @@ -59,6 +67,14 @@ BMPleninfoheader(int classv) return 40; case C_OS2: return 12; + case C_WINV2: + return 52; + case C_WINV3: + return 56; + case C_WINV4: + return 108; + case C_WINV5: + return 124; default: pm_error(er_internal, "BMPleninfoheader"); return 0; @@ -107,17 +123,6 @@ BMPlenline(int classv, unsigned long bitcount, unsigned long x) { unsigned long bitsperline; - switch (classv) - { - case C_WIN: - break; - case C_OS2: - break; - default: - pm_error(er_internal, "BMPlenline"); - return 0; - } - bitsperline = x * bitcount; /* diff --git a/panda/src/pnmimagetypes/pnmFileTypeBMPReader.cxx b/panda/src/pnmimagetypes/pnmFileTypeBMPReader.cxx index 4688efffe9..e0ec77441d 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeBMPReader.cxx +++ b/panda/src/pnmimagetypes/pnmFileTypeBMPReader.cxx @@ -191,39 +191,47 @@ BMPreadinfoheader( { case 12: classv = C_OS2; - - cx = GetShort(fp); - cy = GetShort(fp); - cPlanes = GetShort(fp); - cBitCount = GetShort(fp); - break; - case 40: + case 40: // BITMAPINFOHEADER classv = C_WIN; - - cx = GetLong(fp); - cy = GetLong(fp); - cPlanes = GetShort(fp); - cBitCount = GetShort(fp); - - /* - * We've read 16 bytes so far, need to read 24 more - * for the required total of 40. - */ - - GetLong(fp); - GetLong(fp); - GetLong(fp); - GetLong(fp); - GetLong(fp); - GetLong(fp); - + break; + case 52: // BITMAPV2INFOHEADER + classv = C_WINV2; + break; + case 56: // BITMAPV3INFOHEADER + classv = C_WINV3; + break; + case 108: // BITMAPV4HEADER + classv = C_WINV4; + break; + case 124: // BITMAPV5HEADER + classv = C_WINV5; break; default: pm_error("%s: unknown cbFix: %d", ifname, cbFix); break; } + if (classv == C_OS2) { + cx = GetShort(fp); + cy = GetShort(fp); + } else { + cx = GetLong(fp); + cy = GetLong(fp); + } + cPlanes = GetShort(fp); + cBitCount = GetShort(fp); + + /* + * We've read 16 bytes so far, need to read more + * for the required total. + */ + if (classv != C_OS2) { + for (int i = 0; i < cbFix - 16; i += 4) { + GetLong(fp); + } + } + if (cPlanes != 1) { pm_error("%s: don't know how to handle cPlanes = %d" @@ -239,6 +247,16 @@ BMPreadinfoheader( ,cy ,cBitCount); break; + case C_WINV2: + case C_WINV3: + case C_WINV4: + case C_WINV5: + pm_message("Windows BMP V%d, %dx%dx%d" + ,(classv - C_WINV2 + 2) + ,cx + ,cy + ,cBitCount); + break; case C_OS2: pm_message("OS/2 BMP, %dx%dx%d" ,cx @@ -288,7 +306,7 @@ BMPreadrgbtable( R[i] = (pixval) GetByte(fp); nbyte += 3; - if (classv == C_WIN) + if (classv != C_OS2) { (void) GetByte(fp); nbyte++; @@ -307,6 +325,7 @@ BMPreadrow( istream *fp, unsigned long *ppos, /* number of bytes read from fp */ pixel *row, + xelval *alpha_row, unsigned long cx, unsigned short cBitCount, int indexed, @@ -335,6 +354,10 @@ BMPreadrow( b = GetByte(fp); g = GetByte(fp); r = GetByte(fp); + if (cBitCount > 24) { + *(alpha_row++) = GetByte(fp); + ++nbyte; + } nbyte += 3; PPM_ASSIGN(*row, r, g, b); } else { @@ -369,7 +392,7 @@ BMPreadrow( } static void -BMPreadbits(xel *array, +BMPreadbits(xel *array, xelval *alpha_array, istream *fp, unsigned long *ppos, /* number of bytes read from fp */ unsigned long offBits, @@ -386,7 +409,7 @@ BMPreadbits(xel *array, readto(fp, ppos, offBits); - if(cBitCount > 24) + if(cBitCount > 24 && cBitCount != 32) { pm_error("%s: cannot handle cBitCount: %d" ,ifname @@ -400,7 +423,7 @@ BMPreadbits(xel *array, for (y = (long)cy - 1; y >= 0; y--) { int rc; - rc = BMPreadrow(fp, ppos, array + y*cx, cx, cBitCount, indexed, R, G, B); + rc = BMPreadrow(fp, ppos, array + y*cx, alpha_array + y*cx, cx, cBitCount, indexed, R, G, B); if(rc == -1) { pm_error("%s: couldn't read row %d" @@ -472,7 +495,11 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) : } } - _num_channels = 3; + if (cBitCount > 24) { + _num_channels = 4; + } else { + _num_channels = 3; + } _x_size = (int)cx; _y_size = (int)cy; _maxval = 255; @@ -498,8 +525,8 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) : // below. //////////////////////////////////////////////////////////////////// int PNMFileTypeBMP::Reader:: -read_data(xel *array, xelval *) { - BMPreadbits(array, _file, &pos, offBits, _x_size, _y_size, +read_data(xel *array, xelval *alpha_array) { + BMPreadbits(array, alpha_array, _file, &pos, offBits, _x_size, _y_size, cBitCount, classv, indexed, R, G, B); if (pos != BMPlenfile(classv, cBitCount, _x_size, _y_size)) {