mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 00:32:57 -04:00
Support various kinds of BMP headers (incl reading bmp with alpha)
This commit is contained in:
parent
2c61260c5f
commit
623d81db6b
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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) :
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user