From 849dc8cccbd19e3da8941156fb53d8c2432ee1a3 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 16 Dec 2009 06:57:52 +0000 Subject: [PATCH] add PNMImage::threshold() --- panda/src/pnmimage/pnmImage.cxx | 94 +++++++++++++++++++++++++++++++++ panda/src/pnmimage/pnmImage.h | 4 ++ 2 files changed, 98 insertions(+) diff --git a/panda/src/pnmimage/pnmImage.cxx b/panda/src/pnmimage/pnmImage.cxx index e7c7a59a2d..6b333703d1 100644 --- a/panda/src/pnmimage/pnmImage.cxx +++ b/panda/src/pnmimage/pnmImage.cxx @@ -939,6 +939,100 @@ lighten_sub_image(const PNMImage ©, int xto, int yto, } } +//////////////////////////////////////////////////////////////////// +// Function: PNMImage::threshold +// Access: Published +// Description: Selectively copies each pixel from either one source +// or another source, depending on the alpha channel of +// alpha_image. +// +// For each pixel (x, y), assigns the corresponding +// pixel (x, y) in this image to: +// +// lt.get_xel(x, y) if alpha_image(x, y).get_alpha() <= +// threshold, or +// +// ge.get_xel(x, y) if alpha_image(x, y).get_alpha() > +// threshold +// +// Any of alpha_image, lt, or ge may be the same PNMImge +// object as this image, or the same as each other; or +// they may all be different. +// +// All images must be the same size. +//////////////////////////////////////////////////////////////////// +void PNMImage:: +threshold(const PNMImage &alpha_image, + const PNMImage <, const PNMImage &ge, + double threshold) { + nassertv(get_x_size() <= alpha_image.get_x_size() && get_y_size() <= alpha_image.get_y_size()); + nassertv(get_x_size() <= lt.get_x_size() && get_y_size() <= lt.get_y_size()); + nassertv(get_x_size() <= ge.get_x_size() && get_y_size() <= ge.get_y_size()); + nassertv(alpha_image.has_alpha()); + + xelval threshold_val = (xelval)(alpha_image.get_maxval() * threshold + 0.5); + + if (get_maxval() == lt.get_maxval() && get_maxval() == ge.get_maxval()) { + // Simple case: the maxvals are all equal. Copy by integer value. + int x, y; + + if (has_alpha() && lt.has_alpha() && ge.has_alpha()) { + // Copy alpha channel too. + for (y = 0; y < get_y_size(); y++) { + for (x = 0; x < get_x_size(); x++) { + if (alpha_image.get_alpha_val(x, y) < threshold_val) { + set_xel_val(x, y, lt.get_xel_val(x, y)); + set_alpha_val(x, y, lt.get_alpha_val(x, y)); + } else { + set_xel_val(x, y, ge.get_xel_val(x, y)); + set_alpha_val(x, y, ge.get_alpha_val(x, y)); + } + } + } + + } else { + // Don't copy alpha channel. + for (y = 0; y < get_y_size(); y++) { + for (x = 0; x < get_x_size(); x++) { + if (alpha_image.get_alpha_val(x, y) < threshold_val) { + set_xel_val(x, y, lt.get_xel_val(x, y)); + } else { + set_xel_val(x, y, ge.get_xel_val(x, y)); + } + } + } + } + + } else { + // General case: the maxvals are different. Copy by floating-point value. + int x, y; + + if (has_alpha() && lt.has_alpha() && ge.has_alpha()) { + for (y = 0; y < get_y_size(); y++) { + for (x = 0; x < get_x_size(); x++) { + if (alpha_image.get_alpha_val(x, y) < threshold_val) { + set_xel(x, y, lt.get_xel(x, y)); + set_alpha(x, y, lt.get_alpha(x, y)); + } else { + set_xel(x, y, ge.get_xel(x, y)); + set_alpha(x, y, ge.get_alpha(x, y)); + } + } + } + } else { + for (y = 0; y < get_y_size(); y++) { + for (x = 0; x < get_x_size(); x++) { + if (alpha_image.get_alpha_val(x, y) < threshold_val) { + set_xel(x, y, lt.get_xel(x, y)); + } else { + set_xel(x, y, ge.get_xel(x, y)); + } + } + } + } + } +} + //////////////////////////////////////////////////////////////////// // Function: PNMImage::copy_channel // Access: Published diff --git a/panda/src/pnmimage/pnmImage.h b/panda/src/pnmimage/pnmImage.h index dcebaaebc7..6465e1155b 100644 --- a/panda/src/pnmimage/pnmImage.h +++ b/panda/src/pnmimage/pnmImage.h @@ -206,6 +206,10 @@ PUBLISHED: int xfrom = 0, int yfrom = 0, int x_size = -1, int y_size = -1, double pixel_scale = 1.0); + void threshold(const PNMImage &alpha_image, + const PNMImage <, const PNMImage &ge, + double threshold); + void copy_channel(const PNMImage ©, int xto, int yto, int cto, int xfrom = 0, int yfrom = 0, int cfrom = 0, int x_size = -1, int y_size = -1);