Hello,

the following used sRGB_linear.icc uses a single value gamma of 1.0 inside a version 2.x ICC profile.

$ transicc -i *xyz -o sRGB_linear.icc
LittleCMS ColorSpace conversion calculator - 4.1 [LittleCMS 2.03]

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

R=0.0000 G=0.0000 B=0.0000
The expected negative values where simply clipped.

The clipping happens in DefaultEvalParametricFn():
https://github.com/mm2/Little-CMS/blob/master/src/cmsgamma.c#L243
if (R < 0)
    Val = 0;

Use case:
The graphics community discusses to use traditional sRGB primaries and use floating point values to preserve wide gamut values as negative numbers.
(The above observed clipping effectively prevents that.)

Solution:
check for gamma of 1.0 and allow for negatives.
A first proof of concept patch is attached.

Would that approach integrate reasonable?


kind regards
Kai-Uwe Behrmann
--
www.oyranos.org
diff --git a/src/cmsgamma.c b/src/cmsgamma.c
index 02dc910..cb2fa76 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];
------------------------------------------------------------------------------
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