aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party
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-25 17:54:32 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-25 18:19:47 +0000
commit677809ac1696b7fe8f11bc7e616b3ca6d5954ed7 (patch)
tree8bd1bd795c7524b3b2aa7817bf339e8161fca663 /third_party
parentde5cffbc48fce4decd1caf84d5a5e4fc0b5b48ed (diff)
Roll skia/third_party/skcms 48c6ca0..509a65e (1 commits)
https://skia.googlesource.com/skcms.git/+log/48c6ca0..509a65e 2018-04-25 mtklein@chromium.org Reland "use linear segment instead of recalculating it" 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: I61527be2081ed737ca323a4e87ff778270a59104 Reviewed-on: https://skia-review.googlesource.com/123723 Reviewed-by: skcms-skia-autoroll <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com> Commit-Queue: skcms-skia-autoroll <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com>
Diffstat (limited to 'third_party')
-rw-r--r--third_party/skcms/src/PolyTF.c102
-rwxr-xr-xthird_party/skcms/version.sha12
2 files changed, 57 insertions, 47 deletions
diff --git a/third_party/skcms/src/PolyTF.c b/third_party/skcms/src/PolyTF.c
index f4aaa4877d..f4d837b9b6 100644
--- a/third_party/skcms/src/PolyTF.c
+++ b/third_party/skcms/src/PolyTF.c
@@ -67,7 +67,7 @@ static bool fit_poly_tf(const skcms_Curve* curve, skcms_PolyTF* tf) {
}
const int N = curve->table_entries == 0 ? 256
- :(int)curve->table_entries;
+ : (int)curve->table_entries;
// We'll test the quality of our fit by roundtripping through a skcms_TransferFunction,
// either the inverse of the curve itself if it is parametric, or of its approximation if not.
@@ -78,64 +78,74 @@ static bool fit_poly_tf(const skcms_Curve* curve, skcms_PolyTF* tf) {
} else if (!skcms_ApproximateCurve(curve, &baseline, &err)) {
return false;
}
+
+ // We'll borrow the linear section from baseline, which is either
+ // exactly correct, or already the approximation we'd use anyway.
+ tf->C = baseline.c;
+ tf->D = baseline.d;
+ if (baseline.f != 0) {
+ return false; // Can't fit this (rare) kind of curve here.
+ }
+
+ // Detect linear baseline: (ax + b)^g + e --> ax ~~> Cx
+ if (baseline.g == 1 && baseline.d == 0 && baseline.b + baseline.e == 0) {
+ tf->A = 0;
+ tf->B = 0;
+ tf->C = baseline.a;
+ tf->D = INFINITY_; // Always use Cx, never Ax^3+Bx^2+(1-A-B)
+ return true;
+ }
+ // This case is less likely, but also guards against divide by zero below.
+ if (tf->D == 1) {
+ tf->A = 0;
+ tf->B = 0;
+ return true;
+ }
+
+ // Number of points already fit in the linear section.
+ // If the curve isn't parametric and we approximated instead, this should be exact.
+ const int L = (int)(tf->D * (N-1)) + 1;
+
+ // TODO: handle special case of L == N-1 to avoid /0 in Gauss-Newton.
+
skcms_TransferFunction inv;
if (!skcms_TransferFunction_invert(&baseline, &inv)) {
return false;
}
- const float kTolerances[] = { 1.5f / 65535.0f, 1.0f / 512.0f };
- for (int t = 0; t < ARRAY_COUNT(kTolerances); t++) {
- float f;
- const int L = skcms_fit_linear(curve, N, kTolerances[t], &tf->C, &tf->D, &f);
- if (f != 0) {
+ // Start with guess A = 0, i.e. f(x) ≈ x^2.
+ float P[4] = {0, 0,0,0};
+ for (int i = 0; i < 3; i++) {
+ if (!skcms_gauss_newton_step(skcms_eval_curve, curve,
+ eval_poly_tf, tf,
+ grad_poly_tf, tf,
+ P,
+ tf->D, 1, N-L)) {
return false;
}
+ }
- if (tf->D == 1) {
- tf->A = 0;
- tf->B = 0;
- return true;
- }
+ float A = tf->A = P[0],
+ C = tf->C,
+ D = tf->D;
+ tf->B = (C*D - A*(D*D*D - 1) - 1) / (D*D - 1);
- // Start with guess A = 0, i.e. f(x) = x^2, gamma = 2.
- float P[4] = {0, 0,0,0};
-
- for (int i = 0; i < 3; i++) {
- if (!skcms_gauss_newton_step(skcms_eval_curve, curve,
- eval_poly_tf, tf,
- grad_poly_tf, tf,
- P,
- tf->D, 1, N-L)) {
- goto NEXT;
- }
- }
+ for (int i = 0; i < N; i++) {
+ float x = i * (1.0f/(N-1));
- float A = tf->A = P[0],
- C = tf->C,
- D = tf->D;
- tf->B = (C*D - A*(D*D*D - 1) - 1) / (D*D - 1);
-
- for (int i = 0; i < N; i++) {
- float x = i * (1.0f/(N-1));
-
- float rt = skcms_TransferFunction_eval(&inv, eval_poly_tf(x, tf, P));
- if (!isfinitef_(rt)) {
- goto NEXT;
- }
-
- const int tol = (i == 0 || i == N-1) ? 0
- : N/256;
- int ix = (int)((N-1) * rt + 0.5f);
- if (abs(i - ix) > tol) {
- goto NEXT;
- }
+ float rt = skcms_TransferFunction_eval(&inv, eval_poly_tf(x, tf, P));
+ if (!isfinitef_(rt)) {
+ return false;
}
- return true;
- NEXT: ;
+ const int tol = (i == 0 || i == N-1) ? 0
+ : N/256;
+ int ix = (int)((N-1) * rt + 0.5f);
+ if (abs(i - ix) > tol) {
+ return false;
+ }
}
-
- return false;
+ return true;
}
void skcms_OptimizeForSpeed(skcms_ICCProfile* profile) {
diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1
index d55a1c447d..271e95831e 100755
--- a/third_party/skcms/version.sha1
+++ b/third_party/skcms/version.sha1
@@ -1 +1 @@
-48c6ca003569d11bdb00847ed2619e40af591f44 \ No newline at end of file
+509a65eff46e679cf0d358a6ffbb4450d1df9402 \ No newline at end of file