Create a single, unique pointer to sRGB color space
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1945693002 Review-Url: https://codereview.chromium.org/1945693002
This commit is contained in:
parent
4f16e6361d
commit
02125d10d5
@ -236,7 +236,7 @@ sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) {
|
||||
|
||||
SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
|
||||
mat.set3x3ColMajorf(toXYZD50);
|
||||
return SkColorSpace::NewRGB(mat, std::move(gammas));
|
||||
return SkColorSpace::NewRGB(std::move(gammas), mat);
|
||||
}
|
||||
|
||||
// Last, check for gamma.
|
||||
@ -249,7 +249,7 @@ sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) {
|
||||
float value = png_inverted_fixed_point_to_float(gamma);
|
||||
gammas = SkColorSpace::SkGammas(value, value, value);
|
||||
|
||||
return SkColorSpace::NewRGB(SkMatrix44::I(), std::move(gammas));
|
||||
return SkColorSpace::NewRGB(std::move(gammas), SkMatrix44::I());
|
||||
}
|
||||
|
||||
#endif // LIBPNG >= 1.6
|
||||
|
@ -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]);
|
||||
@ -32,23 +37,50 @@ SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas,
|
||||
, fNamed(kUnknown_Named)
|
||||
{}
|
||||
|
||||
sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkMatrix44& toXYZD50, SkGammas gammas) {
|
||||
return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUnknown_Named));
|
||||
}
|
||||
|
||||
const float 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 SkMatrix44& 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.getFloat(0, 0), gSRGB_toXYZD50[0]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(0, 1), gSRGB_toXYZD50[1]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(0, 2), gSRGB_toXYZD50[2]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(1, 0), gSRGB_toXYZD50[3]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(1, 1), gSRGB_toXYZD50[4]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(1, 2), gSRGB_toXYZD50[5]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(2, 0), gSRGB_toXYZD50[6]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(2, 1), gSRGB_toXYZD50[7]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(2, 2), gSRGB_toXYZD50[8]) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) &&
|
||||
color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f))
|
||||
{
|
||||
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: {
|
||||
SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
|
||||
srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50);
|
||||
return sk_sp<SkColorSpace>(new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50,
|
||||
kSRGB_Named));
|
||||
return sk_ref_sp(sRGB.get([=]{
|
||||
return new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50, kSRGB_Named);
|
||||
}));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -89,10 +121,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,9 +605,10 @@ 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");
|
||||
}
|
||||
|
||||
SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
|
||||
mat.set3x3ColMajorf(toXYZ);
|
||||
return SkColorSpace::NewRGB(mat, std::move(gammas));
|
||||
return SkColorSpace::NewRGB(std::move(gammas), mat);
|
||||
}
|
||||
|
||||
// Recognize color profile specified by A2B0 tag.
|
||||
@ -593,6 +622,12 @@ sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* base, size_t len) {
|
||||
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);
|
||||
}
|
||||
|
||||
return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas),
|
||||
toXYZ));
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
* Return a colorspace instance, given a transform from linear_RGB to D50_XYZ
|
||||
* and the src-gamma, return a ColorSpace
|
||||
*/
|
||||
static sk_sp<SkColorSpace> NewRGB(const SkMatrix44& toXYZD50, SkGammas gammas);
|
||||
static sk_sp<SkColorSpace> NewRGB(SkGammas gammas, const SkMatrix44& toXYZD50);
|
||||
|
||||
static sk_sp<SkColorSpace> NewNamed(Named);
|
||||
static sk_sp<SkColorSpace> NewICC(const void*, size_t);
|
||||
|
@ -41,13 +41,14 @@ static void test_space(skiatest::Reporter* r, SkColorSpace* space,
|
||||
}
|
||||
}
|
||||
|
||||
const float g_sRGB_XYZ[] = { 0.4358f, 0.2224f, 0.0139f, // R
|
||||
0.3853f, 0.7170f, 0.0971f, // G
|
||||
0.1430f, 0.0606f, 0.7139f }; // B
|
||||
|
||||
DEF_TEST(ColorSpace_sRGB, r) {
|
||||
const float srgb_r[] = { 0.4358f, 0.2224f, 0.0139f };
|
||||
const float srgb_g[] = { 0.3853f, 0.7170f, 0.0971f };
|
||||
const float srgb_b[] = { 0.1430f, 0.0606f, 0.7139f };
|
||||
const float srgb_gamma[] = { 2.2f, 2.2f, 2.2f };
|
||||
test_space(r, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named).get(),
|
||||
srgb_r, srgb_g, srgb_b, srgb_gamma);
|
||||
g_sRGB_XYZ, &g_sRGB_XYZ[3], &g_sRGB_XYZ[6], srgb_gamma);
|
||||
|
||||
}
|
||||
|
||||
@ -100,3 +101,21 @@ DEF_TEST(ColorSpaceParseJpegICCProfile, r) {
|
||||
const float gamma[] = { 2.2f, 2.2f, 2.2f };
|
||||
test_space(r, colorSpace, red, green, blue, gamma);
|
||||
}
|
||||
|
||||
DEF_TEST(ColorSpaceSRGBCompare, r) {
|
||||
// Create an sRGB color space by name
|
||||
sk_sp<SkColorSpace> namedColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
|
||||
|
||||
// Create an sRGB color space by value
|
||||
SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
|
||||
srgbToxyzD50.set3x3ColMajorf(g_sRGB_XYZ);
|
||||
sk_sp<SkColorSpace> rgbColorSpace = SkColorSpace::NewRGB(
|
||||
SkColorSpace::SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50);
|
||||
REPORTER_ASSERT(r, namedColorSpace == namedColorSpace);
|
||||
|
||||
// Change a single value from the sRGB matrix
|
||||
srgbToxyzD50.set(2, 2, 0.5f);
|
||||
sk_sp<SkColorSpace> strangeColorSpace = SkColorSpace::NewRGB(
|
||||
SkColorSpace::SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50);
|
||||
REPORTER_ASSERT(r, strangeColorSpace != namedColorSpace);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user