kinow commented on a change in pull request #114:
URL: https://github.com/apache/commons-imaging/pull/114#discussion_r588951722



##########
File path: src/main/java/org/apache/commons/imaging/color/ColorConversions.java
##########
@@ -747,4 +679,147 @@ public static ColorXyz convertCIELuvtoXYZ(final double L, 
final double u, final
 
         return new ColorXyz(X, Y, Z);
     }
+
+    public static ColorDIN99Lab convertCIELabToDIN99bLab(final ColorCieLab 
cie) {
+        return convertCIELabToDIN99bLab(cie.L, cie.a, cie.b);
+    }
+
+    public static ColorDIN99Lab convertCIELabToDIN99bLab(final double L, final 
double a, final double b) {
+        final double FAC_1 = 100.0 / Math.log(129.0 / 50.0); // = 105.51
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double ang = Math.toRadians(16.0);
+
+        final double L99 = kE * FAC_1 * Math.log(1. + 0.0158 * L);
+        double a99 = 0.0;
+        double b99 = 0.0;
+        if (a != 0.0 || b != 0.0) {
+            final double e = a * Math.cos(ang) + b * Math.sin(ang);
+            final double f = 0.7 * (b * Math.cos(ang) - a * Math.sin(ang));
+            final double G = Math.sqrt(e * e + f * f);
+            if (G != 0.) {
+                final double k = Math.log(1. + 0.045 * G) / (0.045 * kCH * kE 
* G);
+                a99 = k * e;
+                b99 = k * f;
+            }
+        }
+        return new ColorDIN99Lab(L99, a99, b99);
+    }
+
+    public static ColorCieLab convertDIN99bLabToCIELab(final ColorDIN99Lab 
dinb) {
+        return convertDIN99bLabToCIELab(dinb.L99, dinb.a99, dinb.b99);
+    }
+
+    public static ColorCieLab convertDIN99bLabToCIELab(final double L99b, 
final double a99b, final double b99b) {
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double FAC_1 = 100.0 / Math.log(129.0 / 50.0); // L99 scaling 
factor = 105.50867113783109
+        final double ang = Math.toRadians(16.0);
+
+        final double hef = Math.atan2(b99b, a99b);
+        final double C = Math.sqrt(a99b * a99b + b99b * b99b);
+        final double G = (Math.exp(0.045 * C * kCH * kE) - 1.0) / 0.045;
+        final double e = G * Math.cos(hef);
+        final double f = G * Math.sin(hef) / 0.7;
+
+        final double L = (Math.exp(L99b * kE / FAC_1) - 1.) / 0.0158;
+        final double a = e * Math.cos(ang) - f * Math.sin(ang);
+        final double b = e * Math.sin(ang) + f * Math.cos(ang);
+        return new ColorCieLab(L, a, b);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorDIN99Lab convertCIELabToDIN99oLab(final ColorCieLab 
cie) {
+        return convertCIELabToDIN99oLab(cie.L, cie.a, cie.b);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorDIN99Lab convertCIELabToDIN99oLab(final double L, final 
double a, final double b) {
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double FAC_1 = 100.0 / Math.log(139.0 / 100.0); // L99 scaling 
factor = 303.67100547050995
+        final double ang = Math.toRadians(26.0);
+
+        final double L99o = FAC_1 / kE * Math.log(1 + 0.0039 * L); // 
Lightness correction kE
+        double a99o = 0.0;
+        double b99o = 0.0;
+        if (a != 0.0 || b != 0.0) {
+            final double eo = a * Math.cos(ang) + b * Math.sin(ang); // a 
stretching
+            final double fo = 0.83 * (b * Math.cos(ang) - a * Math.sin(ang)); 
// b rotation/stretching
+            final double Go = Math.sqrt(eo * eo + fo * fo); // chroma
+            final double C99o = Math.log(1.0 + 0.075 * Go) / (0.0435 * kCH * 
kE); // factor for chroma compression and viewing conditions
+            final double heofo = Math.atan2(fo, eo); // arctan in four 
quadrants
+            final double h99o = heofo + ang; // hue rotation
+            a99o = C99o * Math.cos(h99o);
+            b99o = C99o * Math.sin(h99o);
+        }
+        return new ColorDIN99Lab(L99o, a99o, b99o);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorCieLab convertDIN99oLabToCIELab(final ColorDIN99Lab 
dino) {
+        return convertDIN99oLabToCIELab(dino.L99, dino.a99, dino.b99);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorCieLab convertDIN99oLabToCIELab(final double L99o, 
final double a99o, final double b99o) {
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double FAC_1 = 100.0 / Math.log(139.0 / 100.0); // L99 scaling 
factor = 303.67100547050995
+        final double ang = Math.toRadians(26.0);
+
+        final double L = (Math.exp(L99o * kE / FAC_1) - 1.0) / 0.0039;
+
+        final double h99ef = Math.atan2(b99o, a99o); // arctan in four 
quadrants
+
+        final double heofo = h99ef - ang; // backwards hue rotation
+
+        final double C99 = Math.sqrt(a99o * a99o + b99o * b99o); // DIN99 
chroma
+        final double G = (Math.exp(0.0435 * kE * kCH * C99) - 1.0) / 0.075; // 
factor for chroma decompression and viewing conditions
+        final double e = G * Math.cos(heofo);
+        final double f = G * Math.sin(heofo);
+
+        final double a = e * Math.cos(ang) - f / 0.83 * Math.sin(ang); // 
rotation by 26 degrees
+        final double b = e * Math.sin(ang) + f / 0.83 * Math.cos(ang); // 
rotation by 26 degrees
+
+        return new ColorCieLab(L, a, b);
+    }
+
+    private static double pivotRGB(double n) {
+        if (n > 0.0031308) {
+            n = 1.055 * Math.pow(n, 1 / 2.4) - 0.055;
+        } else {
+            n = 12.92 * n;
+        }
+        return n;
+    }
+
+    private static double unPivotRGB(double n) {
+        if (n > 0.04045) {
+            n = Math.pow((n + 0.055) / 1.055, 2.4);
+        } else {
+            n = n / 12.92;
+        }
+        return n;
+    }
+
+    private static double pivotXYZ(double n) {
+        if (n > XYZ_t0) {
+            n = Math.pow(n, 1 / 3.0);
+        } else {
+            n = XYZ_m * n + 16 / 116.0;
+        }
+        return n;
+    }
+
+    private static double unPivotXYZ(double n) {
+        final double nCube = Math.pow(n, 3);
+        if (nCube > XYZ_t0) {
+            n = nCube;
+        } else {
+            n = (n - 16 / 116.0) / XYZ_m;
+        }
+        return n;

Review comment:
       These functions here are removing **a lot** of duplicate code. Thanks 
for tidying it up.

##########
File path: src/main/java/org/apache/commons/imaging/color/ColorConversions.java
##########
@@ -99,8 +89,8 @@ public static ColorHunterLab convertXYZtoHunterLab(final 
ColorXyz xyz) {
     public static ColorHunterLab convertXYZtoHunterLab(final double X,
             final double Y, final double Z) {
         final double L = 10 * Math.sqrt(Y);
-        final double a = 17.5 * (((1.02 * X) - Y) / Math.sqrt(Y));
-        final double b = 7 * ((Y - (0.847 * Z)) / Math.sqrt(Y));
+        final double a = Y == 0.0 ? 0.0 : 17.5 * (((1.02 * X) - Y) / 
Math.sqrt(Y));
+        final double b = Y == 0.0 ? 0.0 : 7 * ((Y - (0.847 * Z)) / 
Math.sqrt(Y));

Review comment:
       Oh, good catch! :clap: 

##########
File path: src/main/java/org/apache/commons/imaging/color/ColorConversions.java
##########
@@ -747,4 +679,147 @@ public static ColorXyz convertCIELuvtoXYZ(final double L, 
final double u, final
 
         return new ColorXyz(X, Y, Z);
     }
+
+    public static ColorDIN99Lab convertCIELabToDIN99bLab(final ColorCieLab 
cie) {
+        return convertCIELabToDIN99bLab(cie.L, cie.a, cie.b);
+    }
+
+    public static ColorDIN99Lab convertCIELabToDIN99bLab(final double L, final 
double a, final double b) {
+        final double FAC_1 = 100.0 / Math.log(129.0 / 50.0); // = 105.51
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double ang = Math.toRadians(16.0);
+
+        final double L99 = kE * FAC_1 * Math.log(1. + 0.0158 * L);
+        double a99 = 0.0;
+        double b99 = 0.0;
+        if (a != 0.0 || b != 0.0) {
+            final double e = a * Math.cos(ang) + b * Math.sin(ang);
+            final double f = 0.7 * (b * Math.cos(ang) - a * Math.sin(ang));
+            final double G = Math.sqrt(e * e + f * f);
+            if (G != 0.) {
+                final double k = Math.log(1. + 0.045 * G) / (0.045 * kCH * kE 
* G);
+                a99 = k * e;
+                b99 = k * f;
+            }
+        }
+        return new ColorDIN99Lab(L99, a99, b99);
+    }
+
+    public static ColorCieLab convertDIN99bLabToCIELab(final ColorDIN99Lab 
dinb) {
+        return convertDIN99bLabToCIELab(dinb.L99, dinb.a99, dinb.b99);
+    }
+
+    public static ColorCieLab convertDIN99bLabToCIELab(final double L99b, 
final double a99b, final double b99b) {
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double FAC_1 = 100.0 / Math.log(129.0 / 50.0); // L99 scaling 
factor = 105.50867113783109
+        final double ang = Math.toRadians(16.0);
+
+        final double hef = Math.atan2(b99b, a99b);
+        final double C = Math.sqrt(a99b * a99b + b99b * b99b);
+        final double G = (Math.exp(0.045 * C * kCH * kE) - 1.0) / 0.045;
+        final double e = G * Math.cos(hef);
+        final double f = G * Math.sin(hef) / 0.7;
+
+        final double L = (Math.exp(L99b * kE / FAC_1) - 1.) / 0.0158;
+        final double a = e * Math.cos(ang) - f * Math.sin(ang);
+        final double b = e * Math.sin(ang) + f * Math.cos(ang);
+        return new ColorCieLab(L, a, b);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */

Review comment:
       :+1: 
   
   Thanks for keeping variables similar to the original text. With some machine 
translation from German to English, and following your code, I think I've 
managed to review these functions :-) 

##########
File path: src/main/java/org/apache/commons/imaging/color/ColorConversions.java
##########
@@ -168,30 +152,24 @@ public static ColorXyz convertRGBtoXYZ(final int rgb) {
         double var_G = g / 255.0; // Where G = 0 ÷ 255
         double var_B = b / 255.0; // Where B = 0 ÷ 255
 
-        if (var_R > 0.04045) {
-            var_R = Math.pow((var_R + 0.055) / 1.055, 2.4);
-        } else {
-            var_R = var_R / 12.92;
-        }
-        if (var_G > 0.04045) {
-            var_G = Math.pow((var_G + 0.055) / 1.055, 2.4);
-        } else {
-            var_G = var_G / 12.92;
-        }
-        if (var_B > 0.04045) {
-            var_B = Math.pow((var_B + 0.055) / 1.055, 2.4);
-        } else {
-            var_B = var_B / 12.92;
-        }
+        // Pivot RGB:
+        var_R = unPivotRGB(var_R);
+        var_G = unPivotRGB(var_G);
+        var_B = unPivotRGB(var_B);
 
-        var_R = var_R * 100;
-        var_G = var_G * 100;
-        var_B = var_B * 100;
+        var_R *= 100;
+        var_G *= 100;
+        var_B *= 100;
 
         // Observer. = 2°, Illuminant = D65
-        final double X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
-        final double Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
-        final double Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
+        // see: 
https://github.com/StanfordHCI/c3/blob/master/java/src/edu/stanford/vis/color/LAB.java
+        final double X = var_R * 0.4124564 + var_G * 0.3575761 + var_B * 
0.1804375;
+        final double Y = var_R * 0.2126729 + var_G * 0.7151522 + var_B * 
0.0721750;
+        final double Z = var_R * 0.0193339 + var_G * 0.1191920 + var_B * 
0.9503041;
+
+        // final double X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
+        // final double Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
+        // final double Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;

Review comment:
       Was it intentionally commented, or left-overs from the 
development/testing?

##########
File path: src/main/java/org/apache/commons/imaging/color/ColorConversions.java
##########
@@ -747,4 +700,147 @@ public static ColorXyz convertCIELuvtoXYZ(final double L, 
final double u, final
 
         return new ColorXyz(X, Y, Z);
     }
+
+    public static ColorDIN99Lab convertCIELabToDIN99bLab(final ColorCieLab 
cie) {
+        return convertCIELabToDIN99bLab(cie.L, cie.a, cie.b);
+    }
+
+    public static ColorDIN99Lab convertCIELabToDIN99bLab(final double L, final 
double a, final double b) {
+        final double FAC_1 = 100.0 / Math.log(129.0 / 50.0); // = 105.51
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double ang = Math.toRadians(16.0);
+
+        final double L99 = kE * FAC_1 * Math.log(1. + 0.0158 * L);
+        double a99 = 0.0;
+        double b99 = 0.0;
+        if (a != 0.0 || b != 0.0) {
+            final double e = a * Math.cos(ang) + b * Math.sin(ang);
+            final double f = 0.7 * (b * Math.cos(ang) - a * Math.sin(ang));
+            final double G = Math.sqrt(e * e + f * f);
+            if (G != 0.) {
+                final double k = Math.log(1. + 0.045 * G) / (0.045 * kCH * kE 
* G);
+                a99 = k * e;
+                b99 = k * f;
+            }
+        }
+        return new ColorDIN99Lab(L99, a99, b99);
+    }
+
+    public static ColorCieLab convertDIN99bLabToCIELab(final ColorDIN99Lab 
dinb) {
+        return convertDIN99bLabToCIELab(dinb.L99, dinb.a99, dinb.b99);
+    }
+
+    public static ColorCieLab convertDIN99bLabToCIELab(final double L99b, 
final double a99b, final double b99b) {
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double FAC_1 = 100.0 / Math.log(129.0 / 50.0); // L99 scaling 
factor = 105.50867113783109
+        final double ang = Math.toRadians(16.0);
+
+        final double hef = Math.atan2(b99b, a99b);
+        final double C = Math.sqrt(a99b * a99b + b99b * b99b);
+        final double G = (Math.exp(0.045 * C * kCH * kE) - 1.0) / 0.045;
+        final double e = G * Math.cos(hef);
+        final double f = G * Math.sin(hef) / 0.7;
+
+        final double L = (Math.exp(L99b * kE / FAC_1) - 1.) / 0.0158;
+        final double a = e * Math.cos(ang) - f * Math.sin(ang);
+        final double b = e * Math.sin(ang) + f * Math.cos(ang);
+        return new ColorCieLab(L, a, b);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorDIN99Lab convertCIELabToDIN99oLab(final ColorCieLab 
cie) {
+        return convertCIELabToDIN99oLab(cie.L, cie.a, cie.b);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorDIN99Lab convertCIELabToDIN99oLab(final double L, final 
double a, final double b) {
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double FAC_1 = 100.0 / Math.log(139.0 / 100.0); // L99 scaling 
factor = 303.67100547050995
+        final double ang = Math.toRadians(26.0);
+
+        final double L99o = FAC_1 / kE * Math.log(1 + 0.0039 * L); // 
Lightness correction kE
+        double a99o = 0.0;
+        double b99o = 0.0;
+        if (a != 0.0 || b != 0.0) {
+            final double eo = a * Math.cos(ang) + b * Math.sin(ang); // a 
stretching
+            final double fo = 0.83 * (b * Math.cos(ang) - a * Math.sin(ang)); 
// b rotation/stretching
+            final double Go = Math.sqrt(eo * eo + fo * fo); // chroma
+            final double C99o = Math.log(1.0 + 0.075 * Go) / (0.0435 * kCH * 
kE); // factor for chroma compression and viewing conditions
+            final double heofo = Math.atan2(fo, eo); // arctan in four 
quadrants
+            final double h99o = heofo + ang; // hue rotation
+            a99o = C99o * Math.cos(h99o);
+            b99o = C99o * Math.sin(h99o);
+        }
+        return new ColorDIN99Lab(L99o, a99o, b99o);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorCieLab convertDIN99oLabToCIELab(final ColorDIN99Lab 
dino) {
+        return convertDIN99oLabToCIELab(dino.L99, dino.a99, dino.b99);
+    }
+
+    /** DIN99o, see: 
https://de.wikipedia.org/w/index.php?title=Diskussion:DIN99-Farbraum */
+    public static ColorCieLab convertDIN99oLabToCIELab(final double L99o, 
final double a99o, final double b99o) {
+        final double kE = 1.0; // brightness factor, 1.0 for CIE reference 
conditions
+        final double kCH = 1.0; // chroma and hue factor, 1.0 for CIE 
reference conditions
+        final double FAC_1 = 100.0 / Math.log(139.0 / 100.0); // L99 scaling 
factor = 303.67100547050995
+        final double ang = Math.toRadians(26.0);
+
+        final double L = (Math.exp(L99o * kE / FAC_1) - 1.0) / 0.0039;
+
+        final double h99ef = Math.atan2(b99o, a99o); // arctan in four 
quadrants
+
+        final double heofo = h99ef - ang; // backwards hue rotation
+
+        final double C99 = Math.sqrt(a99o * a99o + b99o * b99o); // DIN99 
chroma
+        final double G = (Math.exp(0.0435 * kE * kCH * C99) - 1.0) / 0.075; // 
factor for chroma decompression and viewing conditions
+        final double e = G * Math.cos(heofo);
+        final double f = G * Math.sin(heofo);
+
+        final double a = e * Math.cos(ang) - f / 0.83 * Math.sin(ang); // 
rotation by 26 degrees
+        final double b = e * Math.sin(ang) + f / 0.83 * Math.cos(ang); // 
rotation by 26 degrees
+
+        return new ColorCieLab(L, a, b);
+    }

Review comment:
       Even though the sources are in German, you've done an excellent job 
maintaining this new code as similar as possible to the Wikipedia text, and 
also added some comments :+1: Looks good to me.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to