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