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