From 1a7653d146aa76dcbec236942dcba45dd020e067 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 15 May 2010 08:44:18 +0000 Subject: [PATCH] Ability to add, subtract, multiply PNMImages with each other or with a constant --- panda/src/pnmimage/pnmImage.I | 88 +++++++++++++- panda/src/pnmimage/pnmImage.cxx | 177 +++++++++++++++++++++++++++++ panda/src/pnmimage/pnmImage.h | 14 +++ panda/src/pnmimage/pnmimage_base.h | 12 ++ 4 files changed, 290 insertions(+), 1 deletion(-) diff --git a/panda/src/pnmimage/pnmImage.I b/panda/src/pnmimage/pnmImage.I index 50b587fe08..546abdd889 100644 --- a/panda/src/pnmimage/pnmImage.I +++ b/panda/src/pnmimage/pnmImage.I @@ -939,7 +939,7 @@ setup_sub_image(const PNMImage ©, int &xto, int &yto, // from the center. //////////////////////////////////////////////////////////////////// INLINE void PNMImage:: -compute_spot_pixel(Colord &c, double d2, +compute_spot_pixel(Colord &c, double d2, double min_radius, double max_radius, const Colord &fg, const Colord &bg) { double d = sqrt(d2); @@ -954,3 +954,89 @@ compute_spot_pixel(Colord &c, double d2, c = fg; } } + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator + +// Access: Published +// Description: Returns a new PNMImage in which each pixel value +// is the sum of the corresponding pixel values +// in the two given images. +// Only valid when both images have the same size. +//////////////////////////////////////////////////////////////////// +INLINE PNMImage PNMImage:: +operator + (const PNMImage &other) const { + PNMImage target (*this); + target += other; + return target; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator + +// Access: Published +// Description: Returns a new PNMImage in which the provided color +// is added to each pixel in the provided image. +//////////////////////////////////////////////////////////////////// +INLINE PNMImage PNMImage:: +operator + (const Colord &other) const { + PNMImage target (*this); + target += other; + return target; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator - +// Access: Published +// Description: Returns a new PNMImage in which each pixel value +// from the right image is subtracted from each +// pixel value from the left image. +// Only valid when both images have the same size. +//////////////////////////////////////////////////////////////////// +INLINE PNMImage PNMImage:: +operator - (const PNMImage &other) const { + PNMImage target (*this); + target -= other; + return target; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator - +// Access: Published +// Description: Returns a new PNMImage in which the provided color +// is subtracted from each pixel in the provided image. +//////////////////////////////////////////////////////////////////// +INLINE PNMImage PNMImage:: +operator - (const Colord &other) const { + PNMImage target (*this); + target -= other; + return target; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator * +// Access: Published +// Description: Returns a new PNMImage in which each pixel value +// from the left image is multiplied by each +// pixel value from the right image. Note that the +// floating-point values in the 0..1 range are +// multiplied, not in the 0..maxval range. +// Only valid when both images have the same size. +//////////////////////////////////////////////////////////////////// +INLINE PNMImage PNMImage:: +operator * (const PNMImage &other) const { + PNMImage target (*this); + target *= other; + return target; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator * +// Access: Published +// Description: Multiplies every pixel value in the image by +// a constant floating-point multiplier value. +//////////////////////////////////////////////////////////////////// +INLINE PNMImage PNMImage:: +operator * (double multiplier) const { + PNMImage target (*this); + target *= multiplier; + return target; +} diff --git a/panda/src/pnmimage/pnmImage.cxx b/panda/src/pnmimage/pnmImage.cxx index 630b12cf0b..a606fad944 100644 --- a/panda/src/pnmimage/pnmImage.cxx +++ b/panda/src/pnmimage/pnmImage.cxx @@ -1316,3 +1316,180 @@ setup_rc() { _default_bc = lumin_blu; } } + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator += +// Access: Published +// Description: Returns a new PNMImage in which each pixel value +// is the sum of the corresponding pixel values +// in the two given images. +// Only valid when both images have the same size. +//////////////////////////////////////////////////////////////////// +void PNMImage:: +operator += (const PNMImage &other) { + nassertv(_x_size == other._x_size && _y_size == other._y_size); + nassertv(_maxval == other._maxval && _maxval == other._maxval); + size_t array_size = _x_size * _y_size; + + if (_array != NULL && _alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r + other._array[i].r); + _array[i].g = clamp_val(_array[i].g + other._array[i].g); + _array[i].b = clamp_val(_array[i].b + other._array[i].b); + _alpha[i] = clamp_val(_alpha[i] + other._alpha[i]); + } + } else if (_array != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r + other._array[i].r); + _array[i].g = clamp_val(_array[i].g + other._array[i].g); + _array[i].b = clamp_val(_array[i].b + other._array[i].b); + } + } else if (_alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _alpha[i] = clamp_val(_alpha[i] + other._alpha[i]); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator += +// Access: Published +// Description: Returns a new PNMImage in which the provided color +// is added to each pixel in the provided image. +//////////////////////////////////////////////////////////////////// +void PNMImage:: +operator += (const Colord &other) { + size_t array_size = _x_size * _y_size; + xel addxel (to_val(other.get_x()), to_val(other.get_y()), to_val(other.get_z())); + xelval addalpha = to_val(other.get_w()); + + if (_array != NULL && _alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r + addxel.r); + _array[i].g = clamp_val(_array[i].g + addxel.g); + _array[i].b = clamp_val(_array[i].b + addxel.b); + _alpha[i] = clamp_val(_alpha[i] + addalpha); + } + } else if (_array != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r + addxel.r); + _array[i].g = clamp_val(_array[i].g + addxel.g); + _array[i].b = clamp_val(_array[i].b + addxel.b); + } + } else if (_alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _alpha[i] = clamp_val(_alpha[i] + addalpha); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator -= +// Access: Published +// Description: Returns a new PNMImage in which each pixel value +// from the right image is subtracted from each +// pixel value from the left image. +// Only valid when both images have the same size. +//////////////////////////////////////////////////////////////////// +void PNMImage:: +operator -= (const PNMImage &other) { + nassertv(_x_size == other._x_size && _y_size == other._y_size); + nassertv(_maxval == other._maxval && _maxval == other._maxval); + size_t array_size = _x_size * _y_size; + + if (_array != NULL && _alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r - other._array[i].r); + _array[i].g = clamp_val(_array[i].g - other._array[i].g); + _array[i].b = clamp_val(_array[i].b - other._array[i].b); + _alpha[i] = clamp_val(_alpha[i] - other._alpha[i]); + } + } else if (_array != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r - other._array[i].r); + _array[i].g = clamp_val(_array[i].g - other._array[i].g); + _array[i].b = clamp_val(_array[i].b - other._array[i].b); + } + } else if (_alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _alpha[i] = clamp_val(_alpha[i] - other._alpha[i]); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator -= +// Access: Published +// Description: Returns a new PNMImage in which the provided color +// is subtracted from each pixel in the provided image. +//////////////////////////////////////////////////////////////////// +void PNMImage:: +operator -= (const Colord &other) { + (*this) += (-other); +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator *= +// Access: Published +// Description: Returns a new PNMImage in which each pixel value +// from the left image is multiplied by each +// pixel value from the right image. Note that the +// floating-point values in the 0..1 range are +// multiplied, not in the 0..maxval range. +// Only valid when both images have the same size. +//////////////////////////////////////////////////////////////////// +void PNMImage:: +operator *= (const PNMImage &other) { + nassertv(_x_size == other._x_size && _y_size == other._y_size); + size_t array_size = _x_size * _y_size; + + if (_array != NULL && _alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = to_val(from_val(_array[i].r) * other.from_val(other._array[i].r)); + _array[i].g = to_val(from_val(_array[i].g) * other.from_val(other._array[i].g)); + _array[i].b = to_val(from_val(_array[i].b) * other.from_val(other._array[i].b)); + _alpha[i] = to_val(from_val(_alpha[i]) * other.from_val(other._alpha[i])); + } + } else if (_array != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = to_val(from_val(_array[i].r) * other.from_val(other._array[i].r)); + _array[i].g = to_val(from_val(_array[i].g) * other.from_val(other._array[i].g)); + _array[i].b = to_val(from_val(_array[i].b) * other.from_val(other._array[i].b)); + } + } else if (_alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _alpha[i] = to_val(from_val(_alpha[i]) * other.from_val(other._alpha[i])); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::operator *= +// Access: Published +// Description: Multiplies every pixel value in the image by +// a constant floating-point multiplier value. +//////////////////////////////////////////////////////////////////// +void PNMImage:: +operator *= (double multiplier) { + size_t array_size = _x_size * _y_size; + + if (_array != NULL && _alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r * multiplier); + _array[i].g = clamp_val(_array[i].g * multiplier); + _array[i].b = clamp_val(_array[i].b * multiplier); + _alpha[i] = clamp_val(_alpha[i] * multiplier); + } + } else if (_array != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _array[i].r = clamp_val(_array[i].r * multiplier); + _array[i].g = clamp_val(_array[i].g * multiplier); + _array[i].b = clamp_val(_array[i].b * multiplier); + } + } else if (_alpha != NULL) { + for (size_t i = 0; i < array_size; ++i) { + _alpha[i] = clamp_val(_alpha[i] * multiplier); + } + } +} + diff --git a/panda/src/pnmimage/pnmImage.h b/panda/src/pnmimage/pnmImage.h index d8d1d3e0ea..09b3b76b52 100644 --- a/panda/src/pnmimage/pnmImage.h +++ b/panda/src/pnmimage/pnmImage.h @@ -253,6 +253,20 @@ private: void setup_rc(); +PUBLISHED: + INLINE PNMImage operator + (const PNMImage &other) const; + INLINE PNMImage operator + (const Colord &other) const; + INLINE PNMImage operator - (const PNMImage &other) const; + INLINE PNMImage operator - (const Colord &other) const; + INLINE PNMImage operator * (const PNMImage &other) const; + INLINE PNMImage operator * (double multiplier) const; + void operator += (const PNMImage &other); + void operator += (const Colord &other); + void operator -= (const PNMImage &other); + void operator -= (const Colord &other); + void operator *= (const PNMImage &other); + void operator *= (double multiplier); + private: xel *_array; xelval *_alpha; diff --git a/panda/src/pnmimage/pnmimage_base.h b/panda/src/pnmimage/pnmimage_base.h index 02141eb59c..8d649e8358 100644 --- a/panda/src/pnmimage/pnmimage_base.h +++ b/panda/src/pnmimage/pnmimage_base.h @@ -49,6 +49,18 @@ PUBLISHED: #ifdef HAVE_PYTHON void __setitem__(int i, gray v) { operator[](i) = v; } #endif + pixel operator + (const pixel &other) const + { return pixel(r + other.r, g + other.g, b + other.b); } + pixel operator - (const pixel &other) const + { return pixel(r - other.r, g - other.g, b - other.b); } + pixel operator * (const double mult) const + { return pixel(r * mult, g * mult, b * mult); } + void operator += (const pixel &other) + { r += other.r; g += other.g; b += other.b; } + void operator -= (const pixel &other) + { r -= other.r; g -= other.g; b -= other.b; } + void operator *= (const double mult) + { r *= mult; g *= mult; b *= mult; } gray r, g, b; };