47 static int GetByte (istream * fp);
48 static short GetShort (istream * fp);
49 static long GetLong (istream * fp);
50 static void readto (istream *fp,
unsigned long *ppos,
unsigned long dst);
51 static void BMPreadfileheader (istream *fp,
unsigned long *ppos,
52 unsigned long *poffBits);
53 static void BMPreadinfoheader (istream *fp,
unsigned long *ppos,
54 unsigned long *pcx,
unsigned long *pcy,
unsigned short *pcBitCount,
56 static int BMPreadrgbtable (istream *fp,
unsigned long *ppos,
57 unsigned short cBitCount,
int classv, pixval *R, pixval *G, pixval *B);
59 static const char *ifname =
"BMP";
60 static char er_read[] =
"%s: read error";
68 if ((v = fp->get()) == EOF)
81 if (pm_readlittleshort(fp, &v) == -1)
94 if (pm_readlittlelong(fp, &v) == -1)
120 pm_error(
"%s: internal error in readto()", ifname);
122 for(; pos < dst; pos++)
124 if (fp->get() == EOF)
142 unsigned long *poffBits)
149 unsigned long offBits;
166 offBits = GetLong(fp);
179 unsigned short *pcBitCount,
183 unsigned short cPlanes = 0;
185 unsigned long cx = 0;
186 unsigned long cy = 0;
187 unsigned short cBitCount = 0;
213 pm_error(
"%s: unknown cbFix: %d", ifname, cbFix);
217 if (classv == C_OS2) {
224 cPlanes = GetShort(fp);
225 cBitCount = GetShort(fp);
231 if (classv != C_OS2) {
232 for (
int i = 0; i < (int)cbFix - 16; i += 4) {
239 pm_error(
"%s: don't know how to handle cPlanes = %d" 257 ,(classv - C_WINV2 + 2)
280 *pcBitCount = cBitCount;
293 unsigned short cBitCount,
302 long ncolors = (1 << cBitCount);
304 for (i = 0; i < ncolors; i++)
306 B[i] = (pixval) GetByte(fp);
307 G[i] = (pixval) GetByte(fp);
308 R[i] = (pixval) GetByte(fp);
332 unsigned short cBitCount,
338 BITSTREAM b =
nullptr;
344 if ((b = pm_bitinit(fp,
"r")) ==
nullptr)
350 for (x = 0; x < cx; x++, row++)
359 if (cBitCount > 24) {
360 *(alpha_row++) = GetByte(fp);
364 PPM_ASSIGN(*row, r, g, b);
366 if ((rc = pm_bitread(b, cBitCount, &v)) == -1)
372 PPM_ASSIGN(*row, R[v], G[v], B[v]);
377 if ((rc = pm_bitfini(b)) != 0)
397 BMPreadbits(
xel *array, xelval *alpha_array,
400 unsigned long offBits,
403 unsigned short cBitCount,
412 readto(fp, ppos, offBits);
414 if(cBitCount > 24 && cBitCount != 32)
416 pm_error(
"%s: cannot handle cBitCount: %d" 425 for (y = (
long)cy - 1; y >= 0; y--)
428 rc = BMPreadrow(fp, ppos, array + y*cx, alpha_array + y*cx, cx, cBitCount, indexed, R, G, B);
437 pm_error(
"%s: row had bad number of bytes: %d" 448 PNMFileTypeBMP::Reader::
449 Reader(
PNMFileType *type, istream *file,
bool owns_file,
string magic_number) :
452 if (!read_magic_number(_file, magic_number, 2)) {
454 if (pnmimage_bmp_cat.is_debug()) {
455 pnmimage_bmp_cat.debug()
456 <<
"BMP image file appears to be empty.\n";
462 if (magic_number !=
string(
"BM")) {
463 pnmimage_bmp_cat.error()
464 <<
"File is not a valid BMP file.\n";
476 BMPreadfileheader(file, &pos, &offBits);
477 BMPreadinfoheader(file, &pos, &cx, &cy, &cBitCount, &classv);
479 if (offBits != BMPoffbits(classv, cBitCount)) {
480 pnmimage_bmp_cat.warning()
481 <<
"offBits is " << offBits <<
", expected " 482 << BMPoffbits(classv, cBitCount) <<
"\n";
487 if (cBitCount <= 8) {
489 rc = BMPreadrgbtable(file, &pos, cBitCount, classv, R, G, B);
491 if (rc != (
int)BMPlenrgbtable(classv, cBitCount)) {
492 pnmimage_bmp_cat.warning()
493 << rc <<
"-byte RGB table, expected " 494 << BMPlenrgbtable(classv, cBitCount) <<
" bytes\n";
498 if (cBitCount > 24) {
507 if (pnmimage_bmp_cat.is_debug()) {
508 pnmimage_bmp_cat.debug()
509 <<
"Reading BMP " << *
this <<
"\n";
523 int PNMFileTypeBMP::Reader::
524 read_data(
xel *array, xelval *alpha_array) {
525 BMPreadbits(array, alpha_array, _file, &pos, offBits, _x_size, _y_size,
526 cBitCount, classv, indexed, R, G, B);
528 if (pos != BMPlenfile(classv, cBitCount, _x_size, _y_size)) {
529 pnmimage_bmp_cat.warning()
530 <<
"Read " << pos <<
" bytes, expected to read " 531 << BMPlenfile(classv, cBitCount, _x_size, _y_size) <<
" bytes\n";
void pm_message(const char *format,...)
Outputs the given printf-style message to the user and returns.
This is the base class of a family of classes that represent particular image file types that PNMImag...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void pm_error(const char *format,...)
Outputs the given printf-style message to the user and terminates messily.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract base class that defines the interface for reading image files of various types.