diff options
author | Merov Linden <merov@lindenlab.com> | 2014-01-03 14:19:29 -0800 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2014-01-03 14:19:29 -0800 |
commit | 1b5fb662927ac84606cf767c8c9ec350e82b656f (patch) | |
tree | 9a0afe54bfa84d390f88be17da841f156b9e0a52 /indra/llimage | |
parent | d28b92744ee0d4a19a5587585998e5c351f6d300 (diff) |
ACME-1236 : WIP : Added the vignette mode. Can be applied to colorCorrect and color Transform. Added new -v argument to llimage_libtest
Diffstat (limited to 'indra/llimage')
-rwxr-xr-x | indra/llimage/llimage.cpp | 106 | ||||
-rwxr-xr-x | indra/llimage/llimage.h | 16 |
2 files changed, 106 insertions, 16 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 5dc9c24f6c..da22ed5e5b 100755 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -101,7 +101,9 @@ LLImageBase::LLImageBase() mHistoRed(NULL), mHistoGreen(NULL), mHistoBlue(NULL), - mHistoBrightness(NULL) + mHistoBrightness(NULL), + mVignetteMode(VIGNETTE_MODE_NONE), + mVignetteGamma(1.0) { } @@ -1194,17 +1196,44 @@ void LLImageRaw::colorTransform(const LLMatrix3 &transform) const S32 components = getComponents(); llassert( components >= 1 && components <= 4 ); - S32 pixels = getWidth() * getHeight(); + S32 width = getWidth(); + S32 height = getHeight(); + U8* dst_data = getData(); - for (S32 i = 0; i < pixels; i++) + for (S32 j = 0; j < height; j++) { - LLVector3 src((F32)(dst_data[VRED]),(F32)(dst_data[VGREEN]),(F32)(dst_data[VBLUE])); - LLVector3 dst = src * transform; - dst.clamp(0.0f,255.0f); - dst_data[VRED] = dst.mV[VRED]; - dst_data[VGREEN] = dst.mV[VGREEN]; - dst_data[VBLUE] = dst.mV[VBLUE]; - dst_data += components; + for (S32 i = 0; i < width; i++) + { + LLVector3 src((F32)(dst_data[VRED]),(F32)(dst_data[VGREEN]),(F32)(dst_data[VBLUE])); + LLVector3 dst = src * transform; + dst.clamp(0.0f,255.0f); + if (mVignetteMode == VIGNETTE_MODE_NONE) + { + dst_data[VRED] = dst.mV[VRED]; + dst_data[VGREEN] = dst.mV[VGREEN]; + dst_data[VBLUE] = dst.mV[VBLUE]; + } + else + { + F32 alpha = getVignetteAlpha(i,j); + if (mVignetteMode == VIGNETTE_MODE_BLEND) + { + // Blends with the source image on the edges + F32 inv_alpha = 1.0 - alpha; + dst_data[VRED] = inv_alpha * src.mV[VRED] + alpha * dst.mV[VRED]; + dst_data[VGREEN] = inv_alpha * src.mV[VGREEN] + alpha * dst.mV[VGREEN]; + dst_data[VBLUE] = inv_alpha * src.mV[VBLUE] + alpha * dst.mV[VBLUE]; + } + else // VIGNETTE_MODE_FADE + { + // Fade to black on the edges + dst_data[VRED] = alpha * dst.mV[VRED]; + dst_data[VGREEN] = alpha * dst.mV[VGREEN]; + dst_data[VBLUE] = alpha * dst.mV[VBLUE]; + } + } + dst_data += components; + } } } @@ -1213,17 +1242,62 @@ void LLImageRaw::colorCorrect(const U8* lut_red, const U8* lut_green, const U8* const S32 components = getComponents(); llassert( components >= 1 && components <= 4 ); - S32 pixels = getWidth() * getHeight(); + S32 width = getWidth(); + S32 height = getHeight(); + U8* dst_data = getData(); - for (S32 i = 0; i < pixels; i++) + for (S32 j = 0; j < height; j++) { - dst_data[VRED] = lut_red[dst_data[VRED]]; - dst_data[VGREEN] = lut_green[dst_data[VGREEN]]; - dst_data[VBLUE] = lut_blue[dst_data[VBLUE]]; - dst_data += components; + for (S32 i = 0; i < width; i++) + { + if (mVignetteMode == VIGNETTE_MODE_NONE) + { + dst_data[VRED] = lut_red[dst_data[VRED]]; + dst_data[VGREEN] = lut_green[dst_data[VGREEN]]; + dst_data[VBLUE] = lut_blue[dst_data[VBLUE]]; + } + else + { + F32 alpha = getVignetteAlpha(i,j); + if (mVignetteMode == VIGNETTE_MODE_BLEND) + { + // Blends with the source image on the edges + F32 inv_alpha = 1.0 - alpha; + dst_data[VRED] = inv_alpha * dst_data[VRED] + alpha * lut_red[dst_data[VRED]]; + dst_data[VGREEN] = inv_alpha * dst_data[VGREEN] + alpha * lut_green[dst_data[VGREEN]]; + dst_data[VBLUE] = inv_alpha * dst_data[VBLUE] + alpha * lut_blue[dst_data[VBLUE]]; + } + else // VIGNETTE_MODE_FADE + { + // Fade to black on the edges + dst_data[VRED] = alpha * lut_red[dst_data[VRED]]; + dst_data[VGREEN] = alpha * lut_green[dst_data[VGREEN]]; + dst_data[VBLUE] = alpha * lut_blue[dst_data[VBLUE]]; + } + } + dst_data += components; + } } } +void LLImageRaw::setVignette(EVignetteMode mode, F32 gamma) +{ + mVignetteMode = mode; + mVignetteGamma = gamma; + // We always center the vignette on the image and fits it in the image smallest dimension + mVignetteCenterX = getWidth()/2; + mVignetteCenterY = getHeight()/2; + mVignetteWidth = llmin(getWidth()/2,getHeight()/2); +} + +F32 LLImageRaw::getVignetteAlpha(S32 i, S32 j) +{ + // alpha is a modified gaussian value, with a center and fading in a circular pattern toward the edges + // the gamma parameter controls the intensity of the drop down from alpha 1.0 to 0.0 + F32 d_center_square = (i - mVignetteCenterX)*(i - mVignetteCenterX) + (j - mVignetteCenterY)*(j - mVignetteCenterY); + return powf(F_E, -(powf((d_center_square/(mVignetteWidth*mVignetteWidth)),mVignetteGamma)/2.0f)); +} + U32* LLImageRaw::getBrightnessHistogram() { if (!mHistoBrightness) diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index b62deadee0..b9f6a12bdd 100755 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -87,6 +87,13 @@ typedef enum e_image_codec IMG_CODEC_EOF = 8 } EImageCodec; +typedef enum e_vignette_mode +{ + VIGNETTE_MODE_NONE = 0, + VIGNETTE_MODE_BLEND = 1, + VIGNETTE_MODE_FADE = 2 +} EVignetteMode; + //============================================================================ // library initialization class @@ -157,6 +164,13 @@ protected: U32 *mHistoBlue; U32 *mHistoBrightness; + // Vignette filtering + EVignetteMode mVignetteMode; + S32 mVignetteCenterX; + S32 mVignetteCenterY; + S32 mVignetteWidth; + F32 mVignetteGamma; + public: static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels); @@ -278,6 +292,7 @@ public: // Filter Primitives void colorTransform(const LLMatrix3 &transform); void colorCorrect(const U8* lut_red, const U8* lut_green, const U8* lut_blue); + void setVignette(EVignetteMode mode, F32 gamma); U32* getBrightnessHistogram(); protected: @@ -292,6 +307,7 @@ protected: void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ; void computeHistograms(); + F32 getVignetteAlpha(S32 i, S32 j); public: static S32 sGlobalRawMemory; |