void SkColorSpace::computeLazyDstFields() const { fLazyDstFieldsOnce([this] { // Invert 3x3 gamut, defaulting to sRGB if we can't. { skcms_Matrix3x3 fwd, inv; memcpy(&fwd, fToXYZD50_3x3, 9*sizeof(float)); if (!skcms_Matrix3x3_invert(&fwd, &inv)) { SkAssertResult(skcms_Matrix3x3_invert(&skcms_sRGB_profile()->toXYZD50, &inv)); } memcpy(fFromXYZD50_3x3, &inv, 9*sizeof(float)); } // Invert transfer function, defaulting to sRGB if we can't. { skcms_TransferFunction fwd, inv; this->transferFn(&fwd.g); if (!skcms_TransferFunction_invert(&fwd, &inv)) { inv = *skcms_sRGB_Inverse_TransferFunction(); } memcpy(fInvTransferFn, &inv, 7*sizeof(float)); } }); }
sk_sp<SkColorSpace> SkColorSpace::Make(const skcms_ICCProfile& profile) { // TODO: move below ≈sRGB test? if (!profile.has_toXYZD50 || !profile.has_trc) { return nullptr; } if (skcms_ApproximatelyEqualProfiles(&profile, skcms_sRGB_profile())) { return SkColorSpace::MakeSRGB(); } // TODO: can we save this work and skip lazily inverting the matrix later? skcms_Matrix3x3 inv; if (!skcms_Matrix3x3_invert(&profile.toXYZD50, &inv)) { return nullptr; } // We can't work with tables or mismatched parametric curves, // but if they all look close enough to sRGB, that's fine. // TODO: should we maybe do this unconditionally to snap near-sRGB parametrics to sRGB? const skcms_Curve* trc = profile.trc; if (trc[0].table_entries != 0 || trc[1].table_entries != 0 || trc[2].table_entries != 0 || 0 != memcmp(&trc[0].parametric, &trc[1].parametric, sizeof(trc[0].parametric)) || 0 != memcmp(&trc[0].parametric, &trc[2].parametric, sizeof(trc[0].parametric))) { if (skcms_TRCs_AreApproximateInverse(&profile, skcms_sRGB_Inverse_TransferFunction())) { return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, profile.toXYZD50); } return nullptr; } return SkColorSpace::MakeRGB(profile.trc[0].parametric, profile.toXYZD50); }
DEF_TEST(ColorSpace_skcms_sRGB_exact, r) { skcms_ICCProfile profile; sk_srgb_singleton()->toProfile(&profile); REPORTER_ASSERT(r, 0 == memcmp(&profile, skcms_sRGB_profile(), sizeof(skcms_ICCProfile))); }
DEF_TEST(ColorSpace_skcms_IsSRGB, r) { sk_sp<SkColorSpace> srgb = SkColorSpace::Make(*skcms_sRGB_profile()); REPORTER_ASSERT(r, srgb->isSRGB()); }