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;
381output(ostream &out)
const {
382 out <<
"image: " << _x_size <<
" by " << _y_size <<
" pixels, "
383 << _num_channels <<
" channels, " << _maxval <<
" maxval.";
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) {
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);
486void PNMImageHeader::PixelSpec::
487output(ostream &out)
const {
488 out <<
"(" << _red <<
", " << _green <<
", " << _blue <<
", " << _alpha <<
")";
494void PNMImageHeader::Histogram::
495write(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";
The name of a file, such as a texture file or an Egg file.
std::string get_extension() const
Returns the file extension.
static PNMFileTypeRegistry * get_global_ptr()
Returns a pointer to the global PNMFileTypeRegistry object.
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 the base class of a family of classes that represent particular image file types that PNMImag...
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.
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.
This is an abstract base class that defines the interface for reading image files of various types.
bool is_valid() const
Returns true if the PNMReader can be used to read data, false if something is wrong.
This is an abstract base class that defines the interface for writing image files of various types.
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::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,...
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
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,...
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
This is our own Panda specialization on the default STL vector.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.