diff options
author | Merov Linden <merov@lindenlab.com> | 2014-01-01 19:42:10 -0800 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2014-01-01 19:42:10 -0800 |
commit | 205a4e3dc63c338c05e27a4806cdfd6f50bac2b6 (patch) | |
tree | cb035348ac77061d7278d509a3814ca7d0e48b01 /indra | |
parent | 9dca514c0b416c1b15e9a63e6f5af1b52df70b7e (diff) |
ACME-1236 : WIP : add filterGamma, computeHistograms, colorCorrect, implemented filter gamma to llimage_libtest for testing
Diffstat (limited to 'indra')
-rwxr-xr-x | indra/integration_tests/llimage_libtest/llimage_libtest.cpp | 4 | ||||
-rwxr-xr-x | indra/llimage/llimage.cpp | 92 | ||||
-rwxr-xr-x | indra/llimage/llimage.h | 11 |
3 files changed, 103 insertions, 4 deletions
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 1f9a5f0e18..afd5e2ce98 100755 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -622,6 +622,10 @@ int main(int argc, char** argv) { raw_image->filterRotate((float)(filter_param)); } + else if (filter_name == "gamma") + { + raw_image->filterGamma((float)(filter_param)); + } // Save file if (out_file != out_end) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 8b7c352437..d406995f3a 100755 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -97,7 +97,11 @@ LLImageBase::LLImageBase() mHeight(0), mComponents(0), mBadBufferAllocation(false), - mAllowOverSize(false) + mAllowOverSize(false), + mHistoRed(NULL), + mHistoGreen(NULL), + mHistoBlue(NULL), + mHistoBrightness(NULL) { } @@ -105,10 +109,14 @@ LLImageBase::LLImageBase() LLImageBase::~LLImageBase() { deleteData(); // virtual + ll_aligned_free_16(mHistoRed); + ll_aligned_free_16(mHistoGreen); + ll_aligned_free_16(mHistoBlue); + ll_aligned_free_16(mHistoBrightness); } -//static -void LLImageBase::createPrivatePool() +//static +void LLImageBase::createPrivatePool() { if(!sPrivatePoolp) { @@ -1022,6 +1030,18 @@ void LLImageRaw::filterRotate(F32 alpha) colorTransform(transfo); } +void LLImageRaw::filterGamma(F32 gamma) +{ + U8 gamma_lut[256]; + + for (S32 i = 0; i < 256; i++) + { + gamma_lut[i] = (U8)(255.0 * (llclampf((float)(pow((float)(i)/255.0,gamma))))); + } + + colorCorrect(gamma_lut,gamma_lut,gamma_lut); +} + // Filter Primitives void LLImageRaw::colorTransform(const LLMatrix3 &transform) { @@ -1030,7 +1050,7 @@ void LLImageRaw::colorTransform(const LLMatrix3 &transform) S32 pixels = getWidth() * getHeight(); U8* dst_data = getData(); - for( S32 i=0; i<pixels; i++ ) + for (S32 i = 0; i < pixels; i++) { LLVector3 src((F32)(dst_data[VRED]),(F32)(dst_data[VGREEN]),(F32)(dst_data[VBLUE])); LLVector3 dst = src * transform; @@ -1042,6 +1062,70 @@ void LLImageRaw::colorTransform(const LLMatrix3 &transform) } } +void LLImageRaw::colorCorrect(const U8* lut_red, const U8* lut_green, const U8* lut_blue) +{ + const S32 components = getComponents(); + llassert( components >= 1 && components <= 4 ); + + S32 pixels = getWidth() * getHeight(); + U8* dst_data = getData(); + for (S32 i = 0; i < pixels; i++) + { + 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; + } +} + +void LLImageRaw::computeHistograms() +{ + const S32 components = getComponents(); + llassert( components >= 1 && components <= 4 ); + + // Allocate memory for the histograms + if (!mHistoRed) + { + mHistoRed = (U32*) ll_aligned_malloc_16(256*sizeof(U32)); + } + if (!mHistoGreen) + { + mHistoGreen = (U32*) ll_aligned_malloc_16(256*sizeof(U32)); + } + if (!mHistoBlue) + { + mHistoBlue = (U32*) ll_aligned_malloc_16(256*sizeof(U32)); + } + if (!mHistoBrightness) + { + mHistoBrightness = (U32*) ll_aligned_malloc_16(256*sizeof(U32)); + } + + // Initialize them + for (S32 i = 0; i < 256; i++) + { + mHistoRed[i] = 0; + mHistoGreen[i] = 0; + mHistoBlue[i] = 0; + mHistoBrightness[i] = 0; + } + + // Compute them + S32 pixels = getWidth() * getHeight(); + U8* dst_data = getData(); + for (S32 i = 0; i < pixels; i++) + { + mHistoRed[dst_data[VRED]]++; + mHistoGreen[dst_data[VGREEN]]++; + mHistoBlue[dst_data[VBLUE]]++; + // Note: this is a very simple shorthand for brightness but it's OK for our use + S32 brightness = ((S32)(dst_data[VRED]) + (S32)(dst_data[VGREEN]) + (S32)(dst_data[VBLUE])) / 3; + mHistoBrightness[brightness]++; + // next pixel... + dst_data += components; + } +} + void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ) { const S32 components = getComponents(); diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 3a9c088dbd..89734693cc 100755 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -151,6 +151,12 @@ protected: // special accessor to allow direct setting of mData and mDataSize by LLImageFormatted void setDataAndSize(U8 *data, S32 size); + // Histograms (if we ever happen to need them) + U32 *mHistoRed; + U32 *mHistoGreen; + U32 *mHistoBlue; + U32 *mHistoBrightness; + public: static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels); @@ -262,8 +268,11 @@ public: void filterSepia(); void filterSaturate(F32 saturation); // < 1.0 desaturates, > 1.0 saturates void filterRotate(F32 alpha); // rotates hue, alpha in degrees + void filterGamma(F32 gamma); // Apply a gamma lookup to all channels + // Filter Primitives void colorTransform(const LLMatrix3 &transform); + void colorCorrect(const U8* lut_red, const U8* lut_green, const U8* lut_blue); protected: // Create an image from a local file (generally used in tools) @@ -276,6 +285,8 @@ protected: void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ; + void computeHistograms(); + public: static S32 sGlobalRawMemory; static S32 sRawImageCount; |