ACME-1236 : WIP : add filterGamma, computeHistograms, colorCorrect, implemented filter gamma to llimage_libtest for testing

master
Merov Linden 2014-01-01 19:42:10 -08:00
parent 9dca514c0b
commit 205a4e3dc6
3 changed files with 103 additions and 4 deletions

View File

@ -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)

View File

@ -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();

View File

@ -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;