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