aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/skcms/src
diff options
context:
space:
mode:
authorGravatar skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com>2018-04-24 16:33:32 +0000
committerGravatar Brian Osman <brianosman@google.com>2018-04-24 18:07:33 +0000
commit32d19c42a2296aea9af946accb020ac80dfdc7da (patch)
treeca1ff06d4ed5abda4da62ddbcdc81273a7e300e7 /third_party/skcms/src
parente9a670045f1a0b429e51d38650615227dc0e3409 (diff)
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 <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com>
Diffstat (limited to 'third_party/skcms/src')
-rw-r--r--third_party/skcms/src/Transform.c44
1 files changed, 44 insertions, 0 deletions
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);
+}