diff options
author | Matt Sarett <msarett@google.com> | 2017-01-04 10:53:31 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-04 16:26:58 +0000 |
commit | 1e854246e6ce431838de882116b86f085eb7b08e (patch) | |
tree | 884fa978dca95b0bd0494af1f9a216dec418725c | |
parent | e2b66a769b19780c87a5baf1ecff48158fd63e45 (diff) |
Improve detection of color space transfer fns
BUG=skia:
Change-Id: I744af0efd4d48a8932b834092ed2dbad13008c1d
Reviewed-on: https://skia-review.googlesource.com/6556
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
-rw-r--r-- | src/core/SkColorSpace.cpp | 4 | ||||
-rw-r--r-- | src/core/SkColorSpacePriv.h | 32 | ||||
-rw-r--r-- | tests/ColorSpaceTest.cpp | 54 |
3 files changed, 82 insertions, 8 deletions
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp index f6cbf0acac..239a61bcce 100644 --- a/src/core/SkColorSpace.cpp +++ b/src/core/SkColorSpace.cpp @@ -165,6 +165,10 @@ sk_sp<SkColorSpace> SkColorSpace::MakeRGB(const SkColorSpaceTransferFn& coeffs, return SkColorSpace_Base::MakeRGB(k2Dot2Curve_SkGammaNamed, toXYZD50); } + if (is_almost_linear(coeffs)) { + return SkColorSpace_Base::MakeRGB(kLinear_SkGammaNamed, toXYZD50); + } + void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(SkColorSpaceTransferFn)); sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas(3)); SkColorSpaceTransferFn* fn = SkTAddOffset<SkColorSpaceTransferFn>(memory, sizeof(SkGammas)); diff --git a/src/core/SkColorSpacePriv.h b/src/core/SkColorSpacePriv.h index 9f084e72fc..5b09036ea8 100644 --- a/src/core/SkColorSpacePriv.h +++ b/src/core/SkColorSpacePriv.h @@ -51,7 +51,7 @@ static inline bool is_valid_transfer_fn(const SkColorSpaceTransferFn& coeffs) { } if (coeffs.fD == 0.0f) { - // Y = (aX + b)^g + c for always + // Y = (aX + b)^g + e for always if (0.0f == coeffs.fA || 0.0f == coeffs.fG) { SkColorSpacePrintf("A or G is zero, constant transfer function " "is nonsense"); @@ -60,16 +60,16 @@ static inline bool is_valid_transfer_fn(const SkColorSpaceTransferFn& coeffs) { } if (coeffs.fD >= 1.0f) { - // Y = eX + f for always - if (0.0f == coeffs.fE) { - SkColorSpacePrintf("E is zero, constant transfer function is " + // Y = cX + f for always + if (0.0f == coeffs.fC) { + SkColorSpacePrintf("C is zero, constant transfer function is " "nonsense"); return false; } } if ((0.0f == coeffs.fA || 0.0f == coeffs.fG) && 0.0f == coeffs.fC) { - SkColorSpacePrintf("A or G, and E are zero, constant transfer function " + SkColorSpacePrintf("A or G, and C are zero, constant transfer function " "is nonsense"); return false; } @@ -100,11 +100,27 @@ static inline bool is_almost_srgb(const SkColorSpaceTransferFn& coeffs) { 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.fC) && - color_space_almost_equal(0.0f, coeffs.fD) && color_space_almost_equal(0.0f, coeffs.fE) && + color_space_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; + + // OutputVal = 1.0f * InputVal + const bool linearFn = + color_space_almost_equal(1.0f, coeffs.fC) && color_space_almost_equal(0.0f, coeffs.fF) && - color_space_almost_equal(2.2f, coeffs.fG); + coeffs.fD >= 1.0f; + + return linearExp || linearFn; } static inline void value_to_parametric(SkColorSpaceTransferFn* coeffs, float exponent) { diff --git a/tests/ColorSpaceTest.cpp b/tests/ColorSpaceTest.cpp index df253c09e3..ba355cd612 100644 --- a/tests/ColorSpaceTest.cpp +++ b/tests/ColorSpaceTest.cpp @@ -10,6 +10,7 @@ #include "SkColorSpace.h" #include "SkColorSpace_Base.h" #include "SkColorSpace_XYZ.h" +#include "SkColorSpacePriv.h" #include "Test.h" #include "png.h" @@ -111,6 +112,17 @@ DEF_TEST(ColorSpaceSRGBCompare, r) { SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, srgbToxyzD50); REPORTER_ASSERT(r, rgbColorSpace == namedColorSpace); + SkColorSpaceTransferFn srgbFn; + srgbFn.fA = (1.0f / 1.055f); + srgbFn.fB = (0.055f / 1.055f); + srgbFn.fC = (1.0f / 12.92f); + srgbFn.fD = 0.04045f; + srgbFn.fE = 0.0f; + srgbFn.fF = 0.0f; + srgbFn.fG = 2.4f; + sk_sp<SkColorSpace> rgbColorSpace2 = SkColorSpace::MakeRGB(srgbFn, srgbToxyzD50); + REPORTER_ASSERT(r, rgbColorSpace2 == namedColorSpace); + // Change a single value from the sRGB matrix srgbToxyzD50.set(2, 2, 0.5f); sk_sp<SkColorSpace> strangeColorSpace = @@ -135,6 +147,28 @@ DEF_TEST(ColorSpaceSRGBLinearCompare, r) { SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, srgbToxyzD50); REPORTER_ASSERT(r, rgbColorSpace == namedColorSpace); + SkColorSpaceTransferFn linearExpFn; + linearExpFn.fA = 1.0f; + linearExpFn.fB = 0.0f; + linearExpFn.fC = 0.0f; + linearExpFn.fD = 0.0f; + linearExpFn.fE = 0.0f; + linearExpFn.fF = 0.0f; + linearExpFn.fG = 1.0f; + sk_sp<SkColorSpace> rgbColorSpace2 = SkColorSpace::MakeRGB(linearExpFn, srgbToxyzD50); + REPORTER_ASSERT(r, rgbColorSpace2 == namedColorSpace); + + SkColorSpaceTransferFn linearFn; + linearFn.fA = 0.0f; + linearFn.fB = 0.0f; + linearFn.fC = 1.0f; + linearFn.fD = 1.0f; + linearFn.fE = 0.0f; + linearFn.fF = 0.0f; + linearFn.fG = 0.0f; + sk_sp<SkColorSpace> rgbColorSpace3 = SkColorSpace::MakeRGB(linearFn, srgbToxyzD50); + REPORTER_ASSERT(r, rgbColorSpace3 == namedColorSpace); + // Change a single value from the sRGB matrix srgbToxyzD50.set(2, 2, 0.5f); sk_sp<SkColorSpace> strangeColorSpace = @@ -142,6 +176,26 @@ DEF_TEST(ColorSpaceSRGBLinearCompare, r) { REPORTER_ASSERT(r, strangeColorSpace != namedColorSpace); } +DEF_TEST(ColorSpaceAdobeCompare, r) { + // Create an sRGB color space by name + sk_sp<SkColorSpace> namedColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kAdobeRGB_Named); + + // Create an sRGB color space by value + SkMatrix44 adobeToxyzD50(SkMatrix44::kUninitialized_Constructor); + adobeToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50); + + SkColorSpaceTransferFn fn; + fn.fA = 1.0f; + fn.fB = 0.0f; + fn.fC = 0.0f; + fn.fD = 0.0f; + fn.fE = 0.0f; + fn.fF = 0.0f; + fn.fG = 2.2f; + sk_sp<SkColorSpace> rgbColorSpace = SkColorSpace::MakeRGB(fn, adobeToxyzD50); + REPORTER_ASSERT(r, rgbColorSpace == namedColorSpace); +} + DEF_TEST(ColorSpace_Named, r) { const struct { SkColorSpace::Named fNamed; |