diff options
author | Ravi Mistry <rmistry@google.com> | 2016-12-17 01:26:51 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-17 01:27:10 +0000 |
commit | eb733fbf56538838a36814c75cd03f917462cb22 (patch) | |
tree | 2ac19e158200809964bffad6d5ca1794c84c4d8f | |
parent | 2ee084e73056b0ad76b721017f576168b7306da3 (diff) |
Revert "WIP: Skia support library for ICC tasks"
This reverts commit fc8dc3194acb959ee5980b41766660ca0644bcab.
Reason for revert: Breaks Build-Mac-Clang-Arm7-{Debug,Release}-iOS builds.
Example tasks:
* https://chromium-swarm.appspot.com/task?id=3322f668620b9e10&refresh=10
* https://chromium-swarm.appspot.com/task?id=332296146331e810&refresh=10
Original change's description:
> WIP: Skia support library for ICC tasks
>
> As a starting point, this would be mostly trivial to implement using
> SkColorSpace.
>
> This also would give us the flexibility to begin to move all of
> the ICC related code from SkColorSpace to SkICC.
>
> What are the advantages of moving this away from SkColorSpace?
> (1) A long term goal (once Chrome uses SkCodec), might be to
> move SkColorSpace::MakeICC() out of the public API. That way,
> we can guarantee that we can draw to/from *any* SkColorSpace.
> (2) Keeps SkColorSpace separate from ICC-specific representations
> like SkColorSpaceTransferFn etc.
>
> BUG=skia:
>
> Change-Id: Iddeb9903221fb57fbfc01218d8641c928b4a5165
> Reviewed-on: https://skia-review.googlesource.com/5676
> Commit-Queue: Matt Sarett <msarett@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Reed <reed@google.com>
>
TBR=mtklein@google.com,msarett@google.com,brianosman@google.com,reed@google.com,reviews@skia.org
BUG=skia:
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Change-Id: Ibdf272fce25892402bd3e85595fb8814cdf59856
Reviewed-on: https://skia-review.googlesource.com/6232
Commit-Queue: Ravi Mistry <rmistry@google.com>
Reviewed-by: Ravi Mistry <rmistry@google.com>
-rw-r--r-- | gn/core.gni | 1 | ||||
-rw-r--r-- | gn/tests.gni | 1 | ||||
-rw-r--r-- | include/core/SkICC.h | 73 | ||||
-rw-r--r-- | src/core/SkColorSpacePriv.h | 51 | ||||
-rw-r--r-- | src/core/SkColorSpaceXform_A2B.cpp | 56 | ||||
-rw-r--r-- | src/core/SkColorSpace_A2B.h | 13 | ||||
-rw-r--r-- | src/core/SkColorSpace_Base.h | 12 | ||||
-rw-r--r-- | src/core/SkColorSpace_XYZ.cpp | 26 | ||||
-rw-r--r-- | src/core/SkColorSpace_XYZ.h | 2 | ||||
-rw-r--r-- | src/core/SkICC.cpp | 36 | ||||
-rw-r--r-- | tests/ICCTest.cpp | 97 |
11 files changed, 48 insertions, 320 deletions
diff --git a/gn/core.gni b/gn/core.gni index 2e457531c8..d88ac5a299 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -153,7 +153,6 @@ skia_core_sources = [ "$_src/core/SkGraphics.cpp", "$_src/core/SkHalf.cpp", "$_src/core/SkHalf.h", - "$_src/core/SkICC.cpp", "$_src/core/SkImageFilter.cpp", "$_src/core/SkImageFilterCache.cpp", "$_src/core/SkImageFilterCache.h", diff --git a/gn/tests.gni b/gn/tests.gni index 79fd4be34c..5f2d8b7931 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -99,7 +99,6 @@ tests_sources = [ "$_tests/GrTRecorderTest.cpp", "$_tests/HashTest.cpp", "$_tests/image-bitmap.cpp", - "$_tests/ICCTest.cpp", "$_tests/ImageCacheTest.cpp", "$_tests/ImageFilterCacheTest.cpp", "$_tests/ImageFilterTest.cpp", diff --git a/include/core/SkICC.h b/include/core/SkICC.h deleted file mode 100644 index 3780498df9..0000000000 --- a/include/core/SkICC.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkICC_DEFINED -#define SkICC_DEFINED - -#include "SkRefCnt.h" - -struct SkColorSpaceTransferFn; -class SkColorSpace; -class SkData; -class SkMatrix44; - -class SK_API SkICC : public SkRefCnt { -public: - - /** - * Parse an ICC profile. - * - * Returns nullptr if the data is not a valid ICC profile or if the profile - * input space is not RGB. - */ - static sk_sp<SkICC> Make(const void*, size_t); - - /** - * If the gamut can be represented as transformation into XYZ D50, returns - * true and sets the proper values in |toXYZD50|. - * - * If not, returns false. This indicates that the ICC data is too complex - * to isolate a simple gamut transformation. - */ - bool toXYZD50(SkMatrix44* toXYZD50) const; - - /** - * If the transfer function can be represented as coefficients to the standard - * equation, returns true and sets |fn| to the proper values. - * - * If not, returns false. This indicates one of the following: - * (1) The R, G, and B transfer functions are not the same. - * (2) The transfer function is represented as a table that we have not managed - * to match to a standard curve. - * (3) The ICC data is too complex to isolate a single transfer function. - */ - bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const; - - /** - * If the transfer function can be approximated as coefficients to the standard - * equation, returns true and sets |fn| to the proper values. - * - * If not, returns false. This indicates one of the following: - * (1) The R, G, and B transfer functions are not the same. - * (2) The transfer function is represented as a table that is not increasing with - * end points at zero and one. - * (3) The ICC data is too complex to isolate a single transfer function. - */ - bool approximateNumericalTransferFn(SkColorSpaceTransferFn* fn) const; - - /** - * Write an ICC profile with transfer function |fn| and gamut |toXYZD50|. - */ - static sk_sp<SkData> WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix44& toXYZD50); - -private: - SkICC(sk_sp<SkColorSpace> colorSpace); - - sk_sp<SkColorSpace> fColorSpace; -}; - -#endif diff --git a/src/core/SkColorSpacePriv.h b/src/core/SkColorSpacePriv.h index 32981ae875..73038738ff 100644 --- a/src/core/SkColorSpacePriv.h +++ b/src/core/SkColorSpacePriv.h @@ -5,22 +5,14 @@ * found in the LICENSE file. */ -#include <math.h> - #define SkColorSpacePrintf(...) static inline bool color_space_almost_equal(float a, float b) { return SkTAbs(a - b) < 0.01f; } -static inline float add_epsilon(float v) { - return v + FLT_MIN; -} - 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. - return (0.0f <= v) && (v <= add_epsilon(1.0f)); + return (0.0f <= v) && (v <= 1.0f); } static inline bool is_valid_transfer_fn(const SkColorSpaceTransferFn& coeffs) { @@ -92,44 +84,3 @@ static inline bool is_almost_2dot2(const SkColorSpaceTransferFn& coeffs) { color_space_almost_equal(0.0f, coeffs.fF) && color_space_almost_equal(2.2f, coeffs.fG); } - -static inline void value_to_parametric(SkColorSpaceTransferFn* coeffs, float exponent) { - coeffs->fA = 1.0f; - coeffs->fB = 0.0f; - coeffs->fC = 0.0f; - coeffs->fD = 0.0f; - coeffs->fE = 0.0f; - coeffs->fF = 0.0f; - coeffs->fG = exponent; -} - -static inline bool named_to_parametric(SkColorSpaceTransferFn* coeffs, - SkGammaNamed gammaNamed) { - switch (gammaNamed) { - case kSRGB_SkGammaNamed: - coeffs->fA = 1.0f / 1.055f; - coeffs->fB = 0.055f / 1.055f; - coeffs->fC = 0.0f; - coeffs->fD = 0.04045f; - coeffs->fE = 1.0f / 12.92f; - coeffs->fF = 0.0f; - coeffs->fG = 2.4f; - return true; - case k2Dot2Curve_SkGammaNamed: - value_to_parametric(coeffs, 2.2f); - return true; - case kLinear_SkGammaNamed: - coeffs->fA = 0.0f; - coeffs->fB = 0.0f; - coeffs->fC = 0.0f; - // Make sure that we use the linear segment of the transfer function even - // when the x-value is 1.0f. - coeffs->fD = add_epsilon(1.0f); - coeffs->fE = 1.0f; - coeffs->fF = 0.0f; - coeffs->fG = 0.0f; - return true; - default: - return false; - } -} diff --git a/src/core/SkColorSpaceXform_A2B.cpp b/src/core/SkColorSpaceXform_A2B.cpp index cb8dd57f9d..83f1d910ae 100644 --- a/src/core/SkColorSpaceXform_A2B.cpp +++ b/src/core/SkColorSpaceXform_A2B.cpp @@ -69,19 +69,35 @@ bool SkColorSpaceXform_A2B::onApply(ColorFormat dstFormat, void* dst, ColorForma return true; } -static inline bool gamma_to_parametric(SkColorSpaceTransferFn* coeffs, const SkGammas& gammas, - int channel) { +static inline SkColorSpaceTransferFn value_to_parametric(float exp) { + return {exp, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f}; +} + +static inline SkColorSpaceTransferFn gammanamed_to_parametric(SkGammaNamed gammaNamed) { + switch (gammaNamed) { + case kLinear_SkGammaNamed: + return value_to_parametric(1.f); + case kSRGB_SkGammaNamed: + return {2.4f, (1.f / 1.055f), (0.055f / 1.055f), 0.f, 0.04045f, (1.f / 12.92f), 0.f}; + case k2Dot2Curve_SkGammaNamed: + return value_to_parametric(2.2f); + default: + SkASSERT(false); + return {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; + } +} + +static inline SkColorSpaceTransferFn gamma_to_parametric(const SkGammas& gammas, int channel) { switch (gammas.type(channel)) { case SkGammas::Type::kNamed_Type: - return named_to_parametric(coeffs, gammas.data(channel).fNamed); + return gammanamed_to_parametric(gammas.data(channel).fNamed); case SkGammas::Type::kValue_Type: - value_to_parametric(coeffs, gammas.data(channel).fValue); - return true; + return value_to_parametric(gammas.data(channel).fValue); case SkGammas::Type::kParam_Type: - *coeffs = gammas.params(channel); - return true; + return gammas.params(channel); default: - return false; + SkASSERT(false); + return {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; } } static inline SkColorSpaceTransferFn invert_parametric(const SkColorSpaceTransferFn& fn) { @@ -167,10 +183,6 @@ SkColorSpaceXform_A2B::SkColorSpaceXform_A2B(SkColorSpace_A2B* srcSpace, currentChannels = e.outputChannels(); switch (e.type()) { case SkColorSpace_A2B::Element::Type::kGammaNamed: - if (kLinear_SkGammaNamed == e.gammaNamed()) { - break; - } - // take the fast path for 3-channel named gammas if (3 == currentChannels) { if (k2Dot2Curve_SkGammaNamed == e.gammaNamed()) { @@ -184,11 +196,12 @@ SkColorSpaceXform_A2B::SkColorSpaceXform_A2B(SkColorSpace_A2B* srcSpace, break; } } - - SkCSXformPrintf("Gamma stage added: %s\n", debugGammaNamed[(int)e.gammaNamed()]); - SkColorSpaceTransferFn fn; - SkAssertResult(named_to_parametric(&fn, e.gammaNamed())); - this->addTransferFns(fn, currentChannels); + if (kLinear_SkGammaNamed != e.gammaNamed()) { + SkCSXformPrintf("Gamma stage added: %s\n", + debugGammaNamed[(int)e.gammaNamed()]); + SkColorSpaceTransferFn fn = gammanamed_to_parametric(e.gammaNamed()); + this->addTransferFns(fn, currentChannels); + } break; case SkColorSpace_A2B::Element::Type::kGammas: { const SkGammas& gammas = e.gammas(); @@ -208,8 +221,7 @@ SkColorSpaceXform_A2B::SkColorSpaceXform_A2B(SkColorSpace_A2B* srcSpace, this->addTableFn(table, channel); gammaNeedsRef = true; } else { - SkColorSpaceTransferFn fn; - SkAssertResult(gamma_to_parametric(&fn, gammas, channel)); + SkColorSpaceTransferFn fn = gamma_to_parametric(gammas, channel); this->addTransferFn(fn, channel); } } @@ -289,9 +301,9 @@ SkColorSpaceXform_A2B::SkColorSpaceXform_A2B(SkColorSpace_A2B* srcSpace, this->addTableFn(table, channel); } else { - SkColorSpaceTransferFn fn; - SkAssertResult(gamma_to_parametric(&fn, gammas, channel)); - this->addTransferFn(invert_parametric(fn), channel); + SkColorSpaceTransferFn fn = + invert_parametric(gamma_to_parametric(gammas, channel)); + this->addTransferFn(fn, channel); } } } diff --git a/src/core/SkColorSpace_A2B.h b/src/core/SkColorSpace_A2B.h index 084c5934ce..ed90713a2c 100644 --- a/src/core/SkColorSpace_A2B.h +++ b/src/core/SkColorSpace_A2B.h @@ -47,10 +47,15 @@ public: return nullptr; } - // There is no single gamma curve in an A2B0 profile - bool onGammaCloseToSRGB() const override { return false; } - bool onGammaIsLinear() const override { return false; } - bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const override { return false; } + bool onGammaCloseToSRGB() const override { + // There is no single gamma curve in an A2B0 profile + return false; + } + + bool onGammaIsLinear() const override { + // There is no single gamma curve in an A2B0 profile + return false; + } sk_sp<SkColorSpace> makeLinearGamma() override { // TODO: Analyze the extrema of our projection into XYZ and use suitable primaries? diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h index af8ec3133f..e7dbf128b4 100644 --- a/src/core/SkColorSpace_Base.h +++ b/src/core/SkColorSpace_Base.h @@ -55,10 +55,6 @@ struct SkGammas : SkRefCnt { this->fTable.fSize == that.fTable.fSize; } - inline bool operator!=(const Data& that) const { - return !(*this == that); - } - SkGammaNamed fNamed; float fValue; Table fTable; @@ -157,13 +153,11 @@ public: * Returns nullptr if color gamut cannot be described in terms of XYZ D50. */ virtual const SkMatrix44* fromXYZD50() const = 0; - + virtual bool onGammaCloseToSRGB() const = 0; - + virtual bool onGammaIsLinear() const = 0; - - virtual bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const = 0; - + /** * Returns a color space with the same gamut as this one, but with a linear gamma. * For color spaces whose gamut can not be described in terms of XYZ D50, returns diff --git a/src/core/SkColorSpace_XYZ.cpp b/src/core/SkColorSpace_XYZ.cpp index 30f70b6e26..b91789614f 100644 --- a/src/core/SkColorSpace_XYZ.cpp +++ b/src/core/SkColorSpace_XYZ.cpp @@ -5,9 +5,8 @@ * found in the LICENSE file. */ -#include "SkChecksum.h" #include "SkColorSpace_XYZ.h" -#include "SkColorSpacePriv.h" +#include "SkChecksum.h" #include "SkColorSpaceXform_Base.h" static constexpr float gSRGB_toXYZD50[] { @@ -65,29 +64,6 @@ bool SkColorSpace_XYZ::onGammaIsLinear() const { return kLinear_SkGammaNamed == fGammaNamed; } -bool SkColorSpace_XYZ::onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const { - if (named_to_parametric(coeffs, fGammaNamed)) { - return true; - } - - SkASSERT(fGammas); - if (fGammas->data(0) != fGammas->data(1) || fGammas->data(0) != fGammas->data(2)) { - return false; - } - - if (fGammas->isValue(0)) { - value_to_parametric(coeffs, fGammas->data(0).fValue); - return true; - } - - if (fGammas->isParametric(0)) { - *coeffs = fGammas->params(0); - return true; - } - - return false; -} - sk_sp<SkColorSpace> SkColorSpace_XYZ::makeLinearGamma() { if (this->gammaIsLinear()) { return sk_ref_sp(this); diff --git a/src/core/SkColorSpace_XYZ.h b/src/core/SkColorSpace_XYZ.h index d0ce0f813e..4a32188d53 100644 --- a/src/core/SkColorSpace_XYZ.h +++ b/src/core/SkColorSpace_XYZ.h @@ -23,8 +23,6 @@ public: bool onGammaIsLinear() const override; - bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const override; - Type type() const override { return Type::kXYZ; } sk_sp<SkColorSpace> makeLinearGamma() override; diff --git a/src/core/SkICC.cpp b/src/core/SkICC.cpp deleted file mode 100644 index 9a1a3c6e33..0000000000 --- a/src/core/SkICC.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkColorSpace_Base.h" -#include "SkICC.h" - -SkICC::SkICC(sk_sp<SkColorSpace> colorSpace) - : fColorSpace(std::move(colorSpace)) -{} - -sk_sp<SkICC> SkICC::Make(const void* ptr, size_t len) { - sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(ptr, len); - if (!colorSpace) { - return nullptr; - } - - return sk_sp<SkICC>(new SkICC(std::move(colorSpace))); -} - -bool SkICC::toXYZD50(SkMatrix44* toXYZD50) const { - const SkMatrix44* m = as_CSB(fColorSpace)->toXYZD50(); - if (!m) { - return false; - } - - *toXYZD50 = *m; - return true; -} - -bool SkICC::isNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const { - return as_CSB(fColorSpace)->onIsNumericalTransferFn(coeffs); -} diff --git a/tests/ICCTest.cpp b/tests/ICCTest.cpp deleted file mode 100644 index f4639f0003..0000000000 --- a/tests/ICCTest.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "Resources.h" -#include "SkColorSpace.h" -#include "SkData.h" -#include "SkICC.h" -#include "SkMatrix44.h" -#include "Test.h" - -static bool almost_equal(float a, float b) { - return SkTAbs(a - b) < 0.001f; -} - -static inline void test_to_xyz_d50(skiatest::Reporter* r, SkICC* icc, bool shouldSucceed, - const float* reference) { - SkMatrix44 result; - REPORTER_ASSERT(r, shouldSucceed == icc->toXYZD50(&result)); - if (shouldSucceed) { - float resultVals[16]; - result.asColMajorf(resultVals); - for (int i = 0; i < 16; i++) { - REPORTER_ASSERT(r, almost_equal(resultVals[i], reference[i])); - } - } -} - -DEF_TEST(ICC_ToXYZD50, r) { - const float z30Reference[16] = { - 0.59825f, 0.27103f, 0.00603f, 0.0f, 0.22243f, 0.67447f, 0.07368f, 0.0f, 0.14352f, 0.05449f, - 0.74519f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, - }; - - sk_sp<SkData> data = SkData::MakeFromFileName( - GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str()); - sk_sp<SkICC> z30 = SkICC::Make(data->data(), data->size()); - test_to_xyz_d50(r, z30.get(), true, z30Reference); - - const float z32Reference[16] = { - 0.61583f, 0.28789f, 0.00513f, 0.0f, 0.20428f, 0.66972f, 0.06609f, 0.0f, 0.14409f, 0.04237f, - 0.75368f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, - }; - - data = SkData::MakeFromFileName( GetResourcePath("icc_profiles/HP_Z32x.icc").c_str()); - sk_sp<SkICC> z32 = SkICC::Make(data->data(), data->size()); - test_to_xyz_d50(r, z32.get(), true, z32Reference); - - data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperLeft.icc").c_str()); - sk_sp<SkICC> upperLeft = SkICC::Make(data->data(), data->size()); - test_to_xyz_d50(r, upperLeft.get(), false, z32Reference); - - data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperRight.icc").c_str()); - sk_sp<SkICC> upperRight = SkICC::Make(data->data(), data->size()); - test_to_xyz_d50(r, upperRight.get(), false, z32Reference); -} - -static inline void test_is_numerical_transfer_fn(skiatest::Reporter* r, SkICC* icc, - bool shouldSucceed, - const SkColorSpaceTransferFn& reference) { - SkColorSpaceTransferFn result; - REPORTER_ASSERT(r, shouldSucceed == icc->isNumericalTransferFn(&result)); - if (shouldSucceed) { - REPORTER_ASSERT(r, 0 == memcmp(&result, &reference, sizeof(SkColorSpaceTransferFn))); - } -} - -DEF_TEST(ICC_IsNumericalTransferFn, r) { - SkColorSpaceTransferFn referenceFn; - referenceFn.fA = 1.0f; - referenceFn.fB = 0.0f; - referenceFn.fC = 0.0f; - referenceFn.fD = 0.0f; - referenceFn.fE = 0.0f; - referenceFn.fF = 0.0f; - referenceFn.fG = 2.2f; - - sk_sp<SkData> data = SkData::MakeFromFileName( - GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str()); - sk_sp<SkICC> z30 = SkICC::Make(data->data(), data->size()); - test_is_numerical_transfer_fn(r, z30.get(), true, referenceFn); - - data = SkData::MakeFromFileName( GetResourcePath("icc_profiles/HP_Z32x.icc").c_str()); - sk_sp<SkICC> z32 = SkICC::Make(data->data(), data->size()); - test_is_numerical_transfer_fn(r, z32.get(), true, referenceFn); - - data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperLeft.icc").c_str()); - sk_sp<SkICC> upperLeft = SkICC::Make(data->data(), data->size()); - test_is_numerical_transfer_fn(r, upperLeft.get(), false, referenceFn); - - data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperRight.icc").c_str()); - sk_sp<SkICC> upperRight = SkICC::Make(data->data(), data->size()); - test_is_numerical_transfer_fn(r, upperRight.get(), false, referenceFn); -} |