Panda3D
Loading...
Searching...
No Matches
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 */
17INLINE PNMImage::
18PNMImage() {
19 _array = nullptr;
20 _alpha = nullptr;
21
22 clear();
23}
24
25/**
26 *
27 */
28INLINE PNMImage::
29PNMImage(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 */
40INLINE PNMImage::
41PNMImage(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 */
53INLINE void PNMImage::
54operator = (const PNMImage &copy) {
55 copy_from(copy);
56}
57
58/**
59 *
60 */
61INLINE PNMImage::
62~PNMImage() {
63 clear();
64}
65
66/**
67 * A handy function to clamp values to [0..get_maxval()].
68 */
69INLINE xelval PNMImage::
70clamp_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 */
79to_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 */
129INLINE xelval PNMImage::
130to_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 */
161INLINE xelval PNMImage::
162to_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 */
170INLINE LRGBColorf PNMImage::
171from_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 */
208INLINE float PNMImage::
209from_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 */
237INLINE float PNMImage::
238from_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 */
245INLINE void PNMImage::
246fill(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 */
254INLINE void PNMImage::
255fill(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 */
263INLINE void PNMImage::
264fill_val(xelval gray) {
265 fill_val(gray, gray, gray);
266}
267
268/**
269 * Sets the entire alpha channel to the given level.
270 */
271INLINE void PNMImage::
272alpha_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 */
287INLINE void PNMImage::
288set_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 */
297INLINE void PNMImage::
299 _has_read_size = false;
300}
301
302/**
303 * Returns true if set_read_size() has been called.
304 */
305INLINE bool PNMImage::
306has_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 */
314INLINE int PNMImage::
315get_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 */
323INLINE int PNMImage::
324get_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 */
331INLINE ColorSpace PNMImage::
332get_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 */
341INLINE bool PNMImage::
342is_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 */
352INLINE void PNMImage::
353set_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 */
362INLINE void PNMImage::
363add_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 */
370INLINE void PNMImage::
371remove_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 */
379INLINE void PNMImage::
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 */
388INLINE void PNMImage::
389make_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 */
398get_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 */
408get_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 */
418INLINE void PNMImage::
419set_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 */
429INLINE void PNMImage::
430set_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 */
441INLINE void PNMImage::
442set_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 */
451INLINE xelval PNMImage::
452get_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 */
461INLINE xelval PNMImage::
462get_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 */
471INLINE xelval PNMImage::
472get_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 */
483INLINE xelval PNMImage::
484get_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 */
493INLINE xelval PNMImage::
494get_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 */
505INLINE void PNMImage::
506set_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 */
517INLINE void PNMImage::
518set_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 */
529INLINE void PNMImage::
530set_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 */
544INLINE void PNMImage::
545set_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 */
558INLINE void PNMImage::
559set_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 */
568INLINE LRGBColorf PNMImage::
569get_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 */
578INLINE void PNMImage::
579set_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 */
588INLINE void PNMImage::
589set_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 */
597INLINE void PNMImage::
598set_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 */
607INLINE LColorf PNMImage::
608get_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 */
674INLINE void PNMImage::
675set_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 */
760INLINE void PNMImage::
761set_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 */
769INLINE float PNMImage::
770get_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 */
778INLINE float PNMImage::
779get_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 */
787INLINE float PNMImage::
788get_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 */
798INLINE float PNMImage::
799get_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 */
808INLINE float PNMImage::
809get_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 */
817INLINE void PNMImage::
818set_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 */
826INLINE void PNMImage::
827set_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 */
835INLINE void PNMImage::
836set_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 */
848INLINE void PNMImage::
849set_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 */
858INLINE void PNMImage::
859set_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 */
868INLINE float PNMImage::
869get_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 */
878INLINE float PNMImage::
879get_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 */
888INLINE float PNMImage::
889get_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 */
899INLINE void PNMImage::
900blend(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 */
908INLINE void PNMImage::
909box_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 */
917INLINE void PNMImage::
918gaussian_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 */
927INLINE void PNMImage::
928gamma_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 */
937INLINE void PNMImage::
938gamma_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 */
946INLINE void PNMImage::
947apply_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 */
955INLINE void PNMImage::
956apply_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 */
966INLINE void PNMImage::
967apply_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 */
974INLINE PNMImage::Row::
975Row(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 */
982INLINE size_t PNMImage::Row::
983size() const {
984 return _image.get_x_size();
985}
986
987/**
988 * Fetch the RGB value at the given column in the row.
989 */
990INLINE LColorf PNMImage::Row::
991operator[](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 */
1000INLINE 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 */
1010get_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 */
1018set_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 */
1025INLINE xelval PNMImage::Row::
1026get_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 */
1034set_alpha_val(int x, xelval v) {
1035 _image.set_alpha_val(x, _y, v);
1036}
1037
1038/**
1039
1040 */
1041INLINE PNMImage::CRow::
1042CRow(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 */
1049INLINE size_t PNMImage::CRow::
1050size() const {
1051 return _image.get_x_size();
1052}
1053
1054/**
1055 * Fetch the RGB value at the given column in the row.
1056 */
1057INLINE LColorf PNMImage::CRow::
1058operator[](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 */
1066get_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 */
1073INLINE xelval PNMImage::CRow::
1074get_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 */
1082operator [] (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 */
1090operator [] (int y) const {
1091 return CRow(*this, y);
1092}
1093
1094/**
1095 * Directly access the underlying PNMImage array. Know what you are doing!
1096 */
1098get_array() {
1099 return _array;
1100}
1101
1102/**
1103 * Directly access the underlying PNMImage array. Know what you are doing!
1104 */
1105INLINE const xel *PNMImage::
1106get_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 */
1114INLINE xelval *PNMImage::
1116 return _alpha;
1117}
1118
1119/**
1120 * Directly access the underlying PNMImage array of alpha values. Know what
1121 * you are doing!
1122 */
1123INLINE const xelval *PNMImage::
1124get_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 */
1135take_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 */
1147INLINE xelval *PNMImage::
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 */
1158INLINE void PNMImage::
1159allocate_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 */
1166INLINE void PNMImage::
1167allocate_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 */
1174INLINE xel *PNMImage::
1175row(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 */
1184INLINE xelval *PNMImage::
1185alpha_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 */
1194INLINE void PNMImage::
1195setup_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 */
1241INLINE void PNMImage::
1242compute_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 */
1264operator + (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 */
1275operator + (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 */
1287operator - (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 */
1298operator - (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 */
1311operator * (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 */
1322operator * (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 */
1333operator * (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.
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...
EXPCL_PANDA_PNMIMAGE unsigned char encode_sRGB_uchar(unsigned char val)
Encodes the linearized unsigned char value to an sRGB-encoded unsigned char value.