From 86168a1972c23221a3900f5b8c1eab0480109fc4 Mon Sep 17 00:00:00 2001 From: "skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com" Date: Thu, 17 May 2018 17:58:48 +0000 Subject: Roll skia/third_party/skcms 06d773b..3f444c5 (1 commits) https://skia.googlesource.com/skcms.git/+log/06d773b..3f444c5 2018-05-17 mtklein@chromium.org rm skcms_PolyTF and skcms_OptimizeForSpeed() 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: Ibdab92aa3d3cd9cc478623051ad1abb915765a7e Reviewed-on: https://skia-review.googlesource.com/128981 Reviewed-by: skcms-skia-autoroll Commit-Queue: Kevin Lubick --- third_party/skcms/skcms.c | 1 - third_party/skcms/skcms.gni | 1 - third_party/skcms/skcms.h | 15 +-- third_party/skcms/src/ICCProfile.c | 7 -- third_party/skcms/src/PolyTF.c | 175 ---------------------------------- third_party/skcms/src/Transform.c | 8 -- third_party/skcms/src/Transform.h | 3 - third_party/skcms/src/Transform_inl.h | 11 --- third_party/skcms/version.sha1 | 2 +- 9 files changed, 3 insertions(+), 220 deletions(-) delete mode 100644 third_party/skcms/src/PolyTF.c (limited to 'third_party') diff --git a/third_party/skcms/skcms.c b/third_party/skcms/skcms.c index 54467af9d9..80ea143cb0 100644 --- a/third_party/skcms/skcms.c +++ b/third_party/skcms/skcms.c @@ -11,7 +11,6 @@ #include "src/GaussNewton.c" #include "src/ICCProfile.c" #include "src/LinearAlgebra.c" -#include "src/PolyTF.c" #include "src/PortableMath.c" #include "src/TransferFunction.c" #include "src/Transform.c" diff --git a/third_party/skcms/skcms.gni b/third_party/skcms/skcms.gni index 7729208436..64eeb16111 100644 --- a/third_party/skcms/skcms.gni +++ b/third_party/skcms/skcms.gni @@ -12,7 +12,6 @@ skcms_sources = [ "src/LinearAlgebra.c", "src/LinearAlgebra.h", "src/Macros.h", - "src/PolyTF.c", "src/PortableMath.c", "src/PortableMath.h", "src/RandomBytes.h", diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h index ffc8901019..ece944c56b 100644 --- a/third_party/skcms/skcms.h +++ b/third_party/skcms/skcms.h @@ -43,11 +43,6 @@ typedef struct skcms_TransferFunction { float g, a,b,c,d,e,f; } skcms_TransferFunction; -// A transfer function that's cheaper to evaluate than skcms_TransferFunction. -typedef struct skcms_PolyTF { - float A,B,C,D; -} skcms_PolyTF; - // Unified representation of 'curv' or 'para' tag data, or a 1D table from 'mft1' or 'mft2' typedef union skcms_Curve { struct { @@ -113,10 +108,6 @@ typedef struct skcms_ICCProfile { // and has_A2B to true. bool has_A2B; skcms_A2B A2B; - - // If the profile has_trc, we may be able to approximate those curves with skcms_PolyTF. - bool has_poly_tf[3]; - skcms_PolyTF poly_tf[3]; } skcms_ICCProfile; // The sRGB color profile is so commonly used that we offer a canonical skcms_ICCProfile for it. @@ -135,9 +126,8 @@ SKCMS_API bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A, // will be used. SKCMS_API bool skcms_Parse(const void*, size_t, skcms_ICCProfile*); -// skcms_Parse() creates a profile that directs skcms_Transform() to favor accuracy. -// If you want to trade a little accuracy for a big speedup, call skcms_OptimizeForSpeed(). -SKCMS_API void skcms_OptimizeForSpeed(skcms_ICCProfile*); +// No-op, to be removed. +static inline void skcms_OptimizeForSpeed(skcms_ICCProfile* p) { (void)p; } SKCMS_API bool skcms_ApproximateCurve(const skcms_Curve* curve, skcms_TransferFunction* approx, @@ -258,7 +248,6 @@ static inline void skcms_SetTransferFunction(skcms_ICCProfile* p, for (int i = 0; i < 3; ++i) { p->trc[i].table_entries = 0; p->trc[i].parametric = *tf; - p->has_poly_tf[i] = false; } } diff --git a/third_party/skcms/src/ICCProfile.c b/third_party/skcms/src/ICCProfile.c index b1a431210a..324a34cc06 100644 --- a/third_party/skcms/src/ICCProfile.c +++ b/third_party/skcms/src/ICCProfile.c @@ -831,13 +831,6 @@ const skcms_ICCProfile* skcms_sRGB_profile() { { 0.222488403f, 0.716873169f, 0.060607910f }, { 0.013916016f, 0.097076416f, 0.714096069f }, }}, - - .has_poly_tf = { true, true, true }, - .poly_tf = { - {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 deleted file mode 100644 index f74cf5418d..0000000000 --- a/third_party/skcms/src/PolyTF.c +++ /dev/null @@ -1,175 +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 "Curve.h" -#include "GaussNewton.h" -#include "Macros.h" -#include "PortableMath.h" -#include "TransferFunction.h" -#include -#include - -// f(x) = skcms_PolyTF{A,B,C,D}(x) = -// Cx x < D -// A(x^3-1) + B(x^2-1) + 1 x ≥ D -// -// We'll fit C and D directly, and then hold them constant -// and fit the other part using Gauss-Newton, subject to -// the constraint that both parts meet at x=D: -// -// CD = A(D^3-1) + B(D^2-1) + 1 -// -// This lets us solve for B, reducing the optimization problem -// for that part down to just a single parameter A: -// -// CD - A(D^3-1) - 1 -// B = ----------------- -// D^2-1 -// -// x^2-1 -// f(x) = A(x^3-1) + ----- [CD - A(D^3-1) - 1] + 1 -// D^2-1 -// -// (x^2-1) (D^3-1) -// ∂f/∂A = x^3-1 - --------------- -// D^2-1 -// -// It's important to evaluate as f(x) as A(x^3-1) + B(x^2-1) + 1 -// and not Ax^3 + Bx^2 + (1-A-B) to ensure that f(1.0f) == 1.0f. - - -static float eval_poly_tf(float A, float B, float C, float D, - float x) { - return x < D ? C*x - : A*(x*x*x-1) + B*(x*x-1) + 1; -} - -typedef struct { - const skcms_Curve* curve; - const skcms_PolyTF* tf; -} rg_poly_tf_arg; - -static float rg_poly_tf(float x, const void* ctx, const float P[3], float dfdP[3]) { - const rg_poly_tf_arg* arg = (const rg_poly_tf_arg*)ctx; - const skcms_PolyTF* tf = arg->tf; - - float A = P[0], - C = tf->C, - D = tf->D; - float B = (C*D - A*(D*D*D - 1) - 1) / (D*D - 1); - - dfdP[0] = (x*x*x - 1) - (x*x-1)*(D*D*D-1)/(D*D-1); - - return skcms_eval_curve(arg->curve, x) - - eval_poly_tf(A,B,C,D, x); -} - -static bool fit_poly_tf(const skcms_Curve* curve, skcms_PolyTF* tf) { - if (curve->table_entries > (uint32_t)INT_MAX) { - return false; - } - - 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. - skcms_TransferFunction baseline; - float err; - if (curve->table_entries == 0) { - baseline = curve->parametric; - } 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) { - if (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; - } else { - return false; // Just like baseline.f != 0 above, can't represent this offset. - } - } - - // 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/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. - // We could connect the last point with a quadratic, but let's just be lazy. - return false; - } - - skcms_TransferFunction inv; - if (!skcms_TransferFunction_invert(&baseline, &inv)) { - return false; - } - - // Start with guess A = 0, i.e. f(x) ≈ x^2. - float P[3] = {0, 0,0}; - for (int i = 0; i < 3; i++) { - rg_poly_tf_arg arg = { curve, tf }; - if (!skcms_gauss_newton_step(rg_poly_tf, &arg, - P, - L*dx, dx, N-L)) { - return false; - } - } - - float A = tf->A = P[0], - C = tf->C, - D = tf->D, - B = 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(A,B,C,D, x)) - * (N-1) + 0.5f; - if (!isfinitef_(rt) || rt >= N || rt < 0) { - return false; - } - - const int tol = (i == 0 || i == N-1) ? 0 - : N/256; - if (abs(i - (int)rt) > tol) { - return false; - } - } - return true; -} - -void skcms_OptimizeForSpeed(skcms_ICCProfile* profile) { - for (int i = 0; profile->has_trc && i < 3; i++) { - if (!profile->has_poly_tf[i]) { - profile->has_poly_tf[i] = fit_poly_tf(&profile->trc[i], &profile->poly_tf[i]); - } - } -} diff --git a/third_party/skcms/src/Transform.c b/third_party/skcms/src/Transform.c index 79feebcb01..791671e6f9 100644 --- a/third_party/skcms/src/Transform.c +++ b/third_party/skcms/src/Transform.c @@ -321,11 +321,6 @@ typedef struct { const void* arg; } OpAndArg; -static OpAndArg select_poly_tf_op(const skcms_PolyTF* tf, int channel) { - static const Op ops[] = { Op_poly_tf_r, Op_poly_tf_g, Op_poly_tf_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 }, @@ -518,9 +513,6 @@ bool skcms_Transform(const void* src, for (int i = 0; i < 3; i++) { OpAndArg oa = select_curve_op(&srcProfile->trc[i], i); if (oa.op != Op_noop) { - if (srcProfile->has_poly_tf[i]) { - oa = select_poly_tf_op(&srcProfile->poly_tf[i], i); - } *ops++ = oa.op; *args++ = oa.arg; } diff --git a/third_party/skcms/src/Transform.h b/third_party/skcms/src/Transform.h index c5892f1377..1c4c15b4e3 100644 --- a/third_party/skcms/src/Transform.h +++ b/third_party/skcms/src/Transform.h @@ -34,9 +34,6 @@ M(tf_g) \ M(tf_b) \ M(tf_a) \ - M(poly_tf_r) \ - M(poly_tf_g) \ - M(poly_tf_b) \ M(table_8_r) \ M(table_8_g) \ M(table_8_b) \ diff --git a/third_party/skcms/src/Transform_inl.h b/third_party/skcms/src/Transform_inl.h index 97b2ea0c07..cb11777e52 100644 --- a/third_party/skcms/src/Transform_inl.h +++ b/third_party/skcms/src/Transform_inl.h @@ -252,13 +252,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_poly_tf_)(const skcms_PolyTF* tf, F x) { - // TODO: handle x<0 - return (F)if_then_else(x < tf->D, tf->C*x - , tf->A*(x*x*x-1) + tf->B*(x*x-1) + 1); -} -#define apply_poly_tf NS(apply_poly_tf_) - // Strided loads and stores of N values, starting from p. #if N == 1 #define LOAD_3(T, p) (T)(p)[0] @@ -860,10 +853,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_poly_tf_r:{ r = apply_poly_tf(*args++, r); } break; - case Op_poly_tf_g:{ g = apply_poly_tf(*args++, g); } break; - case Op_poly_tf_b:{ b = apply_poly_tf(*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; diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1 index e72ae03313..1ca44cf38f 100755 --- a/third_party/skcms/version.sha1 +++ b/third_party/skcms/version.sha1 @@ -1 +1 @@ -06d773bdba22d7d60599a3da5c8475bba3f45934 \ No newline at end of file +3f444c5a52cb85be179f86ab1bef61719d2d949f \ No newline at end of file -- cgit v1.2.3