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 {
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void pm_message(const char *format,...)
Outputs the given printf-style message to the user and returns.
int pm_maxvaltobits(int maxval)
Returns the number of bits sufficient to hold the indicated maxval value.
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.
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
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 writing image files of various types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.