From 9dca514c0b416c1b15e9a63e6f5af1b52df70b7e Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 1 Jan 2014 17:58:52 -0800
Subject: [PATCH] ACME-1236 : WIP : add filterRotate to rotate hue, add rotate
 as a valid argument to --filter in llimage_libtest

---
 .../llimage_libtest/llimage_libtest.cpp       | 11 +++--
 indra/llimage/llimage.cpp                     | 48 ++++++++++++++++---
 indra/llimage/llimage.h                       |  3 +-
 3 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index d1535bf3cfc..1f9a5f0e18f 100755
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -84,9 +84,10 @@ static const char USAGE[] = "\n"
 "        Set the compression to be lossless (reversible in j2c parlance).\n"
 "        Only valid for output j2c images.\n"
 " -f, --filter <name> [<param>]\n"
-"        Apply the filter <name> to the input images using the optional param (float) value.\n"
-"        Notes: - 'grayscale' and 'sepia' are supported (no param).\n"
-"               - 'saturate' uses the param: param < 1.0 will desaturate the colors, param > 1.0 will saturate them.\n"
+"        Apply the filter <name> to the input images using the optional param (float) value:\n"
+"        - 'grayscale' and 'sepia' just do that (no param).\n"
+"        - 'saturate' changes color saturation according to param: param < 1.0 will desaturate, param > 1.0 will saturate.\n"
+"        - 'rotate' rotates the color hue according to param (in degree, positive value only).\n"
 " -log, --logmetrics <metric>\n"
 "        Log performance data for <metric>. Results in <metric>.slp\n"
 "        Note: so far, only ImageCompressionTester has been tested.\n"
@@ -617,6 +618,10 @@ int main(int argc, char** argv)
         {
             raw_image->filterSaturate((float)(filter_param));
         }
+        else if (filter_name == "rotate")
+        {
+            raw_image->filterRotate((float)(filter_param));
+        }
 	
 		// Save file
 		if (out_file != out_end)
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 40285148983..8b7c352437e 100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -962,13 +962,15 @@ void LLImageRaw::filterSaturate(F32 saturation)
     LLMatrix3 r_b;
 
     // 45 degre rotation around z
-    r_a.setRows(LLVector3(0.7071,  0.7071, 0.0),
-                LLVector3(-0.7071,  0.7071, 0.0),
-                LLVector3(0.0,     0.0,    1.0));
+    r_a.setRows(LLVector3( OO_SQRT2,  OO_SQRT2, 0.0),
+                LLVector3(-OO_SQRT2,  OO_SQRT2, 0.0),
+                LLVector3( 0.0,       0.0,      1.0));
     // 54.73 degre rotation around y
-    r_b.setRows(LLVector3(0.5773,  0.0, -0.8165),
-                LLVector3(0.0,     1.0,  0.0),
-                LLVector3(0.8165,  0.0,  0.5773));
+    float oo_sqrt3 = 1.0f / F_SQRT3;
+    float sin_54 = F_SQRT2 * oo_sqrt3;
+    r_b.setRows(LLVector3(oo_sqrt3, 0.0, -sin_54),
+                LLVector3(0.0,      1.0,  0.0),
+                LLVector3(sin_54,   0.0,  oo_sqrt3));
 
     // Coordinate conversion
     LLMatrix3 Lij = r_b * r_a;
@@ -986,6 +988,40 @@ void LLImageRaw::filterSaturate(F32 saturation)
     colorTransform(transfo);
 }
 
+void LLImageRaw::filterRotate(F32 alpha)
+{
+    // Matrix to Lij
+    LLMatrix3 r_a;
+    LLMatrix3 r_b;
+    
+    // 45 degre rotation around z
+    r_a.setRows(LLVector3( OO_SQRT2,  OO_SQRT2, 0.0),
+                LLVector3(-OO_SQRT2,  OO_SQRT2, 0.0),
+                LLVector3( 0.0,       0.0,      1.0));
+    // 54.73 degre rotation around y
+    float oo_sqrt3 = 1.0f / F_SQRT3;
+    float sin_54 = F_SQRT2 * oo_sqrt3;
+    r_b.setRows(LLVector3(oo_sqrt3, 0.0, -sin_54),
+                LLVector3(0.0,      1.0,  0.0),
+                LLVector3(sin_54,   0.0,  oo_sqrt3));
+    
+    // Coordinate conversion
+    LLMatrix3 Lij = r_b * r_a;
+    LLMatrix3 Lij_inv = Lij;
+    Lij_inv.transpose();
+    
+    // Local color rotation transform
+    LLMatrix3 r;
+    alpha *= DEG_TO_RAD;
+    r.setRows(LLVector3( cosf(alpha), sinf(alpha), 0.0),
+              LLVector3(-sinf(alpha), cosf(alpha), 0.0),
+              LLVector3( 0.0,         0.0,         1.0));
+    
+    // Global color rotation transform
+    LLMatrix3 transfo = Lij_inv * r * Lij;
+    colorTransform(transfo);
+}
+
 // Filter Primitives
 void LLImageRaw::colorTransform(const LLMatrix3 &transform)
 {
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 1742cf8a713..3a9c088dbd3 100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -260,7 +260,8 @@ class LLImageRaw : public LLImageBase
     // Filter Operations
     void filterGrayScale();
     void filterSepia();
-    void filterSaturate(F32 s);
+    void filterSaturate(F32 saturation);    // < 1.0 desaturates, > 1.0 saturates
+    void filterRotate(F32 alpha);           // rotates hue, alpha in degrees
     // Filter Primitives
     void colorTransform(const LLMatrix3 &transform);
 
-- 
GitLab