/* * 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_XYZ.h" #include "SkChecksum.h" #include "SkColorSpaceXform_Base.h" static constexpr float gSRGB_toXYZD50[] { 0.4358f, 0.3853f, 0.1430f, // Rx, Gx, Bx 0.2224f, 0.7170f, 0.0606f, // Ry, Gy, Gz 0.0139f, 0.0971f, 0.7139f, // Rz, Gz, Bz }; SkColorSpace_XYZ::SkColorSpace_XYZ(SkGammaNamed gammaNamed, const SkMatrix44& toXYZD50) : INHERITED(nullptr) , fGammaNamed(gammaNamed) , fGammas(nullptr) , fToXYZD50(toXYZD50) , fToXYZD50Hash(SkGoodHash()(toXYZD50)) , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) {} SkColorSpace_XYZ::SkColorSpace_XYZ(SkGammaNamed gammaNamed, sk_sp gammas, const SkMatrix44& toXYZD50, sk_sp profileData) : INHERITED(std::move(profileData)) , fGammaNamed(gammaNamed) , fGammas(std::move(gammas)) , fToXYZD50(toXYZD50) , fToXYZD50Hash(SkGoodHash()(toXYZD50)) , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) {} const SkMatrix44* SkColorSpace_XYZ::fromXYZD50() const { fFromXYZOnce([this] { if (!fToXYZD50.invert(&fFromXYZD50)) { // If a client gives us a dst gamut with a transform that we can't invert, we will // simply give them back a transform to sRGB gamut. SkDEBUGFAIL("Non-invertible XYZ matrix, defaulting to sRGB"); SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); srgbToxyzD50.invert(&fFromXYZD50); } }); return &fFromXYZD50; } bool SkColorSpace_XYZ::onGammaCloseToSRGB() const { return kSRGB_SkGammaNamed == fGammaNamed || k2Dot2Curve_SkGammaNamed == fGammaNamed; } bool SkColorSpace_XYZ::onGammaIsLinear() const { return kLinear_SkGammaNamed == fGammaNamed; } sk_sp SkColorSpace_XYZ::makeLinearGamma() { if (this->gammaIsLinear()) { return sk_ref_sp(this); } return SkColorSpace_Base::MakeRGB(kLinear_SkGammaNamed, fToXYZD50); } void SkColorSpace_XYZ::toDstGammaTables(const uint8_t* tables[3], sk_sp* storage, int numTables) const { fToDstGammaOnce([this, numTables] { const bool gammasAreMatching = numTables <= 1; fDstStorage = SkData::MakeUninitialized(numTables * SkColorSpaceXform_Base::kDstGammaTableSize); SkColorSpaceXform_Base::BuildDstGammaTables(fToDstGammaTables, (uint8_t*) fDstStorage->writable_data(), this, gammasAreMatching); }); *storage = fDstStorage; tables[0] = fToDstGammaTables[0]; tables[1] = fToDstGammaTables[1]; tables[2] = fToDstGammaTables[2]; }