| Index: src/core/SkColorSpace.cpp
|
| diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
|
| index cc8d0b0606044468e79d51b7fd1ca5d82fd4a8ce..172082b781e9b69fb5b3f984a16497a0c3436ae0 100644
|
| --- a/src/core/SkColorSpace.cpp
|
| +++ b/src/core/SkColorSpace.cpp
|
| @@ -7,31 +7,28 @@
|
|
|
| #include "SkAtomics.h"
|
| #include "SkColorSpace.h"
|
| +#include "SkColorSpacePriv.h"
|
| #include "SkOnce.h"
|
|
|
| static bool color_space_almost_equal(float a, float b) {
|
| return SkTAbs(a - b) < 0.01f;
|
| }
|
|
|
| -void SkFloat3::dump() const {
|
| - SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]);
|
| -}
|
| -
|
| //////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
| static int32_t gUniqueColorSpaceID;
|
|
|
| -SkColorSpace::SkColorSpace(SkGammas gammas, const SkMatrix44& toXYZD50, Named named)
|
| - : fGammas(std::move(gammas))
|
| +SkColorSpace::SkColorSpace(sk_sp<SkGammas> gammas, const SkMatrix44& toXYZD50, Named named)
|
| + : fGammas(gammas)
|
| , fToXYZD50(toXYZD50)
|
| , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
|
| , fNamed(named)
|
| {}
|
|
|
| -SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas,
|
| +SkColorSpace::SkColorSpace(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas,
|
| const SkMatrix44& toXYZD50)
|
| - : fColorLUT(std::move(colorLUT))
|
| - , fGammas(std::move(gammas))
|
| + : fColorLUT(colorLUT)
|
| + , fGammas(gammas)
|
| , fToXYZD50(toXYZD50)
|
| , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
|
| , fNamed(kUnknown_Named)
|
| @@ -74,12 +71,22 @@ static bool xyz_almost_equal(const SkMatrix44& toXYZD50, const float* standard)
|
| color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f);
|
| }
|
|
|
| -sk_sp<SkColorSpace> SkColorSpace::NewRGB(SkGammas gammas, const SkMatrix44& toXYZD50) {
|
| +static SkOnce gStandardGammasOnce;
|
| +static SkGammas* gStandardGammas;
|
| +
|
| +sk_sp<SkColorSpace> SkColorSpace::NewRGB(float gammaVals[3], const SkMatrix44& toXYZD50) {
|
| + sk_sp<SkGammas> gammas = nullptr;
|
| +
|
| // Check if we really have sRGB or Adobe RGB
|
| - if (color_space_almost_equal(2.2f, gammas.fRed.fValue) &&
|
| - color_space_almost_equal(2.2f, gammas.fGreen.fValue) &&
|
| - color_space_almost_equal(2.2f, gammas.fBlue.fValue))
|
| + if (color_space_almost_equal(2.2f, gammaVals[0]) &&
|
| + color_space_almost_equal(2.2f, gammaVals[1]) &&
|
| + color_space_almost_equal(2.2f, gammaVals[2]))
|
| {
|
| + gStandardGammasOnce([] {
|
| + gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f);
|
| + });
|
| + gammas = sk_ref_sp(gStandardGammas);
|
| +
|
| if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) {
|
| return SkColorSpace::NewNamed(kSRGB_Named);
|
| } else if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) {
|
| @@ -87,7 +94,10 @@ sk_sp<SkColorSpace> SkColorSpace::NewRGB(SkGammas gammas, const SkMatrix44& toXY
|
| }
|
| }
|
|
|
| - return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUnknown_Named));
|
| + if (!gammas) {
|
| + gammas = sk_ref_sp(new SkGammas(gammaVals[0], gammaVals[1], gammaVals[2]));
|
| + }
|
| + return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZD50, kUnknown_Named));
|
| }
|
|
|
| sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
| @@ -98,18 +108,26 @@ sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
|
|
| switch (named) {
|
| case kSRGB_Named: {
|
| + gStandardGammasOnce([] {
|
| + gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f);
|
| + });
|
| +
|
| sRGBOnce([] {
|
| SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
|
| srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50);
|
| - sRGB = new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50, kSRGB_Named);
|
| + sRGB = new SkColorSpace(sk_ref_sp(gStandardGammas), srgbToxyzD50, kSRGB_Named);
|
| });
|
| return sk_ref_sp(sRGB);
|
| }
|
| case kAdobeRGB_Named: {
|
| + gStandardGammasOnce([] {
|
| + gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f);
|
| + });
|
| +
|
| adobeRGBOnce([] {
|
| SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Constructor);
|
| adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50);
|
| - adobeRGB = new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), adobergbToxyzD50,
|
| + adobeRGB = new SkColorSpace(sk_ref_sp(gStandardGammas), adobergbToxyzD50,
|
| kAdobeRGB_Named);
|
| });
|
| return sk_ref_sp(adobeRGB);
|
| @@ -536,7 +554,7 @@ bool load_matrix(SkMatrix44* toXYZ, const uint8_t* src, size_t len) {
|
| return true;
|
| }
|
|
|
| -bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, SkGammas* gammas, SkMatrix44* toXYZ,
|
| +bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas, SkMatrix44* toXYZ,
|
| const uint8_t* src, size_t len) {
|
| if (len < 32) {
|
| SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
|
| @@ -662,47 +680,62 @@ sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) {
|
|
|
| // It is not uncommon to see missing or empty gamma tags. This indicates
|
| // that we should use unit gamma.
|
| - SkGammas gammas;
|
| + sk_sp<SkGammas> gammas(new SkGammas());
|
| r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC);
|
| g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC);
|
| b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC);
|
| - if (!r || !SkColorSpace::LoadGammas(&gammas.fRed, 1,
|
| + if (!r || !SkColorSpace::LoadGammas(&gammas->fRed, 1,
|
| r->addr((const uint8_t*) base), r->fLength)) {
|
| SkColorSpacePrintf("Failed to read R gamma tag.\n");
|
| }
|
| - if (!g || !SkColorSpace::LoadGammas(&gammas.fGreen, 1,
|
| + if (!g || !SkColorSpace::LoadGammas(&gammas->fGreen, 1,
|
| g->addr((const uint8_t*) base), g->fLength)) {
|
| SkColorSpacePrintf("Failed to read G gamma tag.\n");
|
| }
|
| - if (!b || !SkColorSpace::LoadGammas(&gammas.fBlue, 1,
|
| + if (!b || !SkColorSpace::LoadGammas(&gammas->fBlue, 1,
|
| b->addr((const uint8_t*) base), b->fLength)) {
|
| SkColorSpacePrintf("Failed to read B gamma tag.\n");
|
| }
|
|
|
| SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
|
| mat.set3x3ColMajorf(toXYZ);
|
| - return SkColorSpace::NewRGB(std::move(gammas), mat);
|
| + if (gammas->isValues()) {
|
| + // When we have values, take advantage of the NewFromRGB initializer.
|
| + // This allows us to check for canonical sRGB and Adobe RGB.
|
| + float gammaVals[3];
|
| + gammaVals[0] = gammas->fRed.fValue;
|
| + gammaVals[1] = gammas->fGreen.fValue;
|
| + gammaVals[2] = gammas->fBlue.fValue;
|
| + return SkColorSpace::NewRGB(gammaVals, mat);
|
| + } else {
|
| + return sk_sp<SkColorSpace>(new SkColorSpace(gammas, mat, kUnknown_Named));
|
| + }
|
| }
|
|
|
| // Recognize color profile specified by A2B0 tag.
|
| const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0);
|
| if (a2b0) {
|
| - SkColorLookUpTable colorLUT;
|
| - SkGammas gammas;
|
| + SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTable());
|
| + sk_sp<SkGammas> gammas(new SkGammas());
|
| SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
|
| - if (!SkColorSpace::LoadA2B0(&colorLUT, &gammas, &toXYZ,
|
| + if (!SkColorSpace::LoadA2B0(colorLUT, gammas, &toXYZ,
|
| a2b0->addr((const uint8_t*) base), a2b0->fLength)) {
|
| return_null("Failed to parse A2B0 tag");
|
| }
|
|
|
| - // If there is no colorLUT, use NewRGB. This allows us to check if the
|
| - // profile is sRGB.
|
| - if (!colorLUT.fTable) {
|
| - return SkColorSpace::NewRGB(std::move(gammas), toXYZ);
|
| + if (colorLUT->fTable) {
|
| + return sk_sp<SkColorSpace>(new SkColorSpace(colorLUT.release(), gammas, toXYZ));
|
| + } else if (gammas->isValues()) {
|
| + // When we have values, take advantage of the NewFromRGB initializer.
|
| + // This allows us to check for canonical sRGB and Adobe RGB.
|
| + float gammaVals[3];
|
| + gammaVals[0] = gammas->fRed.fValue;
|
| + gammaVals[1] = gammas->fGreen.fValue;
|
| + gammaVals[2] = gammas->fBlue.fValue;
|
| + return SkColorSpace::NewRGB(gammaVals, toXYZ);
|
| + } else {
|
| + return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZ, kUnknown_Named));
|
| }
|
| -
|
| - return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas),
|
| - toXYZ));
|
| }
|
|
|
| }
|
|
|