From 32d19c42a2296aea9af946accb020ac80dfdc7da Mon Sep 17 00:00:00 2001 From: "skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com" Date: Tue, 24 Apr 2018 16:33:32 +0000 Subject: Roll skia/third_party/skcms 4028d14..8e64fbf (1 commits) https://skia.googlesource.com/skcms.git/+log/4028d14..8e64fbf 2018-04-24 brianosman@google.com skcms_EnsureUsableAsDestinationWithSingleCurve 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. TBR=stani@google.com Change-Id: I4847f6687e95aca7e1b98b9bb24bcd12ed0fa2cd Reviewed-on: https://skia-review.googlesource.com/123399 Reviewed-by: skcms-skia-autoroll --- third_party/skcms/skcms.h | 6 ++++++ third_party/skcms/src/Transform.c | 44 +++++++++++++++++++++++++++++++++++++++ third_party/skcms/version.sha1 | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) (limited to 'third_party') diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h index 54c9e8ebae..108eb58863 100644 --- a/third_party/skcms/skcms.h +++ b/third_party/skcms/skcms.h @@ -203,6 +203,12 @@ bool skcms_Transform(const void* src, // (e.g. skcms_sRGB_profile) where not. void skcms_EnsureUsableAsDestination(skcms_ICCProfile* profile, const skcms_ICCProfile* fallback); +// If profile cannot be used as a destination profile with a single parametric transfer function, +// (ie for rasterization), rewrite it with approximations where reasonable or by pulling from +// fallback (e.g. skcms_sRGB_profile) where not. +void skcms_EnsureUsableAsDestinationWithSingleCurve(skcms_ICCProfile* profile, + const skcms_ICCProfile* fallback); + #ifdef __cplusplus } #endif diff --git a/third_party/skcms/src/Transform.c b/third_party/skcms/src/Transform.c index b3a6b55705..16cfaec0a2 100644 --- a/third_party/skcms/src/Transform.c +++ b/third_party/skcms/src/Transform.c @@ -6,6 +6,7 @@ */ #include "../skcms.h" +#include "GaussNewton.h" #include "LinearAlgebra.h" #include "Macros.h" #include "PortableMath.h" @@ -643,3 +644,46 @@ void skcms_EnsureUsableAsDestination(skcms_ICCProfile* profile, const skcms_ICCP *profile = ok; assert_usable_as_destination(profile); } + +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(x, curve); + err = fmaxf_(err, fabsf_(x - skcms_TransferFunction_eval(inv_tf, y))); + } + return err; +} + +void skcms_EnsureUsableAsDestinationWithSingleCurve(skcms_ICCProfile* profile, + const skcms_ICCProfile* fallback) { + // Operate on a copy of profile, so we can choose the best TF for the original curves + skcms_ICCProfile result = *profile; + skcms_EnsureUsableAsDestination(&result, fallback); + + int best_tf = 0; + float min_max_error = INFINITY_; + const skcms_ICCProfile* ref = profile->has_trc ? profile : fallback; + for (int i = 0; i < 3; i++) { + skcms_TransferFunction inv; + skcms_TransferFunction_invert(&result.trc[i].parametric, &inv); + + float err = 0; + for (int j = 0; j < 3; ++j) { + err = fmaxf_(err, max_roundtrip_error(&inv, &ref->trc[j])); + } + if (min_max_error > err) { + min_max_error = err; + best_tf = i; + } + } + + for (int i = 0; i < 3; i++) { + result.trc[i].parametric = result.trc[best_tf].parametric; + } + + *profile = result; + assert_usable_as_destination(profile); +} diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1 index 72a033c208..5e4190ba95 100755 --- a/third_party/skcms/version.sha1 +++ b/third_party/skcms/version.sha1 @@ -1 +1 @@ -4028d1477684db34b7cf4da8c6b2438071062b32 \ No newline at end of file +8e64fbf367c7d3186ab4b002b142eca84431ddcc \ No newline at end of file -- cgit v1.2.3