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;
197 cPlanes = GetShort(fp);
198 cBitCount = GetShort(fp);
206 cPlanes = GetShort(fp);
207 cBitCount = GetShort(fp);
223 pm_error(
"%s: unknown cbFix: %d", ifname, cbFix);
229 pm_error(
"%s: don't know how to handle cPlanes = %d"
237 pm_message(
"Windows BMP, %dx%dx%d"
243 pm_message(
"OS/2 BMP, %dx%dx%d"
251 pm_message(
"cbFix: %d", cbFix);
252 pm_message(
"cx: %d", cx);
253 pm_message(
"cy: %d", cy);
254 pm_message(
"cPlanes: %d", cPlanes);
255 pm_message(
"cBitCount: %d", cBitCount);
260 *pcBitCount = cBitCount;
273 unsigned short cBitCount,
282 long ncolors = (1 << cBitCount);
284 for (i = 0; i < ncolors; i++)
286 B[i] = (pixval) GetByte(fp);
287 G[i] = (pixval) GetByte(fp);
288 R[i] = (pixval) GetByte(fp);
311 unsigned short cBitCount,
323 if ((b = pm_bitinit(fp,
"r")) == (
BITSTREAM) 0)
329 for (x = 0; x < cx; x++, row++)
339 PPM_ASSIGN(*row, r, g, b);
341 if ((rc = pm_bitread(b, cBitCount, &v)) == -1)
347 PPM_ASSIGN(*row, R[v], G[v], B[v]);
352 if ((rc = pm_bitfini(b)) != 0)
372 BMPreadbits(
xel *array,
375 unsigned long offBits,
378 unsigned short cBitCount,
387 readto(fp, ppos, offBits);
391 pm_error(
"%s: cannot handle cBitCount: %d"
400 for (y = (
long)cy - 1; y >= 0; y--)
403 rc = BMPreadrow(fp, ppos, array + y*cx, cx, cBitCount, indexed, R, G, B);
406 pm_error(
"%s: couldn't read row %d"
412 pm_error(
"%s: row had bad number of bytes: %d"
425 PNMFileTypeBMP::Reader::
426 Reader(
PNMFileType *type, istream *file,
bool owns_file,
string magic_number) :
429 if (!read_magic_number(_file, magic_number, 2)) {
431 if (pnmimage_bmp_cat.is_debug()) {
432 pnmimage_bmp_cat.debug()
433 <<
"BMP image file appears to be empty.\n";
439 if (magic_number !=
string(
"BM")) {
440 pnmimage_bmp_cat.error()
441 <<
"File is not a valid BMP file.\n";
453 BMPreadfileheader(file, &pos, &offBits);
454 BMPreadinfoheader(file, &pos, &cx, &cy, &cBitCount, &classv);
456 if (offBits != BMPoffbits(classv, cBitCount)) {
457 pnmimage_bmp_cat.warning()
458 <<
"offBits is " << offBits <<
", expected "
459 << BMPoffbits(classv, cBitCount) <<
"\n";
464 if (cBitCount <= 8) {
466 rc = BMPreadrgbtable(file, &pos, cBitCount, classv, R, G, B);
468 if (rc != (
int)BMPlenrgbtable(classv, cBitCount)) {
469 pnmimage_bmp_cat.warning()
470 << rc <<
"-byte RGB table, expected "
471 << BMPlenrgbtable(classv, cBitCount) <<
" bytes\n";
480 if (pnmimage_bmp_cat.is_debug()) {
481 pnmimage_bmp_cat.debug()
482 <<
"Reading BMP " << *
this <<
"\n";
500 int PNMFileTypeBMP::Reader::
501 read_data(
xel *array, xelval *) {
502 BMPreadbits(array, _file, &pos, offBits, _x_size, _y_size,
503 cBitCount, classv, indexed, R, G, B);
505 if (pos != BMPlenfile(classv, cBitCount, _x_size, _y_size)) {
506 pnmimage_bmp_cat.warning()
507 <<
"Read " << pos <<
" bytes, expected to read "
508 << 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...