aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/skcms
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-05-16 16:03:08 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-16 17:18:52 +0000
commit6c78b2b7cd01525c43939dcee4e5e370a5b66ac2 (patch)
tree1e1e512a461aa5aa026f861382424733cb94022e /third_party/skcms
parentd6b41a27678f0c153eff982be4f1120e6cb65692 (diff)
Roll skia/third_party/skcms e040063..a7e79c5 (2 commits)
https://skia.googlesource.com/skcms.git/+log/e040063..a7e79c5 2018-05-16 mtklein@chromium.org try yet again to fix gauss-newton stepping 2018-05-16 mtklein@chromium.org add clang.O0 build 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: I63a0ed3f912f69b114e3100ea44311f478563d3a Reviewed-on: https://skia-review.googlesource.com/128475 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>
Diffstat (limited to 'third_party/skcms')
-rw-r--r--third_party/skcms/src/Curve.c7
-rw-r--r--third_party/skcms/src/GaussNewton.c3
-rw-r--r--third_party/skcms/src/GaussNewton.h4
-rw-r--r--third_party/skcms/src/ICCProfile.c6
-rw-r--r--third_party/skcms/src/PolyTF.c6
-rw-r--r--third_party/skcms/src/TransferFunction.c30
-rwxr-xr-xthird_party/skcms/version.sha12
7 files changed, 32 insertions, 26 deletions
diff --git a/third_party/skcms/src/Curve.c b/third_party/skcms/src/Curve.c
index 1e48d65799..f52eb983fe 100644
--- a/third_party/skcms/src/Curve.c
+++ b/third_party/skcms/src/Curve.c
@@ -6,7 +6,9 @@
*/
#include "Curve.h"
+#include "PortableMath.h"
#include "TransferFunction.h"
+#include <assert.h>
float skcms_eval_curve(const skcms_Curve* curve, float x) {
if (curve->table_entries == 0) {
@@ -15,7 +17,10 @@ float skcms_eval_curve(const skcms_Curve* curve, float x) {
// TODO: today we should always hit an entry exactly, but if that changes, lerp?
// (We add half to account for slight int -> float -> int round tripping issues.)
- int ix = (int)( x*(curve->table_entries - 1) + 0.5f );
+ float fx = x*(curve->table_entries - 1);
+ int ix = (int)( fx + 0.5f );
+
+ assert ( fabsf_(fx - (float)ix) < 0.0005 );
if (curve->table_8) {
return curve->table_8[ix] * (1/255.0f);
diff --git a/third_party/skcms/src/GaussNewton.c b/third_party/skcms/src/GaussNewton.c
index 7e9f774538..61aeddbcdb 100644
--- a/third_party/skcms/src/GaussNewton.c
+++ b/third_party/skcms/src/GaussNewton.c
@@ -16,7 +16,7 @@
bool skcms_gauss_newton_step(float (*rg)(float x, const void*, const float P[3], float dfdP[3]),
const void* ctx,
float P[3],
- float x0, float x1, int N) {
+ float x0, float dx, int N) {
// We'll sample x from the range [x0,x1] (both inclusive) N times with even spacing.
//
// We want to do P' = P + (Jf^T Jf)^-1 Jf^T r(P),
@@ -56,7 +56,6 @@ bool skcms_gauss_newton_step(float (*rg)(float x, const void*, const float P[3],
// 1,2) evaluate lhs and evaluate rhs
// We want to evaluate Jf only once, but both lhs and rhs involve Jf^T,
// so we'll have to update lhs and rhs at the same time.
- float dx = (x1-x0)/(N-1);
for (int i = 0; i < N; i++) {
float x = x0 + i*dx;
diff --git a/third_party/skcms/src/GaussNewton.h b/third_party/skcms/src/GaussNewton.h
index 1c18b9ad93..5de9927ed3 100644
--- a/third_party/skcms/src/GaussNewton.h
+++ b/third_party/skcms/src/GaussNewton.h
@@ -14,7 +14,7 @@
// rg: residual function r(x,P) to minimize, and gradient at x in dfdP
// ctx: arbitrary context argument passed to rg
// P: in-out, both your initial guess for parameters of r(), and our updated values
-// x0,x1,N: N x-values to test in [x0,x1] (both inclusive) with even spacing
+// x0,dx,N: N x-values to test with even dx spacing, [x0, x0+dx, x0+2dx, ...]
//
// If you have fewer than 3 parameters, set the unused P to zero, don't touch their dfdP.
//
@@ -22,4 +22,4 @@
bool skcms_gauss_newton_step(float (*rg)(float x, const void*, const float P[3], float dfdP[3]),
const void* ctx,
float P[3],
- float x0, float x1, int N);
+ float x0, float dx, int N);
diff --git a/third_party/skcms/src/ICCProfile.c b/third_party/skcms/src/ICCProfile.c
index b3f34d10ce..b1a431210a 100644
--- a/third_party/skcms/src/ICCProfile.c
+++ b/third_party/skcms/src/ICCProfile.c
@@ -834,9 +834,9 @@ const skcms_ICCProfile* skcms_sRGB_profile() {
.has_poly_tf = { true, true, true },
.poly_tf = {
- {0.294143557548523f, 0.703896820545197f, (float)(1/12.92), 0.04045f},
- {0.294143557548523f, 0.703896820545197f, (float)(1/12.92), 0.04045f},
- {0.294143557548523f, 0.703896820545197f, (float)(1/12.92), 0.04045f},
+ {0.294143527746201f, 0.703896880149841f, (float)(1/12.92), 0.04045f},
+ {0.294143527746201f, 0.703896880149841f, (float)(1/12.92), 0.04045f},
+ {0.294143527746201f, 0.703896880149841f, (float)(1/12.92), 0.04045f},
},
};
return &sRGB_profile;
diff --git a/third_party/skcms/src/PolyTF.c b/third_party/skcms/src/PolyTF.c
index ff93ec5586..f74cf5418d 100644
--- a/third_party/skcms/src/PolyTF.c
+++ b/third_party/skcms/src/PolyTF.c
@@ -76,6 +76,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;
+ const float dx = 1.0f / (N-1);
// 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.
@@ -117,7 +118,8 @@ static bool fit_poly_tf(const skcms_Curve* curve, skcms_PolyTF* tf) {
// 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;
+ // const int L = (int)( tf->D/dx + 0.5f ) + 1
+ const int L = (int)(tf->D * (N-1) + 0.5f) + 1;
if (L == N-1) {
// All points but one fit the linear section.
@@ -136,7 +138,7 @@ static bool fit_poly_tf(const skcms_Curve* curve, skcms_PolyTF* tf) {
rg_poly_tf_arg arg = { curve, tf };
if (!skcms_gauss_newton_step(rg_poly_tf, &arg,
P,
- tf->D, 1, N-L)) {
+ L*dx, dx, N-L)) {
return false;
}
}
diff --git a/third_party/skcms/src/TransferFunction.c b/third_party/skcms/src/TransferFunction.c
index 94ad410b40..a27bd13bd2 100644
--- a/third_party/skcms/src/TransferFunction.c
+++ b/third_party/skcms/src/TransferFunction.c
@@ -198,7 +198,7 @@ int skcms_fit_linear(const skcms_Curve* curve, int N, float tol, float* c, float
// Some points' error intervals may intersect the running interval but not lie fully
// within it. So we keep track of the last point we saw that is a valid end point candidate,
// and once the search is done, back up to build the line through *that* point.
- const float x_scale = 1.0f / (N - 1);
+ const float dx = 1.0f / (N - 1);
int lin_points = 1;
*f = skcms_eval_curve(curve, 0);
@@ -206,7 +206,7 @@ int skcms_fit_linear(const skcms_Curve* curve, int N, float tol, float* c, float
float slope_min = -INFINITY_;
float slope_max = +INFINITY_;
for (int i = 1; i < N; ++i) {
- float x = i * x_scale;
+ float x = i * dx;
float y = skcms_eval_curve(curve, x);
float slope_max_i = (y + tol - *f) / x,
@@ -226,16 +226,16 @@ int skcms_fit_linear(const skcms_Curve* curve, int N, float tol, float* c, float
}
// Set D to the last point that met our tolerance.
- *d = (lin_points - 1) * x_scale;
+ *d = (lin_points - 1) * dx;
return lin_points;
}
-// Fit the points in [start,N) to the non-linear piece of tf, or return false if we can't.
-static bool fit_nonlinear(const skcms_Curve* curve, int start, int N, skcms_TransferFunction* tf) {
+// Fit the points in [L,N) to the non-linear piece of tf, or return false if we can't.
+static bool fit_nonlinear(const skcms_Curve* curve, int L, int N, skcms_TransferFunction* tf) {
float P[3] = { tf->g, tf->a, tf->b };
- // No matter where we start, x_scale should always represent N even steps from 0 to 1.
- const float x_scale = 1.0f / (N-1);
+ // No matter where we start, dx should always represent N even steps from 0 to 1.
+ const float dx = 1.0f / (N-1);
for (int j = 0; j < 3/*TODO: tune*/; j++) {
// These extra constraints a >= 0 and ad+b >= 0 are not modeled in the optimization.
@@ -253,7 +253,7 @@ static bool fit_nonlinear(const skcms_Curve* curve, int start, int N, skcms_Tran
rg_nonlinear_arg arg = { curve, tf};
if (!skcms_gauss_newton_step(rg_nonlinear, &arg,
P,
- start*x_scale, 1, N-start)) {
+ L*dx, dx, N-L)) {
return false;
}
}
@@ -292,7 +292,7 @@ bool skcms_ApproximateCurve(const skcms_Curve* curve,
}
int N = (int)curve->table_entries;
- const float x_scale = 1.0f / (N - 1);
+ const float dx = 1.0f / (N - 1);
*max_error = INFINITY_;
const float kTolerances[] = { 1.5f / 65535.0f, 1.0f / 512.0f };
@@ -311,11 +311,11 @@ bool skcms_ApproximateCurve(const skcms_Curve* curve,
} else if (L == N - 1) {
// Degenerate case with only two points in the nonlinear segment. Solve directly.
tf.g = 1;
- tf.a = (skcms_eval_curve(curve, (N-1)*x_scale) -
- skcms_eval_curve(curve, (N-2)*x_scale))
- / x_scale;
- tf.b = skcms_eval_curve(curve, (N-2)*x_scale)
- - tf.a * (N-2)*x_scale;
+ tf.a = (skcms_eval_curve(curve, (N-1)*dx) -
+ skcms_eval_curve(curve, (N-2)*dx))
+ / dx;
+ tf.b = skcms_eval_curve(curve, (N-2)*dx)
+ - tf.a * (N-2)*dx;
tf.e = 0;
} else {
// Start by guessing a gamma-only curve through the midpoint.
@@ -353,7 +353,7 @@ bool skcms_ApproximateCurve(const skcms_Curve* curve,
float err = 0;
for (int i = 0; i < N; i++) {
- float x = i * x_scale,
+ float x = i * dx,
y = skcms_eval_curve(curve, x);
err = fmaxf_(err, fabsf_(x - skcms_TransferFunction_eval(&tf_inv, y)));
}
diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1
index b0e2170f56..a7ddc513c7 100755
--- a/third_party/skcms/version.sha1
+++ b/third_party/skcms/version.sha1
@@ -1 +1 @@
-e040063b5d7d52615d0060bd79cbe90c5e2d90b4 \ No newline at end of file
+a7e79c5f3f8b2ac778d7ef6fb28d81a79be5debb \ No newline at end of file