15 #include "pnmFileTypeBMP.h" 19 #include "config_pnmimagetypes.h" 45 static int GetByte (istream * fp);
46 static short GetShort (istream * fp);
47 static long GetLong (istream * fp);
48 static void readto (istream *fp,
unsigned long *ppos,
unsigned long dst);
49 static void BMPreadfileheader (istream *fp,
unsigned long *ppos,
50 unsigned long *poffBits);
51 static void BMPreadinfoheader (istream *fp,
unsigned long *ppos,
52 unsigned long *pcx,
unsigned long *pcy,
unsigned short *pcBitCount,
54 static int BMPreadrgbtable (istream *fp,
unsigned long *ppos,
55 unsigned short cBitCount,
int classv, pixval *R, pixval *G, pixval *B);
57 static const char *ifname =
"BMP";
58 static char er_read[] =
"%s: read error";
66 if ((v = fp->get()) == EOF)
68 pm_error(er_read, ifname);
79 if (pm_readlittleshort(fp, &v) == -1)
81 pm_error(er_read, ifname);
92 if (pm_readlittlelong(fp, &v) == -1)
94 pm_error(er_read, ifname);
118 pm_error(
"%s: internal error in readto()", ifname);
120 for(; pos < dst; pos++)
122 if (fp->get() == EOF)
124 pm_error(er_read, ifname);
140 unsigned long *poffBits)
147 unsigned long offBits;
164 offBits = GetLong(fp);
177 unsigned short *pcBitCount,
181 unsigned short cPlanes = 0;
183 unsigned long cx = 0;
184 unsigned long cy = 0;
185 unsigned short cBitCount = 0;
211 pm_error(
"%s: unknown cbFix: %d", ifname, cbFix);
215 if (classv == C_OS2) {
222 cPlanes = GetShort(fp);
223 cBitCount = GetShort(fp);
229 if (classv != C_OS2) {
230 for (
int i = 0; i < (int)cbFix - 16; i += 4) {
237 pm_error(
"%s: don't know how to handle cPlanes = %d" 245 pm_message(
"Windows BMP, %dx%dx%d" 254 pm_message(
"Windows BMP V%d, %dx%dx%d" 255 ,(classv - C_WINV2 + 2)
261 pm_message(
"OS/2 BMP, %dx%dx%d" 269 pm_message(
"cbFix: %d", cbFix);
270 pm_message(
"cx: %d", cx);
271 pm_message(
"cy: %d", cy);
272 pm_message(
"cPlanes: %d", cPlanes);
273 pm_message(
"cBitCount: %d", cBitCount);
278 *pcBitCount = cBitCount;
291 unsigned short cBitCount,
300 long ncolors = (1 << cBitCount);
302 for (i = 0; i < ncolors; i++)
304 B[i] = (pixval) GetByte(fp);
305 G[i] = (pixval) GetByte(fp);
306 R[i] = (pixval) GetByte(fp);
330 unsigned short cBitCount,
342 if ((b = pm_bitinit(fp,
"r")) == (
BITSTREAM) 0)
348 for (x = 0; x < cx; x++, row++)
357 if (cBitCount > 24) {
358 *(alpha_row++) = GetByte(fp);
362 PPM_ASSIGN(*row, r, g, b);
364 if ((rc = pm_bitread(b, cBitCount, &v)) == -1)
370 PPM_ASSIGN(*row, R[v], G[v], B[v]);
375 if ((rc = pm_bitfini(b)) != 0)
395 BMPreadbits(
xel *array, xelval *alpha_array,
398 unsigned long offBits,
401 unsigned short cBitCount,
410 readto(fp, ppos, offBits);
412 if(cBitCount > 24 && cBitCount != 32)
414 pm_error(
"%s: cannot handle cBitCount: %d" 423 for (y = (
long)cy - 1; y >= 0; y--)
426 rc = BMPreadrow(fp, ppos, array + y*cx, alpha_array + y*cx, cx, cBitCount, indexed, R, G, B);
429 pm_error(
"%s: couldn't read row %d" 435 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";
527 int PNMFileTypeBMP::Reader::
528 read_data(
xel *array, xelval *alpha_array) {
529 BMPreadbits(array, alpha_array, _file, &pos, offBits, _x_size, _y_size,
530 cBitCount, classv, indexed, R, G, B);
532 if (pos != BMPlenfile(classv, cBitCount, _x_size, _y_size)) {
533 pnmimage_bmp_cat.warning()
534 <<
"Read " << pos <<
" bytes, expected to read " 535 << BMPlenfile(classv, cBitCount, _x_size, _y_size) <<
" bytes\n";
This is the base class of a family of classes that represent particular image file types that PNMImag...
This is an abstract base class that defines the interface for reading image files of various types...