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:
parent
d6b41a2767
commit
6c78b2b7cd
7
third_party/skcms/src/Curve.c
vendored
7
third_party/skcms/src/Curve.c
vendored
@ -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);
|
||||
|
3
third_party/skcms/src/GaussNewton.c
vendored
3
third_party/skcms/src/GaussNewton.c
vendored
@ -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;
|
||||
|
||||
|
4
third_party/skcms/src/GaussNewton.h
vendored
4
third_party/skcms/src/GaussNewton.h
vendored
@ -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);
|
||||
|
6
third_party/skcms/src/ICCProfile.c
vendored
6
third_party/skcms/src/ICCProfile.c
vendored
@ -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;
|
||||
|
6
third_party/skcms/src/PolyTF.c
vendored
6
third_party/skcms/src/PolyTF.c
vendored
@ -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;
|
||||
}
|
||||
}
|
||||
|
30
third_party/skcms/src/TransferFunction.c
vendored
30
third_party/skcms/src/TransferFunction.c
vendored
@ -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)));
|
||||
}
|
||||
|
2
third_party/skcms/version.sha1
vendored
2
third_party/skcms/version.sha1
vendored
@ -1 +1 @@
|
||||
e040063b5d7d52615d0060bd79cbe90c5e2d90b4
|
||||
a7e79c5f3f8b2ac778d7ef6fb28d81a79be5debb
|
Loading…
Reference in New Issue
Block a user