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";