Roll skia/third_party/skcms 3f444c5..3e527c6 (1 commits)

https://skia.googlesource.com/skcms.git/+log/3f444c5..3e527c6

2018-05-17 brianosman@google.com Added skcms_AreApproximateInverses(Curve, TransferFunction)


The AutoRoll server is located here: https://skcms-skia-roll.skia.org

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md

If the roll is causing failures, please contact the current sheriff, who should
be CC'd on the roll, and stop the roller if necessary.



CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel
TBR=herb@google.com

Change-Id: Ia10c2fe8dc17972b8e5570819ff6ac197f4d77f8
Reviewed-on: https://skia-review.googlesource.com/128984
Commit-Queue: skcms-skia-autoroll <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com>
Reviewed-by: skcms-skia-autoroll <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com>
diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h
index ece944c..97728c4 100644
--- a/third_party/skcms/skcms.h
+++ b/third_party/skcms/skcms.h
@@ -56,12 +56,6 @@
     };
 } skcms_Curve;
 
-// Practical equality test for two skcms_Curves.
-// The implementation is subject to change, but it will always try to answer
-// "can I substitute A for B?" and "can I skip transforming from A to B?".
-SKCMS_API bool skcms_ApproximatelyEqualCurves(const skcms_Curve* A,
-                                              const skcms_Curve* B);
-
 typedef struct skcms_A2B {
     // Optional: N 1D curves, followed by an N-dimensional CLUT.
     // If input_channels == 0, these curves and CLUT are skipped,
@@ -115,12 +109,28 @@
 // Ditto for XYZD50, the most common profile connection space.
 SKCMS_API const skcms_ICCProfile* skcms_XYZD50_profile(void);
 
+SKCMS_API const skcms_TransferFunction* skcms_sRGB_TransferFunction(void);
+SKCMS_API const skcms_TransferFunction* skcms_sRGB_Inverse_TransferFunction(void);
+SKCMS_API const skcms_TransferFunction* skcms_Identity_TransferFunction(void);
+
 // Practical equality test for two skcms_ICCProfiles.
 // The implementation is subject to change, but it will always try to answer
 // "can I substitute A for B?" and "can I skip transforming from A to B?".
 SKCMS_API bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A,
                                                 const skcms_ICCProfile* B);
 
+// Practical test that answers: Is curve roughly the inverse of inv_tf? Typically used by passing
+// the inverse of a known parametric transfer function (like sRGB), to determine if a particular
+// curve is very close to sRGB.
+SKCMS_API bool skcms_AreApproximateInverses(const skcms_Curve* curve,
+                                            const skcms_TransferFunction* inv_tf);
+
+// Similar to above, answering the question for all three TRC curves of the given profile. Again,
+// passing skcms_sRGB_InverseTransferFunction as inv_tf will answer the question:
+// "Does this profile have a transfer function that is very close to sRGB?"
+SKCMS_API bool skcms_TRCs_AreApproximateInverse(const skcms_ICCProfile* profile,
+                                                const skcms_TransferFunction* inv_tf);
+
 // Parse an ICC profile and return true if possible, otherwise return false.
 // The buffer is not copied, it must remain valid as long as the skcms_ICCProfile
 // will be used.
diff --git a/third_party/skcms/src/Curve.c b/third_party/skcms/src/Curve.c
index 2b5a042..a1a3c62 100644
--- a/third_party/skcms/src/Curve.c
+++ b/third_party/skcms/src/Curve.c
@@ -43,3 +43,19 @@
     }
     return l + (h-l)*t;
 }
+
+float skcms_MaxRoundtripError(const skcms_Curve* curve, const skcms_TransferFunction* inv_tf) {
+    uint32_t N = curve->table_entries > 256 ? curve->table_entries : 256;
+    const float dx = 1.0f / (N - 1);
+    float err = 0;
+    for (uint32_t i = 0; i < N; i++) {
+        float x = i * dx,
+              y = skcms_eval_curve(curve, x);
+        err = fmaxf_(err, fabsf_(x - skcms_TransferFunction_eval(inv_tf, y)));
+    }
+    return err;
+}
+
+bool skcms_AreApproximateInverses(const skcms_Curve* curve, const skcms_TransferFunction* inv_tf) {
+    return skcms_MaxRoundtripError(curve, inv_tf) < (1/512.0f);
+}
diff --git a/third_party/skcms/src/Curve.h b/third_party/skcms/src/Curve.h
index af01d53..1316562 100644
--- a/third_party/skcms/src/Curve.h
+++ b/third_party/skcms/src/Curve.h
@@ -11,3 +11,5 @@
 
 // Evaluate an skcms_Curve at x.
 float skcms_eval_curve(const skcms_Curve*, float x);
