diff options
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; | 
