Panda3D
imageFile.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file imageFile.cxx
10  * @author drose
11  * @date 2000-11-29
12  */
13 
14 #include "imageFile.h"
15 #include "palettizer.h"
16 #include "filenameUnifier.h"
17 #include "paletteGroup.h"
18 
19 #include "pnmImage.h"
20 #include "pnmFileType.h"
21 #include "eggTexture.h"
22 #include "datagram.h"
23 #include "datagramIterator.h"
24 #include "bamReader.h"
25 #include "bamWriter.h"
26 
27 using std::string;
28 
29 TypeHandle ImageFile::_type_handle;
30 
31 /**
32  *
33  */
34 ImageFile::
35 ImageFile() {
36  _alpha_file_channel = 0;
37  _size_known = false;
38  _x_size = 0;
39  _y_size = 0;
40 }
41 
42 /**
43  * Sets up the ImageFile as a "shadow image" of a particular PaletteImage.
44  * This is a temporary ImageFile that's used to read and write the shadow
45  * palette image, which is used to keep a working copy of the palette.
46  *
47  * Returns true if the filename changes from what it was previously, false
48  * otherwise.
49  */
50 bool ImageFile::
51 make_shadow_image(const string &basename) {
52  bool any_changed = false;
53 
54  if (_properties._color_type != pal->_shadow_color_type ||
55  _properties._alpha_type != pal->_shadow_alpha_type) {
56 
57  _properties._color_type = pal->_shadow_color_type;
58  _properties._alpha_type = pal->_shadow_alpha_type;
59  any_changed = true;
60  }
61 
62  if (set_filename(pal->_shadow_dirname, basename)) {
63  any_changed = true;
64  }
65 
66  return any_changed;
67 }
68 
69 /**
70  * Returns true if the size of the image file is known, false otherwise.
71  */
72 bool ImageFile::
73 is_size_known() const {
74  return _size_known;
75 }
76 
77 /**
78  * Returns the size of the image file in pixels in the X direction. It is an
79  * error to call this unless is_size_known() returns true.
80  */
81 int ImageFile::
82 get_x_size() const {
83  nassertr(is_size_known(), 0);
84  return _x_size;
85 }
86 
87 /**
88  * Returns the size of the image file in pixels in the Y direction. It is an
89  * error to call this unless is_size_known() returns true.
90  */
91 int ImageFile::
92 get_y_size() const {
93  nassertr(is_size_known(), 0);
94  return _y_size;
95 }
96 
97 /**
98  * Returns true if the number of channels in the image is known, false
99  * otherwise.
100  */
101 bool ImageFile::
103  return _properties.has_num_channels();
104 }
105 
106 /**
107  * Returns the number of channels of the image. It is an error to call this
108  * unless has_num_channels() returns true.
109  */
110 int ImageFile::
112  return _properties.get_num_channels();
113 }
114 
115 /**
116  * Returns the grouping properties of the image.
117  */
119 get_properties() const {
120  return _properties;
121 }
122 
123 /**
124  * Resets the properties to a neutral state, for instance in preparation for
125  * calling update_properties() with all the known contributing properties.
126  */
127 void ImageFile::
129  _properties.clear_basic();
130 }
131 
132 /**
133  * If the indicate TextureProperties structure is more specific than this one,
134  * updates this one.
135  */
136 void ImageFile::
138  _properties.update_properties(properties);
139 }
140 
141 /**
142  * Sets the filename, and if applicable, the alpha_filename, from the
143  * indicated basename. The extension appropriate to the image file type
144  * specified in _color_type (and _alpha_type) is automatically applied.
145  *
146  * Returns true if the filename changes from what it was previously, false
147  * otherwise.
148  */
149 bool ImageFile::
150 set_filename(PaletteGroup *group, const string &basename) {
151  // Synthesize the directory name based on the map_dirname set to the
152  // palettizer, and the group's dirname.
153  string dirname;
154  string::iterator pi;
155  pi = pal->_map_dirname.begin();
156  while (pi != pal->_map_dirname.end()) {
157  if (*pi == '%') {
158  ++pi;
159  switch (*pi) {
160  case '%':
161  dirname += '%';
162  break;
163 
164  case 'g':
165  if (group != nullptr) {
166  dirname += group->get_dirname();
167  }
168  break;
169  }
170  } else {
171  dirname += *pi;
172  }
173  ++pi;
174  }
175 
176  return set_filename(dirname, basename);
177 }
178 
179 /**
180  * Sets the filename, and if applicable, the alpha_filename, from the
181  * indicated basename. The extension appropriate to the image file type
182  * specified in _color_type (and _alpha_type) is automatically applied.
183  *
184  * Returns true if the filename changes from what it was previously, false
185  * otherwise.
186  */
187 bool ImageFile::
188 set_filename(const string &dirname, const string &basename) {
189  Filename orig_filename = _filename;
190  Filename orig_alpha_filename = _alpha_filename;
191 
192  _filename = Filename(dirname, basename);
193  _filename.standardize();
194 
195  // Since we use set_extension() here, if the file already contains a
196  // filename extension it will be lost.
197 
198  // It is particularly important to note that a single embedded dot will
199  // appear to begin a filename extension, so if the filename does *not*
200  // contain an extension, but does contain an embedded dot, the filename will
201  // be truncated at that dot. It is therefore important that the supplied
202  // basename always contains either an extension or a terminating dot.
203 
204  if (_properties._color_type != nullptr) {
205  _filename.set_extension
206  (_properties._color_type->get_suggested_extension());
207  }
208 
209  if (_properties._alpha_type != nullptr) {
210  _alpha_filename = _filename.get_fullpath_wo_extension() + "_a.";
211  _alpha_filename.set_extension
212  (_properties._alpha_type->get_suggested_extension());
213  } else {
214  _alpha_filename = Filename();
215  }
216 
217  return (_filename != orig_filename ||
218  _alpha_filename != orig_alpha_filename);
219 }
220 
221 /**
222  * Returns the primary filename of the image file.
223  */
224 const Filename &ImageFile::
225 get_filename() const {
226  return _filename;
227 }
228 
229 /**
230  * Returns the alpha filename of the image file. This is the name of the file
231  * that contains the alpha channel, if it is stored in a separate file, or the
232  * empty string if it is not.
233  */
234 const Filename &ImageFile::
236  return _alpha_filename;
237 }
238 
239 /**
240  * Returns the particular channel number of the alpha image file from which
241  * the alpha channel should be extracted. This is normally 0 to represent the
242  * grayscale combination of r, g, and b; or it may be a 1-based channel number
243  * (for instance, 4 for the alpha channel of a 4-component image).
244  */
245 int ImageFile::
247  return _alpha_file_channel;
248 }
249 
250 
251 /**
252  * Returns true if the file or files named by the image file exist, false
253  * otherwise.
254  */
255 bool ImageFile::
256 exists() const {
257  if (!_filename.exists()) {
258  return false;
259  }
260  if (_properties._alpha_type != nullptr &&
261  _properties.uses_alpha() &&
262  !_alpha_filename.empty()) {
263  if (!_alpha_filename.exists()) {
264  return false;
265  }
266  }
267 
268  return true;
269 }
270 
271 /**
272  * Reads in the image (or images, if the alpha_filename is separate) and
273  * stores it in the indicated PNMImage. Returns true on success, false on
274  * failure.
275  */
276 bool ImageFile::
277 read(PNMImage &image) const {
278  nassertr(!_filename.empty(), false);
279 
280  image.set_type(_properties._color_type);
281  nout << "Reading " << FilenameUnifier::make_user_filename(_filename) << "\n";
282  if (!image.read(_filename)) {
283  nout << "Unable to read.\n";
284  return false;
285  }
286 
287  if (!_alpha_filename.empty() && _alpha_filename.exists()) {
288  // Read in a separate color image and an alpha channel image.
289  PNMImage alpha_image;
290  alpha_image.set_type(_properties._alpha_type);
291  nout << "Reading " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
292  if (!alpha_image.read(_alpha_filename)) {
293  nout << "Unable to read.\n";
294  return false;
295  }
296  if (image.get_x_size() != alpha_image.get_x_size() ||
297  image.get_y_size() != alpha_image.get_y_size()) {
298  return false;
299  }
300 
301  image.add_alpha();
302 
303  if (_alpha_file_channel == 4 ||
304  (_alpha_file_channel == 2 && alpha_image.get_num_channels() == 2)) {
305  // Use the alpha channel.
306  for (int x = 0; x < image.get_x_size(); x++) {
307  for (int y = 0; y < image.get_y_size(); y++) {
308  image.set_alpha(x, y, alpha_image.get_alpha(x, y));
309  }
310  }
311 
312  } else if (_alpha_file_channel >= 1 && _alpha_file_channel <= 3 &&
313  alpha_image.get_num_channels() >= 3) {
314  // Use the appropriate red, green, or blue channel.
315  for (int x = 0; x < image.get_x_size(); x++) {
316  for (int y = 0; y < image.get_y_size(); y++) {
317  image.set_alpha(x, y, alpha_image.get_channel_val(x, y, _alpha_file_channel - 1));
318  }
319  }
320 
321  } else {
322  // Use the grayscale channel.
323  for (int x = 0; x < image.get_x_size(); x++) {
324  for (int y = 0; y < image.get_y_size(); y++) {
325  image.set_alpha(x, y, alpha_image.get_gray(x, y));
326  }
327  }
328  }
329  }
330 
331  return true;
332 }
333 
334 /**
335  * Writes out the image in the indicated PNMImage to the _filename and/or
336  * _alpha_filename. Returns true on success, false on failure.
337  */
338 bool ImageFile::
339 write(const PNMImage &image) const {
340  nassertr(!_filename.empty(), false);
341 
342  if (!image.has_alpha() ||
343  _properties._alpha_type == nullptr) {
344  if (!_alpha_filename.empty() && _alpha_filename.exists()) {
345  nout << "Deleting " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
346  _alpha_filename.unlink();
347  }
348  nout << "Writing " << FilenameUnifier::make_user_filename(_filename) << "\n";
349  _filename.make_dir();
350  if (!image.write(_filename, _properties._color_type)) {
351  nout << "Unable to write.\n";
352  return false;
353  }
354  return true;
355  }
356 
357  // Write out a separate color image and an alpha channel image.
358  PNMImage alpha_image(image.get_x_size(), image.get_y_size(), 1,
359  image.get_maxval());
360  for (int y = 0; y < image.get_y_size(); y++) {
361  for (int x = 0; x < image.get_x_size(); x++) {
362  alpha_image.set_gray_val(x, y, image.get_alpha_val(x, y));
363  }
364  }
365 
366  PNMImage image_copy(image);
367  image_copy.remove_alpha();
368  nout << "Writing " << FilenameUnifier::make_user_filename(_filename) << "\n";
369  _filename.make_dir();
370  if (!image_copy.write(_filename, _properties._color_type)) {
371  nout << "Unable to write.\n";
372  return false;
373  }
374 
375  nout << "Writing " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
376  _alpha_filename.make_dir();
377  if (!alpha_image.write(_alpha_filename, _properties._alpha_type)) {
378  nout << "Unable to write.\n";
379  return false;
380  }
381  return true;
382 }
383 
384 /**
385  * Deletes the image file or files.
386  */
387 void ImageFile::
389  if (!_filename.empty() && _filename.exists()) {
390  nout << "Deleting " << FilenameUnifier::make_user_filename(_filename) << "\n";
391  _filename.unlink();
392  }
393  if (!_alpha_filename.empty() && _alpha_filename.exists()) {
394  nout << "Deleting " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
395  _alpha_filename.unlink();
396  }
397 }
398 
399 /**
400  * Sets the indicated EggTexture to refer to this file.
401  */
402 void ImageFile::
403 update_egg_tex(EggTexture *egg_tex) const {
404  nassertv(egg_tex != nullptr);
405 
406  egg_tex->set_filename(FilenameUnifier::make_egg_filename(_filename));
407 
408  if (_properties.uses_alpha() &&
409  !_alpha_filename.empty()) {
410  egg_tex->set_alpha_filename(FilenameUnifier::make_egg_filename(_alpha_filename));
411  egg_tex->set_alpha_file_channel(_alpha_file_channel);
412  } else {
413  egg_tex->clear_alpha_filename();
414  egg_tex->clear_alpha_file_channel();
415  }
416 
417  _properties.update_egg_tex(egg_tex);
418 }
419 
420 /**
421  * Writes the filename (or pair of filenames) to the indicated output stream.
422  */
423 void ImageFile::
424 output_filename(std::ostream &out) const {
425  out << FilenameUnifier::make_user_filename(_filename);
426  if (_properties.uses_alpha() && !_alpha_filename.empty()) {
427  out << " " << FilenameUnifier::make_user_filename(_alpha_filename);
428  }
429 }
430 
431 /**
432  * Fills the indicated datagram up with a binary representation of the current
433  * object, in preparation for writing to a Bam file.
434  */
435 void ImageFile::
436 write_datagram(BamWriter *writer, Datagram &datagram) {
437  TypedWritable::write_datagram(writer, datagram);
438  _properties.write_datagram(writer, datagram);
439  datagram.add_string(FilenameUnifier::make_bam_filename(_filename));
440  datagram.add_string(FilenameUnifier::make_bam_filename(_alpha_filename));
441  datagram.add_uint8(_alpha_file_channel);
442  datagram.add_bool(_size_known);
443  datagram.add_int32(_x_size);
444  datagram.add_int32(_y_size);
445 }
446 
447 /**
448  * Called after the object is otherwise completely read from a Bam file, this
449  * function's job is to store the pointers that were retrieved from the Bam
450  * file for each pointer object written. The return value is the number of
451  * pointers processed from the list.
452  */
453 int ImageFile::
455  int pi = TypedWritable::complete_pointers(p_list, manager);
456 
457  pi += _properties.complete_pointers(p_list + pi, manager);
458 
459  return pi;
460 }
461 
462 /**
463  * Reads the binary data from the given datagram iterator, which was written
464  * by a previous call to write_datagram().
465  */
466 void ImageFile::
467 fillin(DatagramIterator &scan, BamReader *manager) {
468  TypedWritable::fillin(scan, manager);
469  _properties.fillin(scan, manager);
470  _filename = FilenameUnifier::get_bam_filename(scan.get_string());
471  _alpha_filename = FilenameUnifier::get_bam_filename(scan.get_string());
472  if (Palettizer::_read_pi_version >= 10) {
473  _alpha_file_channel = scan.get_uint8();
474  } else {
475  _alpha_file_channel = 0;
476  }
477  _size_known = scan.get_bool();
478  _x_size = scan.get_int32();
479  _y_size = scan.get_int32();
480 }
void set_gray_val(int x, int y, xelval gray)
Sets the gray component color at the indicated pixel.
Definition: pnmImage.I:456
bool write(const PNMImage &image) const
Writes out the image in the indicated PNMImage to the _filename and/or _alpha_filename.
Definition: imageFile.cxx:339
static Filename make_bam_filename(Filename filename)
Returns a new filename that's made relative to the bam file itself, suitable for writing to the bam f...
bool read(PNMImage &image) const
Reads in the image (or images, if the alpha_filename is separate) and stores it in the indicated PNMI...
Definition: imageFile.cxx:277
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_extension(const std::string &s)
Replaces the file extension.
Definition: filename.cxx:804
int get_num_channels() const
Returns the number of channels (1 through 4) associated with the image.
void update_egg_tex(EggTexture *egg_tex) const
Sets the indicated EggTexture to refer to this file.
Definition: imageFile.cxx:403
xelval get_channel_val(int x, int y, int channel) const
Returns the nth component color at the indicated pixel.
Definition: pnmImage.cxx:837
bool get_bool()
Extracts a boolean value.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
Definition: pnmImage.h:58
bool exists() const
Returns true if the file or files named by the image file exist, false otherwise.
Definition: imageFile.cxx:256
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_num_channels
Returns the number of channels in the image.
int get_alpha_file_channel() const
Returns the particular channel number of the alpha image file from which the alpha channel should be ...
Definition: imageFile.cxx:246
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function's job is to store...
Definition: imageFile.cxx:454
float get_gray(int x, int y) const
Returns the gray component color at the indicated pixel.
Definition: pnmImage.I:785
get_suggested_extension
Returns a suitable filename extension (without a leading dot) to suggest for files of this type,...
Definition: pnmFileType.h:49
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:30
int get_y_size() const
Returns the size of the image file in pixels in the Y direction.
Definition: imageFile.cxx:92
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
bool write(const Filename &filename, PNMFileType *type=nullptr) const
Writes the image to the indicated filename.
Definition: pnmImage.cxx:385
This is the highest level of grouping for TextureImages.
Definition: paletteGroup.h:43
bool read(const Filename &filename, PNMFileType *type=nullptr, bool report_unknown_type=true)
Reads the indicated image filename.
Definition: pnmImage.cxx:278
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function's job is to store...
void output_filename(std::ostream &out) const
Writes the filename (or pair of filenames) to the indicated output stream.
Definition: imageFile.cxx:424
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
int32_t get_int32()
Extracts a signed 32-bit integer.
void set_type(PNMFileType *type)
Sets the file type of this PNMImage.
void remove_alpha()
Removes the image's alpha channel, if it exists.
Definition: pnmImage.I:282
std::string get_string()
Extracts a variable-length string.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
void standardize()
Converts the filename to standard form by replacing consecutive slashes with a single slash,...
Definition: filename.cxx:900
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_y_size() const
Returns the number of pixels in the Y direction.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
int get_x_size() const
Returns the number of pixels in the X direction.
void update_egg_tex(EggTexture *egg_tex) const
Adjusts the texture properties of the indicated egg reference to match these properties.
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
Definition: imageFile.cxx:436
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
Definition: imageFile.cxx:119
bool set_filename(PaletteGroup *group, const std::string &basename)
Sets the filename, and if applicable, the alpha_filename, from the indicated basename.
Definition: imageFile.cxx:150
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
static Filename make_user_filename(Filename filename)
Returns a new filename that's made relative to the current directory, suitable for reporting to the u...
get_maxval
Returns the maximum channel value allowable for any pixel in this image; for instance,...
bool is_size_known() const
Returns true if the size of the image file is known, false otherwise.
Definition: imageFile.cxx:73
static Filename make_egg_filename(Filename filename)
Returns a new filename that's made relative to the rel_directory, suitable for writing out within egg...
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_x_size() const
Returns the size of the image file in pixels in the X direction.
Definition: imageFile.cxx:82
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
static bool has_alpha(ColorType color_type)
This static variant of has_alpha() returns true if the indicated image type includes an alpha channel...
static Filename get_bam_filename(Filename filename)
Returns an absolute pathname based on the given relative pathname, presumably read from the bam file ...
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:219
const std::string & get_dirname() const
Returns the directory name associated with the palette group.
int get_num_channels() const
Returns the number of channels of the image.
Definition: imageFile.cxx:111
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear_basic_properties()
Resets the properties to a neutral state, for instance in preparation for calling update_properties()...
Definition: imageFile.cxx:128
bool unlink() const
Permanently deletes the file associated with the filename, if possible.
Definition: filename.cxx:2319
bool uses_alpha() const
Returns true if the texture uses an alpha channel, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_num_channels() const
Returns true if the number of channels is known.
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
const Filename & get_alpha_filename() const
Returns the alpha filename of the image file.
Definition: imageFile.cxx:235
void add_alpha()
Adds an alpha channel to the image, if it does not already have one.
Definition: pnmImage.I:274
void unlink()
Deletes the image file or files.
Definition: imageFile.cxx:388
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:67
void set_alpha(int x, int y, float a)
Sets the alpha component color only at the indicated pixel.
Definition: pnmImage.I:845
clear_alpha_file_channel
Removes the specification of a particular channel to use from the alpha- file image.
Definition: eggTexture.h:346
set_alpha_filename
Specifies a separate file that will be loaded in with the 1- or 3-component texture and applied as th...
Definition: eggTexture.h:343
bool has_num_channels() const
Returns true if the number of channels in the image is known, false otherwise.
Definition: imageFile.cxx:102
bool make_shadow_image(const std::string &basename)
Sets up the ImageFile as a "shadow image" of a particular PaletteImage.
Definition: imageFile.cxx:51
void clear_basic()
Resets only the properties that might be changed by update_properties() to a neutral state.
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
Definition: datagram.I:50
void update_properties(const TextureProperties &properties)
If the indicate TextureProperties structure is more specific than this one, updates this one.
Definition: imageFile.cxx:137
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...
Definition: filename.cxx:2484
A class to retrieve the individual data elements previously stored in a Datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_alpha_file_channel
If a separate alpha-file is specified, this indicates which channel number should be extracted from t...
Definition: eggTexture.h:346
xelval get_alpha_val(int x, int y) const
Returns the alpha component color at the indicated pixel.
Definition: pnmImage.I:405
void update_properties(const TextureProperties &other)
If the indicate TextureProperties structure is more specific than this one, updates this one.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const Filename & get_filename() const
Returns the primary filename of the image file.
Definition: imageFile.cxx:225
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
std::string get_fullpath_wo_extension() const
Returns the full filename–directory and basename parts–except for the extension.
Definition: filename.I:377
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
Definition: filename.cxx:1267
float get_alpha(int x, int y) const
Returns the alpha component color at the indicated pixel.
Definition: pnmImage.I:795
This is the set of characteristics of a texture that, if different from another texture,...