Allow decoding without color conversion

Bug: b/135133301

Especially for the Android NDK, which may not be able to report the
default profile, we should be able to decode the image without doing
any color correction. That way if the client wants to figure out
the color profile on their own (e.g. by parsing the data manually),
they can retrieve the un-corrected pixels and treat them appropriately.

Note that internally, we still require a destination profile for F16,
but we will use the source profile if there is one, or SRGB for source
and destination otherwise. Regardless, this will result in no color
correction.

Change-Id: Id1157bb99d3119a114b25f64b38620480a027f34
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/268157
Reviewed-by: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
This commit is contained in:
Leon Scroggins III 2020-02-03 12:39:54 -05:00 committed by Skia Commit-Bot
parent d33f5746e3
commit 196f319b72
3 changed files with 30 additions and 22 deletions

View File

@ -7,6 +7,9 @@ This file includes a list of high level updates for each milestone release.
Milestone 82
<Insert new notes here- top is most recent.>
* An SkImageInfo with a null SkColorSpace passed to SkCodec::getPixels() and
related calls is treated as a request to do no color correction at decode
time.
* Remove CGFontRef parameter from SkCreateTypefaceFromCTFont.
Use CTFontManagerCreateFontDescriptorFromData instead of

View File

@ -175,9 +175,8 @@ bool SkCodec::conversionSupported(const SkImageInfo& dst, bool srcIsOpaque, bool
switch (dst.colorType()) {
case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
return true;
case kRGBA_F16_SkColorType:
return dst.colorSpace();
return true;
case kRGB_565_SkColorType:
return srcIsOpaque;
case kGray_8_SkColorType:
@ -331,13 +330,8 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
? kSuccess : kInvalidConversion;
}
SkCodec::Result SkCodec::getPixels(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
const Options* options) {
SkImageInfo info = dstInfo;
if (!info.colorSpace()) {
info = info.makeColorSpace(SkColorSpace::MakeSRGB());
}
if (kUnknown_SkColorType == info.colorType()) {
return kInvalidConversion;
}
@ -406,14 +400,10 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& dstInfo, void* pixels, siz
return result;
}
SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& dstInfo, void* pixels,
SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& info, void* pixels,
size_t rowBytes, const SkCodec::Options* options) {
fStartedIncrementalDecode = false;
SkImageInfo info = dstInfo;
if (!info.colorSpace()) {
info = info.makeColorSpace(SkColorSpace::MakeSRGB());
}
if (kUnknown_SkColorType == info.colorType()) {
return kInvalidConversion;
}
@ -479,16 +469,11 @@ SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& dstInfo, void
}
SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& info,
const SkCodec::Options* options) {
// Reset fCurrScanline in case of failure.
fCurrScanline = -1;
SkImageInfo info = dstInfo;
if (!info.colorSpace()) {
info = info.makeColorSpace(SkColorSpace::MakeSRGB());
}
if (!this->rewindIfNeeded()) {
return kCouldNotRewind;
}
@ -649,11 +634,18 @@ bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo, SkEncodedInfo::Al
bool srcIsOpaque) {
fXformTime = kNo_XformTime;
bool needsColorXform = false;
if (this->usesColorXform() && dstInfo.colorSpace()) {
dstInfo.colorSpace()->toProfile(&fDstProfile);
if (this->usesColorXform()) {
if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
needsColorXform = true;
} else {
if (dstInfo.colorSpace()) {
dstInfo.colorSpace()->toProfile(&fDstProfile);
} else {
// Use the srcProfile to avoid conversion.
const auto* srcProfile = fEncodedInfo.profile();
fDstProfile = srcProfile ? *srcProfile : *skcms_sRGB_profile();
}
} else if (dstInfo.colorSpace()) {
dstInfo.colorSpace()->toProfile(&fDstProfile);
const auto* srcProfile = fEncodedInfo.profile();
if (!srcProfile) {
srcProfile = skcms_sRGB_profile();

View File

@ -1774,3 +1774,16 @@ DEF_TEST(Codec_crbug807324, r) {
}
}
}
DEF_TEST(Codec_F16_noColorSpace, r) {
const char* path = "images/color_wheel.png";
auto data = GetResourceAsData(path);
if (!data) {
return;
}
auto codec = SkCodec::MakeFromData(std::move(data));
SkImageInfo info = codec->getInfo().makeColorType(kRGBA_F16_SkColorType)
.makeColorSpace(nullptr);
test_info(r, codec.get(), info, SkCodec::kSuccess, nullptr);
}