From f85f2a9c9314242a727afcaee00d07f14c6a48b0 Mon Sep 17 00:00:00 2001 From: Matt Sarett Date: Mon, 13 Mar 2017 18:21:42 -0400 Subject: Increase precision of equality checking for color space transfer fns BUG=skia: Change-Id: I7b921d34539c071e63a47fb7151dc1dcdaa08cb3 Reviewed-on: https://skia-review.googlesource.com/9636 Commit-Queue: Brian Osman Reviewed-by: Brian Osman --- src/core/SkColorSpacePriv.h | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/core/SkColorSpacePriv.h b/src/core/SkColorSpacePriv.h index 0f5af2781e..4a63ddfa14 100644 --- a/src/core/SkColorSpacePriv.h +++ b/src/core/SkColorSpacePriv.h @@ -58,6 +58,12 @@ static inline bool color_space_almost_equal(float a, float b) { return SkTAbs(a - b) < 0.01f; } +// Let's use a stricter version for transfer functions. Worst case, these are encoded +// in ICC format, which offers 16-bits of fractional precision. +static inline bool transfer_fn_almost_equal(float a, float b) { + return SkTAbs(a - b) < 0.001f; +} + static inline bool is_zero_to_one(float v) { // Because we allow a value just barely larger than 1, the client can use an // entirely linear transfer function. @@ -115,37 +121,37 @@ static inline bool is_valid_transfer_fn(const SkColorSpaceTransferFn& coeffs) { } static inline bool is_almost_srgb(const SkColorSpaceTransferFn& coeffs) { - return color_space_almost_equal(1.0f / 1.055f, coeffs.fA) && - color_space_almost_equal(0.055f / 1.055f, coeffs.fB) && - color_space_almost_equal(1.0f / 12.92f, coeffs.fC) && - color_space_almost_equal(0.04045f, coeffs.fD) && - color_space_almost_equal(0.00000f, coeffs.fE) && - color_space_almost_equal(0.00000f, coeffs.fF) && - color_space_almost_equal(2.40000f, coeffs.fG); + return transfer_fn_almost_equal(1.0f / 1.055f, coeffs.fA) && + transfer_fn_almost_equal(0.055f / 1.055f, coeffs.fB) && + transfer_fn_almost_equal(1.0f / 12.92f, coeffs.fC) && + transfer_fn_almost_equal(0.04045f, coeffs.fD) && + transfer_fn_almost_equal(0.00000f, coeffs.fE) && + transfer_fn_almost_equal(0.00000f, coeffs.fF) && + transfer_fn_almost_equal(2.40000f, coeffs.fG); } static inline bool is_almost_2dot2(const SkColorSpaceTransferFn& coeffs) { - return color_space_almost_equal(1.0f, coeffs.fA) && - color_space_almost_equal(0.0f, coeffs.fB) && - color_space_almost_equal(0.0f, coeffs.fE) && - color_space_almost_equal(2.2f, coeffs.fG) && + return transfer_fn_almost_equal(1.0f, coeffs.fA) && + transfer_fn_almost_equal(0.0f, coeffs.fB) && + transfer_fn_almost_equal(0.0f, coeffs.fE) && + transfer_fn_almost_equal(2.2f, coeffs.fG) && coeffs.fD <= 0.0f; } static inline bool is_almost_linear(const SkColorSpaceTransferFn& coeffs) { // OutputVal = InputVal ^ 1.0f const bool linearExp = - color_space_almost_equal(1.0f, coeffs.fA) && - color_space_almost_equal(0.0f, coeffs.fB) && - color_space_almost_equal(0.0f, coeffs.fE) && - color_space_almost_equal(1.0f, coeffs.fG) && - coeffs.fD <= 0.0f; + transfer_fn_almost_equal(1.0f, coeffs.fA) && + transfer_fn_almost_equal(0.0f, coeffs.fB) && + transfer_fn_almost_equal(0.0f, coeffs.fE) && + transfer_fn_almost_equal(1.0f, coeffs.fG) && + coeffs.fD <= 0.0f; // OutputVal = 1.0f * InputVal const bool linearFn = - color_space_almost_equal(1.0f, coeffs.fC) && - color_space_almost_equal(0.0f, coeffs.fF) && - coeffs.fD >= 1.0f; + transfer_fn_almost_equal(1.0f, coeffs.fC) && + transfer_fn_almost_equal(0.0f, coeffs.fF) && + coeffs.fD >= 1.0f; return linearExp || linearFn; } -- cgit v1.2.3