diff options
Diffstat (limited to 'indra')
| -rwxr-xr-x | indra/integration_tests/llimage_libtest/llimage_libtest.cpp | 47 | ||||
| -rwxr-xr-x | indra/llimage/llimage.cpp | 106 | ||||
| -rwxr-xr-x | indra/llimage/llimage.h | 16 | 
3 files changed, 152 insertions, 17 deletions
| diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 4d32282a0d..45e60f64e6 100755 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -97,6 +97,10 @@ static const char USAGE[] = "\n"  "        - 'darken' substracts <param> light to the image (<param> between 0 and 255).\n"  "        - 'linearize' optimizes the contrast using the brightness histogram. <param> is the fraction (between 0.0 and 1.0) of discarded tail of the histogram.\n"  "        - 'posterize' redistributes the colors between <param> classes per channel (<param> between 2 and 255).\n" +" -v, --vignette <name> [<feather>]\n" +"        Apply a circular central vignette <name> to the filter using the optional <feather> value. Admissible names:\n" +"        - 'blend' : the filter is applied with full intensity in the center and blends with the image to the periphery.\n" +"        - 'fade' : the filter is applied with full intensity in the center and fades to black to the periphery.\n"  " -log, --logmetrics <metric>\n"  "        Log performance data for <metric>. Results in <metric>.slp\n"  "        Note: so far, only ImageCompressionTester has been tested.\n" @@ -366,6 +370,8 @@ int main(int argc, char** argv)  	bool reversible = false;      std::string filter_name = "";      double filter_param = 0.0; +    std::string vignette_name = ""; +    double vignette_param = 1.0;  	// Init whatever is necessary  	ll_init_apr(); @@ -568,7 +574,36 @@ int main(int argc, char** argv)                 }              }  		} -		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a")) +		else if (!strcmp(argv[arg], "--vignette") || !strcmp(argv[arg], "-v")) +		{ +			// '--vignette' needs to be specified with a named vignette argument +			if ((arg + 1) < argc) +			{ +				vignette_name = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (vignette_name[0] == '-')) +			{ +				// We don't have an argument left in the arg list or the next argument is another option +				std::cout << "No --vignette argument given, no vignette will be applied to filters" << std::endl; +			} +			else +			{ +				arg += 1;					// Skip that arg now we know it's a valid vignette name +				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +					break; +                // --vignette can also have an optional parameter +                std::string value_str; +                value_str = argv[arg+1];    // Check the next arg +                if (value_str[0] != '-')    // If it's not another argument, it's a vignette parameter value +                { +                    vignette_param = atof(value_str.c_str()); +                    arg += 1;					// Skip that arg now we used it as a valid vignette param +                    if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +                        break; +                } +            } +		} +        else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a"))  		{  			analyze_performance = true;  		} @@ -614,6 +649,16 @@ int main(int argc, char** argv)  			continue;  		} +        // Set the vignette if any +        if (vignette_name == "blend") +        { +            raw_image->setVignette(VIGNETTE_MODE_BLEND,(float)(vignette_param)); +        } +        else if (vignette_name == "fade") +        { +            raw_image->setVignette(VIGNETTE_MODE_FADE,(float)(vignette_param)); +        } +                  // Apply filter if any          if (filter_name == "sepia")          { 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; | 
