summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2014-01-01 19:42:10 -0800
committerMerov Linden <merov@lindenlab.com>2014-01-01 19:42:10 -0800
commit205a4e3dc63c338c05e27a4806cdfd6f50bac2b6 (patch)
treecb035348ac77061d7278d509a3814ca7d0e48b01 /indra/llimage
parent9dca514c0b416c1b15e9a63e6f5af1b52df70b7e (diff)
ACME-1236 : WIP : add filterGamma, computeHistograms, colorCorrect, implemented filter gamma to llimage_libtest for testing
Diffstat (limited to 'indra/llimage')
-rwxr-xr-xindra/llimage/llimage.cpp92
-rwxr-xr-xindra/llimage/llimage.h11
2 files changed, 99 insertions, 4 deletions
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;