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>
This commit is contained in:
skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com 2018-05-16 16:03:08 +00:00 committed by Skia Commit-Bot
parent d6b41a2767
commit 6c78b2b7cd
7 changed files with 32 additions and 26 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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)));
}

View File

@ -1 +1 @@
e040063b5d7d52615d0060bd79cbe90c5e2d90b4
a7e79c5f3f8b2ac778d7ef6fb28d81a79be5debb