Roll skia/third_party/skcms 5cbdc0a..011b614 (1 commits)
https://skia.googlesource.com/skcms.git/+log/5cbdc0a..011b614 2018-04-24 mtklein@chromium.org gut TF13 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: I87e281fc5ac75f11acdcf7d4621d6635836b7a67 Reviewed-on: https://skia-review.googlesource.com/123393 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>
This commit is contained in:
parent
738a25645d
commit
eb43fdaaf8
1
third_party/skcms/skcms.c
vendored
1
third_party/skcms/skcms.c
vendored
@ -11,6 +11,5 @@
|
||||
#include "src/ICCProfile.c"
|
||||
#include "src/LinearAlgebra.c"
|
||||
#include "src/PortableMath.c"
|
||||
#include "src/TF13.c"
|
||||
#include "src/TransferFunction.c"
|
||||
#include "src/Transform.c"
|
||||
|
12
third_party/skcms/skcms.h
vendored
12
third_party/skcms/skcms.h
vendored
@ -73,12 +73,6 @@ typedef struct skcms_A2B {
|
||||
skcms_Curve output_curves[3];
|
||||
} skcms_A2B;
|
||||
|
||||
// A specialized approximation for transfer functions with gamma between 1 and 3.
|
||||
// f(x) = sign(x) * (A|x|^3 + B|x|^2 + (1-A-B)|x|)
|
||||
typedef struct skcms_TF13 {
|
||||
float A,B;
|
||||
} skcms_TF13;
|
||||
|
||||
typedef struct skcms_ICCProfile {
|
||||
const uint8_t* buffer;
|
||||
|
||||
@ -103,10 +97,6 @@ typedef struct skcms_ICCProfile {
|
||||
// and has_A2B to true.
|
||||
bool has_A2B;
|
||||
skcms_A2B A2B;
|
||||
|
||||
// If has_trc, we may be able to approximate the curves more efficiently.
|
||||
bool has_tf13[3];
|
||||
skcms_TF13 tf13[3];
|
||||
} skcms_ICCProfile;
|
||||
|
||||
// The sRGB color profile is so commonly used that we offer a canonical skcms_ICCProfile for it.
|
||||
@ -131,8 +121,6 @@ void skcms_OptimizeForSpeed(skcms_ICCProfile*);
|
||||
bool skcms_ApproximateCurve(const skcms_Curve* curve, skcms_TransferFunction* approx,
|
||||
float* max_error);
|
||||
|
||||
bool skcms_ApproximateCurve13(const skcms_Curve* curve, skcms_TF13* approx, float* max_error);
|
||||
|
||||
// What is the best single transfer function to use for the given profile? Note that there is
|
||||
// no real upper bound on the error of this transfer function.
|
||||
skcms_TransferFunction skcms_BestSingleCurve(const skcms_ICCProfile*);
|
||||
|
7
third_party/skcms/src/ICCProfile.c
vendored
7
third_party/skcms/src/ICCProfile.c
vendored
@ -782,11 +782,8 @@ bool skcms_Parse(const void* buf, size_t len, skcms_ICCProfile* profile) {
|
||||
}
|
||||
|
||||
void skcms_OptimizeForSpeed(skcms_ICCProfile* profile) {
|
||||
// If we can approximate any of the TRC curves with a skcms_TF13, do so.
|
||||
for (int i = 0; profile->has_trc && i < 3; i++) {
|
||||
float err;
|
||||
profile->has_tf13[i] = skcms_ApproximateCurve13(&profile->trc[i], &profile->tf13[i], &err);
|
||||
}
|
||||
(void)profile;
|
||||
// TODO
|
||||
}
|
||||
|
||||
const skcms_ICCProfile skcms_sRGB_profile = {
|
||||
|
88
third_party/skcms/src/TF13.c
vendored
88
third_party/skcms/src/TF13.c
vendored
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "../skcms.h"
|
||||
#include "GaussNewton.h"
|
||||
#include "PortableMath.h"
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Evaluating skcms_TF13{A,B} at x:
|
||||
// f(x) = Ax^3 + Bx^2 + (1-A-B)x
|
||||
//
|
||||
// ∂f/∂A = x^3 - x
|
||||
// ∂f/∂B = x^2 - x
|
||||
|
||||
static float eval_13(float x, const void* ctx, const float P[4]) {
|
||||
(void)ctx;
|
||||
return x*(x*(x*P[0] + P[1]) + (1 - P[0] - P[1]));
|
||||
}
|
||||
static void grad_13(float x, const void* ctx, const float P[4], float dfdP[4]) {
|
||||
(void)ctx;
|
||||
(void)P;
|
||||
dfdP[0] = x*(x*x - 1);
|
||||
dfdP[1] = x*(x - 1);
|
||||
}
|
||||
|
||||
bool skcms_ApproximateCurve13(const skcms_Curve* curve, skcms_TF13* approx, float* max_error) {
|
||||
// Start a guess at skcms_TF13{0,1}, i.e. f(x) = x^2, i.e. gamma = 2.
|
||||
// TODO: guess better somehow, like we do in skcms_ApproximateCurve()?
|
||||
float P[4] = { 0,1, 0,0 };
|
||||
|
||||
if (curve->table_entries > (uint32_t)INT_MAX) {
|
||||
// That's just crazy.
|
||||
return false;
|
||||
}
|
||||
const int N = curve->table_entries == 0 ? 257 /*TODO: tune?*/
|
||||
: (int)curve->table_entries;
|
||||
|
||||
for (int i = 0; i < 3/*TODO: Tune???*/; i++) {
|
||||
if (!skcms_gauss_newton_step(skcms_eval_curve, curve,
|
||||
eval_13, NULL,
|
||||
grad_13, NULL,
|
||||
P,
|
||||
0,1,N)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*max_error = 0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
float x = i * (1.0f / (N-1));
|
||||
|
||||
const float got = eval_13(x,NULL,P),
|
||||
want = skcms_eval_curve(x, curve);
|
||||
|
||||
const float err = fabsf_(got - want);
|
||||
if (err > *max_error) {
|
||||
*max_error = err;
|
||||
}
|
||||
|
||||
assert( isfinitef_(want) );
|
||||
if (!isfinitef_(got)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare what bytes we'd choose for these floats, rounded, and scaled by 255,
|
||||
// but intentionally not clamped... if this goes negative, we want it to hurt.
|
||||
|
||||
const int gbyte = (int)(255.0f * got + 0.5f),
|
||||
wbyte = (int)(255.0f * want + 0.5f);
|
||||
|
||||
// Allow no more than 1/256 error, and no error at all at the beginning or end.
|
||||
const int tol = (i == 0 || i == N-1) ? 0
|
||||
: 1;
|
||||
if (abs(gbyte - wbyte) > tol) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
approx->A = P[0];
|
||||
approx->B = P[1];
|
||||
return true;
|
||||
}
|
10
third_party/skcms/src/Transform.c
vendored
10
third_party/skcms/src/Transform.c
vendored
@ -320,11 +320,6 @@ typedef struct {
|
||||
const void* arg;
|
||||
} OpAndArg;
|
||||
|
||||
static OpAndArg select_tf13_op(const skcms_TF13* tf, int channel) {
|
||||
static const Op ops[] = { Op_tf13_r, Op_tf13_g, Op_tf13_b };
|
||||
return (OpAndArg){ ops[channel], tf };
|
||||
}
|
||||
|
||||
static OpAndArg select_curve_op(const skcms_Curve* curve, int channel) {
|
||||
static const struct { Op parametric, table_8, table_16; } ops[] = {
|
||||
{ Op_tf_r, Op_table_8_r, Op_table_16_r },
|
||||
@ -524,13 +519,8 @@ bool skcms_Transform(const void* src,
|
||||
|
||||
} else if (srcProfile->has_trc && srcProfile->has_toXYZD50) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// Favor Op_noop (identity curve) over anything else,
|
||||
// and select_tf_op() over over select_curve_op() when possible.
|
||||
OpAndArg oa = select_curve_op(&srcProfile->trc[i], i);
|
||||
if (oa.op != Op_noop) {
|
||||
if (srcProfile->has_tf13[i]) {
|
||||
oa = select_tf13_op(&srcProfile->tf13[i], i);
|
||||
}
|
||||
*ops++ = oa.op;
|
||||
*args++ = oa.arg;
|
||||
}
|
||||
|
3
third_party/skcms/src/Transform.h
vendored
3
third_party/skcms/src/Transform.h
vendored
@ -34,9 +34,6 @@
|
||||
M(tf_g) \
|
||||
M(tf_b) \
|
||||
M(tf_a) \
|
||||
M(tf13_r) \
|
||||
M(tf13_g) \
|
||||
M(tf13_b) \
|
||||
M(table_8_r) \
|
||||
M(table_8_g) \
|
||||
M(table_8_b) \
|
||||
|
10
third_party/skcms/src/Transform_inl.h
vendored
10
third_party/skcms/src/Transform_inl.h
vendored
@ -246,12 +246,6 @@ SI ATTR F NS(apply_transfer_function_)(const skcms_TransferFunction* tf, F x) {
|
||||
}
|
||||
#define apply_transfer_function NS(apply_transfer_function_)
|
||||
|
||||
SI ATTR F NS(apply_tf13_)(const skcms_TF13* tf, F x) {
|
||||
F sign = (F)if_then_else(x < 0, -F1, F1);
|
||||
return x*(x*(x*tf->A + sign*tf->B) + (1 - tf->A - tf->B) );
|
||||
}
|
||||
#define apply_tf13 NS(apply_tf13_)
|
||||
|
||||
// Strided loads and stores of N values, starting from p.
|
||||
#if N == 1
|
||||
#define LOAD_3(T, p) (T)(p)[0]
|
||||
@ -853,10 +847,6 @@ static void NS(exec_ops)(const Op* ops, const void** args,
|
||||
case Op_tf_b:{ b = apply_transfer_function(*args++, b); } break;
|
||||
case Op_tf_a:{ a = apply_transfer_function(*args++, a); } break;
|
||||
|
||||
case Op_tf13_r:{ r = apply_tf13(*args++, r); } break;
|
||||
case Op_tf13_g:{ g = apply_tf13(*args++, g); } break;
|
||||
case Op_tf13_b:{ b = apply_tf13(*args++, b); } break;
|
||||
|
||||
case Op_table_8_r: { r = NS(table_8_ )(*args++, r); } break;
|
||||
case Op_table_8_g: { g = NS(table_8_ )(*args++, g); } break;
|
||||
case Op_table_8_b: { b = NS(table_8_ )(*args++, b); } break;
|
||||
|
2
third_party/skcms/version.sha1
vendored
2
third_party/skcms/version.sha1
vendored
@ -1 +1 @@
|
||||
5cbdc0acf72bc4031f409516fbeb50e254ba638b
|
||||
011b61429dcc624f7e9a2d6fd39a3dbfb92c40a9
|
Loading…
Reference in New Issue
Block a user