Add support for gray + colorspace to SkCodec

In both PNG and JPEG, support passing Gray8 directly to skcms, and
remove assertions about gray never having a color xform.

Remove SkImage_Lazy hacks to strip color spaces when decoding gray.

Change-Id: I64c7b480c51a2b0c839e7eb8ed3a5fdea5aa4e41
Reviewed-on: https://skia-review.googlesource.com/150909
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2018-08-31 11:48:04 -04:00 committed by Skia Commit-Bot
parent 8378dfb6a1
commit 8491dd80c8
5 changed files with 22 additions and 34 deletions

View File

@ -156,7 +156,6 @@ bool SkCodec::conversionSupported(const SkImageInfo& dst, SkColorType srcColor,
case kRGB_565_SkColorType:
return srcIsOpaque;
case kGray_8_SkColorType:
SkASSERT(!needsColorXform);
return kGray_8_SkColorType == srcColor && srcIsOpaque;
case kAlpha_8_SkColorType:
// conceptually we can convert anything into alpha_8, but we haven't actually coded
@ -610,6 +609,9 @@ static inline bool select_xform_format(SkColorType colorType, bool forColorTable
case kRGBA_F16_SkColorType:
*outFormat = skcms_PixelFormat_RGBA_hhhh;
break;
case kGray_8_SkColorType:
*outFormat = skcms_PixelFormat_G_8;
break;
default:
return false;
}
@ -625,9 +627,6 @@ bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo, SkEncodedInfo::Al
if (kRGBA_F16_SkColorType == dstInfo.colorType()
|| !skcms_ApproximatelyEqualProfiles(fEncodedInfo.profile(), &fDstProfile) ) {
needsColorXform = true;
if (kGray_8_SkColorType == dstInfo.colorType()) {
return false;
}
}
}

View File

@ -300,10 +300,17 @@ std::unique_ptr<SkCodec> SkJpegCodec::MakeFromStream(std::unique_ptr<SkStream> s
return nullptr;
}
static skcms_PixelFormat jpeg_select_xform_format(const SkEncodedInfo& info) {
if (SkEncodedInfo::kGray_Color == info.color()) {
return skcms_PixelFormat_G_8;
} else {
return skcms_PixelFormat_RGBA_8888;
}
}
SkJpegCodec::SkJpegCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
JpegDecoderMgr* decoderMgr, SkEncodedOrigin origin)
: INHERITED(std::move(info), skcms_PixelFormat_RGBA_8888, std::move(stream),
origin)
: INHERITED(std::move(info), jpeg_select_xform_format(info), std::move(stream), origin)
, fDecoderMgr(decoderMgr)
, fReadyState(decoderMgr->dinfo()->global_state)
, fSwizzleSrcRow(nullptr)
@ -426,7 +433,6 @@ bool SkJpegCodec::conversionSupported(const SkImageInfo& dstInfo, SkColorType sr
}
break;
case kGray_8_SkColorType:
SkASSERT(!needsColorXform);
if (JCS_GRAYSCALE != encodedColorType) {
return false;
}

View File

@ -456,6 +456,8 @@ static skcms_PixelFormat png_select_xform_format(const SkEncodedInfo& info) {
} else if (SkEncodedInfo::kRGB_Color == info.color()) {
return skcms_PixelFormat_RGB_161616;
}
} else if (SkEncodedInfo::kGray_Color == info.color()) {
return skcms_PixelFormat_G_8;
}
return skcms_PixelFormat_RGBA_8888;
@ -1020,6 +1022,7 @@ SkCodec::Result SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const O
// Fall through
case SkEncodedInfo::kRGBA_Color:
case SkEncodedInfo::kGray_Color:
skipFormatConversion = this->colorXform();
break;
default:

View File

@ -29,8 +29,6 @@ class SkImageCacherator {
public:
virtual ~SkImageCacherator() {}
virtual SkImageInfo buildCacheInfo() const = 0;
#if SK_SUPPORT_GPU
// Returns the texture proxy. If the cacherator is generating the texture and wants to cache it,
// it should use the passed in key (if the key is valid).

View File

@ -127,8 +127,6 @@ public:
void makeCacheKeyFromOrigKey(const GrUniqueKey& origKey, GrUniqueKey* cacheKey) override;
#endif
SkImageInfo buildCacheInfo() const override;
private:
class ScopedGenerator;
@ -233,16 +231,6 @@ SkImage_Lazy::SkImage_Lazy(Validator* validator)
//////////////////////////////////////////////////////////////////////////////////////////////////
SkImageInfo SkImage_Lazy::buildCacheInfo() const {
if (kGray_8_SkColorType == fInfo.colorType()) {
return fInfo.makeColorSpace(nullptr);
} else {
return fInfo;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) {
SkASSERT(bitmap.getGenerationID() == expectedID);
SkASSERT(bitmap.isImmutable());
@ -384,8 +372,7 @@ sk_sp<SkData> SkImage_Lazy::onRefEncoded() const {
bool SkImage_Lazy::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpace,
CachingHint chint) const {
const SkImageInfo cacheInfo = this->buildCacheInfo();
return this->lockAsBitmap(bitmap, chint, cacheInfo);
return this->lockAsBitmap(bitmap, chint, fInfo);
}
bool SkImage_Lazy::onIsValid(GrContext* context) const {
@ -497,16 +484,11 @@ static void set_key_on_proxy(GrProxyProvider* proxyProvider,
sk_sp<SkColorSpace> SkImage_Lazy::getColorSpace(GrContext* ctx, SkColorSpace* dstColorSpace) {
// TODO: Is this ever needed? Is the output of this function going to be:
// return dstColorSpace ? fInfo.refColorSpace() : dstColorSpace;
// Yes, except for gray?
if (!dstColorSpace) {
// In legacy mode, we do no modification to the image's color space or encoding.
// Subsequent legacy drawing is likely to ignore the color space, but some clients
// may want to know what space the image data is in, so return it.
return fInfo.refColorSpace();
} else {
SkImageInfo cacheInfo = this->buildCacheInfo();
return cacheInfo.refColorSpace();
}
}
/*
@ -558,7 +540,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
// What format are we going to ask the generator to create?
// TODO: Based on the dstColorSpace?
const SkImageInfo cacheInfo = this->buildCacheInfo();
const SkImageInfo cacheInfo = fInfo;
// 2. Ask the generator to natively create one
if (!proxy) {