Add SkColorSpace::Equals() API

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2196743002

Review-Url: https://codereview.chromium.org/2196743002
This commit is contained in:
msarett 2016-08-01 09:43:08 -07:00 committed by Commit bot
parent 8d7f5c3f29
commit abbd6d5e02
6 changed files with 108 additions and 12 deletions

View File

@ -104,6 +104,12 @@ public:
static sk_sp<SkColorSpace> Deserialize(const void* data, size_t length);
/**
* If both are null, we return true. If one is null and the other is not, we return false.
* If both are non-null, we do a deeper compare.
*/
static bool Equals(const SkColorSpace* src, const SkColorSpace* dst);
protected:
SkColorSpace(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Named named);

View File

@ -289,12 +289,10 @@ public:
bool operator==(const SkImageInfo& other) const {
return fWidth == other.fWidth && fHeight == other.fHeight &&
fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
fColorSpace == other.fColorSpace;
SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
}
bool operator!=(const SkImageInfo& other) const {
return fWidth != other.fWidth || fHeight != other.fHeight ||
fColorType != other.fColorType || fAlphaType != other.fAlphaType ||
fColorSpace != other.fColorSpace;
return !(*this == other);
}
void unflatten(SkReadBuffer&);

View File

@ -475,10 +475,9 @@ bool SkJpegCodec::onDimensionsSupported(const SkISize& size) {
}
static bool needs_color_xform(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo) {
// FIXME (msarett):
// Do a better check for color space equality.
return (kRGBA_F16_SkColorType == dstInfo.colorType()) ||
(dstInfo.colorSpace() && (dstInfo.colorSpace() != srcInfo.colorSpace()));
(dstInfo.colorSpace() && !SkColorSpace::Equals(srcInfo.colorSpace(),
dstInfo.colorSpace()));
}
int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count) {

View File

@ -316,6 +316,51 @@ sk_sp<SkColorSpace> SkColorSpace::Deserialize(const void* data, size_t length) {
return NewICC(data, profileSize);
}
bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) {
if (src == dst) {
return true;
}
if (!src || !dst) {
return false;
}
switch (src->fNamed) {
case kSRGB_Named:
case kAdobeRGB_Named:
return src->fNamed == dst->fNamed;
case kUnknown_Named:
if (kUnknown_Named != dst->fNamed) {
return false;
}
break;
}
SkData* srcData = as_CSB(src)->fProfileData.get();
SkData* dstData = as_CSB(dst)->fProfileData.get();
if (srcData || dstData) {
if (srcData && dstData) {
return srcData->size() == dstData->size() &&
0 == memcmp(srcData->data(), dstData->data(), srcData->size());
}
return false;
}
// It's important to check fProfileData before named gammas. Some profiles may have named
// gammas, but also include other wacky features that cause us to save the data.
switch (src->fGammaNamed) {
case kSRGB_GammaNamed:
case k2Dot2Curve_GammaNamed:
case kLinear_GammaNamed:
return (src->fGammaNamed == dst->fGammaNamed) && (src->fToXYZD50 == dst->fToXYZD50);
default:
// If |src| does not have a named gamma, fProfileData should be non-null.
SkASSERT(false);
return false;
}
}
bool SkColorSpace::gammasAreMatching() const {
const SkGammas* gammas = as_CSB(this)->gammas();
SkASSERT(gammas);

View File

@ -221,3 +221,34 @@ DEF_TEST(ColorSpace_Serialize, r) {
test_serialize(r, SkColorSpace::NewICC(monitorData->data(), monitorData->size()).get(), false);
}
DEF_TEST(ColorSpace_Equals, r) {
sk_sp<SkColorSpace> srgb = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
sk_sp<SkColorSpace> adobe = SkColorSpace::NewNamed(SkColorSpace::kAdobeRGB_Named);
sk_sp<SkData> data = SkData::MakeFromFileName(
GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str());
sk_sp<SkColorSpace> z30 = SkColorSpace::NewICC(data->data(), data->size());
data = SkData::MakeFromFileName( GetResourcePath("icc_profiles/HP_Z32x.icc").c_str());
sk_sp<SkColorSpace> z32 = SkColorSpace::NewICC(data->data(), data->size());
data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperLeft.icc").c_str());
sk_sp<SkColorSpace> upperLeft = SkColorSpace::NewICC(data->data(), data->size());
data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperRight.icc").c_str());
sk_sp<SkColorSpace> upperRight = SkColorSpace::NewICC(data->data(), data->size());
REPORTER_ASSERT(r, SkColorSpace::Equals(nullptr, nullptr));
REPORTER_ASSERT(r, SkColorSpace::Equals(srgb.get(), srgb.get()));
REPORTER_ASSERT(r, SkColorSpace::Equals(adobe.get(), adobe.get()));
REPORTER_ASSERT(r, SkColorSpace::Equals(z30.get(), z30.get()));
REPORTER_ASSERT(r, SkColorSpace::Equals(z32.get(), z32.get()));
REPORTER_ASSERT(r, SkColorSpace::Equals(upperLeft.get(), upperLeft.get()));
REPORTER_ASSERT(r, SkColorSpace::Equals(upperRight.get(), upperRight.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(nullptr, srgb.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(srgb.get(), nullptr));
REPORTER_ASSERT(r, !SkColorSpace::Equals(adobe.get(), srgb.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(z30.get(), srgb.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(z32.get(), z30.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(upperLeft.get(), srgb.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(upperLeft.get(), upperRight.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(z30.get(), upperRight.get()));
REPORTER_ASSERT(r, !SkColorSpace::Equals(upperRight.get(), adobe.get()));
}

View File

@ -6,6 +6,7 @@
*/
#include "SkTypes.h"
#include "Resources.h"
#include "Test.h"
#if SK_SUPPORT_GPU
@ -17,13 +18,15 @@
#include "SkWriteBuffer.h"
static void test_flatten(skiatest::Reporter* reporter, const SkImageInfo& info) {
// just need a safe amount of storage, but ensure that it is 4-byte aligned.
int32_t storage[(sizeof(SkImageInfo)*2) / sizeof(int32_t)];
SkBinaryWriteBuffer wb(storage, sizeof(storage));
// Need a safe amount of 4-byte aligned storage. Note that one of the test ICC profiles
// is ~7500 bytes.
const size_t storageBytes = 8000;
SkAutoTMalloc<uint32_t> storage(storageBytes / sizeof(uint32_t));
SkBinaryWriteBuffer wb(storage.get(), storageBytes);
info.flatten(wb);
SkASSERT(wb.bytesWritten() < sizeof(storage));
SkASSERT(wb.bytesWritten() < storageBytes);
SkReadBuffer rb(storage, wb.bytesWritten());
SkReadBuffer rb(storage.get(), wb.bytesWritten());
// pick a noisy byte pattern, so we ensure that unflatten sets all of our fields
SkImageInfo info2 = SkImageInfo::Make(0xB8, 0xB8, (SkColorType) 0xB8, (SkAlphaType) 0xB8);
@ -35,10 +38,24 @@ static void test_flatten(skiatest::Reporter* reporter, const SkImageInfo& info)
}
DEF_TEST(ImageInfo_flattening, reporter) {
sk_sp<SkData> data =
SkData::MakeFromFileName(GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str());
sk_sp<SkColorSpace> space0 = SkColorSpace::NewICC(data->data(), data->size());
data = SkData::MakeFromFileName( GetResourcePath("icc_profiles/HP_Z32x.icc").c_str());
sk_sp<SkColorSpace> space1 = SkColorSpace::NewICC(data->data(), data->size());
data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperLeft.icc").c_str());
sk_sp<SkColorSpace> space2 = SkColorSpace::NewICC(data->data(), data->size());
data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperRight.icc").c_str());
sk_sp<SkColorSpace> space3 = SkColorSpace::NewICC(data->data(), data->size());
sk_sp<SkColorSpace> spaces[] = {
nullptr,
SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named),
SkColorSpace::NewNamed(SkColorSpace::kAdobeRGB_Named),
space0,
space1,
space2,
space3,
};
for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {