DEF_TEST(ColorSpaceWriteICC, r) { // Test writing a new ICC profile sk_sp<SkColorSpace> namedColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); sk_sp<SkData> namedData = as_CSB(namedColorSpace)->writeToICC(); sk_sp<SkColorSpace> iccColorSpace = SkColorSpace::NewICC(namedData->data(), namedData->size()); test_space(r, iccColorSpace.get(), g_sRGB_XYZ, &g_sRGB_XYZ[3], &g_sRGB_XYZ[6], SkColorSpace::k2Dot2Curve_GammaNamed); // FIXME (msarett): Test disabled. sRGB profiles are written approximately as 2.2f curves. // REPORTER_ASSERT(r, iccColorSpace == namedColorSpace); // Test saving the original ICC data sk_sp<SkData> monitorData = SkData::MakeFromFileName( GetResourcePath("monitor_profiles/HP_ZR30w.icc").c_str()); REPORTER_ASSERT(r, monitorData); if (!monitorData) { return; } sk_sp<SkColorSpace> monitorSpace = SkColorSpace::NewICC(monitorData->data(), monitorData->size()); sk_sp<SkData> newMonitorData = as_CSB(monitorSpace)->writeToICC(); sk_sp<SkColorSpace> newMonitorSpace = SkColorSpace::NewICC(newMonitorData->data(), newMonitorData->size()); REPORTER_ASSERT(r, monitorSpace->xyz() == newMonitorSpace->xyz()); REPORTER_ASSERT(r, monitorSpace->gammaNamed() == newMonitorSpace->gammaNamed()); }
sk_sp<SkData> SkColorSpace::serialize() const { // If we have a named profile, only write the enum. switch (fNamed) { case kSRGB_Named: case kAdobeRGB_Named: { sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(ColorSpaceHeader)); *((ColorSpaceHeader*) data->writable_data()) = ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, 0); return data; } default: break; } // If we have a named gamma, write the enum and the matrix. switch (fGammaNamed) { case kSRGB_GammaNamed: case k2Dot2Curve_GammaNamed: case kLinear_GammaNamed: { sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(ColorSpaceHeader) + 12 * sizeof(float)); void* dataPtr = data->writable_data(); *((ColorSpaceHeader*) dataPtr) = ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, ColorSpaceHeader::kMatrix_Flag); dataPtr = SkTAddOffset<void>(dataPtr, sizeof(ColorSpaceHeader)); fToXYZD50.as4x3ColMajorf((float*) dataPtr); return data; } default: break; } // If we do not have a named gamma, this must have been created from an ICC profile. // Since we were unable to recognize the gamma, we will have saved the ICC data. SkASSERT(as_CSB(this)->fProfileData); size_t profileSize = as_CSB(this)->fProfileData->size(); if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { return nullptr; } sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(ColorSpaceHeader) + sizeof(uint32_t) + SkAlign4(profileSize)); void* dataPtr = data->writable_data(); *((ColorSpaceHeader*) dataPtr) = ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, ColorSpaceHeader::kICC_Flag); dataPtr = SkTAddOffset<void>(dataPtr, sizeof(ColorSpaceHeader)); *((uint32_t*) dataPtr) = (uint32_t) SkAlign4(profileSize); dataPtr = SkTAddOffset<void>(dataPtr, sizeof(uint32_t)); memcpy(dataPtr, as_CSB(this)->fProfileData->data(), profileSize); memset(SkTAddOffset<void>(dataPtr, profileSize), 0, SkAlign4(profileSize) - profileSize); return data; }
void ColorCodecBench::onDelayedSetup() { SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(fEncoded)); fSrcData = codec->getICCData(); sk_sp<SkData> dstData = SkData::MakeFromFileName( GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str()); SkASSERT(dstData); fDstSpace = nullptr; #if defined(SK_TEST_QCMS) if (FLAGS_qcms) { fDstSpaceQCMS.reset(FLAGS_srgb ? qcms_profile_sRGB() : qcms_profile_from_memory(dstData->data(), dstData->size())); SkASSERT(fDstSpaceQCMS); // This call takes a non-trivial amount of time, but I think it's the most fair to // treat it as overhead. It only needs to happen once. qcms_profile_precache_output_transform(fDstSpaceQCMS); } else #endif { fDstSpace = FLAGS_srgb ? SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named) : SkColorSpace::MakeICC(dstData->data(), dstData->size()); SkASSERT(fDstSpace); } fSrcInfo = codec->getInfo().makeColorType(kRGBA_8888_SkColorType); fDstInfo = fSrcInfo; if (FLAGS_half) { fDstInfo = fDstInfo.makeColorType(kRGBA_F16_SkColorType); SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(fDstSpace)->type()); fDstSpace = static_cast<SkColorSpace_XYZ*>(fDstSpace.get())->makeLinearGamma(); } if (FLAGS_nonstd) { SkColorSpaceTransferFn gamma; gamma.fA = 1.0f; gamma.fB = gamma.fC = gamma.fD = gamma.fE = gamma.fF = 0.0f; gamma.fG = 4.0f; SkMatrix44 matrix = SkMatrix44(SkMatrix44::kUninitialized_Constructor); matrix.set3x3(0.30f, 0.31f, 0.28f, 0.32f, 0.33f, 0.29f, 0.27f, 0.30f, 0.30f); fDstSpace = SkColorSpace::MakeRGB(gamma, matrix); } fDstInfo = fDstInfo.makeColorSpace(fDstSpace); fDst.reset(fDstInfo.getSafeSize(fDstInfo.minRowBytes())); if (FLAGS_xform_only) { fSrc.reset(fSrcInfo.getSafeSize(fSrcInfo.minRowBytes())); codec->getPixels(fSrcInfo, fSrc.get(), fSrcInfo.minRowBytes()); } #if defined(SK_TEST_QCMS) else if (FLAGS_qcms) { // Set-up a row buffer to decode into before transforming to dst. fSrc.reset(fSrcInfo.minRowBytes()); } #endif }
void onOnceBeforeDraw() override { SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA, SK_ColorCYAN, SK_ColorYELLOW, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA, }; static_assert(kNumColors == SK_ARRAY_COUNT(colors), "Fix number of colors."); for (int i = 0; i < kNumColors; i++) { fSRGBColors[i] = SkColor4f::FromColor(colors[i]); } static constexpr float kWideGamutRGB_toXYZD50[]{ 0.7161046f, 0.1009296f, 0.1471858f, 0.2581874f, 0.7249378f, 0.0168748f, 0.0000000f, 0.0517813f, 0.7734287f, }; SkMatrix44 wideGamut(SkMatrix44::kUninitialized_Constructor); wideGamut.set3x3RowMajorf(kWideGamutRGB_toXYZD50); // Test BGRA input. sk_sp<SkColorSpace> srcSpace = SkColorSpace::MakeSRGB(); sk_sp<SkColorSpace> dstSpace = SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, wideGamut); std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get()); xform->apply(SkColorSpaceXform::kRGBA_F32_ColorFormat, fWideGamutColors0, SkColorSpaceXform::kBGRA_8888_ColorFormat, colors, kNumColors, kOpaque_SkAlphaType); // Test F32 input. srcSpace = as_CSB(srcSpace)->makeLinearGamma(); xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get()); xform->apply(SkColorSpaceXform::kRGBA_F32_ColorFormat, fWideGamutColors1, SkColorSpaceXform::kRGBA_F32_ColorFormat, fSRGBColors, kNumColors, kOpaque_SkAlphaType); }