27 static const char *
const extensions_PNM[] = {
28 "pbm",
"pgm",
"ppm",
"pnm" 30 static const int num_extensions_PNM =
sizeof(extensions_PNM) /
sizeof(
const char *);
36 #define PBM_MAGIC1 'P' 37 #define PBM_MAGIC2 '1' 38 #define RPBM_MAGIC2 '4' 39 #define PBM_FORMAT (PBM_MAGIC1 * 256 + PBM_MAGIC2) 40 #define RPBM_FORMAT (PBM_MAGIC1 * 256 + RPBM_MAGIC2) 41 #define PBM_TYPE PBM_FORMAT 43 #define PBM_FORMAT_TYPE(f) \ 44 ((f) == PBM_FORMAT || (f) == RPBM_FORMAT ? PBM_TYPE : -1) 46 #define PGM_OVERALLMAXVAL 65535 48 #define PGM_MAGIC1 'P' 49 #define PGM_MAGIC2 '2' 50 #define RPGM_MAGIC2 '5' 51 #define PGM_FORMAT (PGM_MAGIC1 * 256 + PGM_MAGIC2) 52 #define RPGM_FORMAT (PGM_MAGIC1 * 256 + RPGM_MAGIC2) 53 #define PGM_TYPE PGM_FORMAT 55 #define PGM_FORMAT_TYPE(f) ((f) == PGM_FORMAT || (f) == RPGM_FORMAT ? PGM_TYPE : PBM_FORMAT_TYPE(f)) 57 #define PPM_OVERALLMAXVAL PGM_OVERALLMAXVAL 58 #define PPM_MAXMAXVAL PGM_MAXMAXVAL 60 #define PPM_MAGIC1 'P' 61 #define PPM_MAGIC2 '3' 62 #define RPPM_MAGIC2 '6' 63 #define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2) 64 #define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2) 65 #define PPM_TYPE PPM_FORMAT 67 #define PPM_FORMAT_TYPE(f) \ 68 ((f) == PPM_FORMAT || (f) == RPPM_FORMAT ? PPM_TYPE : PGM_FORMAT_TYPE(f)) 70 #define PNM_OVERALLMAXVAL PPM_OVERALLMAXVAL 71 #define PNM_GET1(x) PPM_GETB(x) 73 #define PNM_FORMAT_TYPE(f) PPM_FORMAT_TYPE(f) 75 typedef unsigned char bit;
79 #define pbm_allocarray(cols, rows) \ 80 ((bit**) pm_allocarray(cols, rows, sizeof(bit))) 81 #define pbm_allocrow(cols) ((bit*) pm_allocrow(cols, sizeof(bit))) 82 #define pbm_freearray(bits, rows) pm_freearray((char**) bits, rows) 83 #define pbm_freerow(bitrow) pm_freerow((char*) bitrow) 84 #define pbm_packed_bytes(cols) (((cols)+7)/8) 85 #define pbm_allocrow_packed(cols) \ 86 ((unsigned char *) pm_allocrow(pbm_packed_bytes(cols), \ 87 sizeof(unsigned char))) 88 #define pbm_freerow_packed(packed_bits) \ 89 pm_freerow((char *) packed_bits) 90 #define pbm_allocarray_packed(cols, rows) ((unsigned char **) \ 91 pm_allocarray(pbm_packed_bytes(cols), rows, sizeof(unsigned char))) 92 #define pbm_freearray_packed(packed_bits, rows) \ 93 pm_freearray((char **) packed_bits, rows) 95 #define pgm_allocarray( cols, rows ) ((gray**) pm_allocarray( cols, rows, sizeof(gray) )) 96 #define pgm_allocrow( cols ) ((gray*) pm_allocrow( cols, sizeof(gray) )) 97 #define pgm_freearray( grays, rows ) pm_freearray( (char**) grays, rows ) 98 #define pgm_freerow( grayrow ) pm_freerow( (char*) grayrow ) 100 #define ppm_allocarray( cols, rows ) ((pixel**) pm_allocarray( cols, rows, sizeof(pixel) )) 101 #define ppm_allocrow( cols ) ((pixel*) pm_allocrow( cols, sizeof(pixel) )) 102 #define ppm_freearray( pixels, rows ) pm_freearray( (char**) pixels, rows ) 103 #define ppm_freerow( pixelrow ) pm_freerow( (char*) pixelrow ) 105 static const bool pm_plain_output =
false;
111 pm_allocarray(
int const cols,
int const rows,
int const size ) {
133 rowIndex = (
char **)PANDA_MALLOC_ARRAY((rows + 1) *
sizeof(
char *));
134 if ( rowIndex ==
nullptr )
135 pm_error(
"out of memory allocating row index (%u rows) for an array",
137 rowheap = (
char *)PANDA_MALLOC_ARRAY( rows * cols * size );
138 if ( rowheap ==
nullptr ) {
144 rowIndex[rows] =
nullptr;
146 for (row = 0; row < rows; ++row) {
148 if (rowIndex[row] ==
nullptr)
149 pm_error(
"out of memory allocating Row %u " 150 "(%u columns, %u bytes per tuple) " 151 "of an array", row, cols, size);
156 rowIndex[rows] = rowheap;
158 for (row = 0; row < rows; ++row)
159 rowIndex[row] = &(rowheap[row * cols * size]);
165 pm_freearray(
char **
const rowIndex,
168 void *
const rowheap = rowIndex[rows];
170 if (rowheap !=
nullptr) {
171 PANDA_FREE_ARRAY(rowheap);
174 for (row = 0; row < rows; ++row) {
178 PANDA_FREE_ARRAY(rowIndex);
182 pm_getuint(istream *
const ifP) {
207 }
while (ch != EOF && ch !=
'\n');
209 }
while (ch ==
' ' || ch ==
'\t' || ch ==
'\n' || ch ==
'\r');
211 if (ch < '0' || ch >
'9')
212 pm_error(
"junk in file where an unsigned integer should be");
216 unsigned int const digitVal = ch -
'0';
218 if (i > INT_MAX/10 - digitVal)
219 pm_error(
"ASCII decimal integer in file is " 220 "too large to be processed. ");
221 i = i * 10 + digitVal;
223 }
while (ch >=
'0' && ch <=
'9');
229 ppm_readppminitrest(istream *
const file,
232 pixval *
const maxvalP) {
236 *colsP = (int)pm_getuint(file);
237 *rowsP = (int)pm_getuint(file);
240 maxval = pm_getuint(file);
241 if (maxval > PPM_OVERALLMAXVAL)
242 pm_error(
"maxval of input image (%u) is too large. " 243 "The maximum allowed by the PPM is %u.",
244 maxval, PPM_OVERALLMAXVAL);
246 pm_error(
"maxval of input image is zero.");
252 pgm_readpgminitrest(istream *
const file,
255 gray *
const maxvalP) {
260 *colsP = (int)pm_getuint(file);
261 *rowsP = (int)pm_getuint(file);
264 maxval = pm_getuint(file);
265 if (maxval > PGM_OVERALLMAXVAL)
266 pm_error(
"maxval of input image (%u) is too large. " 267 "The maximum allowed by PGM is %u.",
268 maxval, PGM_OVERALLMAXVAL);
270 pm_error(
"maxval of input image is zero.");
276 pbm_readpbminitrest(istream* file,
280 *colsP = (int)pm_getuint( file );
281 *rowsP = (int)pm_getuint( file );
292 pm_error(
"Number of columns in header is too large.");
294 pm_error(
"Number of columns in header is too large.");
298 pm_getrawbyte(istream *
const file) {
303 pm_error(
"EOF / read error reading a one-byte sample");
304 return (
unsigned char) iby;
308 getbit (istream *
const file) {
313 }
while ( ch ==
' ' || ch ==
'\t' || ch ==
'\n' || ch ==
'\r' );
315 if ( ch !=
'0' && ch !=
'1' )
316 pm_error(
"junk in file where bits should be" );
318 return ( ch ==
'1' ) ? 1 : 0;
322 pbm_readpbmrow( istream *file, bit *bitrow,
int cols,
int format ) {
329 for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
330 *bP = getbit( file );
335 bitshift = -1; item = 0;
336 for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
338 if ( bitshift == -1 )
340 item = pm_getrawbyte( file );
343 *bP = ( item >> bitshift ) & 1;
355 pgm_getrawsample(istream *
const file, gray
const maxval) {
359 return(pm_getrawbyte(file));
362 unsigned char byte_pair[2];
365 file->read((
char *)byte_pair, 2);
366 pairs_read = file->gcount();
368 pm_error(
"EOF /read error while reading a long sample");
373 return((byte_pair[0]<<8) | byte_pair[1]);
378 pgm_readpgmrow(istream*
const file, gray*
const grayrow,
379 int const cols, gray
const maxval,
int const format) {
384 for (col = 0; col < cols; ++col) {
385 grayrow[col] = pm_getuint(file);
387 if (grayrow[col] > maxval)
388 pm_error(
"value out of bounds (%u > %u)",
389 grayrow[col], maxval );
397 for (col = 0; col < cols; ++col) {
398 grayrow[col] = pgm_getrawsample( file, maxval );
400 if ( grayrow[col] > maxval )
401 pm_error(
"value out of bounds (%u > %u)",
402 grayrow[col], maxval );
414 bitrow = pbm_allocrow(cols);
415 pbm_readpbmrow( file, bitrow, cols, format );
416 for (col = 0; col < cols; ++col)
417 grayrow[col] = (bitrow[col] == PBM_WHITE ) ? maxval : 0;
428 ppm_readppmrow(istream*
const fileP,
429 pixel*
const pixelrow,
437 for (col = 0; col < cols; ++col) {
438 pixval
const r = pm_getuint(fileP);
439 pixval
const g = pm_getuint(fileP);
440 pixval
const b = pm_getuint(fileP);
441 PPM_ASSIGN(pixelrow[col], r, g, b);
448 for (col = 0; col < cols; ++col) {
449 pixval
const r = pgm_getrawsample(fileP, maxval);
450 pixval
const g = pgm_getrawsample(fileP, maxval);
451 pixval
const b = pgm_getrawsample(fileP, maxval);
452 PPM_ASSIGN(pixelrow[col], r, g, b);
459 gray *
const grayrow = pgm_allocrow(cols);
462 pgm_readpgmrow(fileP, grayrow, cols, maxval, format);
463 for (col = 0; col < cols; ++col) {
464 pixval
const g = grayrow[col];
465 PPM_ASSIGN(pixelrow[col], g, g, g);
467 pgm_freerow(grayrow);
473 bit *
const bitrow = pbm_allocrow(cols);
476 pbm_readpbmrow(fileP, bitrow, cols, format);
477 for (col = 0; col < cols; ++col) {
478 pixval
const g = (bitrow[col] == PBM_WHITE) ? maxval : 0;
479 PPM_ASSIGN(pixelrow[col], g, g, g);
491 pnm_readpnmrow( istream* file,
xel* xelrow,
int cols, xelval maxval,
int format ) {
499 switch ( PNM_FORMAT_TYPE(format) )
502 ppm_readppmrow( file, (
pixel*) xelrow, cols, (pixval) maxval, format );
506 grayrow = pgm_allocrow( cols );
507 pgm_readpgmrow( file, grayrow, cols, (gray) maxval, format );
508 for ( col = 0, xP = xelrow, gP = grayrow; col < cols; ++col, ++xP, ++gP )
509 PNM_ASSIGN1( *xP, *gP );
510 pgm_freerow( grayrow );
514 bitrow = pbm_allocrow( cols );
515 pbm_readpbmrow( file, bitrow, cols, format );
516 for ( col = 0, xP = xelrow, bP = bitrow; col < cols; ++col, ++xP, ++bP )
517 PNM_ASSIGN1( *xP, *bP == PBM_BLACK ? 0: maxval );
518 pbm_freerow( bitrow );
527 pbm_writepbminit(ostream *
const fileP,
530 int const forceplain) {
532 if (!forceplain && !pm_plain_output) {
537 << cols <<
' ' << rows <<
'\n';
543 << cols <<
' ' << rows <<
'\n';
548 pgm_writepgminit(ostream *
const fileP,
552 int const forceplain) {
554 bool const plainFormat = forceplain || pm_plain_output;
556 if (maxval > PGM_OVERALLMAXVAL && !plainFormat)
557 pm_error(
"too-large maxval passed to ppm_writepgminit(): %d.\n" 558 "Maximum allowed by the PGM format is %d.",
559 maxval, PGM_OVERALLMAXVAL);
563 << (
char)(plainFormat ? PGM_MAGIC2 : RPGM_MAGIC2)
565 << cols <<
' ' << rows <<
'\n' << maxval <<
'\n';
569 ppm_writeppminit(ostream*
const fileP,
573 int const forceplain) {
575 bool const plainFormat = forceplain || pm_plain_output;
577 if (maxval > PPM_OVERALLMAXVAL && !plainFormat)
578 pm_error(
"too-large maxval passed to ppm_writeppminit(): %d." 579 "Maximum allowed by the PPM format is %d.",
580 maxval, PPM_OVERALLMAXVAL);
584 << (
char)(plainFormat ? PPM_MAGIC2 : RPPM_MAGIC2)
586 << cols <<
' ' << rows <<
'\n' << maxval <<
'\n';
590 pnm_writepnminit(ostream *
const fileP,
595 int const forceplain) {
597 bool const plainFormat = forceplain || pm_plain_output;
599 switch (PNM_FORMAT_TYPE(format)) {
601 ppm_writeppminit(fileP, cols, rows, (pixval) maxval, plainFormat);
605 pgm_writepgminit(fileP, cols, rows, (gray) maxval, plainFormat);
609 pbm_writepbminit(fileP, cols, rows, plainFormat);
613 pm_error(
"invalid format argument received by pnm_writepnminit(): %d" 614 "PNM_FORMAT_TYPE(format) must be %d, %d, or %d",
615 format, PBM_TYPE, PGM_TYPE, PPM_TYPE);
620 packBitsGeneric(ostream *
const fileP,
621 const bit *
const bitrow,
622 unsigned char *
const packedBits,
624 int *
const nextColP) {
635 #define iszero(x) ((x) == 0 ? 0 : 1) 637 for (col = 0; col + 7 < cols; col += 8)
638 packedBits[col/8] = (
639 iszero(bitrow[col+0]) << 7 |
640 iszero(bitrow[col+1]) << 6 |
641 iszero(bitrow[col+2]) << 5 |
642 iszero(bitrow[col+3]) << 4 |
643 iszero(bitrow[col+4]) << 3 |
644 iszero(bitrow[col+5]) << 2 |
645 iszero(bitrow[col+6]) << 1 |
646 iszero(bitrow[col+7]) << 0
652 writePackedRawRow(ostream *
const fileP,
653 const unsigned char *
const packed_bits,
656 fileP->write((
const char *)packed_bits, pbm_packed_bytes(cols));
658 pm_error(
"I/O error writing packed row to raw PBM file.");
663 writePbmRowRaw(ostream *
const fileP,
664 const bit *
const bitrow,
669 unsigned char *
const packedBits = pbm_allocrow_packed(cols);
671 packBitsGeneric(fileP, bitrow, packedBits, cols, &nextCol);
685 for (col = nextCol; col < cols; ++col, --bitshift )
687 item |= 1 << bitshift
690 packedBits[col/8] = item;
693 writePackedRawRow(fileP, packedBits, cols);
695 pbm_freerow_packed(packedBits);
701 writePbmRowPlain(ostream *
const fileP,
708 for (col = 0; col < cols; ++col) {
709 if (charcount >= 70) {
713 fileP->put(bitrow[col] ?
'1' :
'0');
720 pbm_writepbmrow(ostream *
const fileP,
723 int const forceplain) {
725 if (!forceplain && !pm_plain_output)
726 writePbmRowRaw(fileP, bitrow, cols);
728 writePbmRowPlain(fileP, bitrow, cols);
732 pgm_writerawsample(ostream *file,
const gray val,
const gray maxval) {
738 pm_error(
"Error writing single byte sample to file");
741 unsigned char outval[2];
746 outval[0] = val >> 8;
747 outval[1] = val & 0xFF;
748 file->write((
const char *)outval, 2);
750 pm_error(
"Error writing double byte sample to file");
755 pgm_writepgmrowraw(ostream *file, gray *grayrow,
int cols, gray maxval ) {
758 for (col = 0; col < cols; ++col) {
760 if (grayrow[col] > maxval)
761 pm_error(
"value out of bounds (%u > %u)", grayrow[col], maxval);
763 pgm_writerawsample(file, grayrow[col], maxval);
768 putus(
unsigned short const n,
769 ostream *
const fileP) {
772 putus(n / 10, fileP);
773 fileP->put(n % 10 +
'0');
778 pgm_writepgmrowplain(ostream *
const fileP,
779 gray *
const grayrow,
787 for (col = 0, gP = grayrow; col < cols; ++col, ++gP) {
788 if (charcount >= 65) {
791 }
else if (charcount > 0) {
797 pm_error(
"value out of bounds (%u > %u)", *gP, maxval);
799 putus((
unsigned short)*gP, fileP);
807 pgm_writepgmrow(ostream*
const fileP,
811 int const forceplain) {
813 if (forceplain || pm_plain_output )
814 pgm_writepgmrowplain(fileP, grayrow, cols, maxval);
816 pgm_writepgmrowraw(fileP, grayrow, cols, maxval);
820 ppm_writeppmrowraw(ostream *file,
pixel *pixelrow,
int cols, pixval maxval ) {
824 for ( col = 0; col < cols; ++col )
826 val = PPM_GETR( pixelrow[col] );
829 pm_error(
"r value out of bounds (%u > %u)", val, maxval );
831 pgm_writerawsample( file, val, maxval );
832 val = PPM_GETG( pixelrow[col] );
835 pm_error(
"g value out of bounds (%u > %u)", val, maxval );
837 pgm_writerawsample( file, val, maxval );
838 val = PPM_GETB( pixelrow[col] );
841 pm_error(
"b value out of bounds (%u > %u)", val, maxval );
843 pgm_writerawsample( file, val, maxval );
848 ppm_writeppmrowplain(ostream *file,
pixel *pixelrow,
int cols, pixval maxval ) {
854 for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP )
856 if ( charcount >= 65 )
858 (void) file->put(
'\n' );
861 else if ( charcount > 0 )
863 (void) file->put(
' ' );
864 (void) file->put(
' ' );
867 val = PPM_GETR( *pP );
870 pm_error(
"r value out of bounds (%u > %u)", val, maxval );
873 (void) file->put(
' ' );
874 val = PPM_GETG( *pP );
877 pm_error(
"g value out of bounds (%u > %u)", val, maxval );
880 (void) file->put(
' ' );
881 val = PPM_GETB( *pP );
884 pm_error(
"b value out of bounds (%u > %u)", val, maxval );
890 (void) file->put(
'\n' );
894 ppm_writeppmrow(ostream *
const fileP,
895 pixel *
const pixelrow,
898 int const forceplain) {
900 if (forceplain || pm_plain_output )
901 ppm_writeppmrowplain(fileP, pixelrow, cols, maxval);
903 ppm_writeppmrowraw(fileP, pixelrow, cols, maxval);
907 pnm_writepnmrow(ostream *
const fileP,
912 int const forceplain) {
914 bool const plainFormat = forceplain || pm_plain_output;
916 switch (PNM_FORMAT_TYPE(format)) {
918 ppm_writeppmrow(fileP, (
pixel*) xelrow, cols, (pixval) maxval,
926 grayrow = pgm_allocrow(cols);
928 for (col = 0; col < cols; ++col)
929 grayrow[col] = PNM_GET1(xelrow[col]);
931 pgm_writepgmrow(fileP, grayrow, cols, (gray) maxval, plainFormat);
933 pgm_freerow( grayrow );
941 bitrow = pbm_allocrow(cols);
943 for (col = 0; col < cols; ++col)
944 bitrow[col] = PNM_GET1(xelrow[col]) == 0 ? PBM_BLACK : PBM_WHITE;
946 pbm_writepbmrow(fileP, bitrow, cols, plainFormat);
953 pm_error(
"invalid format argument received by pnm_writepnmrow(): %d" 954 "PNM_FORMAT_TYPE(format) must be %d, %d, or %d",
955 format, PBM_TYPE, PGM_TYPE, PPM_TYPE);
969 string PNMFileTypePNM::
971 return "NetPBM-style PBM/PGM/PPM/PNM";
979 get_num_extensions()
const {
980 return num_extensions_PNM;
987 string PNMFileTypePNM::
988 get_extension(
int n)
const {
989 nassertr(n >= 0 && n < num_extensions_PNM,
string());
990 return extensions_PNM[n];
997 string PNMFileTypePNM::
998 get_suggested_extension()
const {
1006 bool PNMFileTypePNM::
1007 has_magic_number()
const {
1016 bool PNMFileTypePNM::
1017 matches_magic_number(
const string &magic_number)
const {
1018 return (magic_number.size() >= 2) &&
1019 magic_number[0] ==
'P' &&
1020 (magic_number[1] >=
'1' && magic_number[1] <=
'6');
1029 make_reader(istream *file,
bool owns_file,
const string &magic_number) {
1031 return new Reader(
this, file, owns_file, magic_number);
1040 make_writer(ostream *file,
bool owns_file) {
1042 return new Writer(
this, file, owns_file);
1049 PNMFileTypePNM::Reader::
1050 Reader(
PNMFileType *type, istream *file,
bool owns_file,
string magic_number) :
1055 if (pnmimage_pnm_cat.is_debug()) {
1056 pnmimage_pnm_cat.debug()
1057 <<
"PNM file appears to be empty.\n";
1064 ((
unsigned char)magic_number[0] << 8) |
1065 (
unsigned char)magic_number[1];
1067 switch ( PNM_FORMAT_TYPE(_ftype) ) {
1069 ppm_readppminitrest( file, &_x_size, &_y_size, &_maxval );
1074 pgm_readpgminitrest( file, &_x_size, &_y_size, &_maxval );
1079 pbm_readpbminitrest( file, &_x_size, &_y_size );
1088 if (pnmimage_pnm_cat.is_debug()) {
1090 pnmimage_pnm_cat.debug()
1092 switch (PNM_FORMAT_TYPE(_ftype)) {
1094 pnmimage_pnm_cat.debug(
false) <<
"PPM";
1097 pnmimage_pnm_cat.debug(
false) <<
"PGM";
1100 pnmimage_pnm_cat.debug(
false) <<
"PBM";
1103 pnmimage_pnm_cat.debug(
false)
1104 <<
" " << *
this <<
"\n";
1106 pnmimage_pnm_cat.debug()
1107 <<
"File is not a valid PNM image.\n";
1118 bool PNMFileTypePNM::Reader::
1119 supports_read_row()
const {
1135 bool PNMFileTypePNM::Reader::
1136 read_row(
xel *array, xelval *,
int x_size,
int y_size) {
1140 pnm_readpnmrow(_file, array, x_size, _maxval, _ftype);
1148 PNMFileTypePNM::Writer::
1149 Writer(
PNMFileType *type, ostream *file,
bool owns_file) :
1160 bool PNMFileTypePNM::Writer::
1161 supports_write_row()
const {
1175 bool PNMFileTypePNM::Writer::
1177 switch (get_color_type()) {
1178 case PNMImageHeader::CT_grayscale:
1179 case PNMImageHeader::CT_two_channel:
1181 _pnm_format = PBM_TYPE;
1183 _pnm_format = PGM_TYPE;
1187 case PNMImageHeader::CT_color:
1188 case PNMImageHeader::CT_four_channel:
1189 _pnm_format = PPM_TYPE;
1196 pnm_writepnminit(_file, _x_size, _y_size, _maxval, _pnm_format, 0);
1211 bool PNMFileTypePNM::Writer::
1212 write_row(
xel *row_data, xelval *) {
1213 pnm_writepnmrow(_file, row_data, _x_size, _maxval, _pnm_format, 0);
1221 void PNMFileTypePNM::
1222 register_with_read_factory() {
1224 register_factory(get_class_type(), make_PNMFileTypePNM);
bool is_valid() const
Returns true if the PNMWriter can be used to write data, false if something is wrong.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
This is the base class of a family of classes that represent particular image file types that PNMImag...
void pm_freerow(char *itrow)
Frees the row previously allocated withm pm_allocrow().
static PNMFileTypeRegistry * get_global_ptr()
Returns a pointer to the global PNMFileTypeRegistry object.
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.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PNMFileType * get_type_by_handle(TypeHandle handle) const
Returns the PNMFileType instance stored in the registry for the given TypeHandle, e....
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract base class that defines the interface for reading image files of various types.
char * pm_allocrow(int cols, int size)
Allocates a row of cols * size bytes.
This is an abstract base class that defines the interface for writing image files of various types.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
TypeHandle is the identifier used to differentiate C++ class types.