From 3315f7e9c635a3277e8457c77cb9813aae8db5dc Mon Sep 17 00:00:00 2001 From: "skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com" Date: Mon, 23 Apr 2018 18:57:32 +0000 Subject: Roll skia/third_party/skcms fe14a6a..e8bc226 (1 commits) https://skia.googlesource.com/skcms.git/+log/fe14a6a..e8bc226 2018-04-23 mtklein@chromium.org 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. TBR=stani@google.com Change-Id: Ib0c40a1dc5314ee6ca18da6ddac9895977c12bdc Reviewed-on: https://skia-review.googlesource.com/123072 Reviewed-by: skcms-skia-autoroll Commit-Queue: skcms-skia-autoroll --- third_party/skcms/skcms.h | 20 ++++++++++++++------ third_party/skcms/src/ICCProfile.c | 8 ++++++++ third_party/skcms/src/Transform.c | 10 ++++++++++ third_party/skcms/src/Transform.h | 3 +++ third_party/skcms/src/Transform_inl.h | 10 ++++++++++ third_party/skcms/version.sha1 | 2 +- 6 files changed, 46 insertions(+), 7 deletions(-) (limited to 'third_party') diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h index 08779a40e6..9c25b1d538 100644 --- a/third_party/skcms/skcms.h +++ b/third_party/skcms/skcms.h @@ -73,6 +73,12 @@ 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; @@ -97,6 +103,10 @@ 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. @@ -114,15 +124,13 @@ bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A, const skcms_ICC // will be used. 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(). +void skcms_OptimizeForSpeed(skcms_ICCProfile*); + bool skcms_ApproximateCurve(const skcms_Curve* curve, skcms_TransferFunction* approx, float* max_error); -// A specialized approximation for transfer functions with gamma between 1 and 3. -// f(x) = Ax^3 + Bx^2 + (1-A-B)x -typedef struct skcms_TF13 { - float A,B; -} skcms_TF13; - 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 diff --git a/third_party/skcms/src/ICCProfile.c b/third_party/skcms/src/ICCProfile.c index 4eed21c64e..3c3e02abde 100644 --- a/third_party/skcms/src/ICCProfile.c +++ b/third_party/skcms/src/ICCProfile.c @@ -781,6 +781,14 @@ bool skcms_Parse(const void* buf, size_t len, skcms_ICCProfile* profile) { return usable_as_src(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); + } +} + const skcms_ICCProfile skcms_sRGB_profile = { // These fields are moot when not a skcms_Parse()'d profile. .buffer = NULL, diff --git a/third_party/skcms/src/Transform.c b/third_party/skcms/src/Transform.c index ef256b5eb7..cb023c3046 100644 --- a/third_party/skcms/src/Transform.c +++ b/third_party/skcms/src/Transform.c @@ -314,6 +314,11 @@ 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 }, @@ -513,8 +518,13 @@ 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; } diff --git a/third_party/skcms/src/Transform.h b/third_party/skcms/src/Transform.h index 1c4c15b4e3..feb0dbca2a 100644 --- a/third_party/skcms/src/Transform.h +++ b/third_party/skcms/src/Transform.h @@ -34,6 +34,9 @@ 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) \ diff --git a/third_party/skcms/src/Transform_inl.h b/third_party/skcms/src/Transform_inl.h index aba8b7ea16..bc3cc1489d 100644 --- a/third_party/skcms/src/Transform_inl.h +++ b/third_party/skcms/src/Transform_inl.h @@ -239,6 +239,12 @@ 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] @@ -840,6 +846,10 @@ 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; diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1 index d09df616d5..4152b6ef71 100755 --- a/third_party/skcms/version.sha1 +++ b/third_party/skcms/version.sha1 @@ -1 +1 @@ -fe14a6aff9d05024284bbf576a93919c3cf8e9c4 \ No newline at end of file +e8bc22664f84326c18feeb0444f573e8a0c75f42 \ No newline at end of file -- cgit v1.2.3