Revert "WIP: Skia support library for ICC tasks"

This reverts commit fc8dc3194a.

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>
This commit is contained in:
Ravi Mistry 2016-12-17 01:26:51 +00:00 committed by Skia Commit-Bot
parent 2ee084e730
commit eb733fbf56
11 changed files with 48 additions and 320 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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

View File

@ -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;
}
}

View File

@ -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()));
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);
}
}
}

View File

@ -47,10 +47,15 @@ public:
return nullptr;
}
bool onGammaCloseToSRGB() const override {
// 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; }
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?

View File

@ -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;
@ -162,8 +158,6 @@ public:
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

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}