54 static char er_write[] =
"stdout: write error";
57 static void PutByte (ostream *fp,
char v);
58 static void PutShort (ostream *fp,
short v);
59 static void PutLong (ostream *fp,
long v);
60 static int BMPwritefileheader (ostream *fp,
int classv,
unsigned long bitcount,
61 unsigned long x,
unsigned long y);
62 static int BMPwriteinfoheader (ostream *fp,
int classv,
unsigned long bitcount,
63 unsigned long x,
unsigned long y);
64 static int BMPwritergb (ostream *fp,
int classv, pixval R, pixval G, pixval B);
65 static int BMPwritergbtable (ostream *fp,
int classv,
int bpp,
int colors,
66 pixval *R, pixval *G, pixval *B);
67 static int colorstobpp (
int colors);
68 static void BMPEncode (ostream *fp,
int classv,
int x,
int y,
pixel **pixels,
86 if (pm_writelittleshort(fp, v) == -1)
97 if (pm_writelittlelong(fp, v) == -1)
114 unsigned long bitcount,
122 PutLong(fp, (
long)BMPlenfile(classv, bitcount, x, y));
131 PutLong(fp, (
long)BMPoffbits(classv, bitcount));
143 unsigned long bitcount,
157 PutLong(fp, (
long)x);
159 PutLong(fp, (
long)y);
163 PutShort(fp, (
short)bitcount);
184 PutShort(fp, (
short)x);
186 PutShort(fp, (
short)y);
190 PutShort(fp, (
short)bitcount);
194 pm_error(er_internal,
"BMPwriteinfoheader");
225 pm_error(er_internal,
"BMPwritergb");
247 for (i = 0; i < colors; i++)
249 nbyte += BMPwritergb(fp,classv,R[i],G[i],B[i]);
252 ncolors = (1 << bpp);
254 for (; i < ncolors; i++)
256 nbyte += BMPwritergb(fp,classv,0,0,0);
281 if ((b = pm_bitinit(fp,
"w")) ==
nullptr)
286 for (x = 0; x < cx; x++, row++)
288 if ((rc = pm_bitwrite(b, bpp, ppm_lookupcolor(cht, row))) == -1)
295 if ((rc = pm_bitfini(b)) == -1)
302 for (x = 0; x < cx; x++, row++)
304 PutByte(fp, PPM_GETB(*row) * 255 / maxval);
305 PutByte(fp, PPM_GETG(*row) * 255 / maxval);
306 PutByte(fp, PPM_GETR(*row) * 255 / maxval);
331 unsigned short cBitCount,
342 pm_error(
"cannot handle cBitCount: %d"
350 for (y = (
long)cy - 1; y >= 0; y--)
353 rc = BMPwriterow(fp, pixels[y], cx, cBitCount, indexed, cht,
363 pm_error(
"row had bad number of bytes: %d"
378 colorstobpp(
int colors)
384 pm_error(
"can't have less than one color");
416 unsigned long nbyte = 0;
419 int needs_bpp = colorstobpp(colors);
420 if (bpp != 0 && bpp < needs_bpp) {
421 pnmimage_bmp_cat.info()
422 <<
"too many colors for " << bmp_bpp <<
"-bit image.\n";
453 pnmimage_bmp_cat.info()
454 <<
"Using " << bpp <<
" bits per pixel.\n";
456 nbyte += BMPwritefileheader(fp, classv, bpp, x, y);
457 nbyte += BMPwriteinfoheader(fp, classv, bpp, x, y);
458 nbyte += BMPwritergbtable(fp, classv, bpp, colors, R, G, B);
460 if(nbyte != ( BMPlenfileheader(classv)
461 + BMPleninfoheader(classv)
462 + BMPlenrgbtable(classv, bpp)))
467 nbyte += BMPwritebits(fp, x, y, bpp, pixels,
true, cht, 255);
468 if(nbyte != BMPlenfile(classv, bpp, x, y))
486 unsigned long nbyte = 0;
489 pnmimage_bmp_cat.info()
490 <<
"Using " << bpp <<
" bits per pixel.\n";
492 nbyte += BMPwritefileheader(fp, classv, bpp, x, y);
493 nbyte += BMPwriteinfoheader(fp, classv, bpp, x, y);
495 if(nbyte != ( BMPlenfileheader(classv)
496 + BMPleninfoheader(classv)))
498 pm_error(er_internal,
"BMPEncode24");
503 if(nbyte != BMPlenfile(classv, bpp, x, y))
505 pm_error(er_internal,
"BMPEncode24");
513 PNMFileTypeBMP::Writer::
514 Writer(
PNMFileType *type, ostream *file,
bool owns_file) :
536 int PNMFileTypeBMP::Writer::
537 write_data(
xel *array, xelval *) {
538 if (_y_size<=0 || _x_size<=0) {
547 pixval Red[MAXCOLORS];
548 pixval Green[MAXCOLORS];
549 pixval Blue[MAXCOLORS];
574 pixels = (
pixel **)alloca(
sizeof(
pixel *) * _y_size);
575 for (i = 0; i < _y_size; i++) {
576 pixels[i] = (
pixel *)(array + i * _x_size);
580 chv = ppm_computecolorhist(pixels, _x_size, _y_size, MAXCOLORS, &colors);
583 BMPEncode24(_file, classv, _x_size, _y_size, pixels, _maxval);
585 }
else if (chv ==
nullptr) {
588 pnmimage_bmp_cat.info()
589 <<
"too many colors for " << bmp_bpp <<
"-bit image.\n";
592 BMPEncode24(_file, classv, _x_size, _y_size, pixels, _maxval);
595 pnmimage_bmp_cat.debug()
596 << colors <<
" colors found\n";
602 pnmimage_bmp_cat.debug()
603 <<
"maxval is not 255 - automatically rescaling colors\n";
606 for (i = 0; i < colors; ++i) {
607 if (_maxval == 255) {
608 Red[i] = PPM_GETR(chv[i].color);
609 Green[i] = PPM_GETG(chv[i].color);
610 Blue[i] = PPM_GETB(chv[i].color);
612 Red[i] = (pixval) PPM_GETR(chv[i].color) * 255 / _maxval;
613 Green[i] = (pixval) PPM_GETG(chv[i].color) * 255 / _maxval;
614 Blue[i] = (pixval) PPM_GETB(chv[i].color) * 255 / _maxval;
619 cht = ppm_colorhisttocolorhash(chv, colors);
620 ppm_freecolorhist(chv);
622 BMPEncode(_file, classv, _x_size, _y_size, pixels, colors, cht,
636 bool PNMFileTypeBMP::Writer::
637 supports_grayscale()
const {