Panda3D

pnmImage.I

00001 // Filename: pnmImage.I
00002 // Created by:  drose (15Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 ////////////////////////////////////////////////////////////////////
00016 //     Function: PNMImage::Constructor
00017 //       Access: Published
00018 //  Description:
00019 ////////////////////////////////////////////////////////////////////
00020 INLINE PNMImage::
00021 PNMImage() {
00022   _array = NULL;
00023   _alpha = NULL;
00024 
00025   clear();
00026 }
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: PNMImage::Constructor
00030 //       Access: Published
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 INLINE PNMImage::
00034 PNMImage(int x_size, int y_size, int num_channels, xelval maxval,
00035          PNMFileType *type) {
00036   _array = NULL;
00037   _alpha = NULL;
00038 
00039   clear(x_size, y_size, num_channels, maxval, type);
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: PNMImage::Copy Constructor
00044 //       Access: Published
00045 //  Description:
00046 ////////////////////////////////////////////////////////////////////
00047 INLINE PNMImage::
00048 PNMImage(const PNMImage &copy) {
00049   // We don't need to invoke PNMImageHeader's copy constructor,
00050   // because we'll just call copy_from().
00051   _array = NULL;
00052   _alpha = NULL;
00053 
00054   copy_from(copy);
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: PNMImage::Copy Assignment Operator
00059 //       Access: Published
00060 //  Description:
00061 ////////////////////////////////////////////////////////////////////
00062 INLINE void PNMImage::
00063 operator = (const PNMImage &copy) {
00064   copy_from(copy);
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: PNMImage::Destructor
00069 //       Access: Published
00070 //  Description:
00071 ////////////////////////////////////////////////////////////////////
00072 INLINE PNMImage::
00073 ~PNMImage() {
00074   clear();
00075 }
00076 
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: PNMImage::clamp_val
00080 //       Access: Published
00081 //  Description: A handy function to clamp values to
00082 //               [0..get_maxval()].
00083 ////////////////////////////////////////////////////////////////////
00084 INLINE xelval PNMImage::
00085 clamp_val(int input_value) const {
00086   return (xelval)min(max(0, input_value), (int)get_maxval());
00087 }
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: PNMImage::to_val
00091 //       Access: Published
00092 //  Description: A handy function to scale values from [0..1] to
00093 //               [0..get_maxval()].
00094 ////////////////////////////////////////////////////////////////////
00095 INLINE xelval PNMImage::
00096 to_val(double input_value) const {
00097   return clamp_val((int)(input_value * get_maxval() + 0.5));
00098 }
00099 
00100 ////////////////////////////////////////////////////////////////////
00101 //     Function: PNMImage::from_val
00102 //       Access: Published
00103 //  Description: A handy function to scale values from
00104 //               [0..get_maxval()] to [0..1].
00105 ////////////////////////////////////////////////////////////////////
00106 INLINE double PNMImage::
00107 from_val(xelval input_value) const {
00108   return (double)input_value / (double)get_maxval();
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: PNMImage::fill
00113 //       Access: Published
00114 //  Description: Sets the entire image (except the alpha channel) to
00115 //               the given color.
00116 ////////////////////////////////////////////////////////////////////
00117 INLINE void PNMImage::
00118 fill(double red, double green, double blue) {
00119   fill_val(to_val(red), to_val(green), to_val(blue));
00120 }
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: PNMImage::fill
00124 //       Access: Published
00125 //  Description: Sets the entire image (except the alpha channel) to
00126 //               the given grayscale level.
00127 ////////////////////////////////////////////////////////////////////
00128 INLINE void PNMImage::
00129 fill(double gray) {
00130   fill(gray, gray, gray);
00131 }
00132 
00133 ////////////////////////////////////////////////////////////////////
00134 //     Function: PNMImage::fill_val
00135 //       Access: Published
00136 //  Description: Sets the entire image (except the alpha channel) to
00137 //               the given grayscale level.
00138 ////////////////////////////////////////////////////////////////////
00139 INLINE void PNMImage::
00140 fill_val(xelval gray) {
00141   fill_val(gray, gray, gray);
00142 }
00143 
00144 ////////////////////////////////////////////////////////////////////
00145 //     Function: PNMImage::alpha_fill
00146 //       Access: Published
00147 //  Description: Sets the entire alpha channel to the given level.
00148 ////////////////////////////////////////////////////////////////////
00149 INLINE void PNMImage::
00150 alpha_fill(double alpha) {
00151   alpha_fill_val(to_val(alpha));
00152 }
00153 
00154 ////////////////////////////////////////////////////////////////////
00155 //     Function: PNMImage::set_read_size
00156 //       Access: Published
00157 //  Description: Specifies the size to we'd like to scale the image
00158 //               upon reading it.  This will affect the next call to
00159 //               read().  This is usually used to reduce the image
00160 //               size, e.g. for a thumbnail.
00161 //
00162 //               If the file type reader supports it (e.g. JPEG), then
00163 //               this will scale the image during the read operation,
00164 //               consequently reducing memory and CPU utilization.  If
00165 //               the file type reader does not support it, this will
00166 //               load the image normally, and them perform a linear
00167 //               scale after it has been loaded.
00168 ////////////////////////////////////////////////////////////////////
00169 INLINE void PNMImage::
00170 set_read_size(int x_size, int y_size) {
00171   _read_x_size = x_size;
00172   _read_y_size = y_size;
00173   _has_read_size = true;
00174 }
00175 
00176 ////////////////////////////////////////////////////////////////////
00177 //     Function: PNMImage::clear_read_size
00178 //       Access: Published
00179 //  Description: Undoes the effect of a previous call to
00180 //               set_read_size().
00181 ////////////////////////////////////////////////////////////////////
00182 INLINE void PNMImage::
00183 clear_read_size() {
00184   _has_read_size = false;
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: PNMImage::has_read_size
00189 //       Access: Published
00190 //  Description: Returns true if set_read_size() has been called.
00191 ////////////////////////////////////////////////////////////////////
00192 INLINE bool PNMImage::
00193 has_read_size() const {
00194   return _has_read_size;
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: PNMImage::get_read_x_size
00199 //       Access: Published
00200 //  Description: Returns the requested x_size of the image if
00201 //               set_read_size() has been called, or the image x_size
00202 //               otherwise (if it is known).
00203 ////////////////////////////////////////////////////////////////////
00204 INLINE int PNMImage::
00205 get_read_x_size() const {
00206   return _has_read_size ? _read_x_size : get_x_size();
00207 }
00208 
00209 ////////////////////////////////////////////////////////////////////
00210 //     Function: PNMImage::get_read_y_size
00211 //       Access: Published
00212 //  Description: Returns the requested y_size of the image if
00213 //               set_read_size() has been called, or the image y_size
00214 //               otherwise (if it is known).
00215 ////////////////////////////////////////////////////////////////////
00216 INLINE int PNMImage::
00217 get_read_y_size() const {
00218   return _has_read_size ? _read_y_size : get_y_size();
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: PNMImage::is_valid
00223 //       Access: Published
00224 //  Description: Returns true if the image has been read in or
00225 //               correctly initialized with a height and width.  If
00226 //               this returns false, virtually all member functions
00227 //               except clear() and read() are invalid function calls.
00228 ////////////////////////////////////////////////////////////////////
00229 INLINE bool PNMImage::
00230 is_valid() const {
00231   return (_array != NULL);
00232 }
00233 
00234 ////////////////////////////////////////////////////////////////////
00235 //     Function: PNMImage::set_num_channels
00236 //       Access: Published
00237 //  Description: Changes the number of channels associated with the
00238 //               image.  The new number of channels must be an integer
00239 //               in the range 1 through 4, inclusive.  This will
00240 //               allocate and/or deallocate memory as necessary to
00241 //               accommodate; see set_color_type().
00242 ////////////////////////////////////////////////////////////////////
00243 INLINE void PNMImage::
00244 set_num_channels(int num_channels) {
00245   nassertv(num_channels >= 1 && num_channels <= 4);
00246   set_color_type((ColorType)num_channels);
00247 }
00248 
00249 ////////////////////////////////////////////////////////////////////
00250 //     Function: PNMImage::add_alpha
00251 //       Access: Published
00252 //  Description: Adds an alpha channel to the image, if it does not
00253 //               already have one.  The alpha channel is initialized
00254 //               to zeros.
00255 ////////////////////////////////////////////////////////////////////
00256 INLINE void PNMImage::
00257 add_alpha() {
00258   set_color_type(is_grayscale() ? CT_two_channel : CT_four_channel);
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: PNMImage::remove_alpha
00263 //       Access: Published
00264 //  Description: Removes the image's alpha channel, if it exists.
00265 ////////////////////////////////////////////////////////////////////
00266 INLINE void PNMImage::
00267 remove_alpha() {
00268   set_color_type(is_grayscale() ? CT_grayscale : CT_color);
00269 }
00270 
00271 ////////////////////////////////////////////////////////////////////
00272 //     Function: PNMImage::make_grayscale
00273 //       Access: Published
00274 //  Description: Converts the image from RGB to grayscale.  Any alpha
00275 //               channel, if present, is left undisturbed.
00276 ////////////////////////////////////////////////////////////////////
00277 INLINE void PNMImage::
00278 make_grayscale() {
00279   make_grayscale(_default_rc, _default_gc, _default_bc);
00280 }
00281 
00282 ////////////////////////////////////////////////////////////////////
00283 //     Function: PNMImage::make_rgb
00284 //       Access: Published
00285 //  Description: Converts the image from grayscale to RGB.  Any alpha
00286 //               channel, if present, is left undisturbed.
00287 ////////////////////////////////////////////////////////////////////
00288 INLINE void PNMImage::
00289 make_rgb() {
00290   set_color_type(has_alpha() ? CT_four_channel : CT_color);
00291 }
00292 
00293 ////////////////////////////////////////////////////////////////////
00294 //     Function: PNMImage::get_xel_val
00295 //       Access: Published
00296 //  Description: Returns the RGB color at the indicated pixel.  Each
00297 //               component is in the range 0..maxval.
00298 ////////////////////////////////////////////////////////////////////
00299 INLINE const xel &PNMImage::
00300 get_xel_val(int x, int y) const {
00301   nassertr(x >= 0 && x < _x_size && y >= 0 && y < _y_size, _array[0]);
00302   return row(y)[x];
00303 }
00304 
00305 ////////////////////////////////////////////////////////////////////
00306 //     Function: PNMImage::set_xel_val
00307 //       Access: Published
00308 //  Description: Changes the RGB color at the indicated pixel.  Each
00309 //               component is in the range 0..maxval.
00310 ////////////////////////////////////////////////////////////////////
00311 INLINE void PNMImage::
00312 set_xel_val(int x, int y, const xel &value) {
00313   nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00314   row(y)[x] = value;
00315 }
00316 
00317 ////////////////////////////////////////////////////////////////////
00318 //     Function: PNMImage::set_xel_val
00319 //       Access: Published
00320 //  Description: Changes the RGB color at the indicated pixel.  Each
00321 //               component is in the range 0..maxval.
00322 ////////////////////////////////////////////////////////////////////
00323 INLINE void PNMImage::
00324 set_xel_val(int x, int y, xelval r, xelval g, xelval b) {
00325   nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00326   PPM_ASSIGN(row(y)[x], r, g, b);
00327 }
00328 
00329 ////////////////////////////////////////////////////////////////////
00330 //     Function: PNMImage::set_xel_val
00331 //       Access: Published
00332 //  Description: Changes all three color components at the indicated
00333 //               pixel to the same value.  The value is in the range
00334 //               0..maxval.
00335 ////////////////////////////////////////////////////////////////////
00336 INLINE void PNMImage::
00337 set_xel_val(int x, int y, xelval gray) {
00338   nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00339   PPM_ASSIGN(row(y)[x], gray, gray, gray);
00340 }
00341 
00342 ////////////////////////////////////////////////////////////////////
00343 //     Function: PNMImage::get_red_val
00344 //       Access: Published
00345 //  Description: Returns the red component color at the indicated
00346 //               pixel.  The value returned is in the range 0..maxval.
00347 ////////////////////////////////////////////////////////////////////
00348 INLINE xelval PNMImage::
00349 get_red_val(int x, int y) const {
00350   return PPM_GETR(get_xel_val(x, y));
00351 }
00352 
00353 ////////////////////////////////////////////////////////////////////
00354 //     Function: PNMImage::get_green_val
00355 //       Access: Published
00356 //  Description: Returns the green component color at the indicated
00357 //               pixel.  The value returned is in the range 0..maxval.
00358 ////////////////////////////////////////////////////////////////////
00359 INLINE xelval PNMImage::
00360 get_green_val(int x, int y) const {
00361   return PPM_GETG(get_xel_val(x, y));
00362 }
00363 
00364 ////////////////////////////////////////////////////////////////////
00365 //     Function: PNMImage::get_blue_val
00366 //       Access: Published
00367 //  Description: Returns the blue component color at the indicated
00368 //               pixel.  The value returned is in the range 0..maxval.
00369 ////////////////////////////////////////////////////////////////////
00370 INLINE xelval PNMImage::
00371 get_blue_val(int x, int y) const {
00372   return PPM_GETB(get_xel_val(x, y));
00373 }
00374 
00375 ////////////////////////////////////////////////////////////////////
00376 //     Function: PNMImage::get_gray_val
00377 //       Access: Published
00378 //  Description: Returns the gray component color at the indicated
00379 //               pixel.  This only has a meaningful value for
00380 //               grayscale images; for other image types, this returns
00381 //               the value of the blue channel only.  However, also
00382 //               see the get_bright() function.  The value returned is
00383 //               in the range 0..maxval.
00384 ////////////////////////////////////////////////////////////////////
00385 INLINE xelval PNMImage::
00386 get_gray_val(int x, int y) const {
00387   return PPM_GETB(get_xel_val(x, y));
00388 }
00389 
00390 ////////////////////////////////////////////////////////////////////
00391 //     Function: PNMImage::get_alpha_val
00392 //       Access: Published
00393 //  Description: Returns the alpha component color at the indicated
00394 //               pixel.  It is an error to call this unless
00395 //               has_alpha() is true.  The value returned is in the
00396 //               range 0..maxval.
00397 ////////////////////////////////////////////////////////////////////
00398 INLINE xelval PNMImage::
00399 get_alpha_val(int x, int y) const {
00400   nassertr(_alpha != NULL && x >= 0 && x < _x_size && y >= 0 && y < _y_size, 0);
00401   return alpha_row(y)[x];
00402 }
00403 
00404 ////////////////////////////////////////////////////////////////////
00405 //     Function: PNMImage::set_red_val
00406 //       Access: Published
00407 //  Description: Sets the red component color only at the indicated
00408 //               pixel.  The value given should be in the range
00409 //               0..maxval.
00410 ////////////////////////////////////////////////////////////////////
00411 INLINE void PNMImage::
00412 set_red_val(int x, int y, xelval r) {
00413   nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00414   PPM_PUTR(row(y)[x], r);
00415 }
00416 
00417 ////////////////////////////////////////////////////////////////////
00418 //     Function: PNMImage::set_green_val
00419 //       Access: Published
00420 //  Description: Sets the green component color only at the indicated
00421 //               pixel.  The value given should be in the range
00422 //               0..maxval.
00423 ////////////////////////////////////////////////////////////////////
00424 INLINE void PNMImage::
00425 set_green_val(int x, int y, xelval g) {
00426   nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00427   PPM_PUTG(row(y)[x], g);
00428 }
00429 
00430 ////////////////////////////////////////////////////////////////////
00431 //     Function: PNMImage::set_blue_val
00432 //       Access: Published
00433 //  Description: Sets the blue component color only at the indicated
00434 //               pixel.  The value given should be in the range
00435 //               0..maxval.
00436 ////////////////////////////////////////////////////////////////////
00437 INLINE void PNMImage::
00438 set_blue_val(int x, int y, xelval b) {
00439   nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00440   PPM_PUTB(row(y)[x], b);
00441 }
00442 
00443 ////////////////////////////////////////////////////////////////////
00444 //     Function: PNMImage::set_gray_val
00445 //       Access: Published
00446 //  Description: Sets the gray component color at the indicated
00447 //               pixel.  This is only meaningful for grayscale images;
00448 //               for other image types, this simply sets the blue
00449 //               component color.  However, also see set_xel_val(),
00450 //               which can set all the component colors to the same
00451 //               grayscale level, and hence works correctly both for
00452 //               grayscale and color images.  The value given should
00453 //               be in the range 0..maxval.
00454 ////////////////////////////////////////////////////////////////////
00455 INLINE void PNMImage::
00456 set_gray_val(int x, int y, xelval gray) {
00457   nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00458   PPM_PUTB(row(y)[x], gray);
00459 }
00460 
00461 ////////////////////////////////////////////////////////////////////
00462 //     Function: PNMImage::set_alpha_val
00463 //       Access: Published
00464 //  Description: Sets the alpha component color only at the indicated
00465 //               pixel.  It is an error to call this unless
00466 //               has_alpha() is true.  The value given should be in
00467 //               the range 0..maxval.
00468 ////////////////////////////////////////////////////////////////////
00469 INLINE void PNMImage::
00470 set_alpha_val(int x, int y, xelval a) {
00471   nassertv(_alpha != NULL && x >= 0 && x < _x_size && y >= 0 && y < _y_size);
00472   alpha_row(y)[x] = a;
00473 }
00474 
00475 ////////////////////////////////////////////////////////////////////
00476 //     Function: PNMImage::get_xel
00477 //       Access: Published
00478 //  Description: Returns the RGB color at the indicated pixel.  Each
00479 //               component is a double in the range 0..1.
00480 ////////////////////////////////////////////////////////////////////
00481 INLINE LRGBColord PNMImage::
00482 get_xel(int x, int y) const {
00483   return LRGBColord(from_val(get_red_val(x, y)),
00484                    from_val(get_green_val(x, y)),
00485                    from_val(get_blue_val(x, y)));
00486 }
00487 
00488 ////////////////////////////////////////////////////////////////////
00489 //     Function: PNMImage::set_xel
00490 //       Access: Published
00491 //  Description: Changes the RGB color at the indicated pixel.  Each
00492 //               component is a double in the range 0..1.
00493 ////////////////////////////////////////////////////////////////////
00494 INLINE void PNMImage::
00495 set_xel(int x, int y, const LRGBColord &value) {
00496   set_xel_val(x, y, to_val(value[0]), to_val(value[1]), to_val(value[2]));
00497 }
00498 
00499 ////////////////////////////////////////////////////////////////////
00500 //     Function: PNMImage::set_xel
00501 //       Access: Published
00502 //  Description: Changes the RGB color at the indicated pixel.  Each
00503 //               component is a double in the range 0..1.
00504 ////////////////////////////////////////////////////////////////////
00505 INLINE void PNMImage::
00506 set_xel(int x, int y, double r, double g, double b) {
00507   set_xel_val(x, y, to_val(r), to_val(g), to_val(b));
00508 }
00509 
00510 ////////////////////////////////////////////////////////////////////
00511 //     Function: PNMImage::set_xel
00512 //       Access: Published
00513 //  Description: Changes all three color components at the indicated
00514 //               pixel to the same value.  The value is a double in
00515 //               the range 0..1.
00516 ////////////////////////////////////////////////////////////////////
00517 INLINE void PNMImage::
00518 set_xel(int x, int y, double gray) {
00519   set_xel_val(x, y, to_val(gray), to_val(gray), to_val(gray));
00520 }
00521 
00522 ////////////////////////////////////////////////////////////////////
00523 //     Function: PNMImage::get_xel_a
00524 //       Access: Published
00525 //  Description: Returns the RGBA color at the indicated pixel.  Each
00526 //               component is a double in the range 0..1.
00527 ////////////////////////////////////////////////////////////////////
00528 INLINE LColord PNMImage::
00529 get_xel_a(int x, int y) const {
00530   if (has_alpha()) {
00531     return LColord(from_val(get_red_val(x, y)),
00532                   from_val(get_green_val(x, y)),
00533                   from_val(get_blue_val(x, y)),
00534                   from_val(get_alpha_val(x, y)));
00535   } else {
00536     return LColord(from_val(get_red_val(x, y)),
00537                   from_val(get_green_val(x, y)),
00538                   from_val(get_blue_val(x, y)),
00539                   0.0);
00540   }
00541 }
00542 
00543 ////////////////////////////////////////////////////////////////////
00544 //     Function: PNMImage::set_xel_a
00545 //       Access: Published
00546 //  Description: Changes the RGBA color at the indicated pixel.  Each
00547 //               component is a double in the range 0..1.
00548 ////////////////////////////////////////////////////////////////////
00549 INLINE void PNMImage::
00550 set_xel_a(int x, int y, const LColord &value) {
00551   set_xel_val(x, y, to_val(value[0]), to_val(value[1]), to_val(value[2]));
00552   if (has_alpha()) {
00553     set_alpha_val(x, y, to_val(value[3]));
00554   }
00555 }
00556 
00557 ////////////////////////////////////////////////////////////////////
00558 //     Function: PNMImage::set_xel_a
00559 //       Access: Published
00560 //  Description: Changes the RGBA color at the indicated pixel.  Each
00561 //               component is a double in the range 0..1.
00562 ////////////////////////////////////////////////////////////////////
00563 INLINE void PNMImage::
00564 set_xel_a(int x, int y, double r, double g, double b, double a) {
00565   set_xel_val(x, y, to_val(r), to_val(g), to_val(b));
00566   if (has_alpha()) {
00567     set_alpha_val(x, y, to_val(a));
00568   }
00569 }
00570 
00571 ////////////////////////////////////////////////////////////////////
00572 //     Function: PNMImage::get_red
00573 //       Access: Published
00574 //  Description: Returns the red component color at the indicated
00575 //               pixel.  The value returned is a double in the range
00576 //               0..1.
00577 ////////////////////////////////////////////////////////////////////
00578 INLINE double PNMImage::
00579 get_red(int x, int y) const {
00580   return from_val(get_red_val(x, y));
00581 }
00582 
00583 ////////////////////////////////////////////////////////////////////
00584 //     Function: PNMImage::get_green
00585 //       Access: Published
00586 //  Description: Returns the green component color at the indicated
00587 //               pixel.  The value returned is a double in the range
00588 //               0..1.
00589 ////////////////////////////////////////////////////////////////////
00590 INLINE double PNMImage::
00591 get_green(int x, int y) const {
00592   return from_val(get_green_val(x, y));
00593 }
00594 
00595 ////////////////////////////////////////////////////////////////////
00596 //     Function: PNMImage::get_blue
00597 //       Access: Published
00598 //  Description: Returns the blue component color at the indicated
00599 //               pixel.  The value returned is a double in the range
00600 //               0..1.
00601 ////////////////////////////////////////////////////////////////////
00602 INLINE double PNMImage::
00603 get_blue(int x, int y) const {
00604   return from_val(get_blue_val(x, y));
00605 }
00606 
00607 ////////////////////////////////////////////////////////////////////
00608 //     Function: PNMImage::get_gray
00609 //       Access: Published
00610 //  Description: Returns the gray component color at the indicated
00611 //               pixel.  This only has a meaningful value for
00612 //               grayscale images; for other image types, this returns
00613 //               the value of the blue channel only.  However, also
00614 //               see the get_bright() function.  The value returned is
00615 //               a double in the range 0..1.
00616 ////////////////////////////////////////////////////////////////////
00617 INLINE double PNMImage::
00618 get_gray(int x, int y) const {
00619   return from_val(get_gray_val(x, y));
00620 }
00621 
00622 ////////////////////////////////////////////////////////////////////
00623 //     Function: PNMImage::get_alpha
00624 //       Access: Published
00625 //  Description: Returns the alpha component color at the indicated
00626 //               pixel.  It is an error to call this unless
00627 //               has_alpha() is true.  The value returned is a double
00628 //               in the range 0..1.
00629 ////////////////////////////////////////////////////////////////////
00630 INLINE double PNMImage::
00631 get_alpha(int x, int y) const {
00632   return from_val(get_alpha_val(x, y));
00633 }
00634 
00635 ////////////////////////////////////////////////////////////////////
00636 //     Function: PNMImage::set_red
00637 //       Access: Published
00638 //  Description: Sets the red component color only at the indicated
00639 //               pixel.  The value given should be a double in the
00640 //               range 0..1.
00641 ////////////////////////////////////////////////////////////////////
00642 INLINE void PNMImage::
00643 set_red(int x, int y, double r) {
00644   set_red_val(x, y, to_val(r));
00645 }
00646 
00647 ////////////////////////////////////////////////////////////////////
00648 //     Function: PNMImage::set_green
00649 //       Access: Published
00650 //  Description: Sets the green component color only at the indicated
00651 //               pixel.  The value given should be a double in the
00652 //               range 0..1.
00653 ////////////////////////////////////////////////////////////////////
00654 INLINE void PNMImage::
00655 set_green(int x, int y, double r) {
00656   set_green_val(x, y, to_val(r));
00657 }
00658 
00659 ////////////////////////////////////////////////////////////////////
00660 //     Function: PNMImage::set_blue
00661 //       Access: Published
00662 //  Description: Sets the blue component color only at the indicated
00663 //               pixel.  The value given should be a double in the
00664 //               range 0..1.
00665 ////////////////////////////////////////////////////////////////////
00666 INLINE void PNMImage::
00667 set_blue(int x, int y, double r) {
00668   set_blue_val(x, y, to_val(r));
00669 }
00670 
00671 ////////////////////////////////////////////////////////////////////
00672 //     Function: PNMImage::set_gray
00673 //       Access: Published
00674 //  Description: Sets the gray component color at the indicated
00675 //               pixel.  This is only meaningful for grayscale images;
00676 //               for other image types, this simply sets the blue
00677 //               component color.  However, also see set_xel(), which
00678 //               can set all the component colors to the same
00679 //               grayscale level, and hence works correctly both for
00680 //               grayscale and color images.  The value given should
00681 //               be a double in the range 0..1.
00682 ////////////////////////////////////////////////////////////////////
00683 INLINE void PNMImage::
00684 set_gray(int x, int y, double r) {
00685   set_gray_val(x, y, to_val(r));
00686 }
00687 
00688 ////////////////////////////////////////////////////////////////////
00689 //     Function: PNMImage::set_alpha
00690 //       Access: Published
00691 //  Description: Sets the alpha component color only at the indicated
00692 //               pixel.  It is an error to call this unless
00693 //               has_alpha() is true.  The value given should be in
00694 //               the range 0..1.
00695 ////////////////////////////////////////////////////////////////////
00696 INLINE void PNMImage::
00697 set_alpha(int x, int y, double r) {
00698   set_alpha_val(x, y, to_val(r));
00699 }
00700 
00701 ////////////////////////////////////////////////////////////////////
00702 //     Function: PNMImage::get_channel
00703 //       Access: Published
00704 //  Description: Returns the nth component color at the indicated
00705 //               pixel.  The channel index should be in the range
00706 //               0..(get_num_channels()-1).  The channels are ordered B,
00707 //               G, R, A.  This is slightly less optimal than
00708 //               accessing the component values directly by named
00709 //               methods.  The value returned is a double in the range
00710 //               0..1.
00711 ////////////////////////////////////////////////////////////////////
00712 INLINE double PNMImage::
00713 get_channel(int x, int y, int channel) const {
00714   return from_val(get_channel_val(x, y, channel));
00715 }
00716 
00717 ////////////////////////////////////////////////////////////////////
00718 //     Function: PNMImage::set_channel_val
00719 //       Access: Published
00720 //  Description: Sets the nth component color at the indicated
00721 //               pixel.  The channel index should be in the range
00722 //               0..(get_num_channels()-1).  The channels are ordered B,
00723 //               G, R, A.  This is slightly less optimal than
00724 //               setting the component values directly by named
00725 //               methods.  The value given should be a double in the
00726 //               range 0..1.
00727 ////////////////////////////////////////////////////////////////////
00728 INLINE void PNMImage::
00729 set_channel(int x, int y, int channel, double value) {
00730   set_channel_val(x, y, channel, to_val(value));
00731 }
00732 
00733 ////////////////////////////////////////////////////////////////////
00734 //     Function: PNMImage::get_bright
00735 //       Access: Published
00736 //  Description: Returns the linear brightness of the given xel, as a
00737 //               double in the range 0..1.  This flavor of
00738 //               get_bright() returns the correct grayscale brightness
00739 //               level for both full-color and grayscale images.
00740 ////////////////////////////////////////////////////////////////////
00741 INLINE double PNMImage::
00742 get_bright(int x, int y) const {
00743   return get_bright(x, y, _default_rc, _default_gc, _default_bc);
00744 }
00745 
00746 ////////////////////////////////////////////////////////////////////
00747 //     Function: PNMImage::get_bright
00748 //       Access: Published
00749 //  Description: This flavor of get_bright() works correctly only for
00750 //               color images.  It returns a single brightness value
00751 //               for the RGB color at the indicated pixel, based on
00752 //               the supplied weights for each component.
00753 ////////////////////////////////////////////////////////////////////
00754 INLINE double PNMImage::
00755 get_bright(int x, int y, double rc, double gc, double bc) const {
00756   return from_val((int)(rc * get_red_val(x, y) +
00757                         gc * get_green_val(x, y) +
00758                         bc * get_blue_val(x, y)));
00759 }
00760 
00761 ////////////////////////////////////////////////////////////////////
00762 //     Function: PNMImage::get_bright
00763 //       Access: Published
00764 //  Description: This flavor of get_bright() works correctly only for
00765 //               four-channel images.  It returns a single brightness
00766 //               value for the RGBA color at the indicated pixel,
00767 //               based on the supplied weights for each component.
00768 ////////////////////////////////////////////////////////////////////
00769 INLINE double PNMImage::
00770 get_bright(int x, int y, double rc, double gc, double bc, double ac) const {
00771   return from_val((int)(rc * get_red_val(x, y) +
00772                         gc * get_green_val(x, y) +
00773                         bc * get_blue_val(x, y) +
00774                         ac * get_alpha_val(x, y)));
00775 }
00776 
00777 ////////////////////////////////////////////////////////////////////
00778 //     Function: PNMImage::blend
00779 //       Access: Published
00780 //  Description: Smoothly blends the indicated pixel value in with
00781 //               whatever was already in the image, based on the given
00782 //               alpha value.  An alpha of 1.0 is fully opaque and
00783 //               completely replaces whatever was there previously;
00784 //               alpha of 0.0 is fully transparent and does nothing.
00785 ////////////////////////////////////////////////////////////////////
00786 INLINE void PNMImage::
00787 blend(int x, int y, const LRGBColord &val, double alpha) {
00788   blend(x, y, val[0], val[1], val[2], alpha);
00789 }
00790 
00791 ////////////////////////////////////////////////////////////////////
00792 //     Function: PNMImage::Array Operator
00793 //       Access: Published
00794 //  Description: Allows the PNMImage to appear to be a 2-d array of
00795 //               xels.
00796 ////////////////////////////////////////////////////////////////////
00797 INLINE xel *PNMImage::
00798 operator [] (int y) {
00799   return row(y);
00800 }
00801 
00802 ////////////////////////////////////////////////////////////////////
00803 //     Function: PNMImage::Array Operator
00804 //       Access: Published
00805 //  Description: Allows the PNMImage to appear to be a 2-d array of
00806 //               xels.
00807 ////////////////////////////////////////////////////////////////////
00808 INLINE const xel *PNMImage::
00809 operator [] (int y) const {
00810   return row(y);
00811 }
00812 
00813 ////////////////////////////////////////////////////////////////////
00814 //     Function: PNMImage::box_filter
00815 //       Access: Published
00816 //  Description: This flavor of box_filter() will apply the filter
00817 //               over the entire image without resizing or copying;
00818 //               the effect is that of a blur operation.
00819 ////////////////////////////////////////////////////////////////////
00820 INLINE void PNMImage::
00821 box_filter(double radius) {
00822   box_filter_from(radius, *this);
00823 }
00824 
00825 ////////////////////////////////////////////////////////////////////
00826 //     Function: PNMImage::gaussian_filter
00827 //       Access: Published
00828 //  Description: This flavor of gaussian_filter() will apply the filter
00829 //               over the entire image without resizing or copying;
00830 //               the effect is that of a blur operation.
00831 ////////////////////////////////////////////////////////////////////
00832 INLINE void PNMImage::
00833 gaussian_filter(double radius) {
00834   gaussian_filter_from(radius, *this);
00835 }
00836 
00837 ////////////////////////////////////////////////////////////////////
00838 //     Function: PNMImage::gamma_correct
00839 //       Access: Published
00840 //  Description: Assuming the image was constructed with a gamma curve
00841 //               of from_gamma in the RGB channels, converts it to an
00842 //               image with a gamma curve of to_gamma in the RGB
00843 //               channels.  Does not affect the alpha channel.
00844 ////////////////////////////////////////////////////////////////////
00845 INLINE void PNMImage::
00846 gamma_correct(double from_gamma, double to_gamma) {
00847   apply_exponent(from_gamma / to_gamma);
00848 }
00849 
00850 ////////////////////////////////////////////////////////////////////
00851 //     Function: PNMImage::gamma_correct_alpha
00852 //       Access: Published
00853 //  Description: Assuming the image was constructed with a gamma curve
00854 //               of from_gamma in the alpha channel, converts it to an
00855 //               image with a gamma curve of to_gamma in the alpha
00856 //               channel.  Does not affect the RGB channels.
00857 ////////////////////////////////////////////////////////////////////
00858 INLINE void PNMImage::
00859 gamma_correct_alpha(double from_gamma, double to_gamma) {
00860   apply_exponent(1.0, from_gamma / to_gamma);
00861 }
00862 
00863 ////////////////////////////////////////////////////////////////////
00864 //     Function: PNMImage::apply_exponent
00865 //       Access: Published
00866 //  Description: Adjusts each channel of the image by raising the
00867 //               corresponding component value to the indicated
00868 //               exponent, such that L' = L ^ exponent.
00869 ////////////////////////////////////////////////////////////////////
00870 INLINE void PNMImage::
00871 apply_exponent(double gray_exponent) {
00872   apply_exponent(gray_exponent, gray_exponent, gray_exponent, 1.0);
00873 }
00874 
00875 ////////////////////////////////////////////////////////////////////
00876 //     Function: PNMImage::apply_exponent
00877 //       Access: Published
00878 //  Description: Adjusts each channel of the image by raising the
00879 //               corresponding component value to the indicated
00880 //               exponent, such that L' = L ^ exponent.
00881 ////////////////////////////////////////////////////////////////////
00882 INLINE void PNMImage::
00883 apply_exponent(double gray_exponent, double alpha_exponent) {
00884   apply_exponent(gray_exponent, gray_exponent, gray_exponent, alpha_exponent);
00885 }
00886 
00887 ////////////////////////////////////////////////////////////////////
00888 //     Function: PNMImage::apply_exponent
00889 //       Access: Published
00890 //  Description: Adjusts each channel of the image by raising the
00891 //               corresponding component value to the indicated
00892 //               exponent, such that L' = L ^ exponent.  For a
00893 //               grayscale image, the blue_exponent value is used for
00894 //               the grayscale value, and red_exponent and
00895 //               green_exponent are unused.
00896 ////////////////////////////////////////////////////////////////////
00897 INLINE void PNMImage::
00898 apply_exponent(double red_exponent, double green_exponent, double blue_exponent) {
00899   apply_exponent(red_exponent, green_exponent, blue_exponent, 1.0);
00900 }
00901 
00902 
00903 ////////////////////////////////////////////////////////////////////
00904 //     Function: PNMImage::allocate_array
00905 //       Access: Private
00906 //  Description: Allocates the internal memory for the RGB or
00907 //               grayscale pixels in the image (except alpha).
00908 ////////////////////////////////////////////////////////////////////
00909 INLINE void PNMImage::
00910 allocate_array() {
00911   _array = (xel *)PANDA_MALLOC_ARRAY(_x_size * _y_size * sizeof(xel));
00912 }
00913 
00914 ////////////////////////////////////////////////////////////////////
00915 //     Function: PNMImage::allocate_alpha
00916 //       Access: Private
00917 //  Description: Allocates the internal memory for the alpha pixels in
00918 //               the image.
00919 ////////////////////////////////////////////////////////////////////
00920 INLINE void PNMImage::
00921 allocate_alpha() {
00922   _alpha = (xelval *)PANDA_MALLOC_ARRAY(_x_size * _y_size * sizeof(xelval));
00923 }
00924 
00925 ////////////////////////////////////////////////////////////////////
00926 //     Function: PNMImage::row
00927 //       Access: Private
00928 //  Description: Returns an array of xels corresponding to the nth row
00929 //               of the image.
00930 ////////////////////////////////////////////////////////////////////
00931 INLINE xel *PNMImage::
00932 row(int y) const {
00933   nassertr(y >= 0 && y < _y_size, NULL);
00934   return _array + y * _x_size;
00935 }
00936 
00937 ////////////////////////////////////////////////////////////////////
00938 //     Function: PNMImage::alpha_row
00939 //       Access: Private
00940 //  Description: Returns an array of xelvals corresponding to the nth
00941 //               row of the alpha channel.
00942 ////////////////////////////////////////////////////////////////////
00943 INLINE xelval *PNMImage::
00944 alpha_row(int y) const {
00945   nassertr(_alpha != NULL && y >= 0 && y < _y_size, NULL);
00946   return _alpha + y * _x_size;
00947 }
00948 
00949 ////////////////////////////////////////////////////////////////////
00950 //     Function: PNMImage::setup_sub_image
00951 //       Access: Private
00952 //  Description: Computes xmin, ymin, xmax, and ymax, based on the
00953 //               input parameters for copy_sub_image() and related
00954 //               methods.
00955 ////////////////////////////////////////////////////////////////////
00956 INLINE void PNMImage::
00957 setup_sub_image(const PNMImage &copy, int &xto, int &yto,
00958                 int &xfrom, int &yfrom, int &x_size, int &y_size,
00959                 int &xmin, int &ymin, int &xmax, int &ymax) {
00960   if (x_size < 0) {
00961     x_size = copy.get_x_size() - xfrom;
00962   }
00963   if (y_size < 0) {
00964     y_size = copy.get_y_size() - yfrom;
00965   }
00966 
00967   if (xfrom < 0) {
00968     xto += -xfrom;
00969     x_size -= -xfrom;
00970     xfrom = 0;
00971   }
00972   if (yfrom < 0) {
00973     yto += -yfrom;
00974     y_size -= -yfrom;
00975     yfrom = 0;
00976   }
00977 
00978   if (xto < 0) {
00979     xfrom += -xto;
00980     x_size -= -xto;
00981     xto = 0;
00982   }
00983   if (yto < 0) {
00984     yfrom += -yto;
00985     y_size -= -yto;
00986     yto = 0;
00987   }
00988 
00989   x_size = min(x_size, copy.get_x_size() - xfrom);
00990   y_size = min(y_size, copy.get_y_size() - yfrom);
00991 
00992   xmin = xto;
00993   ymin = yto;
00994 
00995   xmax = min(xmin + x_size, get_x_size());
00996   ymax = min(ymin + y_size, get_y_size());
00997 }
00998 
00999 ////////////////////////////////////////////////////////////////////
01000 //     Function: PNMImage::compute_spot_pixel
01001 //       Access: Private, Static
01002 //  Description: Called by render_spot to compute the color of a
01003 //               single pixel, based in (the square of) its distance
01004 //               from the center.
01005 ////////////////////////////////////////////////////////////////////
01006 INLINE void PNMImage::
01007 compute_spot_pixel(LColord &c, double d2,
01008                    double min_radius, double max_radius,
01009                    const LColord &fg, const LColord &bg) {
01010   double d = sqrt(d2);
01011   if (d > max_radius) {
01012     c = bg;
01013   } else if (d > min_radius) {
01014     d = (d - min_radius) / (max_radius - min_radius);
01015     double d2 = d * d;
01016     double t = (3.0 * d2) - (2.0 * d * d2);
01017     c = fg + t * (bg - fg);
01018   } else {
01019     c = fg;
01020   }
01021 }
01022 
01023 ////////////////////////////////////////////////////////////////////
01024 //     Function: PNMImage::operator +
01025 //       Access: Published
01026 //  Description: Returns a new PNMImage in which each pixel value
01027 //               is the sum of the corresponding pixel values
01028 //               in the two given images.
01029 //               Only valid when both images have the same size.
01030 ////////////////////////////////////////////////////////////////////
01031 INLINE PNMImage PNMImage::
01032 operator + (const PNMImage &other) const {
01033   PNMImage target (*this);
01034   target += other;
01035   return target;
01036 }
01037 
01038 ////////////////////////////////////////////////////////////////////
01039 //     Function: PNMImage::operator +
01040 //       Access: Published
01041 //  Description: Returns a new PNMImage in which the provided color
01042 //               is added to each pixel in the provided image.
01043 ////////////////////////////////////////////////////////////////////
01044 INLINE PNMImage PNMImage::
01045 operator + (const LColord &other) const {
01046   PNMImage target (*this);
01047   target += other;
01048   return target;
01049 }
01050 
01051 ////////////////////////////////////////////////////////////////////
01052 //     Function: PNMImage::operator -
01053 //       Access: Published
01054 //  Description: Returns a new PNMImage in which each pixel value
01055 //               from the right image is subtracted from each
01056 //               pixel value from the left image.
01057 //               Only valid when both images have the same size.
01058 ////////////////////////////////////////////////////////////////////
01059 INLINE PNMImage PNMImage::
01060 operator - (const PNMImage &other) const {
01061   PNMImage target (*this);
01062   target -= other;
01063   return target;
01064 }
01065 
01066 ////////////////////////////////////////////////////////////////////
01067 //     Function: PNMImage::operator -
01068 //       Access: Published
01069 //  Description: Returns a new PNMImage in which the provided color
01070 //               is subtracted from each pixel in the provided image.
01071 ////////////////////////////////////////////////////////////////////
01072 INLINE PNMImage PNMImage::
01073 operator - (const LColord &other) const {
01074   PNMImage target (*this);
01075   target -= other;
01076   return target;
01077 }
01078 
01079 ////////////////////////////////////////////////////////////////////
01080 //     Function: PNMImage::operator *
01081 //       Access: Published
01082 //  Description: Returns a new PNMImage in which each pixel value
01083 //               from the left image is multiplied by each
01084 //               pixel value from the right image. Note that the
01085 //               floating-point values in the 0..1 range are
01086 //               multiplied, not in the 0..maxval range.
01087 //               Only valid when both images have the same size.
01088 ////////////////////////////////////////////////////////////////////
01089 INLINE PNMImage PNMImage::
01090 operator * (const PNMImage &other) const {
01091   PNMImage target (*this);
01092   target *= other;
01093   return target;
01094 }
01095 
01096 ////////////////////////////////////////////////////////////////////
01097 //     Function: PNMImage::operator *
01098 //       Access: Published
01099 //  Description: Multiplies every pixel value in the image by
01100 //               a constant floating-point multiplier value.
01101 ////////////////////////////////////////////////////////////////////
01102 INLINE PNMImage PNMImage::
01103 operator * (double multiplier) const {
01104   PNMImage target (*this);
01105   target *= multiplier;
01106   return target;
01107 }
 All Classes Functions Variables Enumerations