Am 23.04.12, 11:46 +0200 schrieb marti.ma...@littlecms.com:
I think it makes complete sense. I would, however, only modify
case of pure gamma function (type 0). It happens that the spec already
defines what to do on negative parts for other types. Just try the
build-in sRGB for  example, that already has this feature enabled:

transicc -i*XYZ -o *sRGB
LittleCMS ColorSpace conversion calculator - 4.1 [LittleCMS 2.04]

Enter values, 'q' to quit
X? -10
Y? -10
Z? -10

R=-350.9086 G=-332.4046 B=-424.3584

wonderful :-)

I'm adding the change to my development sources, will commit in a
week or so (I have many changes for 2.4 this time)

The attached patch covers the remaining occurences of pow in DefaultEvalParametricFn(). However, I could not test it appropriately.

kind regards
Kai-Uwe Behrmann
--
www.oyranos.org

PS: the patch is attributed to Marti Maria and MIT licensed.
diff --git a/src/cmsgamma.c b/src/cmsgamma.c
index 02dc910..1eb127f 100644
--- a/src/cmsgamma.c
+++ b/src/cmsgamma.c
@@ -250,16 +250,24 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
 
     // X = Y ^ Gamma
     case 1:
-        if (R < 0) 
-            Val = 0;
+        if (R < 0) {
+            if (Params[0] == 1.0)
+                Val = R;
+            else
+                Val = 0;
+        }
         else
             Val = pow(R, Params[0]);
         break;
 
     // Type 1 Reversed: X = Y ^1/gamma
     case -1:
-        if (R < 0)
-            Val = 0;
+        if (R < 0) {
+            if (Params[0] == 1.0)
+                Val = R;
+            else
+                Val = 0;
+        }
         else
             Val = pow(R, 1/Params[0]);
         break;
@@ -276,8 +284,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
 
             if (e > 0)
                 Val = pow(e, Params[0]);
-            else
-                Val = 0;
+            else {
+                if (Params[0] == 1.0)
+                    Val = e;
+                else
+                    Val = 0;
+            }
         }
         else
             Val = 0;
@@ -286,13 +298,14 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
      // Type 2 Reversed
      // X = (Y ^1/g  - b) / a
      case -2: 
-         if (R < 0)
-             Val = 0;
+         if (R < 0) {
+            if (Params[0] == 1.0)
+                Val = R;
+            else
+                Val = 0;
+         }
          else
              Val = (pow(R, 1.0/Params[0]) - Params[2]) / Params[1];
-
-         if (Val < 0)
-              Val = 0;                            
          break;
 
 
@@ -301,8 +314,6 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
     // Y = c              | else
     case 3:
         disc = -Params[2] / Params[1];
-        if (disc < 0)
-            disc = 0;
 
         if (R >= disc) {
 
@@ -310,8 +321,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
 
             if (e > 0)
                 Val = pow(e, Params[0]) + Params[3];
-            else
-                Val = 0;
+            else {
+                if (Params[0] == 1.0)
+                    Val = pow(e, Params[0]) + Params[3];
+                else
+                    Val = 0;
+            }
         }
         else
             Val = Params[3];
@@ -328,8 +343,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
 
             if (e > 0)
                 Val = (pow(e, 1/Params[0]) - Params[2]) / Params[1];
-            else 
-                Val = 0;
+            else {
+                if (Params[0] == 1.0)
+                    Val = (pow(e, 1/Params[0]) - Params[2]) / Params[1];
+                else
+                    Val = 0;
+            }
         }
         else {
             Val = -Params[2] / Params[1];
@@ -347,8 +366,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
 
             if (e > 0)
                 Val = pow(e, Params[0]);
-            else
-                Val = 0;
+            else {
+                if (Params[0] == 1.0)
+                    Val = e;
+                else
+                    Val = 0;
+            }
         }
         else
             Val = R * Params[3];
@@ -359,8 +382,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
     // X=Y/c              | Y< (ad+b)^g
     case -4:
         e = Params[1] * Params[4] + Params[2];
-        if (e < 0)
-            disc = 0;
+        if (e < 0) {
+            if (Params[0] == 1.0)
+                disc = Params[0];
+            else
+                disc = 0;
+        }
         else
             disc = pow(e, Params[0]);
 
@@ -383,8 +410,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
 
             if (e > 0)
                 Val = pow(e, Params[0]) + Params[5];
-            else
-                Val = 0;
+            else {
+                if (Params[0] == 1.0)
+                    Val = e + Params[5];
+                else
+                    Val = 0;
+            }
         }        
         else
             Val = R*Params[3] + Params[6];
@@ -400,8 +431,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
         if (R >= disc) {
 
             e = R - Params[5];
-            if (e < 0) 
-                Val = 0;
+            if (e < 0) {
+                if (Params[0] == 1.0)
+                    Val = (e - Params[2]) / Params[1];
+                else
+                    Val = 0;
+            }
             else
                 Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
         }
@@ -418,8 +453,11 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
     case 6:    
         e = Params[1]*R + Params[2];
 
-        if (e < 0) 
-            Val = 0;
+        if (e < 0) {
+            if (Params[0] == 1.0)
+                Val = e + Params[3];
+            else
+                Val = 0;
         else 
             Val = pow(e, Params[0]) + Params[3];
         break;
@@ -427,10 +465,14 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
     // ((Y - c) ^1/Gamma - b) / a                        
     case -6:
         e = R - Params[3];
-        if (e < 0)
-            Val = 0;
+        if (e < 0) {
+            if (Params[0] == 1.0)
+                Val = (e - Params[2]) / Params[1];
+            else
+                Val = 0;
+        }
         else 
-        Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
+            Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1];
         break;
 
 
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user

Reply via email to