Panda3D
pnmImageHeader.I
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 pnmImageHeader.I
10  * @author drose
11  * @date 2000-06-15
12  */
13 
14 /**
15  *
16  */
17 INLINE PNMImageHeader::
18 PNMImageHeader() {
19  _x_size = 0;
20  _y_size = 0;
21  _num_channels = 0;
22  _maxval = 255;
23  _color_space = CS_unspecified;
24  _type = nullptr;
25 }
26 
27 /**
28  *
29  */
30 INLINE PNMImageHeader::
31 PNMImageHeader(const PNMImageHeader &copy) :
32  _x_size(copy._x_size),
33  _y_size(copy._y_size),
34  _num_channels(copy._num_channels),
35  _maxval(copy._maxval),
36  _color_space(copy._color_space),
37  _type(copy._type)
38 {
39 }
40 
41 /**
42  *
43  */
44 INLINE void PNMImageHeader::
45 operator = (const PNMImageHeader &copy) {
46  _x_size = copy._x_size;
47  _y_size = copy._y_size;
48  _num_channels = copy._num_channels;
49  _maxval = copy._maxval;
50  _color_space = copy._color_space;
51  _comment = copy._comment;
52  _type = copy._type;
53 }
54 
55 /**
56  *
57  */
58 INLINE PNMImageHeader::
59 ~PNMImageHeader() {
60 }
61 
62 /**
63  * Returns the image type of the image, as an enumerated value. This is
64  * really just the number of channels cast to the enumerated type.
65  */
66 INLINE PNMImageHeader::ColorType PNMImageHeader::
67 get_color_type() const {
68  nassertr(_num_channels >= 1 && _num_channels <= 4, CT_invalid);
69  return (ColorType)_num_channels;
70 }
71 
72 /**
73  * Returns the number of channels in the image.
74  */
75 INLINE int PNMImageHeader::
76 get_num_channels() const {
77  nassertr(_num_channels >= 1 && _num_channels <= 4, 0);
78  return _num_channels;
79 }
80 
81 /**
82  * This static variant of is_grayscale() returns true if the indicated image
83  * type represents a grayscale image, false otherwise.
84  */
85 INLINE bool PNMImageHeader::
86 is_grayscale(PNMImageHeader::ColorType color_type) {
87  return (color_type == CT_grayscale || color_type == CT_two_channel);
88 }
89 
90 /**
91  * Returns false if the image is a full-color image, and has red, green, and
92  * blue components; true if it is a grayscale image and has only a gray
93  * component. (The gray color is actually stored in the blue channel, and the
94  * red and green channels are ignored.)
95  */
96 INLINE bool PNMImageHeader::
97 is_grayscale() const {
98  return is_grayscale(get_color_type());
99 }
100 
101 /**
102  * This static variant of has_alpha() returns true if the indicated image type
103  * includes an alpha channel, false otherwise.
104  */
105 INLINE bool PNMImageHeader::
106 has_alpha(PNMImageHeader::ColorType color_type) {
107  return (color_type == CT_two_channel || color_type == CT_four_channel);
108 }
109 
110 /**
111  * Returns true if the image includes an alpha channel, false otherwise.
112  * Unlike is_grayscale(), if this returns false it is an error to call any of
113  * the functions accessing the alpha channel.
114  */
115 INLINE bool PNMImageHeader::
116 has_alpha() const {
117  return has_alpha(get_color_type());
118 }
119 
120 /**
121  * Returns the maximum channel value allowable for any pixel in this image;
122  * for instance, 255 for a typical 8-bit-per-channel image. A pixel with this
123  * value is full on.
124  */
125 INLINE xelval PNMImageHeader::
126 get_maxval() const {
127  return _maxval;
128 }
129 
130 /**
131  * Returns the color space that the image is encoded in, or CS_unspecified if
132  * unknown.
133  */
134 INLINE ColorSpace PNMImageHeader::
135 get_color_space() const {
136  return _color_space;
137 }
138 
139 /**
140  * Returns the number of pixels in the X direction. This is one more than the
141  * largest allowable X coordinate.
142  */
144 get_x_size() const {
145  return _x_size;
146 }
147 
148 /**
149  * Returns the number of pixels in the Y direction. This is one more than the
150  * largest allowable Y coordinate.
151  */
153 get_y_size() const {
154  return _y_size;
155 }
156 
157 /**
158  * Returns the number of pixels in each direction. This is one more than the
159  * largest allowable coordinates.
160  */
161 INLINE LVecBase2i PNMImageHeader::
162 get_size() const {
163  return LVecBase2i(_x_size, _y_size);
164 }
165 
166 /**
167  * Gets the user comment from the file.
168  */
169 INLINE std::string PNMImageHeader::
170 get_comment() const {
171  return _comment;
172 }
173 
174 /**
175  * Writes a user comment string to the image (header).
176  */
177 INLINE void PNMImageHeader::
178 set_comment(const std::string& comment) {
179  _comment = comment;
180 }
181 
182 /**
183  * Returns true if the PNMImageHeader knows what type it is, false otherwise.
184  */
185 INLINE bool PNMImageHeader::
186 has_type() const {
187  return _type != nullptr;
188 }
189 
190 /**
191  * If the file type is known (e.g. has_type() returns true), returns its
192  * PNMFileType pointer; otherwise, returns NULL.
193  */
195 get_type() const {
196  return _type;
197 }
198 
199 /**
200  * Sets the file type of this PNMImage. This will be the default type used
201  * when an image is read, if the type cannot be determined by magic number or
202  * inferred by extension, or the type used when the image is written, if the
203  * type cannot be inferred from the filename extension.
204  */
205 INLINE void PNMImageHeader::
206 set_type(PNMFileType *type) {
207  _type = type;
208 }
209 
210 /**
211  * Records the indicated color in the histogram.
212  */
213 INLINE void PNMImageHeader::
214 record_color(PNMImageHeader::HistMap &hist,
215  const PNMImageHeader::PixelSpec &color) {
216  // First, try to add the color with a count of 0, in case it does not
217  // already exist in the table.
218  HistMap::iterator hi = hist.insert(HistMap::value_type(color, 0)).first;
219 
220  // Now that either succeeded or failed, but either way hi is now the
221  // iterator to the count value in the table associated with the given color.
222  // Increment that count.
223  (*hi).second++;
224 }
225 
226 /**
227  *
228  */
229 INLINE PNMImageHeader::PixelSpec::
230 PixelSpec(xelval gray_value) :
231  _red(gray_value),
232  _green(gray_value),
233  _blue(gray_value),
234  _alpha(0)
235 {
236 }
237 
238 /**
239  *
240  */
241 INLINE PNMImageHeader::PixelSpec::
242 PixelSpec(xelval gray_value, xelval alpha) :
243  _red(gray_value),
244  _green(gray_value),
245  _blue(gray_value),
246  _alpha(alpha)
247 {
248 }
249 
250 /**
251  *
252  */
253 INLINE PNMImageHeader::PixelSpec::
254 PixelSpec(xelval red, xelval green, xelval blue) :
255  _red(red),
256  _green(green),
257  _blue(blue),
258  _alpha(0)
259 {
260 }
261 
262 /**
263  *
264  */
265 INLINE PNMImageHeader::PixelSpec::
266 PixelSpec(xelval red, xelval green, xelval blue, xelval alpha) :
267  _red(red),
268  _green(green),
269  _blue(blue),
270  _alpha(alpha)
271 {
272 }
273 
274 /**
275  *
276  */
277 INLINE PNMImageHeader::PixelSpec::
278 PixelSpec(const xel &rgb) :
279  _red(PPM_GETR(rgb)),
280  _green(PPM_GETG(rgb)),
281  _blue(PPM_GETB(rgb)),
282  _alpha(0)
283 {
284 }
285 
286 /**
287  *
288  */
289 INLINE PNMImageHeader::PixelSpec::
290 PixelSpec(const xel &rgb, xelval alpha) :
291  _red(PPM_GETR(rgb)),
292  _green(PPM_GETG(rgb)),
293  _blue(PPM_GETB(rgb)),
294  _alpha(alpha)
295 {
296 }
297 
298 /**
299  *
300  */
301 INLINE bool PNMImageHeader::PixelSpec::
302 operator < (const PixelSpec &other) const {
303  return compare_to(other) < 0;
304 }
305 
306 /**
307  *
308  */
309 INLINE bool PNMImageHeader::PixelSpec::
310 operator == (const PixelSpec &other) const {
311  return compare_to(other) == 0;
312 }
313 
314 /**
315  *
316  */
317 INLINE bool PNMImageHeader::PixelSpec::
318 operator != (const PixelSpec &other) const {
319  return compare_to(other) != 0;
320 }
321 
322 /**
323  *
324  */
325 INLINE int PNMImageHeader::PixelSpec::
326 compare_to(const PixelSpec &other) const {
327  if (_red != other._red) {
328  return _red < other._red ? -1 : 1;
329  }
330  if (_green != other._green) {
331  return _green < other._green ? -1 : 1;
332  }
333  if (_blue != other._blue) {
334  return _blue < other._blue ? -1 : 1;
335  }
336  if (_alpha != other._alpha) {
337  return _alpha < other._alpha ? -1 : 1;
338  }
339  return 0;
340 }
341 
342 /**
343  *
344  */
345 INLINE xelval PNMImageHeader::PixelSpec::
346 get_red() const {
347  return _red;
348 }
349 
350 /**
351  *
352  */
353 INLINE xelval PNMImageHeader::PixelSpec::
354 get_green() const {
355  return _green;
356 }
357 
358 /**
359  *
360  */
361 INLINE xelval PNMImageHeader::PixelSpec::
362 get_blue() const {
363  return _blue;
364 }
365 
366 /**
367  *
368  */
369 INLINE xelval PNMImageHeader::PixelSpec::
370 get_alpha() const {
371  return _alpha;
372 }
373 
374 /**
375  *
376  */
377 INLINE void PNMImageHeader::PixelSpec::
378 set_red(xelval red) {
379  _red = red;
380 }
381 
382 /**
383  *
384  */
385 INLINE void PNMImageHeader::PixelSpec::
386 set_green(xelval green) {
387  _green = green;
388 }
389 
390 /**
391  *
392  */
393 INLINE void PNMImageHeader::PixelSpec::
394 set_blue(xelval blue) {
395  _blue = blue;
396 }
397 
398 /**
399  *
400  */
401 INLINE void PNMImageHeader::PixelSpec::
402 set_alpha(xelval alpha) {
403  _alpha = alpha;
404 }
405 
406 /**
407  * Indexes numerically into the components, in the order R, G, B, A. This
408  * also makes the PixelSpec work like a tuple in Python.
409  */
411 operator [](int n) const {
412  nassertr(n >= 0 && n < size(), 0);
413  return (&_red)[n];
414 }
415 
416 /**
417  * Specifies the number of components in the PixelSpec; this is always 4,
418  * regardless of the type of image it was taken from.
419  */
421 size() {
422  return 4;
423 }
424 
425 // Interrogate seems to have some problem with the syntax of this method.
426 // Whatever, we don't need it.
427 #ifndef CPPPARSER
428 /**
429  *
430  */
431 INLINE PNMImageHeader::PixelSpecCount::
432 PixelSpecCount(const PNMImageHeader::PixelSpec &pixel, int count) :
433  _pixel(pixel),
434  _count(count)
435 {
436 }
437 #endif // CPPPARSER
438 
439 /**
440  * Used to sort the pixels in order from most common to least common.
441  */
443 operator < (const PNMImageHeader::PixelSpecCount &other) const {
444  return _count > other._count;
445 }
446 
447 /**
448  *
449  */
450 INLINE PNMImageHeader::Histogram::
451 Histogram() {
452 }
453 
454 /**
455  * Returns the number of unique pixel colors in the histogram.
456  */
458 get_num_pixels() const {
459  return _pixels.size();
460 }
461 
462 /**
463  * Returns the nth unique pixel color in the histogram. These are ordered by
464  * default from most common to least common.
465  */
467 get_pixel(int n) const {
468  nassertr(n >= 0 && n < (int)_pixels.size(), _pixels[0]._pixel);
469  return _pixels[n]._pixel;
470 }
471 
472 /**
473  * Returns the number of occurrences in the image of the nth unique pixel
474  * color in the histogram.
475  */
477 get_count(int n) const {
478  nassertr(n >= 0 && n < (int)_pixels.size(), 0);
479  return _pixels[n]._count;
480 }
481 
482 /**
483  * Returns the number of occurrences in the image of the indicated pixel
484  * color.
485  */
488  HistMap::const_iterator hi;
489  hi = _hist_map.find(pixel);
490  if (hi == _hist_map.end()) {
491  return 0;
492  }
493  return (*hi).second;
494 }
495 
496 /**
497  * Swaps the data in the Histogram with the indicated data. This is normally
498  * used to load the Histogram data initially in PNMImage::make_histogram().
499  */
501 swap(PixelCount &pixels, HistMap &hist_map) {
502  _pixels.swap(pixels);
503  _hist_map.swap(hist_map);
504 }
This is the base class of a family of classes that represent particular image file types that PNMImag...
Definition: pnmFileType.h:32
int get_count(int n) const
Returns the number of occurrences in the image of the nth unique pixel color in the histogram.
get_pixel
Returns the nth unique pixel color in the histogram.
void swap(PixelCount &pixels, HistMap &hist_map)
Swaps the data in the Histogram with the indicated data.
get_num_pixels
Returns the number of unique pixel colors in the histogram.
bool operator<(const PixelSpecCount &other) const
Used to sort the pixels in order from most common to least common.
static int size()
Specifies the number of components in the PixelSpec; this is always 4, regardless of the type of imag...
xelval operator[](int n) const
Indexes numerically into the components, in the order R, G, B, A.
This is the base class of PNMImage, PNMReader, and PNMWriter.
set_comment
Writes a user comment string to the image (header).
get_size
Returns the number of pixels in each direction.
has_type
Returns true if the PNMImageHeader knows what type it is, false otherwise.
get_maxval
Returns the maximum channel value allowable for any pixel in this image; for instance,...
int get_x_size() const
Returns the number of pixels in the X direction.
get_num_channels
Returns the number of channels in the image.
get_color_space
Returns the color space that the image is encoded in, or CS_unspecified if unknown.
int get_y_size() const
Returns the number of pixels in the Y direction.
void set_type(PNMFileType *type)
Sets the file type of this PNMImage.
bool has_alpha() const
Returns true if the image includes an alpha channel, false otherwise.
get_type
If the file type is known (e.g.
bool is_grayscale() const
Returns false if the image is a full-color image, and has red, green, and blue components; true if it...
ColorType get_color_type() const
Returns the image type of the image, as an enumerated value.
get_comment
Gets the user comment from the file.
An STL function object class, this is intended to be used on any ordered collection of class objects ...
Definition: stl_compares.h:73