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  */
143 INLINE int PNMImageHeader::
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  */
152 INLINE int PNMImageHeader::
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  */
194 INLINE PNMFileType *PNMImageHeader::
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::
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  */
410 INLINE xelval PNMImageHeader::PixelSpec::
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  */
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  */
457 INLINE int PNMImageHeader::Histogram::
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  */
500 INLINE void PNMImageHeader::Histogram::
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.
xelval operator [](int n) const
Indexes numerically into the components, in the order R, G, B, A.
void set_type(PNMFileType *type)
Sets the file type of this PNMImage.
int get_y_size() const
Returns the number of pixels in the Y direction.
int get_x_size() const
Returns the number of pixels in the X direction.
void swap(PixelCount &pixels, HistMap &hist_map)
Swaps the data in the Histogram with the indicated data.
get_pixel
Returns the nth unique pixel color in the histogram.
bool operator<(const PixelSpecCount &other) const
Used to sort the pixels in order from most common to least common.
An STL function object class, this is intended to be used on any ordered collection of class objects ...
Definition: stl_compares.h:73
bool has_alpha() const
Returns true if the image includes an alpha channel, false otherwise.
ColorType get_color_type() const
Returns the image type of the image, as an enumerated value.
This is the base class of PNMImage, PNMReader, and PNMWriter.
set_comment
Writes a user comment string to the image (header).
bool is_grayscale() const
Returns false if the image is a full-color image, and has red, green, and blue components; true if it...
static int size()
Specifies the number of components in the PixelSpec; this is always 4, regardless of the type of imag...