54static char er_write[] =
"stdout: write error";
57static void PutByte (ostream *fp,
char v);
58static void PutShort (ostream *fp,
short v);
59static void PutLong (ostream *fp,
long v);
60static int BMPwritefileheader (ostream *fp,
int classv,
unsigned long bitcount,
61 unsigned long x,
unsigned long y);
62static int BMPwriteinfoheader (ostream *fp,
int classv,
unsigned long bitcount,
63 unsigned long x,
unsigned long y);
64static int BMPwritergb (ostream *fp,
int classv, pixval R, pixval G, pixval B);
65static int BMPwritergbtable (ostream *fp,
int classv,
int bpp,
int colors,
66 pixval *R, pixval *G, pixval *B);
67static int colorstobpp (
int colors);
68static 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"
378colorstobpp(
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");
513PNMFileTypeBMP::Writer::
514Writer(
PNMFileType *type, ostream *file,
bool owns_file) :
536int PNMFileTypeBMP::Writer::
537write_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,
636bool PNMFileTypeBMP::Writer::
637supports_grayscale()
const {
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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 writing image files of various types.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int pm_maxvaltobits(int maxval)
Returns the number of bits sufficient to hold the indicated maxval value.
void pm_error(const char *format,...)
Outputs the given printf-style message to the user and terminates messily.
void pm_message(const char *format,...)
Outputs the given printf-style message to the user and returns.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.