DEF_TEST(ColorSpace_Serialize, r) { test_serialize(r, SkColorSpace::MakeSRGB(), true); test_serialize(r, SkColorSpace::MakeSRGBLinear(), true); auto test = [&](const char* path) { sk_sp<SkData> data = GetResourceAsData(path); skcms_ICCProfile profile; REPORTER_ASSERT(r, skcms_Parse(data->data(), data->size(), &profile)); sk_sp<SkColorSpace> space = SkColorSpace::Make(profile); REPORTER_ASSERT(r, space); test_serialize(r, space, false); }; test("icc_profiles/HP_ZR30w.icc"); test("icc_profiles/HP_Z32x.icc"); skcms_TransferFunction fn; fn.a = 1.0f; fn.b = 0.0f; fn.c = 1.0f; fn.d = 0.5f; fn.e = 0.0f; fn.f = 0.0f; fn.g = 1.0f; skcms_Matrix3x3 toXYZ = {{ { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, }}; test_serialize(r, SkColorSpace::MakeRGB(fn, toXYZ), false); }
std::unique_ptr<SkEncodedInfo::ICCProfile> SkEncodedInfo::ICCProfile::Make(sk_sp<SkData> data) { if (data) { skcms_ICCProfile profile; if (skcms_Parse(data->data(), data->size(), &profile)) { return std::unique_ptr<ICCProfile>(new ICCProfile(profile, std::move(data))); } } return nullptr; }
DEF_TEST(ColorSpace_Equals, r) { sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB(); auto parse = [&](const char* path) { sk_sp<SkData> data = GetResourceAsData(path); skcms_ICCProfile profile; REPORTER_ASSERT(r, skcms_Parse(data->data(), data->size(), &profile)); sk_sp<SkColorSpace> space = SkColorSpace::Make(profile); REPORTER_ASSERT(r, space); return space; }; sk_sp<SkColorSpace> z30 = parse("icc_profiles/HP_ZR30w.icc"); sk_sp<SkColorSpace> z32 = parse("icc_profiles/HP_Z32x.icc"); skcms_TransferFunction fn; fn.a = 1.0f; fn.b = 0.0f; fn.c = 1.0f; fn.d = 0.5f; fn.e = 0.0f; fn.f = 0.0f; fn.g = 1.0f; skcms_Matrix3x3 toXYZ = {{ { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, }}; sk_sp<SkColorSpace> rgb4 = SkColorSpace::MakeRGB(fn, toXYZ); REPORTER_ASSERT(r, SkColorSpace::Equals(nullptr, nullptr)); REPORTER_ASSERT(r, SkColorSpace::Equals(srgb.get(), srgb.get())); REPORTER_ASSERT(r, SkColorSpace::Equals(z30.get(), z30.get())); REPORTER_ASSERT(r, SkColorSpace::Equals(z32.get(), z32.get())); REPORTER_ASSERT(r, SkColorSpace::Equals(rgb4.get(), rgb4.get())); REPORTER_ASSERT(r, !SkColorSpace::Equals(nullptr, srgb.get())); REPORTER_ASSERT(r, !SkColorSpace::Equals(srgb.get(), nullptr)); REPORTER_ASSERT(r, !SkColorSpace::Equals(z30.get(), srgb.get())); REPORTER_ASSERT(r, !SkColorSpace::Equals(z32.get(), z30.get())); REPORTER_ASSERT(r, !SkColorSpace::Equals(z30.get(), rgb4.get())); REPORTER_ASSERT(r, !SkColorSpace::Equals(srgb.get(), rgb4.get())); }
static bool cs_to_profile(const SkColorSpace* cs, skcms_ICCProfile* profile) { if (cs->profileData()) { bool result = skcms_Parse(cs->profileData()->data(), cs->profileData()->size(), profile); // We shouldn't encounter color spaces that were constructed from invalid profiles! SkASSERT(result); return result; } SkMatrix44 toXYZ; SkColorSpaceTransferFn tf; if (cs->toXYZD50(&toXYZ) && cs->isNumericalTransferFn(&tf)) { memset(profile, 0, sizeof(*profile)); profile->has_trc = true; profile->trc[0].parametric.g = tf.fG; profile->trc[0].parametric.a = tf.fA; profile->trc[0].parametric.b = tf.fB; profile->trc[0].parametric.c = tf.fC; profile->trc[0].parametric.d = tf.fD; profile->trc[0].parametric.e = tf.fE; profile->trc[0].parametric.f = tf.fF; profile->trc[1].parametric = profile->trc[0].parametric; profile->trc[2].parametric = profile->trc[0].parametric; profile->has_toXYZD50 = true; for (int r = 0; r < 3; ++r) { for (int c = 0; c < 3; ++c) { profile->toXYZD50.vals[r][c] = toXYZ.get(r, c); } } return true; } // It should be impossible to make a color space that gets here with our available factories. // All ICC-based profiles have profileData. All remaining factories produce XYZ spaces with // a single (numerical) transfer function. SkDEBUGFAIL("How did we get here?"); return false; }