+
+float skcms_MaxRoundtripError(const skcms_Curve* curve, const skcms_TransferFunction* inv_tf);
diff --git a/third_party/skcms/src/ICCProfile.c b/third_party/skcms/src/ICCProfile.c
index 324a34c..ca28824 100644
--- a/third_party/skcms/src/ICCProfile.c
+++ b/third_party/skcms/src/ICCProfile.c
@@ -863,6 +863,21 @@
     return &XYZD50_profile;
 }
 
+const skcms_TransferFunction* skcms_sRGB_TransferFunction() {
+    return &skcms_sRGB_profile()->trc[0].parametric;
+}
+
+const skcms_TransferFunction* skcms_sRGB_Inverse_TransferFunction() {
+    static const skcms_TransferFunction sRGB_inv =
+        { (float)(1/2.4), 1.137119f, 0, 12.92f, 0.0031308f, -0.055f, 0 };
+    return &sRGB_inv;
+}
+
+const skcms_TransferFunction* skcms_Identity_TransferFunction() {
+    static const skcms_TransferFunction identity = {1,1,0,0,0,0,0};
+    return &identity;
+}
+
 const uint8_t skcms_252_random_bytes[] = {
     8, 179, 128, 204, 253, 38, 134, 184, 68, 102, 32, 138, 99, 39, 169, 215,
     119, 26, 3, 223, 95, 239, 52, 132, 114, 74, 81, 234, 97, 116, 244, 205, 30,
@@ -928,6 +943,17 @@
     return true;
 }
 
+bool skcms_TRCs_AreApproximateInverse(const skcms_ICCProfile* profile,
+                                      const skcms_TransferFunction* inv_tf) {
+    if (!profile || !profile->has_trc) {
+        return false;
+    }
+
+    return skcms_AreApproximateInverses(&profile->trc[0], inv_tf) &&
+           skcms_AreApproximateInverses(&profile->trc[1], inv_tf) &&
+           skcms_AreApproximateInverses(&profile->trc[2], inv_tf);
+}
+
 static bool is_zero_to_one(float x) {
     return 0 <= x && x <= 1;
 }
diff --git a/third_party/skcms/src/TransferFunction.c b/third_party/skcms/src/TransferFunction.c
index a27bd13..8f8fb36 100644
--- a/third_party/skcms/src/TransferFunction.c
+++ b/third_party/skcms/src/TransferFunction.c
@@ -351,12 +351,7 @@
             continue;
         }
 
-        float err = 0;
-        for (int i = 0; i < N; i++) {
-            float x = i * dx,
-                  y = skcms_eval_curve(curve, x);
-            err = fmaxf_(err, fabsf_(x - skcms_TransferFunction_eval(&tf_inv, y)));
-        }
+        float err = skcms_MaxRoundtripError(curve, &tf_inv);
         if (*max_error > err) {
             *max_error = err;
             *approx    = tf;
diff --git a/third_party/skcms/src/Transform.c b/third_party/skcms/src/Transform.c
index 791671e..9bf6611 100644
--- a/third_party/skcms/src/Transform.c
+++ b/third_party/skcms/src/Transform.c
@@ -605,18 +605,6 @@
 #endif
 }
 
-static float max_roundtrip_error(const skcms_TransferFunction* inv_tf, const skcms_Curve* curve) {
-    int N = curve->table_entries ? (int)curve->table_entries : 256;
-    const float x_scale = 1.0f / (N - 1);
-    float err = 0;
-    for (int i = 0; i < N; i++) {
-        float x = i * x_scale,
-              y = skcms_eval_curve(curve, x);
-        err = fmaxf_(err, fabsf_(x - skcms_TransferFunction_eval(inv_tf, y)));
-    }
-    return err;
-}
-
 bool skcms_MakeUsableAsDestination(skcms_ICCProfile* profile) {
     skcms_Matrix3x3 fromXYZD50;
     if (!profile->has_trc || !profile->has_toXYZD50
@@ -664,7 +652,7 @@
 
         float err = 0;
         for (int j = 0; j < 3; ++j) {
-            err = fmaxf_(err, max_roundtrip_error(&inv, &profile->trc[j]));
+            err = fmaxf_(err, skcms_MaxRoundtripError(&profile->trc[j], &inv));
         }
         if (min_max_error > err) {
             min_max_error = err;
diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1
index 1ca44cf..facaf94 100755
--- a/third_party/skcms/version.sha1
+++ b/third_party/skcms/version.sha1
@@ -1 +1 @@
-3f444c5a52cb85be179f86ab1bef61719d2d949f
\ No newline at end of file
+3e527c628503e17ba8f4756b00b52b1b17f24cfd
\ No newline at end of file