Index: src/core/SkColorSpace.cpp |
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp |
index 54495de9407e62d41d9c556e557c7060297f4a3b..fe2a95f7c17bc335b4b7265a0e918c9a922fbede 100644 |
--- a/src/core/SkColorSpace.cpp |
+++ b/src/core/SkColorSpace.cpp |
@@ -7,6 +7,11 @@ |
#include "SkAtomics.h" |
#include "SkColorSpace.h" |
+#include "SkOncePtr.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]); |
@@ -41,21 +46,41 @@ SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas, |
, fNamed(kUnknown_Named) |
{} |
-sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, SkGammas gammas) { |
- return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUnknown_Named)); |
-} |
- |
const SkFloat3x3 gSRGB_toXYZD50 {{ |
0.4358f, 0.2224f, 0.0139f, // * R |
0.3853f, 0.7170f, 0.0971f, // * G |
0.1430f, 0.0606f, 0.7139f, // * B |
}}; |
+SK_DECLARE_STATIC_ONCE_PTR(SkColorSpace, sRGB); |
+ |
+sk_sp<SkColorSpace> SkColorSpace::NewRGB(SkGammas gammas, const SkFloat3x3& toXYZD50) { |
+ // Check if we really have sRGB |
+ 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) && |
+ color_space_almost_equal(toXYZD50.fMat[0], gSRGB_toXYZD50.fMat[0]) && |
+ color_space_almost_equal(toXYZD50.fMat[1], gSRGB_toXYZD50.fMat[1]) && |
+ color_space_almost_equal(toXYZD50.fMat[2], gSRGB_toXYZD50.fMat[2]) && |
+ color_space_almost_equal(toXYZD50.fMat[3], gSRGB_toXYZD50.fMat[3]) && |
+ color_space_almost_equal(toXYZD50.fMat[4], gSRGB_toXYZD50.fMat[4]) && |
+ color_space_almost_equal(toXYZD50.fMat[5], gSRGB_toXYZD50.fMat[5]) && |
+ color_space_almost_equal(toXYZD50.fMat[6], gSRGB_toXYZD50.fMat[6]) && |
+ color_space_almost_equal(toXYZD50.fMat[7], gSRGB_toXYZD50.fMat[7]) && |
+ color_space_almost_equal(toXYZD50.fMat[8], gSRGB_toXYZD50.fMat[8])) |
+ { |
+ return SkColorSpace::NewNamed(kSRGB_Named); |
+ } |
+ |
+ return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUnknown_Named)); |
+} |
+ |
sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { |
switch (named) { |
case kSRGB_Named: |
- return sk_sp<SkColorSpace>(new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), gSRGB_toXYZD50, |
- kSRGB_Named)); |
+ return sk_ref_sp(sRGB.get([=]{ |
+ return new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), gSRGB_toXYZD50, kSRGB_Named); |
+ })); |
default: |
break; |
} |
@@ -95,10 +120,6 @@ static int32_t read_big_endian_int(const uint8_t* ptr) { |
return (int32_t) read_big_endian_uint(ptr); |
} |
-static bool color_space_almost_equal(float a, float b) { |
- return SkTAbs(a - b) < 0.01f; |
-} |
- |
// This is equal to the header size according to the ICC specification (128) |
// plus the size of the tag count (4). We include the tag count since we |
// always require it to be present anyway. |
@@ -577,7 +598,7 @@ sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) { |
b->addr((const uint8_t*) base), b->fLength)) { |
SkColorSpacePrintf("Failed to read B gamma tag.\n"); |
} |
- return SkColorSpace::NewRGB(toXYZ, std::move(gammas)); |
+ return SkColorSpace::NewRGB(std::move(gammas), toXYZ); |
} |
// Recognize color profile specified by A2B0 tag. |
@@ -592,6 +613,13 @@ sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) { |
return_null("Failed to parse A2B0 tag"); |
} |
+ // If there is no colorLUT or xyzOffset, use NewRGB. This allows us to check |
+ // if the profile is sRGB. |
+ if (!colorLUT.fTable && !toXYZOffset.fVec[0] && !toXYZOffset.fVec[1] && |
+ !toXYZOffset.fVec[2]) { |
+ return SkColorSpace::NewRGB(std::move(gammas), toXYZ); |
+ } |
+ |
return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas), |
toXYZ, toXYZOffset)); |
} |