diff options
| -rwxr-xr-x | indra/integration_tests/llimage_libtest/llimage_libtest.cpp | 66 | ||||
| -rwxr-xr-x | indra/llimage/llimage.cpp | 118 | ||||
| -rwxr-xr-x | indra/llimage/llimage.h | 24 | 
3 files changed, 111 insertions, 97 deletions
| diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 58d7f53dd1..6045ed321d 100755 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -687,73 +687,85 @@ int main(int argc, char** argv)          }          else if (filter_name == "gamma")          { -            raw_image->filterGamma((float)(filter_param)); +            raw_image->filterGamma((float)(filter_param),LLColor3::white);          }          else if (filter_name == "colorize")          { -            // For testing, we just colorize in red, modulate by the alpha passed as a parameter -            LLColor4U color = LLColor4U::red; -            color.setAlpha((U8)(filter_param * 255.0)); -            raw_image->filterColorize(color); +            // For testing, we just colorize in the red channel, modulate by the alpha passed as a parameter +            LLColor3 color(1.0,0.0,0.0); +            LLColor3 alpha((F32)(filter_param),0.0,0.0); +            raw_image->filterColorize(color,alpha);          }          else if (filter_name == "contrast")          { -            raw_image->filterContrast((float)(filter_param)); +            raw_image->filterContrast((float)(filter_param),LLColor3::white);          }          else if (filter_name == "brighten")          { -            raw_image->filterBrightness((S32)(filter_param)); +            raw_image->filterBrightness((S32)(filter_param),LLColor3::white);          }          else if (filter_name == "darken")          { -            raw_image->filterBrightness((S32)(-filter_param)); +            raw_image->filterBrightness((S32)(-filter_param),LLColor3::white);          }          else if (filter_name == "linearize")          { -            raw_image->filterLinearize((float)(filter_param)); +            raw_image->filterLinearize((float)(filter_param),LLColor3::white);          }          else if (filter_name == "posterize")          { -            raw_image->filterEqualize((S32)(filter_param)); +            raw_image->filterEqualize((S32)(filter_param),LLColor3::white);          }          // Test for some "a la Instagram" filters          else if (filter_name == "Lomofi")          {              raw_image->setVignette(VIGNETTE_MODE_BLEND,4.0,0.0); -            raw_image->filterLinearize(0.2); +            raw_image->filterLinearize(0.2,LLColor3::white); +            raw_image->filterBrightness(20,LLColor3::white); +        } +        else if (filter_name == "Poprocket") +        { +            LLColor3 color(1.0,0.0,0.0); +            LLColor3 alpha(0.5,0.0,0.0); +            raw_image->filterLinearize(0.0,LLColor3::white); +            raw_image->filterContrast(0.5,LLColor3::white); +            raw_image->setVignette(VIGNETTE_MODE_FADE,4.0,0.5); +            raw_image->filterColorize(color,alpha);          }          else if (filter_name == "Sutro")          { -            raw_image->filterLinearize(0.2); +            raw_image->filterLinearize(0.2,LLColor3::white);              raw_image->setVignette(VIGNETTE_MODE_FADE,4.0,0.5);              raw_image->filterSepia();          } +        else if (filter_name == "Toaster") +        { +            raw_image->filterContrast(0.8,LLColor3::white); +            raw_image->setVignette(VIGNETTE_MODE_FADE,4.0,0.5); +            raw_image->filterBrightness(10,LLColor3::white); +            //raw_image->filterColorBalance(0.5,1.0,1.0); +        }          else if (filter_name == "Inkwell")          { -            raw_image->filterLinearize(0.0); +            raw_image->filterLinearize(0.0,LLColor3::white);              raw_image->filterGrayScale();          } -        else if (filter_name == "Poprocket") +        else if (filter_name == "Hefe")          { -            LLColor4U color = LLColor4U::red; -            color.setAlpha((U8)(0.2 * 255.0)); -            raw_image->filterLinearize(0.0); +            raw_image->filterLinearize(0.0,LLColor3::white);              raw_image->setVignette(VIGNETTE_MODE_FADE,4.0,0.5); -            raw_image->filterColorize(color); +            raw_image->filterContrast(1.5,LLColor3::white);          }          else if (filter_name == "Gotham")          { -            raw_image->filterLinearize(0.0); -            raw_image->filterColorBalance(1.0,1.0,20.0); +            raw_image->filterLinearize(0.0,LLColor3::white); +            // Blow out the Blue +            LLColor3 color(0.0,0.0,0.0); +            LLColor3 alpha(0.0,0.0,1.0); +            raw_image->filterColorize(color,alpha); +            // Convert to Grayscale              raw_image->filterGrayScale();          } -        else if (filter_name == "Toaster") -        { -            raw_image->filterContrast(0.8); -            raw_image->setVignette(VIGNETTE_MODE_FADE,4.0,0.5); -            raw_image->filterBrightness(10); -            raw_image->filterColorBalance(0.5,1.0,1.0); -        }  		// Save file  		if (out_file != out_end) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 3d86abb26d..977bb09b63 100755 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -29,6 +29,7 @@  #include "llimage.h"  #include "llmath.h" +#include "v3color.h"  #include "v4coloru.h"  #include "m3math.h"  #include "v3math.h" @@ -1033,19 +1034,7 @@ 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); -} - -void LLImageRaw::filterColorBalance(F32 gamma_red, F32 gamma_green, F32 gamma_blue) +void LLImageRaw::filterGamma(F32 gamma, const LLColor3& alpha)  {      U8 gamma_red_lut[256];      U8 gamma_green_lut[256]; @@ -1053,15 +1042,17 @@ void LLImageRaw::filterColorBalance(F32 gamma_red, F32 gamma_green, F32 gamma_bl      for (S32 i = 0; i < 256; i++)      { -        gamma_red_lut[i]   = (U8)(255.0 * (llclampf((float)(pow((float)(i)/255.0,gamma_red))))); -        gamma_green_lut[i] = (U8)(255.0 * (llclampf((float)(pow((float)(i)/255.0,gamma_green))))); -        gamma_blue_lut[i]  = (U8)(255.0 * (llclampf((float)(pow((float)(i)/255.0,gamma_blue))))); +        F32 gamma_i = llclampf((float)(pow((float)(i)/255.0,gamma))); +        // Blend in with alpha values +        gamma_red_lut[i]   = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * 255.0 * gamma_i); +        gamma_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * 255.0 * gamma_i); +        gamma_blue_lut[i]  = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * 255.0 * gamma_i);      }      colorCorrect(gamma_red_lut,gamma_green_lut,gamma_blue_lut);  } -void LLImageRaw::filterLinearize(F32 tail) +void LLImageRaw::filterLinearize(F32 tail, const LLColor3& alpha)  {      // Get the histogram      U32* histo = getBrightnessHistogram(); @@ -1093,13 +1084,19 @@ void LLImageRaw::filterLinearize(F32 tail)      }      // Compute linear lookup table -    U8 linear_lut[256]; +    U8 linear_red_lut[256]; +    U8 linear_green_lut[256]; +    U8 linear_blue_lut[256];      if (max_v == min_v)      {          // Degenerated binary split case          for (S32 i = 0; i < 256; i++)          { -            linear_lut[i] = (i < min_v ? 0 : 255); +            U8 value_i = (i < min_v ? 0 : 255); +            // Blend in with alpha values +            linear_red_lut[i]   = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i); +            linear_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i); +            linear_blue_lut[i]  = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);          }      }      else @@ -1109,15 +1106,19 @@ void LLImageRaw::filterLinearize(F32 tail)          F32 translate = -min_v * slope;          for (S32 i = 0; i < 256; i++)          { -            linear_lut[i] = (U8)(llclampb((S32)(slope*i + translate))); +            U8 value_i = (U8)(llclampb((S32)(slope*i + translate))); +            // Blend in with alpha values +            linear_red_lut[i]   = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i); +            linear_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i); +            linear_blue_lut[i]  = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);          }      }      // Apply lookup table -    colorCorrect(linear_lut,linear_lut,linear_lut);     +    colorCorrect(linear_red_lut,linear_green_lut,linear_blue_lut);  } -void LLImageRaw::filterEqualize(S32 nb_classes) +void LLImageRaw::filterEqualize(S32 nb_classes, const LLColor3& alpha)  {      // Regularize the parameter: must be between 2 and 255      nb_classes = llmax(nb_classes,2); @@ -1142,10 +1143,15 @@ void LLImageRaw::filterEqualize(S32 nb_classes)      S32 current_value = 0;      // Compute equalized lookup table -    U8 equalize_lut[256]; +    U8 equalize_red_lut[256]; +    U8 equalize_green_lut[256]; +    U8 equalize_blue_lut[256];      for (S32 i = 0; i < 256; i++)      { -        equalize_lut[i] = (U8)(current_value); +        // Blend in current_value with alpha values +        equalize_red_lut[i]   = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * current_value); +        equalize_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * current_value); +        equalize_blue_lut[i]  = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * current_value);          if (cumulated_histo[i] >= current_count)          {              current_count += delta_count; @@ -1155,73 +1161,65 @@ void LLImageRaw::filterEqualize(S32 nb_classes)      }      // Apply lookup table -    colorCorrect(equalize_lut,equalize_lut,equalize_lut); +    colorCorrect(equalize_red_lut,equalize_green_lut,equalize_blue_lut);  } -void LLImageRaw::filterColorize(const LLColor4U& color) +void LLImageRaw::filterColorize(const LLColor3& color, const LLColor3& alpha)  {      U8 red_lut[256];      U8 green_lut[256];      U8 blue_lut[256]; -    F32 alpha = (F32)(color.mV[3])/255.0; -    F32 inv_alpha = 1.0 - alpha; -     -    F32 red_composite   =  alpha * (F32)(color.mV[0]); -    F32 green_composite =  alpha * (F32)(color.mV[1]); -    F32 blue_composite  =  alpha * (F32)(color.mV[2]); +    F32 red_composite   =  255.0 * alpha.mV[0] * color.mV[0]; +    F32 green_composite =  255.0 * alpha.mV[1] * color.mV[1]; +    F32 blue_composite  =  255.0 * alpha.mV[2] * color.mV[2];      for (S32 i = 0; i < 256; i++)      { -        red_lut[i]   = (U8)(llclampb((S32)(inv_alpha*(F32)(i) + red_composite))); -        green_lut[i] = (U8)(llclampb((S32)(inv_alpha*(F32)(i) + green_composite))); -        blue_lut[i]  = (U8)(llclampb((S32)(inv_alpha*(F32)(i) + blue_composite))); +        red_lut[i]   = (U8)(llclampb((S32)((1.0 - alpha.mV[0]) * (F32)(i) + red_composite))); +        green_lut[i] = (U8)(llclampb((S32)((1.0 - alpha.mV[1]) * (F32)(i) + green_composite))); +        blue_lut[i]  = (U8)(llclampb((S32)((1.0 - alpha.mV[2]) * (F32)(i) + blue_composite)));      }      colorCorrect(red_lut,green_lut,blue_lut);  } -void LLImageRaw::filterContrast(F32 slope) +void LLImageRaw::filterContrast(F32 slope, const LLColor3& alpha)  { -    U8 contrast_lut[256]; +    U8 contrast_red_lut[256]; +    U8 contrast_green_lut[256]; +    U8 contrast_blue_lut[256];      F32 translate = 128.0 * (1.0 - slope);      for (S32 i = 0; i < 256; i++)      { -        contrast_lut[i] = (U8)(llclampb((S32)(slope*i + translate))); +        U8 value_i = (U8)(llclampb((S32)(slope*i + translate))); +        // Blend in with alpha values +        contrast_red_lut[i]   = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i); +        contrast_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i); +        contrast_blue_lut[i]  = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);      } -    colorCorrect(contrast_lut,contrast_lut,contrast_lut); +    colorCorrect(contrast_red_lut,contrast_green_lut,contrast_blue_lut);  } -void LLImageRaw::filterBrightness(S32 add) +void LLImageRaw::filterBrightness(S32 add, const LLColor3& alpha)  { -    U8 brightness_lut[256]; -     -    for (S32 i = 0; i < 256; i++) -    { -        brightness_lut[i] = (U8)(llclampb((S32)((S32)(i) + add))); -    } -     -    colorCorrect(brightness_lut,brightness_lut,brightness_lut); -} - -void LLImageRaw::filterMinMax(S32 min, S32 max) -{ -    U8 contrast_lut[256]; -    min = llclampb(min); -    max = llclampb(max); -     -    F32 slope = 255.0/(F32)(max - min); -    F32 translate = -slope*min; +    U8 brightness_red_lut[256]; +    U8 brightness_green_lut[256]; +    U8 brightness_blue_lut[256];      for (S32 i = 0; i < 256; i++)      { -        contrast_lut[i] = (U8)(llclampb((S32)(slope*i + translate))); +        U8 value_i = (U8)(llclampb((S32)((S32)(i) + add))); +        // Blend in with alpha values +        brightness_red_lut[i]   = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i); +        brightness_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i); +        brightness_blue_lut[i]  = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);      } -    colorCorrect(contrast_lut,contrast_lut,contrast_lut);     +    colorCorrect(brightness_red_lut,brightness_green_lut,brightness_blue_lut);  }  // Filter Primitives diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 6e58453da5..cc91f95624 100755 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -71,6 +71,7 @@ const S32 HTTP_PACKET_SIZE = 1496;  class LLImageFormatted;  class LLImageRaw;  class LLColor4U; +class LLColor3;  class LLMatrix3;  class LLPrivateMemoryPool; @@ -278,19 +279,22 @@ public:  	// Src and dst are same size.  Src has 4 components.  Dst has 3 components.  	void compositeUnscaled4onto3( LLImageRaw* src ); -    // Filter Operations +    // Filter Operations : Transforms      void filterGrayScale();                         // Convert to grayscale      void filterSepia();                             // Convert to sepia      void filterSaturate(F32 saturation);            // < 1.0 desaturates, > 1.0 saturates -    void filterRotate(F32 alpha);                   // Rotates hue according to alpha, alpha in degrees -    void filterGamma(F32 gamma);                    // Apply gamma to all channels -    void filterLinearize(F32 tail);                 // Use histogram to linearize constrast between min and max values minus tail -    void filterEqualize(S32 nb_classes);            // Use histogram to equalize constrast throughout the image -    void filterColorize(const LLColor4U& color);    // Colorize with color. Alpha will be taken into account for colorization intensity. -    void filterContrast(F32 slope);                 // Change contrast according to slope: > 1.0 more contrast, < 1.0 less contrast -    void filterBrightness(S32 add);                 // Change brightness according to add: > 0 brighter, < 0 darker -    void filterColorBalance(F32 gamma_red, F32 gamma_green, F32 gamma_blue); // Change the color balance applying gammas to each channel -    void filterMinMax(S32 min, S32 max);            // Redistribute contrast / brightness between min and max in a linear way +    void filterRotate(F32 alpha);                   // Rotates hue according to alpha, alpha is an angle in degrees +     +    // Filter Operations : Color Corrections +    // When specified, the LLColor3 alpha parameter indicates the intensity of the effect for each color channel +    // acting in effect as an alpha blending factor different for each channel. For instance (1.0,0.0,0.0) will apply +    // the effect only to the Red channel. Intermediate values blends the effect with the source color. +    void filterGamma(F32 gamma, const LLColor3& alpha);         // Apply gamma to each channel +    void filterLinearize(F32 tail, const LLColor3& alpha);      // Use histogram to linearize constrast between min and max values minus tail +    void filterEqualize(S32 nb_classes, const LLColor3& alpha); // Use histogram to equalize constrast between nb_classes throughout the image +    void filterColorize(const LLColor3& color, const LLColor3& alpha);  // Colorize with color and alpha per channel +    void filterContrast(F32 slope, const LLColor3& alpha);      // Change contrast according to slope: > 1.0 more contrast, < 1.0 less contrast +    void filterBrightness(S32 add, const LLColor3& alpha);      // Change brightness according to add: > 0 brighter, < 0 darker      // Filter Primitives      void colorTransform(const LLMatrix3 &transform); | 
