Panda3D
pnmImage.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 pnmImage.I
10  * @author drose
11  * @date 2000-06-15
12  */
13 
14 /**
15  *
16  */
17 INLINE PNMImage::
18 PNMImage() {
19  _array = nullptr;
20  _alpha = nullptr;
21 
22  clear();
23 }
24 
25 /**
26  *
27  */
28 INLINE PNMImage::
29 PNMImage(int x_size, int y_size, int num_channels, xelval maxval,
30  PNMFileType *type, ColorSpace color_space) {
31  _array = nullptr;
32  _alpha = nullptr;
33 
34  clear(x_size, y_size, num_channels, maxval, type, color_space);
35 }
36 
37 /**
38  *
39  */
40 INLINE PNMImage::
41 PNMImage(const PNMImage &copy) {
42  // We don't need to invoke PNMImageHeader's copy constructor, because we'll
43  // just call copy_from().
44  _array = nullptr;
45  _alpha = nullptr;
46 
47  copy_from(copy);
48 }
49 
50 /**
51  *
52  */
53 INLINE void PNMImage::
54 operator = (const PNMImage &copy) {
55  copy_from(copy);
56 }
57 
58 /**
59  *
60  */
61 INLINE PNMImage::
62 ~PNMImage() {
63  clear();
64 }
65 
66 /**
67  * A handy function to clamp values to [0..get_maxval()].
68  */
69 INLINE xelval PNMImage::
70 clamp_val(int input_value) const {
71  return (xelval)std::min(std::max(0, input_value), (int)get_maxval());
72 }
73 
74 /**
75  * A handy function to scale non-alpha values from [0..1] to
76  * [0..get_maxval()]. Do not use this for alpha values, see to_alpha_val.
77  */
79 to_val(const LRGBColorf &value) const {
80  xel col;
81  switch (_xel_encoding) {
82  case XE_generic:
83  case XE_generic_alpha:
84  {
85  LRGBColorf scaled = value * get_maxval() + 0.5f;
86  col.r = clamp_val((int)scaled[0]);
87  col.g = clamp_val((int)scaled[1]);
88  col.b = clamp_val((int)scaled[2]);
89  }
90  break;
91 
92  case XE_generic_sRGB:
93  case XE_generic_sRGB_alpha:
94  col.r = clamp_val((int)
95  (encode_sRGB_float(value[0]) * get_maxval() + 0.5f));
96  col.g = clamp_val((int)
97  (encode_sRGB_float(value[1]) * get_maxval() + 0.5f));
98  col.b = clamp_val((int)
99  (encode_sRGB_float(value[2]) * get_maxval() + 0.5f));
100  break;
101 
102  case XE_uchar_sRGB:
103  case XE_uchar_sRGB_alpha:
104  encode_sRGB_uchar(LColorf(value, 0.0f), col);
105  break;
106 
107  case XE_uchar_sRGB_sse2:
108  case XE_uchar_sRGB_alpha_sse2:
109  encode_sRGB_uchar_sse2(LColorf(value, 0.0f), col);
110  break;
111 
112  case XE_scRGB:
113  case XE_scRGB_alpha:
114  {
115  LRGBColorf scaled = value * 8192.f + 4096.5f;
116  col.r = std::min(std::max(0, (int)scaled[0]), 65535);
117  col.g = std::min(std::max(0, (int)scaled[1]), 65535);
118  col.b = std::min(std::max(0, (int)scaled[2]), 65535);
119  }
120  break;
121  }
122  return col;
123 }
124 
125 /**
126  * A handy function to scale non-alpha values from [0..1] to
127  * [0..get_maxval()]. Do not use this for alpha values, see to_alpha_val.
128  */
129 INLINE xelval PNMImage::
130 to_val(float input_value) const {
131  switch (_xel_encoding) {
132  case XE_generic:
133  case XE_generic_alpha:
134  return (int)(std::min(1.0f, std::max(0.0f, input_value)) * get_maxval() + 0.5f);
135 
136  case XE_generic_sRGB:
137  case XE_generic_sRGB_alpha:
138  return clamp_val((int)
139  (encode_sRGB_float(input_value) * get_maxval() + 0.5f));
140 
141  case XE_uchar_sRGB:
142  case XE_uchar_sRGB_alpha:
143  return encode_sRGB_uchar(input_value);
144 
145  case XE_uchar_sRGB_sse2:
146  case XE_uchar_sRGB_alpha_sse2:
147  return encode_sRGB_uchar_sse2(input_value);
148 
149  case XE_scRGB:
150  case XE_scRGB_alpha:
151  return std::min(std::max(0, (int)((8192 * input_value) + 4096.5f)), 65535);
152 
153  default:
154  return 0;
155  }
156 }
157 
158 /**
159  * A handy function to scale alpha values from [0..1] to [0..get_maxval()].
160  */
161 INLINE xelval PNMImage::
162 to_alpha_val(float input_value) const {
163  return clamp_val((int)(input_value * get_maxval() + 0.5));
164 }
165 
166 /**
167  * A handy function to scale non-alpha values from [0..get_maxval()] to
168  * [0..1]. Do not use this for alpha values, see from_alpha_val.
169  */
170 INLINE LRGBColorf PNMImage::
171 from_val(const xel &col) const {
172  switch (_xel_encoding) {
173  case XE_generic:
174  case XE_generic_alpha:
175  return LRGBColorf(col.r, col.g, col.b) * _inv_maxval;
176 
177  case XE_generic_sRGB:
178  case XE_generic_sRGB_alpha:
179  return LRGBColorf(
180  decode_sRGB_float(col.r * _inv_maxval),
181  decode_sRGB_float(col.g * _inv_maxval),
182  decode_sRGB_float(col.b * _inv_maxval));
183 
184  case XE_uchar_sRGB:
185  case XE_uchar_sRGB_alpha:
186  case XE_uchar_sRGB_sse2:
187  case XE_uchar_sRGB_alpha_sse2:
188  return LRGBColorf(
189  decode_sRGB_float((unsigned char)col.r),
190  decode_sRGB_float((unsigned char)col.g),
191  decode_sRGB_float((unsigned char)col.b));
192 
193  case XE_scRGB:
194  case XE_scRGB_alpha:
195  return LRGBColorf((int)col.r - 4096,
196  (int)col.g - 4096,
197  (int)col.b - 4096) * (1.f / 8192.f);
198 
199  default:
200  return LRGBColorf(0);
201  }
202 }
203 
204 /**
205  * A handy function to scale non-alpha values from [0..get_maxval()] to
206  * [0..1]. Do not use this for alpha values, see from_alpha_val.
207  */
208 INLINE float PNMImage::
209 from_val(xelval input_value) const {
210  switch (_xel_encoding) {
211  case XE_generic:
212  case XE_generic_alpha:
213  return std::min((float)input_value * _inv_maxval, 1.0f);
214 
215  case XE_generic_sRGB:
216  case XE_generic_sRGB_alpha:
217  return decode_sRGB_float((float)input_value * _inv_maxval);
218 
219  case XE_uchar_sRGB:
220  case XE_uchar_sRGB_alpha:
221  case XE_uchar_sRGB_sse2:
222  case XE_uchar_sRGB_alpha_sse2:
223  return decode_sRGB_float((unsigned char)input_value);
224 
225  case XE_scRGB:
226  case XE_scRGB_alpha:
227  return (input_value - 4096) * (1.f / 8192.f);
228 
229  default:
230  return 0.0f;
231  }
232 }
233 
234 /**
235  * A handy function to scale alpha values from [0..get_maxval()] to [0..1].
236  */
237 INLINE float PNMImage::
238 from_alpha_val(xelval input_value) const {
239  return (float)input_value * _inv_maxval;
240 }
241 
242 /**
243  * Sets the entire image (except the alpha channel) to the given color.
244  */
245 INLINE void PNMImage::
246 fill(float red, float green, float blue) {
247  fill_val(to_val(red), to_val(green), to_val(blue));
248 }
249 
250 /**
251  * Sets the entire image (except the alpha channel) to the given grayscale
252  * level.
253  */
254 INLINE void PNMImage::
255 fill(float gray) {
256  fill(gray, gray, gray);
257 }
258 
259 /**
260  * Sets the entire image (except the alpha channel) to the given grayscale
261  * level.
262  */
263 INLINE void PNMImage::
264 fill_val(xelval gray) {
265  fill_val(gray, gray, gray);
266 }
267 
268 /**
269  * Sets the entire alpha channel to the given level.
270  */
271 INLINE void PNMImage::
272 alpha_fill(float alpha) {
274 }
275 
276 /**
277  * Specifies the size to we'd like to scale the image upon reading it. This
278  * will affect the next call to read(). This is usually used to reduce the
279  * image size, e.g. for a thumbnail.
280  *
281  * If the file type reader supports it (e.g. JPEG), then this will scale the
282  * image during the read operation, consequently reducing memory and CPU
283  * utilization. If the file type reader does not support it, this will load
284  * the image normally, and them perform a linear scale after it has been
285  * loaded.
286  */
287 INLINE void PNMImage::
288 set_read_size(int x_size, int y_size) {
289  _read_x_size = x_size;
290  _read_y_size = y_size;
291  _has_read_size = true;
292 }
293 
294 /**
295  * Undoes the effect of a previous call to set_read_size().
296  */
297 INLINE void PNMImage::
298 clear_read_size() {
299  _has_read_size = false;
300 }
301 
302 /**
303  * Returns true if set_read_size() has been called.
304  */
305 INLINE bool PNMImage::
306 has_read_size() const {
307  return _has_read_size;
308 }
309 
310 /**
311  * Returns the requested x_size of the image if set_read_size() has been
312  * called, or the image x_size otherwise (if it is known).
313  */
314 INLINE int PNMImage::
315 get_read_x_size() const {
316  return _has_read_size ? _read_x_size : get_x_size();
317 }
318 
319 /**
320  * Returns the requested y_size of the image if set_read_size() has been
321  * called, or the image y_size otherwise (if it is known).
322  */
323 INLINE int PNMImage::
324 get_read_y_size() const {
325  return _has_read_size ? _read_y_size : get_y_size();
326 }
327 
328 /**
329  * Returns the color space in which the image is encoded.
330  */
331 INLINE ColorSpace PNMImage::
332 get_color_space() const {
333  return _color_space;
334 }
335 
336 /**
337  * Returns true if the image has been read in or correctly initialized with a
338  * height and width. If this returns false, virtually all member functions
339  * except clear() and read() are invalid function calls.
340  */
341 INLINE bool PNMImage::
342 is_valid() const {
343  return (_array != nullptr);
344 }
345 
346 /**
347  * Changes the number of channels associated with the image. The new number
348  * of channels must be an integer in the range 1 through 4, inclusive. This
349  * will allocate and/or deallocate memory as necessary to accommodate; see
350  * set_color_type().
351  */
352 INLINE void PNMImage::
353 set_num_channels(int num_channels) {
354  nassertv(num_channels >= 1 && num_channels <= 4);
355  set_color_type((ColorType)num_channels);
356 }
357 
358 /**
359  * Adds an alpha channel to the image, if it does not already have one. The
360  * alpha channel is initialized to zeros.
361  */
362 INLINE void PNMImage::
363 add_alpha() {
364  set_color_type(is_grayscale() ? CT_two_channel : CT_four_channel);
365 }
366 
367 /**
368  * Removes the image's alpha channel, if it exists.
369  */
370 INLINE void PNMImage::
371 remove_alpha() {
372  set_color_type(is_grayscale() ? CT_grayscale : CT_color);
373 }
374 
375 /**
376  * Converts the image from RGB to grayscale. Any alpha channel, if present,
377  * is left undisturbed.
378  */
379 INLINE void PNMImage::
380 make_grayscale() {
381  make_grayscale(_default_rc, _default_gc, _default_bc);
382 }
383 
384 /**
385  * Converts the image from grayscale to RGB. Any alpha channel, if present,
386  * is left undisturbed.
387  */
388 INLINE void PNMImage::
389 make_rgb() {
390  set_color_type(has_alpha() ? CT_four_channel : CT_color);
391 }
392 
393 /**
394  * Returns the RGB color at the indicated pixel. Each component is in the
395  * range 0..maxval.
396  */
398 get_xel_val(int x, int y) {
399  nassertr(x >= 0 && x < _x_size && y >= 0 && y < _y_size, _array[0]);
400  return row(y)[x];
401 }
402 
403 /**
404  * Returns the RGB color at the indicated pixel. Each component is in the
405  * range 0..maxval.
406  */
408 get_xel_val(int x, int y) const {
409  nassertr(x >= 0 && x < _x_size && y >= 0 && y < _y_size, _array[0]);
410  return row(y)[x];
411 }
412 
413 /**
414  * Changes the RGB color at the indicated pixel. Each component is in the
415  * range 0..maxval, encoded in the configured color space. See set_xel if you
416  * instead have a linearized and normalized floating-point value.
417  */
418 INLINE void PNMImage::
419 set_xel_val(int x, int y, const xel &value) {
420  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
421  row(y)[x] = value;
422 }
423 
424 /**
425  * Changes the RGB color at the indicated pixel. Each component is in the
426  * range 0..maxval, encoded in the configured color space. See set_xel if you
427  * instead have a linearized and normalized floating-point value.
428  */
429 INLINE void PNMImage::
430 set_xel_val(int x, int y, xelval r, xelval g, xelval b) {
431  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
432  PPM_ASSIGN(row(y)[x], r, g, b);
433 }
434 
435 /**
436  * Changes all three color components at the indicated pixel to the same
437  * value. The value is in the range component is in the range 0..maxval,
438  * encoded in the configured color space. See set_xel if you instead have a
439  * linearized and normalized floating-point value.
440  */
441 INLINE void PNMImage::
442 set_xel_val(int x, int y, xelval gray) {
443  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
444  PPM_ASSIGN(row(y)[x], gray, gray, gray);
445 }
446 
447 /**
448  * Returns the red component color at the indicated pixel. The value returned
449  * is in the range 0..maxval and encoded in the configured color space.
450  */
451 INLINE xelval PNMImage::
452 get_red_val(int x, int y) const {
453  return PPM_GETR(get_xel_val(x, y));
454 }
455 
456 /**
457  * Returns the green component color at the indicated pixel. The value
458  * returned is in the range 0..maxval and encoded in the configured color
459  * space.
460  */
461 INLINE xelval PNMImage::
462 get_green_val(int x, int y) const {
463  return PPM_GETG(get_xel_val(x, y));
464 }
465 
466 /**
467  * Returns the blue component color at the indicated pixel. The value
468  * returned is in the range 0..maxval and encoded in the configured color
469  * space.
470  */
471 INLINE xelval PNMImage::
472 get_blue_val(int x, int y) const {
473  return PPM_GETB(get_xel_val(x, y));
474 }
475 
476 /**
477  * Returns the gray component color at the indicated pixel. This only has a
478  * meaningful value for grayscale images; for other image types, this returns
479  * the value of the blue channel only. However, also see the get_bright()
480  * function. The value returned is in the range 0..maxval and encoded in the
481  * configured color space.
482  */
483 INLINE xelval PNMImage::
484 get_gray_val(int x, int y) const {
485  return PPM_GETB(get_xel_val(x, y));
486 }
487 
488 /**
489  * Returns the alpha component color at the indicated pixel. It is an error
490  * to call this unless has_alpha() is true. The value returned is in the
491  * range 0..maxval and always linear.
492  */
493 INLINE xelval PNMImage::
494 get_alpha_val(int x, int y) const {
495  nassertr(_alpha != nullptr && x >= 0 && x < _x_size && y >= 0 && y < _y_size, 0);
496  return alpha_row(y)[x];
497 }
498 
499 /**
500  * Sets the red component color only at the indicated pixel. The value given
501  * should be in the range 0..maxval, encoded in the configured color space.
502  * See set_red if you instead have a linearized and normalized floating-point
503  * value.
504  */
505 INLINE void PNMImage::
506 set_red_val(int x, int y, xelval r) {
507  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
508  PPM_PUTR(row(y)[x], r);
509 }
510 
511 /**
512  * Sets the green component color only at the indicated pixel. The value
513  * given should be in the range 0..maxval, encoded in the configured color
514  * space. See set_green if you instead have a linearized and normalized
515  * floating-point value.
516  */
517 INLINE void PNMImage::
518 set_green_val(int x, int y, xelval g) {
519  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
520  PPM_PUTG(row(y)[x], g);
521 }
522 
523 /**
524  * Sets the blue component color only at the indicated pixel. The value given
525  * should be in the range 0..maxval, encoded in the configured color space.
526  * See set_blue if you instead have a linearized and normalized floating-point
527  * value.
528  */
529 INLINE void PNMImage::
530 set_blue_val(int x, int y, xelval b) {
531  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
532  PPM_PUTB(row(y)[x], b);
533 }
534 
535 /**
536  * Sets the gray component color at the indicated pixel. This is only
537  * meaningful for grayscale images; for other image types, this simply sets
538  * the blue component color. However, also see set_xel_val(), which can set
539  * all the component colors to the same grayscale level, and hence works
540  * correctly both for grayscale and color images. The value given should be
541  * in the range 0..maxval, encoded in the configured color space. See
542  * set_gray if you instead have a linearized normalized floating-point value.
543  */
544 INLINE void PNMImage::
545 set_gray_val(int x, int y, xelval gray) {
546  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
547  PPM_PUTB(row(y)[x], gray);
548 }
549 
550 /**
551  * Sets the alpha component color only at the indicated pixel. It is an error
552  * to call this unless has_alpha() is true. The value given should be in the
553  * range 0..maxval.
554  *
555  * This value is always linearly encoded, even if the image is set to the sRGB
556  * color space.
557  */
558 INLINE void PNMImage::
559 set_alpha_val(int x, int y, xelval a) {
560  nassertv(_alpha != nullptr && x >= 0 && x < _x_size && y >= 0 && y < _y_size);
561  alpha_row(y)[x] = a;
562 }
563 
564 /**
565  * Returns the RGB color at the indicated pixel. Each component is a
566  * linearized float in the range 0..1.
567  */
568 INLINE LRGBColorf PNMImage::
569 get_xel(int x, int y) const {
570  nassertr(x >= 0 && x < _x_size && y >= 0 && y < _y_size, LRGBColorf::zero());
571  return from_val(row(y)[x]);
572 }
573 
574 /**
575  * Changes the RGB color at the indicated pixel. Each component is a
576  * linearized float in the range 0..1.
577  */
578 INLINE void PNMImage::
579 set_xel(int x, int y, const LRGBColorf &value) {
580  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
581  row(y)[x] = to_val(value);
582 }
583 
584 /**
585  * Changes the RGB color at the indicated pixel. Each component is a
586  * linearized float in the range 0..1.
587  */
588 INLINE void PNMImage::
589 set_xel(int x, int y, float r, float g, float b) {
590  set_xel(x, y, LRGBColorf(r, g, b));
591 }
592 
593 /**
594  * Changes all three color components at the indicated pixel to the same
595  * value. The value is a linearized float in the range 0..1.
596  */
597 INLINE void PNMImage::
598 set_xel(int x, int y, float gray) {
599  xelval val = to_val(gray);
600  set_xel_val(x, y, val);
601 }
602 
603 /**
604  * Returns the RGBA color at the indicated pixel. Each component is a
605  * linearized float in the range 0..1.
606  */
607 INLINE LColorf PNMImage::
608 get_xel_a(int x, int y) const {
609  const xel &col = row(y)[x];
610 
611  switch (_xel_encoding) {
612  case XE_generic:
613  return LColorf(col.r, col.g, col.b, 0.0f) * _inv_maxval;
614 
615  case XE_generic_alpha:
616  return LColorf(col.r, col.g, col.b, alpha_row(y)[x]) * _inv_maxval;
617 
618  case XE_generic_sRGB:
619  return LColorf(
620  decode_sRGB_float(col.r * _inv_maxval),
621  decode_sRGB_float(col.g * _inv_maxval),
622  decode_sRGB_float(col.b * _inv_maxval),
623  0.0f);
624 
625  case XE_generic_sRGB_alpha:
626  return LColorf(
627  decode_sRGB_float(col.r * _inv_maxval),
628  decode_sRGB_float(col.g * _inv_maxval),
629  decode_sRGB_float(col.b * _inv_maxval),
630  alpha_row(y)[x] * _inv_maxval);
631 
632  case XE_uchar_sRGB:
633  case XE_uchar_sRGB_sse2:
634  return LColorf(
635  decode_sRGB_float((unsigned char)col.r),
636  decode_sRGB_float((unsigned char)col.g),
637  decode_sRGB_float((unsigned char)col.b),
638  0.0f);
639 
640  case XE_uchar_sRGB_alpha:
641  case XE_uchar_sRGB_alpha_sse2:
642  return LColorf(
643  decode_sRGB_float((unsigned char)col.r),
644  decode_sRGB_float((unsigned char)col.g),
645  decode_sRGB_float((unsigned char)col.b),
646  alpha_row(y)[x] * (1.f / 255.f));
647 
648  case XE_scRGB:
649  return LColorf((int)col.r - 4096,
650  (int)col.g - 4096,
651  (int)col.b - 4096,
652  0) * (1.f / 8192.f);
653 
654  case XE_scRGB_alpha:
655  {
656  static const LColorf scale(1.f / 8192.f, 1.f / 8192.f, 1.f / 8192.f, 1.f / 65535.f);
657  LColorf color((int)col.r - 4096,
658  (int)col.g - 4096,
659  (int)col.b - 4096,
660  alpha_row(y)[x]);
661  color.componentwise_mult(scale);
662  return color;
663  }
664 
665  default:
666  return LColorf(0);
667  }
668 }
669 
670 /**
671  * Changes the RGBA color at the indicated pixel. Each component is a
672  * linearized float in the range 0..1.
673  */
674 INLINE void PNMImage::
675 set_xel_a(int x, int y, const LColorf &value) {
676  nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
677 
678  xel &col = row(y)[x];
679 
680  switch (_xel_encoding) {
681  case XE_generic:
682  {
683  LColorf scaled = value * get_maxval() + 0.5f;
684  col.r = clamp_val((int)scaled[0]);
685  col.g = clamp_val((int)scaled[1]);
686  col.b = clamp_val((int)scaled[2]);
687  }
688  break;
689 
690  case XE_generic_alpha:
691  {
692  LColorf scaled = value * get_maxval() + 0.5f;
693  col.r = clamp_val((int)scaled[0]);
694  col.g = clamp_val((int)scaled[1]);
695  col.b = clamp_val((int)scaled[2]);
696  alpha_row(y)[x] = clamp_val((int)scaled[3]);
697  }
698  break;
699 
700  case XE_generic_sRGB:
701  col.r = clamp_val((int)
702  (encode_sRGB_float(value[0]) * get_maxval() + 0.5f));
703  col.g = clamp_val((int)
704  (encode_sRGB_float(value[1]) * get_maxval() + 0.5f));
705  col.b = clamp_val((int)
706  (encode_sRGB_float(value[2]) * get_maxval() + 0.5f));
707  break;
708 
709  case XE_generic_sRGB_alpha:
710  col.r = clamp_val((int)
711  (encode_sRGB_float(value[0]) * get_maxval() + 0.5f));
712  col.g = clamp_val((int)
713  (encode_sRGB_float(value[1]) * get_maxval() + 0.5f));
714  col.b = clamp_val((int)
715  (encode_sRGB_float(value[2]) * get_maxval() + 0.5f));
716  alpha_row(y)[x] = clamp_val((int)(value[3] * get_maxval() + 0.5f));
717  break;
718 
719  case XE_uchar_sRGB:
720  encode_sRGB_uchar(value, col);
721  break;
722 
723  case XE_uchar_sRGB_alpha:
724  encode_sRGB_uchar(value, col, alpha_row(y)[x]);
725  break;
726 
727  case XE_uchar_sRGB_sse2:
728  encode_sRGB_uchar_sse2(value, col);
729  break;
730 
731  case XE_uchar_sRGB_alpha_sse2:
732  encode_sRGB_uchar_sse2(value, col, alpha_row(y)[x]);
733  break;
734 
735  case XE_scRGB:
736  {
737  LColorf scaled = value * 8192.0f + 4096.5f;
738  col.r = std::min(std::max(0, (int)scaled[0]), 65535);
739  col.g = std::min(std::max(0, (int)scaled[1]), 65535);
740  col.b = std::min(std::max(0, (int)scaled[2]), 65535);
741  }
742  break;
743 
744  case XE_scRGB_alpha:
745  {
746  LColorf scaled = value * 8192.0f + 4096.5f;
747  col.r = std::min(std::max(0, (int)scaled[0]), 65535);
748  col.g = std::min(std::max(0, (int)scaled[1]), 65535);
749  col.b = std::min(std::max(0, (int)scaled[2]), 65535);
750  alpha_row(y)[x] = std::min(std::max(0, (int)(value[3] * 65535 + 0.5f)), 65535);
751  }
752  break;
753  }
754 }
755 
756 /**
757  * Changes the RGBA color at the indicated pixel. Each component is a
758  * linearized float in the range 0..1.
759  */
760 INLINE void PNMImage::
761 set_xel_a(int x, int y, float r, float g, float b, float a) {
762  set_xel_a(x, y, LColorf(r, g, b, a));
763 }
764 
765 /**
766  * Returns the red component color at the indicated pixel. The value returned
767  * is a linearized float in the range 0..1.
768  */
769 INLINE float PNMImage::
770 get_red(int x, int y) const {
771  return from_val(get_red_val(x, y));
772 }
773 
774 /**
775  * Returns the green component color at the indicated pixel. The value
776  * returned is a linearized float in the range 0..1.
777  */
778 INLINE float PNMImage::
779 get_green(int x, int y) const {
780  return from_val(get_green_val(x, y));
781 }
782 
783 /**
784  * Returns the blue component color at the indicated pixel. The value
785  * returned is a linearized float in the range 0..1.
786  */
787 INLINE float PNMImage::
788 get_blue(int x, int y) const {
789  return from_val(get_blue_val(x, y));
790 }
791 
792 /**
793  * Returns the gray component color at the indicated pixel. This only has a
794  * meaningful value for grayscale images; for other image types, this returns
795  * the value of the blue channel only. However, also see the get_bright()
796  * function. The value returned is a linearized float in the range 0..1.
797  */
798 INLINE float PNMImage::
799 get_gray(int x, int y) const {
800  return from_val(get_gray_val(x, y));
801 }
802 
803 /**
804  * Returns the alpha component color at the indicated pixel. It is an error
805  * to call this unless has_alpha() is true. The value returned is a float in
806  * the range 0..1.
807  */
808 INLINE float PNMImage::
809 get_alpha(int x, int y) const {
810  return from_alpha_val(get_alpha_val(x, y));
811 }
812 
813 /**
814  * Sets the red component color only at the indicated pixel. The value given
815  * should be a linearized float in the range 0..1.
816  */
817 INLINE void PNMImage::
818 set_red(int x, int y, float r) {
819  set_red_val(x, y, to_val(r));
820 }
821 
822 /**
823  * Sets the green component color only at the indicated pixel. The value
824  * given should be a linearized float in the range 0..1.
825  */
826 INLINE void PNMImage::
827 set_green(int x, int y, float g) {
828  set_green_val(x, y, to_val(g));
829 }
830 
831 /**
832  * Sets the blue component color only at the indicated pixel. The value given
833  * should be a linearized float in the range 0..1.
834  */
835 INLINE void PNMImage::
836 set_blue(int x, int y, float b) {
837  set_blue_val(x, y, to_val(b));
838 }
839 
840 /**
841  * Sets the gray component color at the indicated pixel. This is only
842  * meaningful for grayscale images; for other image types, this simply sets
843  * the blue component color. However, also see set_xel(), which can set all
844  * the component colors to the same grayscale level, and hence works correctly
845  * both for grayscale and color images. The value given should be a
846  * linearized float in the range 0..1.
847  */
848 INLINE void PNMImage::
849 set_gray(int x, int y, float gray) {
850  set_gray_val(x, y, to_val(gray));
851 }
852 
853 /**
854  * Sets the alpha component color only at the indicated pixel. It is an error
855  * to call this unless has_alpha() is true. The value given should be in the
856  * range 0..1.
857  */
858 INLINE void PNMImage::
859 set_alpha(int x, int y, float a) {
860  set_alpha_val(x, y, to_alpha_val(a));
861 }
862 
863 /**
864  * Returns the linear brightness of the given xel, as a linearized float in
865  * the range 0..1. This flavor of get_bright() returns the correct grayscale
866  * brightness level for both full-color and grayscale images.
867  */
868 INLINE float PNMImage::
869 get_bright(int x, int y) const {
870  return get_bright(x, y, _default_rc, _default_gc, _default_bc);
871 }
872 
873 /**
874  * This flavor of get_bright() works correctly only for color images. It
875  * returns a single brightness value for the RGB color at the indicated pixel,
876  * based on the supplied weights for each component.
877  */
878 INLINE float PNMImage::
879 get_bright(int x, int y, float rc, float gc, float bc) const {
880  return get_xel(x, y).dot(LVecBase3f(rc, gc, bc));
881 }
882 
883 /**
884  * This flavor of get_bright() works correctly only for four-channel images.
885  * It returns a single brightness value for the RGBA color at the indicated
886  * pixel, based on the supplied weights for each component.
887  */
888 INLINE float PNMImage::
889 get_bright(int x, int y, float rc, float gc, float bc, float ac) const {
890  return get_xel_a(x, y).dot(LVecBase4f(rc, gc, bc, ac));
891 }
892 
893 /**
894  * Smoothly blends the indicated pixel value in with whatever was already in
895  * the image, based on the given alpha value. An alpha of 1.0 is fully opaque
896  * and completely replaces whatever was there previously; alpha of 0.0 is
897  * fully transparent and does nothing.
898  */
899 INLINE void PNMImage::
900 blend(int x, int y, const LRGBColorf &val, float alpha) {
901  blend(x, y, val[0], val[1], val[2], alpha);
902 }
903 
904 /**
905  * This flavor of box_filter() will apply the filter over the entire image
906  * without resizing or copying; the effect is that of a blur operation.
907  */
908 INLINE void PNMImage::
909 box_filter(float radius) {
910  box_filter_from(radius, *this);
911 }
912 
913 /**
914  * This flavor of gaussian_filter() will apply the filter over the entire
915  * image without resizing or copying; the effect is that of a blur operation.
916  */
917 INLINE void PNMImage::
918 gaussian_filter(float radius) {
919  gaussian_filter_from(radius, *this);
920 }
921 
922 /**
923  * Assuming the image was constructed with a gamma curve of from_gamma in the
924  * RGB channels, converts it to an image with a gamma curve of to_gamma in the
925  * RGB channels. Does not affect the alpha channel.
926  */
927 INLINE void PNMImage::
928 gamma_correct(float from_gamma, float to_gamma) {
929  apply_exponent(from_gamma / to_gamma);
930 }
931 
932 /**
933  * Assuming the image was constructed with a gamma curve of from_gamma in the
934  * alpha channel, converts it to an image with a gamma curve of to_gamma in
935  * the alpha channel. Does not affect the RGB channels.
936  */
937 INLINE void PNMImage::
938 gamma_correct_alpha(float from_gamma, float to_gamma) {
939  apply_exponent(1.0, from_gamma / to_gamma);
940 }
941 
942 /**
943  * Adjusts each channel of the image by raising the corresponding component
944  * value to the indicated exponent, such that L' = L ^ exponent.
945  */
946 INLINE void PNMImage::
947 apply_exponent(float gray_exponent) {
948  apply_exponent(gray_exponent, gray_exponent, gray_exponent, 1.0);
949 }
950 
951 /**
952  * Adjusts each channel of the image by raising the corresponding component
953  * value to the indicated exponent, such that L' = L ^ exponent.
954  */
955 INLINE void PNMImage::
956 apply_exponent(float gray_exponent, float alpha_exponent) {
957  apply_exponent(gray_exponent, gray_exponent, gray_exponent, alpha_exponent);
958 }
959 
960 /**
961  * Adjusts each channel of the image by raising the corresponding component
962  * value to the indicated exponent, such that L' = L ^ exponent. For a
963  * grayscale image, the blue_exponent value is used for the grayscale value,
964  * and red_exponent and green_exponent are unused.
965  */
966 INLINE void PNMImage::
967 apply_exponent(float red_exponent, float green_exponent, float blue_exponent) {
968  apply_exponent(red_exponent, green_exponent, blue_exponent, 1.0);
969 }
970 
971 /**
972 
973  */
974 INLINE PNMImage::Row::
975 Row(PNMImage &image, int y) : _image(image), _y(y) {
976  nassertv(y >= 0 && y < _image._y_size);
977 }
978 
979 /**
980  * Get the number of pixels in the row.
981  */
982 INLINE size_t PNMImage::Row::
983 size() const {
984  return _image.get_x_size();
985 }
986 
987 /**
988  * Fetch the RGB value at the given column in the row.
989  */
990 INLINE LColorf PNMImage::Row::
991 operator[](int x) const {
992  return _image.get_xel_a(x, _y);
993 }
994 
995 #ifdef HAVE_PYTHON
996 /**
997  * Set the pixel at the given column in the row. If the image has no alpha
998  * channel, the alpha component is ignored.
999  */
1000 INLINE void PNMImage::Row::
1001 __setitem__(int x, const LColorf &v) {
1002  _image.set_xel_a(x, _y, v);
1003 }
1004 #endif
1005 
1006 /**
1007  * Fetch the pixel at the given column in the row.
1008  */
1010 get_xel_val(int x) {
1011  return _image.get_xel_val(x, _y);
1012 }
1013 
1014 /**
1015  * Set the pixel at the given column in the row.
1016  */
1017 INLINE void PNMImage::Row::
1018 set_xel_val(int x, const xel &v) {
1019  _image.set_xel_val(x, _y, v);
1020 }
1021 
1022 /**
1023  * Fetch the alpha value at the given column in the row.
1024  */
1025 INLINE xelval PNMImage::Row::
1026 get_alpha_val(int x) const {
1027  return _image.get_alpha_val(x, _y);
1028 }
1029 
1030 /**
1031  * Set the alpha value at the given column in the row.
1032  */
1033 INLINE void PNMImage::Row::
1034 set_alpha_val(int x, xelval v) {
1035  _image.set_alpha_val(x, _y, v);
1036 }
1037 
1038 /**
1039 
1040  */
1041 INLINE PNMImage::CRow::
1042 CRow(const PNMImage &image, int y) : _image(image), _y(y) {
1043  nassertv(y >= 0 && y < _image._y_size);
1044 }
1045 
1046 /**
1047  * Get the number of pixels in the row.
1048  */
1049 INLINE size_t PNMImage::CRow::
1050 size() const {
1051  return _image.get_x_size();
1052 }
1053 
1054 /**
1055  * Fetch the RGB value at the given column in the row.
1056  */
1057 INLINE LColorf PNMImage::CRow::
1058 operator[](int x) const {
1059  return _image.get_xel_a(x, _y);
1060 }
1061 
1062 /**
1063  * Fetch the pixel at the given column in the row.
1064  */
1066 get_xel_val(int x) const {
1067  return _image.get_xel_val(x, _y);
1068 }
1069 
1070 /**
1071  * Fetch the alpha value at the given column in the row.
1072  */
1073 INLINE xelval PNMImage::CRow::
1074 get_alpha_val(int x) const {
1075  return _image.get_alpha_val(x, _y);
1076 }
1077 
1078 /**
1079  * Allows the PNMImage to appear to be a 2-d array of xels.
1080  */
1082 operator [] (int y) {
1083  return Row(*this, y);
1084 }
1085 
1086 /**
1087  * Allows the PNMImage to appear to be a 2-d array of xels.
1088  */
1090 operator [] (int y) const {
1091  return CRow(*this, y);
1092 }
1093 
1094 /**
1095  * Directly access the underlying PNMImage array. Know what you are doing!
1096  */
1098 get_array() {
1099  return _array;
1100 }
1101 
1102 /**
1103  * Directly access the underlying PNMImage array. Know what you are doing!
1104  */
1105 INLINE const xel *PNMImage::
1106 get_array() const {
1107  return _array;
1108 }
1109 
1110 /**
1111  * Directly access the underlying PNMImage array of alpha values. Know what
1112  * you are doing!
1113  */
1114 INLINE xelval *PNMImage::
1115 get_alpha_array() {
1116  return _alpha;
1117 }
1118 
1119 /**
1120  * Directly access the underlying PNMImage array of alpha values. Know what
1121  * you are doing!
1122  */
1123 INLINE const xelval *PNMImage::
1124 get_alpha_array() const {
1125  return _alpha;
1126 }
1127 
1128 /**
1129  * Returns the underlying PNMImage array and removes it from the PNMImage.
1130  * You become the owner of this array and must eventually free it with
1131  * PANDA_FREE_ARRAY() (or pass it to another PNMImage with set_array()). Know
1132  * what you are doing!
1133  */
1135 take_array() {
1136  xel *array = _array;
1137  _array = nullptr;
1138  return array;
1139 }
1140 
1141 /**
1142  * Returns the underlying PNMImage array and removes it from the PNMImage.
1143  * You become the owner of this array and must eventually free it with
1144  * PANDA_FREE_ARRAY() (or pass it to another PNMImage with set_alpha_array()).
1145  * Know what you are doing!
1146  */
1147 INLINE xelval *PNMImage::
1148 take_alpha_array() {
1149  xelval *alpha = _alpha;
1150  _alpha = nullptr;
1151  return alpha;
1152 }
1153 
1154 /**
1155  * Allocates the internal memory for the RGB or grayscale pixels in the image
1156  * (except alpha).
1157  */
1158 INLINE void PNMImage::
1159 allocate_array() {
1160  _array = (xel *)PANDA_MALLOC_ARRAY((size_t)_x_size * (size_t)_y_size * sizeof(xel));
1161 }
1162 
1163 /**
1164  * Allocates the internal memory for the alpha pixels in the image.
1165  */
1166 INLINE void PNMImage::
1167 allocate_alpha() {
1168  _alpha = (xelval *)PANDA_MALLOC_ARRAY((size_t)_x_size * (size_t)_y_size * sizeof(xelval));
1169 }
1170 
1171 /**
1172  * Returns an array of xels corresponding to the nth row of the image.
1173  */
1174 INLINE xel *PNMImage::
1175 row(int y) const {
1176  nassertr(y >= 0 && y < _y_size, nullptr);
1177  return _array + y * _x_size;
1178 }
1179 
1180 /**
1181  * Returns an array of xelvals corresponding to the nth row of the alpha
1182  * channel.
1183  */
1184 INLINE xelval *PNMImage::
1185 alpha_row(int y) const {
1186  nassertr(_alpha != nullptr && y >= 0 && y < _y_size, nullptr);
1187  return _alpha + y * _x_size;
1188 }
1189 
1190 /**
1191  * Computes xmin, ymin, xmax, and ymax, based on the input parameters for
1192  * copy_sub_image() and related methods.
1193  */
1194 INLINE void PNMImage::
1195 setup_sub_image(const PNMImage &copy, int &xto, int &yto,
1196  int &xfrom, int &yfrom, int &x_size, int &y_size,
1197  int &xmin, int &ymin, int &xmax, int &ymax) {
1198  if (x_size < 0) {
1199  x_size = copy.get_x_size() - xfrom;
1200  }
1201  if (y_size < 0) {
1202  y_size = copy.get_y_size() - yfrom;
1203  }
1204 
1205  if (xfrom < 0) {
1206  xto += -xfrom;
1207  x_size -= -xfrom;
1208  xfrom = 0;
1209  }
1210  if (yfrom < 0) {
1211  yto += -yfrom;
1212  y_size -= -yfrom;
1213  yfrom = 0;
1214  }
1215 
1216  if (xto < 0) {
1217  xfrom += -xto;
1218  x_size -= -xto;
1219  xto = 0;
1220  }
1221  if (yto < 0) {
1222  yfrom += -yto;
1223  y_size -= -yto;
1224  yto = 0;
1225  }
1226 
1227  x_size = std::min(x_size, copy.get_x_size() - xfrom);
1228  y_size = std::min(y_size, copy.get_y_size() - yfrom);
1229 
1230  xmin = xto;
1231  ymin = yto;
1232 
1233  xmax = std::min(xmin + x_size, get_x_size());
1234  ymax = std::min(ymin + y_size, get_y_size());
1235 }
1236 
1237 /**
1238  * Called by render_spot to compute the color of a single pixel, based in (the
1239  * square of) its distance from the center.
1240  */
1241 INLINE void PNMImage::
1242 compute_spot_pixel(LColorf &c, float d2,
1243  float min_radius, float max_radius,
1244  const LColorf &fg, const LColorf &bg) {
1245  float d = sqrt(d2);
1246  if (d > max_radius) {
1247  c = bg;
1248  } else if (d > min_radius) {
1249  d = (d - min_radius) / (max_radius - min_radius);
1250  float d2 = d * d;
1251  float t = (3.0f * d2) - (2.0f * d * d2);
1252  c = fg + t * (bg - fg);
1253  } else {
1254  c = fg;
1255  }
1256 }
1257 
1258 /**
1259  * Returns a new PNMImage in which each pixel value is the sum of the
1260  * corresponding pixel values in the two given images. Only valid when both
1261  * images have the same size.
1262  */
1264 operator + (const PNMImage &other) const {
1265  PNMImage target (*this);
1266  target += other;
1267  return target;
1268 }
1269 
1270 /**
1271  * Returns a new PNMImage in which the provided color is added to each pixel
1272  * in the provided image.
1273  */
1275 operator + (const LColorf &other) const {
1276  PNMImage target (*this);
1277  target += other;
1278  return target;
1279 }
1280 
1281 /**
1282  * Returns a new PNMImage in which each pixel value from the right image is
1283  * subtracted from each pixel value from the left image. Only valid when both
1284  * images have the same size.
1285  */
1287 operator - (const PNMImage &other) const {
1288  PNMImage target (*this);
1289  target -= other;
1290  return target;
1291 }
1292 
1293 /**
1294  * Returns a new PNMImage in which the provided color is subtracted from each
1295  * pixel in the provided image.
1296  */
1298 operator - (const LColorf &other) const {
1299  PNMImage target (*this);
1300  target -= other;
1301  return target;
1302 }
1303 
1304 /**
1305  * Returns a new PNMImage in which each pixel value from the left image is
1306  * multiplied by each pixel value from the right image. Note that the
1307  * floating-point values in the 0..1 range are multiplied, not in the
1308  * 0..maxval range. Only valid when both images have the same size.
1309  */
1311 operator * (const PNMImage &other) const {
1312  PNMImage target (*this);
1313  target *= other;
1314  return target;
1315 }
1316 
1317 /**
1318  * Multiplies every pixel value in the image by a constant floating-point
1319  * multiplier value.
1320  */
1322 operator * (float multiplier) const {
1323  PNMImage target (*this);
1324  target *= multiplier;
1325  return target;
1326 }
1327 
1328 /**
1329  * Returns a new PNMImage in which the provided color is multiplied to each
1330  * pixel in the provided image.
1331  */
1333 operator * (const LColorf &other) const {
1334  PNMImage target (*this);
1335  target *= other;
1336  return target;
1337 }
This is the base class of a family of classes that represent particular image file types that PNMImag...
Definition: pnmFileType.h:32
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.
int get_y_size() const
Returns the number of pixels in the Y direction.
bool has_alpha() const
Returns true if the image includes an alpha channel, false otherwise.
bool is_grayscale() const
Returns false if the image is a full-color image, and has red, green, and blue components; true if it...
size_t size() const
Get the number of pixels in the row.
Definition: pnmImage.I:1050
xel get_xel_val(int x) const
Fetch the pixel at the given column in the row.
Definition: pnmImage.I:1066
LColorf operator[](int x) const
Fetch the RGB value at the given column in the row.
Definition: pnmImage.I:1058
xelval get_alpha_val(int x) const
Fetch the alpha value at the given column in the row.
Definition: pnmImage.I:1074
void set_alpha_val(int x, xelval v)
Set the alpha value at the given column in the row.
Definition: pnmImage.I:1034
xel & get_xel_val(int x)
Fetch the pixel at the given column in the row.
Definition: pnmImage.I:1010
size_t size() const
Get the number of pixels in the row.
Definition: pnmImage.I:983
void set_xel_val(int x, const xel &v)
Set the pixel at the given column in the row.
Definition: pnmImage.I:1018
xelval get_alpha_val(int x) const
Fetch the alpha value at the given column in the row.
Definition: pnmImage.I:1026
LColorf operator[](int x) const
Fetch the RGB value at the given column in the row.
Definition: pnmImage.I:991
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
void clear()
Frees all memory allocated for the image, and clears all its parameters (size, color,...
Definition: pnmImage.cxx:48
xel & get_xel_val(int x, int y)
Returns the RGB color at the indicated pixel.
Definition: pnmImage.I:398
void set_xel_val(int x, int y, const xel &value)
Changes the RGB color at the indicated pixel.
Definition: pnmImage.I:419
void set_read_size(int x_size, int y_size)
Specifies the size to we'd like to scale the image upon reading it.
Definition: pnmImage.I:288
void set_blue(int x, int y, float b)
Sets the blue component color only at the indicated pixel.
Definition: pnmImage.I:836
void set_blue_val(int x, int y, xelval b)
Sets the blue component color only at the indicated pixel.
Definition: pnmImage.I:530
void fill_val(xelval red, xelval green, xelval blue)
Sets the entire image (except the alpha channel) to the given color.
Definition: pnmImage.cxx:244
void alpha_fill(float alpha=0.0)
Sets the entire alpha channel to the given level.
Definition: pnmImage.I:272
void gaussian_filter_from(float radius, const PNMImage &copy)
Makes a resized copy of the indicated image into this one using the indicated filter.
void set_alpha_val(int x, int y, xelval a)
Sets the alpha component color only at the indicated pixel.
Definition: pnmImage.I:559
xelval get_green_val(int x, int y) const
Returns the green component color at the indicated pixel.
Definition: pnmImage.I:462
void make_grayscale()
Converts the image from RGB to grayscale.
Definition: pnmImage.I:380
PNMImage operator-(const PNMImage &other) const
Returns a new PNMImage in which each pixel value from the right image is subtracted from each pixel v...
Definition: pnmImage.I:1287
void set_green(int x, int y, float g)
Sets the green component color only at the indicated pixel.
Definition: pnmImage.I:827
xel * take_array()
Returns the underlying PNMImage array and removes it from the PNMImage.
Definition: pnmImage.I:1135
float get_blue(int x, int y) const
Returns the blue component color at the indicated pixel.
Definition: pnmImage.I:788
float get_alpha(int x, int y) const
Returns the alpha component color at the indicated pixel.
Definition: pnmImage.I:809
LRGBColorf get_xel(int x, int y) const
Returns the RGB color at the indicated pixel.
Definition: pnmImage.I:569
void set_xel_a(int x, int y, const LColorf &value)
Changes the RGBA color at the indicated pixel.
Definition: pnmImage.I:675
LRGBColorf from_val(const xel &input_value) const
A handy function to scale non-alpha values from [0..get_maxval()] to [0..1].
Definition: pnmImage.I:171
float get_gray(int x, int y) const
Returns the gray component color at the indicated pixel.
Definition: pnmImage.I:799
void remove_alpha()
Removes the image's alpha channel, if it exists.
Definition: pnmImage.I:371
xelval clamp_val(int input_value) const
A handy function to clamp values to [0..get_maxval()].
Definition: pnmImage.I:70
void fill(float red, float green, float blue)
Sets the entire image (except the alpha channel) to the given color.
Definition: pnmImage.I:246
void blend(int x, int y, const LRGBColorf &val, float alpha)
Smoothly blends the indicated pixel value in with whatever was already in the image,...
Definition: pnmImage.I:900
LColorf get_xel_a(int x, int y) const
Returns the RGBA color at the indicated pixel.
Definition: pnmImage.I:608
void set_num_channels(int num_channels)
Changes the number of channels associated with the image.
Definition: pnmImage.I:353
void make_rgb()
Converts the image from grayscale to RGB.
Definition: pnmImage.I:389
void set_gray(int x, int y, float gray)
Sets the gray component color at the indicated pixel.
Definition: pnmImage.I:849
xelval to_alpha_val(float input_value) const
A handy function to scale alpha values from [0..1] to [0..get_maxval()].
Definition: pnmImage.I:162
void set_color_type(ColorType color_type)
Translates the image to or from grayscale, color, or four-color mode.
Definition: pnmImage.cxx:478
void set_gray_val(int x, int y, xelval gray)
Sets the gray component color at the indicated pixel.
Definition: pnmImage.I:545
xelval get_alpha_val(int x, int y) const
Returns the alpha component color at the indicated pixel.
Definition: pnmImage.I:494
void set_red(int x, int y, float r)
Sets the red component color only at the indicated pixel.
Definition: pnmImage.I:818
void box_filter(float radius=1.0)
This flavor of box_filter() will apply the filter over the entire image without resizing or copying; ...
Definition: pnmImage.I:909
float get_bright(int x, int y) const
Returns the linear brightness of the given xel, as a linearized float in the range 0....
Definition: pnmImage.I:869
PNMImage operator*(const PNMImage &other) const
Returns a new PNMImage in which each pixel value from the left image is multiplied by each pixel valu...
Definition: pnmImage.I:1311
bool has_read_size() const
Returns true if set_read_size() has been called.
Definition: pnmImage.I:306
void set_green_val(int x, int y, xelval g)
Sets the green component color only at the indicated pixel.
Definition: pnmImage.I:518
bool is_valid() const
Returns true if the image has been read in or correctly initialized with a height and width.
Definition: pnmImage.I:342
void copy_from(const PNMImage &copy)
Makes this image become a copy of the other image.
Definition: pnmImage.cxx:105
float from_alpha_val(xelval input_value) const
A handy function to scale alpha values from [0..get_maxval()] to [0..1].
Definition: pnmImage.I:238
xelval get_blue_val(int x, int y) const
Returns the blue component color at the indicated pixel.
Definition: pnmImage.I:472
float get_green(int x, int y) const
Returns the green component color at the indicated pixel.
Definition: pnmImage.I:779
void gaussian_filter(float radius=1.0)
This flavor of gaussian_filter() will apply the filter over the entire image without resizing or copy...
Definition: pnmImage.I:918
xel * get_array()
Directly access the underlying PNMImage array.
Definition: pnmImage.I:1098
xelval get_red_val(int x, int y) const
Returns the red component color at the indicated pixel.
Definition: pnmImage.I:452
void set_xel(int x, int y, const LRGBColorf &value)
Changes the RGB color at the indicated pixel.
Definition: pnmImage.I:579
void set_red_val(int x, int y, xelval r)
Sets the red component color only at the indicated pixel.
Definition: pnmImage.I:506
int get_read_y_size() const
Returns the requested y_size of the image if set_read_size() has been called, or the image y_size oth...
Definition: pnmImage.I:324
void box_filter_from(float radius, const PNMImage &copy)
Makes a resized copy of the indicated image into this one using the indicated filter.
void gamma_correct(float from_gamma, float to_gamma)
Assuming the image was constructed with a gamma curve of from_gamma in the RGB channels,...
Definition: pnmImage.I:928
xelval * take_alpha_array()
Returns the underlying PNMImage array and removes it from the PNMImage.
Definition: pnmImage.I:1148
xel to_val(const LRGBColorf &input_value) const
A handy function to scale non-alpha values from [0..1] to [0..get_maxval()].
Definition: pnmImage.I:79
void gamma_correct_alpha(float from_gamma, float to_gamma)
Assuming the image was constructed with a gamma curve of from_gamma in the alpha channel,...
Definition: pnmImage.I:938
xelval get_gray_val(int x, int y) const
Returns the gray component color at the indicated pixel.
Definition: pnmImage.I:484
void set_alpha(int x, int y, float a)
Sets the alpha component color only at the indicated pixel.
Definition: pnmImage.I:859
ColorSpace get_color_space() const
Returns the color space in which the image is encoded.
Definition: pnmImage.I:332
void apply_exponent(float gray_exponent)
Adjusts each channel of the image by raising the corresponding component value to the indicated expon...
Definition: pnmImage.I:947
void clear_read_size()
Undoes the effect of a previous call to set_read_size().
Definition: pnmImage.I:298
void add_alpha()
Adds an alpha channel to the image, if it does not already have one.
Definition: pnmImage.I:363
xelval * get_alpha_array()
Directly access the underlying PNMImage array of alpha values.
Definition: pnmImage.I:1115
void alpha_fill_val(xelval alpha=0)
Sets the entire alpha channel to the given level.
Definition: pnmImage.cxx:258
Row operator[](int y)
Allows the PNMImage to appear to be a 2-d array of xels.
Definition: pnmImage.I:1082
PNMImage operator+(const PNMImage &other) const
Returns a new PNMImage in which each pixel value is the sum of the corresponding pixel values in the ...
Definition: pnmImage.I:1264
int get_read_x_size() const
Returns the requested x_size of the image if set_read_size() has been called, or the image x_size oth...
Definition: pnmImage.I:315
float get_red(int x, int y) const
Returns the red component color at the indicated pixel.
Definition: pnmImage.I:770
BEGIN_PUBLISH EXPCL_PANDA_PNMIMAGE float decode_sRGB_float(unsigned char val)
Decodes the sRGB-encoded unsigned char value to a linearized float in the range 0-1.
Definition: convert_srgb.I:18
EXPCL_PANDA_PNMIMAGE float encode_sRGB_float(unsigned char val)
Encodes the linearized unsigned char value to an sRGB-encoded floating- point value in ther range 0-1...
Definition: convert_srgb.I:56
EXPCL_PANDA_PNMIMAGE unsigned char encode_sRGB_uchar(unsigned char val)
Encodes the linearized unsigned char value to an sRGB-encoded unsigned char value.
Definition: convert_srgb.I:80