mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
PNMImage::gamma_correct()
This commit is contained in:
parent
425fa2608e
commit
003aa9e3dd
@ -145,6 +145,16 @@ cmod(float x, float y) {
|
||||
return x - cfloor(x / y) * y;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: cpow
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float
|
||||
cpow(float x, float y) {
|
||||
return powf(x, y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: cfloor
|
||||
// Description:
|
||||
@ -317,6 +327,15 @@ cmod(double x, double y) {
|
||||
return x - cfloor(x / y) * y;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: cpow
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double
|
||||
cpow(double x, double y) {
|
||||
return pow(x, y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: cnan
|
||||
// Description:
|
||||
|
@ -43,6 +43,7 @@ INLINE float catan2(float y, float x);
|
||||
INLINE float casin(float v);
|
||||
INLINE float cacos(float v);
|
||||
INLINE float cmod(float x, float y);
|
||||
INLINE float cpow(float x, float y);
|
||||
|
||||
INLINE double cfloor(double f);
|
||||
INLINE double cceil(double f);
|
||||
@ -58,6 +59,7 @@ INLINE double catan2(double y, double x);
|
||||
INLINE double casin(double v);
|
||||
INLINE double cacos(double v);
|
||||
INLINE double cmod(double x, double y);
|
||||
INLINE double cpow(double x, double y);
|
||||
|
||||
// Returns true if the number is nan, false if it's a genuine number
|
||||
// or infinity.
|
||||
|
@ -834,6 +834,71 @@ gaussian_filter(double radius) {
|
||||
gaussian_filter_from(radius, *this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::gamma_correct
|
||||
// Access: Published
|
||||
// Description: Assuming the image was constructed with a gamma curve
|
||||
// of from_gamma in the RGB channels, converts it to an
|
||||
// image with a gamma curve of to_gamma in the RGB
|
||||
// channels. Does not affect the alpha channel.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PNMImage::
|
||||
gamma_correct(double from_gamma, double to_gamma) {
|
||||
apply_exponent(from_gamma / to_gamma);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::gamma_correct_alpha
|
||||
// Access: Published
|
||||
// Description: Assuming the image was constructed with a gamma curve
|
||||
// of from_gamma in the alpha channel, converts it to an
|
||||
// image with a gamma curve of to_gamma in the alpha
|
||||
// channel. Does not affect the RGB channels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PNMImage::
|
||||
gamma_correct_alpha(double from_gamma, double to_gamma) {
|
||||
apply_exponent(1.0, from_gamma / to_gamma);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::apply_exponent
|
||||
// Access: Published
|
||||
// Description: Adjusts each channel of the image by raising the
|
||||
// corresponding component value to the indicated
|
||||
// exponent, such that L' = L ^ exponent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PNMImage::
|
||||
apply_exponent(double gray_exponent) {
|
||||
apply_exponent(gray_exponent, gray_exponent, gray_exponent, 1.0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::apply_exponent
|
||||
// Access: Published
|
||||
// Description: Adjusts each channel of the image by raising the
|
||||
// corresponding component value to the indicated
|
||||
// exponent, such that L' = L ^ exponent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PNMImage::
|
||||
apply_exponent(double gray_exponent, double alpha_exponent) {
|
||||
apply_exponent(gray_exponent, gray_exponent, gray_exponent, alpha_exponent);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::apply_exponent
|
||||
// Access: Published
|
||||
// Description: Adjusts each channel of the image by raising the
|
||||
// corresponding component value to the indicated
|
||||
// exponent, such that L' = L ^ exponent. For a
|
||||
// grayscale image, the blue_exponent value is used for
|
||||
// the grayscale value, and red_exponent and
|
||||
// green_exponent are unused.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PNMImage::
|
||||
apply_exponent(double red_exponent, double green_exponent, double blue_exponent) {
|
||||
apply_exponent(red_exponent, green_exponent, blue_exponent, 1.0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::allocate_array
|
||||
|
@ -226,26 +226,6 @@ alpha_fill_val(xelval alpha) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::remix_channels
|
||||
// Access: Published
|
||||
// Description: Transforms every pixel using the operation
|
||||
// (Ro,Go,Bo) = conv.xform_point(Ri,Gi,Bi);
|
||||
// Input must be a color image.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PNMImage::
|
||||
remix_channels(const LMatrix4 &conv) {
|
||||
int nchannels = get_num_channels();
|
||||
nassertv((nchannels >= 3) && (nchannels <= 4));
|
||||
for (int y = 0; y < get_y_size(); y++) {
|
||||
for (int x = 0; x < get_x_size(); x++) {
|
||||
LVector3 inv(get_red(x,y),get_green(x,y),get_blue(x,y));
|
||||
LVector3 outv(conv.xform_point(inv));
|
||||
set_xel(x,y,outv[0],outv[1],outv[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::read
|
||||
// Access: Published
|
||||
@ -1296,6 +1276,122 @@ perlin_noise_fill(StackedPerlinNoise2 &perlin) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::remix_channels
|
||||
// Access: Published
|
||||
// Description: Transforms every pixel using the operation
|
||||
// (Ro,Go,Bo) = conv.xform_point(Ri,Gi,Bi);
|
||||
// Input must be a color image.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PNMImage::
|
||||
remix_channels(const LMatrix4 &conv) {
|
||||
int nchannels = get_num_channels();
|
||||
nassertv((nchannels >= 3) && (nchannels <= 4));
|
||||
for (int y = 0; y < get_y_size(); y++) {
|
||||
for (int x = 0; x < get_x_size(); x++) {
|
||||
LVector3 inv(get_red(x,y), get_green(x,y), get_blue(x,y));
|
||||
LVector3 outv(conv.xform_point(inv));
|
||||
set_xel(x, y, outv[0], outv[1], outv[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::apply_exponent
|
||||
// Access: Published
|
||||
// Description: Adjusts each channel of the image by raising the
|
||||
// corresponding component value to the indicated
|
||||
// exponent, such that L' = L ^ exponent. For a
|
||||
// grayscale image, the blue_exponent value is used for
|
||||
// the grayscale value, and red_exponent and
|
||||
// green_exponent are unused.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PNMImage::
|
||||
apply_exponent(double red_exponent, double green_exponent, double blue_exponent,
|
||||
double alpha_exponent) {
|
||||
int num_channels = _num_channels;
|
||||
if (has_alpha() && alpha_exponent == 1.0) {
|
||||
// If the alpha_exponent is 1, don't bother to apply it.
|
||||
--num_channels;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
|
||||
if (red_exponent == 1.0 && green_exponent == 1.0 && blue_exponent == 1.0) {
|
||||
// If the RGB components are all 1, apply only to the alpha channel.
|
||||
switch (num_channels) {
|
||||
case 1:
|
||||
case 3:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 4:
|
||||
for (y = 0; y < _y_size; ++y) {
|
||||
for (x = 0; x < _x_size; ++x) {
|
||||
double alpha = get_alpha(x, y);
|
||||
alpha = cpow(alpha, blue_exponent);
|
||||
set_alpha(x, y, alpha);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Apply to the color and/or alpha channels.
|
||||
|
||||
switch (num_channels) {
|
||||
case 1:
|
||||
for (y = 0; y < _y_size; ++y) {
|
||||
for (x = 0; x < _x_size; ++x) {
|
||||
double gray = get_gray(x, y);
|
||||
gray = cpow(gray, blue_exponent);
|
||||
set_gray(x, y, gray);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (y = 0; y < _y_size; ++y) {
|
||||
for (x = 0; x < _x_size; ++x) {
|
||||
double gray = get_gray(x, y);
|
||||
gray = cpow(gray, blue_exponent);
|
||||
set_gray(x, y, gray);
|
||||
|
||||
double alpha = get_alpha(x, y);
|
||||
alpha = cpow(alpha, blue_exponent);
|
||||
set_alpha(x, y, alpha);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
for (y = 0; y < _y_size; ++y) {
|
||||
for (x = 0; x < _x_size; ++x) {
|
||||
LRGBColord color = get_xel(x, y);
|
||||
color[0] = cpow(color[0], red_exponent);
|
||||
color[1] = cpow(color[1], green_exponent);
|
||||
color[2] = cpow(color[2], blue_exponent);
|
||||
set_xel(x, y, color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for (y = 0; y < _y_size; ++y) {
|
||||
for (x = 0; x < _x_size; ++x) {
|
||||
LColord color = get_xel_a(x, y);
|
||||
color[0] = cpow(color[0], red_exponent);
|
||||
color[1] = cpow(color[1], green_exponent);
|
||||
color[2] = cpow(color[2], blue_exponent);
|
||||
color[3] = cpow(color[3], alpha_exponent);
|
||||
set_xel_a(x, y, color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMImage::setup_rc
|
||||
// Access: Private
|
||||
|
@ -81,8 +81,6 @@ PUBLISHED:
|
||||
INLINE void fill(double red, double green, double blue);
|
||||
INLINE void fill(double gray = 0.0);
|
||||
|
||||
void remix_channels(const LMatrix4 &conv);
|
||||
|
||||
void fill_val(xelval red, xelval green, xelval blue);
|
||||
INLINE void fill_val(xelval gray = 0);
|
||||
|
||||
@ -236,6 +234,14 @@ PUBLISHED:
|
||||
unsigned long seed = 0);
|
||||
void perlin_noise_fill(StackedPerlinNoise2 &perlin);
|
||||
|
||||
void remix_channels(const LMatrix4 &conv);
|
||||
INLINE void gamma_correct(double from_gamma, double to_gamma);
|
||||
INLINE void gamma_correct_alpha(double from_gamma, double to_gamma);
|
||||
INLINE void apply_exponent(double gray_exponent);
|
||||
INLINE void apply_exponent(double gray_exponent, double alpha_exponent);
|
||||
INLINE void apply_exponent(double red_exponent, double green_exponent, double blue_exponent);
|
||||
void apply_exponent(double red_exponent, double green_exponent, double blue_exponent, double alpha_exponent);
|
||||
|
||||
LRGBColord get_average_xel() const;
|
||||
LColord get_average_xel_a() const;
|
||||
double get_average_gray() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user