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 ©) { 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 ©) { 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 ©, 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 }