From 8c29c14f54984e7848fc860571a7521889e6f012 Mon Sep 17 00:00:00 2001 From: "skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com" Date: Thu, 17 May 2018 18:42:40 +0000 Subject: 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 Reviewed-by: skcms-skia-autoroll --- third_party/skcms/skcms.h | 22 ++++++++++++++++------ third_party/skcms/src/Curve.c | 16 ++++++++++++++++ third_party/skcms/src/Curve.h | 2 ++ third_party/skcms/src/ICCProfile.c | 26 ++++++++++++++++++++++++++ third_party/skcms/src/TransferFunction.c | 7 +------ third_party/skcms/src/Transform.c | 14 +------------- third_party/skcms/version.sha1 | 2 +- 7 files changed, 63 insertions(+), 26 deletions(-) (limited to 'third_party') diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h index ece944c56b..97728c4c8f 100644 --- a/third_party/skcms/skcms.h +++ b/third_party/skcms/skcms.h @@ -56,12 +56,6 @@ typedef union skcms_Curve { }; } 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 @@ SKCMS_API const skcms_ICCProfile* skcms_sRGB_profile(void); // 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 2b5a042500..a1a3c62a3d 100644 --- a/third_party/skcms/src/Curve.c +++ b/third_party/skcms/src/Curve.c @@ -43,3 +43,19 @@ float skcms_eval_curve(const skcms_Curve* curve, float x) { } 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 af01d53b2f..1316562b56 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 324a34cc06..ca28824b9f 100644 --- a/third_party/skcms/src/ICCProfile.c +++ b/third_party/skcms/src/ICCProfile.c @@ -863,6 +863,21 @@ const skcms_ICCProfile* skcms_XYZD50_profile() { 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 @@ bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A, const skcms_ICC 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 a27bd13bd2..8f8fb36c9d 100644 --- a/third_party/skcms/src/TransferFunction.c +++ b/third_party/skcms/src/TransferFunction.c @@ -351,12 +351,7 @@ bool skcms_ApproximateCurve(const skcms_Curve* curve, 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 791671e6f9..9bf66118f2 100644 --- a/third_party/skcms/src/Transform.c +++ b/third_party/skcms/src/Transform.c @@ -605,18 +605,6 @@ static void assert_usable_as_destination(const skcms_ICCProfile* profile) { #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 @@ bool skcms_MakeUsableAsDestinationWithSingleCurve(skcms_ICCProfile* profile) { 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 1ca44cf38f..facaf94c06 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 -- cgit v1.2.3