34 bool report_unknown_type) {
36 if (reader !=
nullptr) {
59 bool report_unknown_type) {
61 (&data,
false, filename,
string(), type, report_unknown_type);
62 if (reader !=
nullptr) {
81 bool report_unknown_type)
const {
82 if (pnmimage_cat.is_debug()) {
84 <<
"Reading image from " << filename <<
"\n";
86 bool owns_file =
false;
87 istream *file =
nullptr;
89 if (filename ==
"-") {
93 if (pnmimage_cat.is_debug()) {
95 <<
"(reading standard input)\n";
103 if (file ==
nullptr) {
104 if (pnmimage_cat.is_debug()) {
106 <<
"Unable to open file.\n";
111 return make_reader(file, owns_file, filename,
string(), type,
112 report_unknown_type);
141 bool report_unknown_type)
const {
142 if (type ==
nullptr) {
145 if (pnmimage_cat.is_debug()) {
147 <<
"Image file appears to be empty.\n";
162 get_type_from_magic_number(magic_number);
164 if (pnmimage_cat.is_debug()) {
165 if (type !=
nullptr) {
167 <<
"By magic number, image file appears to be type " 168 << type->get_name() <<
".\n";
171 <<
"Unable to determine image file type from magic number.\n";
176 if (type ==
nullptr && !filename.empty()) {
181 if (pnmimage_cat.is_debug()) {
182 if (type !=
nullptr) {
184 <<
"From its extension, image file is probably type " 185 << type->get_name() <<
".\n";
188 <<
"Unable to guess image file type from its extension (" 194 if (type ==
nullptr) {
198 if (pnmimage_cat.is_debug() && type !=
nullptr) {
200 <<
"Assuming image file type is " << type->get_name() <<
".\n";
204 if (type ==
nullptr) {
206 if (report_unknown_type && pnmimage_cat.is_error()) {
208 <<
"Cannot determine type of image file " << filename <<
".\n" 209 <<
"Currently supported image types:\n";
211 write(pnmimage_cat.error(
false), 2);
226 if (reader ==
nullptr && owns_file) {
249 if (pnmimage_cat.is_debug()) {
251 <<
"Writing image to " << filename <<
"\n";
253 bool owns_file =
false;
254 ostream *file =
nullptr;
256 if (filename ==
"-") {
260 if (pnmimage_cat.is_debug()) {
262 <<
"(writing to standard output)\n";
267 Filename actual_name = Filename::binary_filename(filename);
269 if (file !=
nullptr) {
274 if (file ==
nullptr) {
275 if (pnmimage_cat.is_debug()) {
277 <<
"Unable to write to file.\n";
282 return make_writer(file, owns_file, filename, type);
306 if (type ==
nullptr && !filename.empty()) {
311 if (pnmimage_cat.is_debug()) {
312 if (type !=
nullptr) {
314 <<
"From its extension, image file is intended to be type " 315 << type->get_name() <<
".\n";
318 <<
"Unable to guess image file type from its extension.\n";
323 if (type ==
nullptr) {
327 if (pnmimage_cat.is_debug() && type !=
nullptr) {
329 <<
"Assuming image file type is " << type->get_name() <<
".\n";
333 if (type ==
nullptr) {
335 if (pnmimage_cat.is_debug()) {
337 <<
"Cannot determine type of image file " << filename <<
".\n";
346 if (writer ==
nullptr && owns_file) {
350 if (writer !=
nullptr && !writer->
is_valid()) {
366 while ((
int)magic_number.size() < num_bytes) {
367 int ch = file->get();
368 if (file->eof() || file->fail()) {
371 magic_number += (char)ch;
380 void PNMImageHeader::
381 output(ostream &out)
const {
382 out <<
"image: " << _x_size <<
" by " << _y_size <<
" pixels, " 383 << _num_channels <<
" channels, " << _maxval <<
" maxval.";
399 bool PNMImageHeader::
401 xel *array, xelval *alpha,
int max_colors) {
402 int num_pixels = _x_size * _y_size;
410 for (pi = 0; pi < num_pixels; pi++) {
411 record_color(hist, PixelSpec(PPM_GETB(array[pi])));
412 if (max_colors > 0 && (
int)hist.size() > max_colors) {
419 for (pi = 0; pi < num_pixels; pi++) {
420 record_color(hist, PixelSpec(PPM_GETB(array[pi]), alpha[pi]));
421 if (max_colors > 0 && (
int)hist.size() > max_colors) {
428 for (pi = 0; pi < num_pixels; pi++) {
429 record_color(hist, PixelSpec(PPM_GETR(array[pi]), PPM_GETG(array[pi]), PPM_GETB(array[pi])));
430 if (max_colors > 0 && (
int)hist.size() > max_colors) {
436 case CT_four_channel:
437 for (pi = 0; pi < num_pixels; pi++) {
438 record_color(hist, PixelSpec(PPM_GETR(array[pi]), PPM_GETG(array[pi]), PPM_GETB(array[pi]), alpha[pi]));
439 if (max_colors > 0 && (
int)hist.size() > max_colors) {
453 bool PNMImageHeader::
455 xel *array, xelval *alpha,
int max_colors) {
458 int num_pixels = _x_size * _y_size;
461 Palette::const_iterator pi;
462 for (pi = palette.begin(); pi != palette.end(); ++pi) {
463 hist.insert(HistMap::value_type(*pi, num_pixels + 1));
466 if (!compute_histogram(hist, array, alpha, max_colors)) {
472 palette.reserve(hist.size());
473 HistMap::const_iterator hi;
474 for (hi = hist.begin(); hi != hist.end(); ++hi) {
475 if ((*hi).second <= num_pixels) {
476 palette.push_back((*hi).first);
486 void PNMImageHeader::PixelSpec::
487 output(ostream &out)
const {
488 out <<
"(" << _red <<
", " << _green <<
", " << _blue <<
", " << _alpha <<
")";
494 void PNMImageHeader::Histogram::
495 write(ostream &out)
const {
496 out <<
"Histogram: {\n";
497 PixelCount::const_iterator pi;
498 for (pi = _pixels.begin(); pi != _pixels.end(); ++pi) {
499 out <<
" " << (*pi)._pixel <<
": " << (*pi)._count <<
",\n";
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_valid() const
Returns true if the PNMWriter can be used to write data, false if something is wrong.
A hierarchy of directories and files that appears to be one continuous file system,...
std::istream * open_read_file(const Filename &filename, bool auto_unwrap) const
Convenience function; returns a newly allocated istream if the file exists and can be read,...
virtual PNMReader * make_reader(std::istream *file, bool owns_file=true, const std::string &magic_number=std::string())
Allocates and returns a new PNMReader suitable for reading from this file type, if possible.
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...
static PNMFileTypeRegistry * get_global_ptr()
Returns a pointer to the global PNMFileTypeRegistry object.
This is our own Panda specialization on the default STL vector.
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
bool is_valid() const
Returns true if the PNMReader can be used to read data, false if something is wrong.
The name of a file, such as a texture file or an Egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
This is an abstract base class that defines the interface for reading image files of various types.
PNMFileType * get_type_from_extension(const std::string &filename) const
Tries to determine what the PNMFileType is likely to be for a particular image file based on its exte...
This is an abstract base class that defines the interface for writing image files of various types.
std::string get_extension() const
Returns the file extension.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream * open_write_file(const Filename &filename, bool auto_wrap, bool truncate)
Convenience function; returns a newly allocated ostream if the file exists and can be written,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual PNMWriter * make_writer(std::ostream *file, bool owns_file=true)
Allocates and returns a new PNMWriter suitable for reading from this file type, if possible.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.