| /* |
| * Copyright 2017 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "gm.h" |
| #include "SkImage.h" |
| #include "SkImageInfoPriv.h" |
| #include "SkJpegEncoder.h" |
| |
| #include "Resources.h" |
| |
| namespace skiagm { |
| |
| static inline void read_into_pixmap(SkPixmap* dst, SkImageInfo dstInfo, void* dstPixels, |
| sk_sp<SkImage> src) { |
| dst->reset(dstInfo, dstPixels, dstInfo.minRowBytes()); |
| src->readPixels(*dst, 0, 0, SkImage::CachingHint::kDisallow_CachingHint); |
| } |
| |
| static inline sk_sp<SkImage> encode_pixmap_and_make_image(const SkPixmap& src, |
| SkJpegEncoder::AlphaOption alphaOption, SkTransferFunctionBehavior blendBehavior) { |
| SkDynamicMemoryWStream dst; |
| SkJpegEncoder::Options options; |
| options.fAlphaOption = alphaOption; |
| options.fBlendBehavior = blendBehavior; |
| SkJpegEncoder::Encode(&dst, src, options); |
| return SkImage::MakeFromEncoded(dst.detachAsData()); |
| } |
| |
| class EncodeJpegAlphaOptsGM : public GM { |
| public: |
| EncodeJpegAlphaOptsGM() {} |
| |
| protected: |
| SkString onShortName() override { |
| return SkString("encode-alpha-jpeg"); |
| } |
| |
| SkISize onISize() override { |
| return SkISize::Make(400, 200); |
| } |
| |
| void onDraw(SkCanvas* canvas) override { |
| sk_sp<SkImage> srcImg = GetResourceAsImage("images/rainbow-gradient.png"); |
| fStorage.reset(srcImg->width() * srcImg->height() * |
| SkColorTypeBytesPerPixel(kRGBA_F16_SkColorType)); |
| |
| SkPixmap src; |
| SkImageInfo info = SkImageInfo::MakeN32Premul(srcImg->width(), srcImg->height(), |
| canvas->imageInfo().colorSpace() ? SkColorSpace::MakeSRGB() : nullptr); |
| read_into_pixmap(&src, info, fStorage.get(), srcImg); |
| |
| SkTransferFunctionBehavior behavior = canvas->imageInfo().colorSpace() ? |
| SkTransferFunctionBehavior::kRespect : SkTransferFunctionBehavior::kIgnore; |
| |
| // Encode 8888 premul. |
| sk_sp<SkImage> img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, |
| behavior); |
| sk_sp<SkImage> img1 = encode_pixmap_and_make_image(src, |
| SkJpegEncoder::AlphaOption::kBlendOnBlack, behavior); |
| canvas->drawImage(img0, 0.0f, 0.0f); |
| canvas->drawImage(img1, 0.0f, 100.0f); |
| |
| // Encode 8888 unpremul |
| info = info.makeAlphaType(kUnpremul_SkAlphaType); |
| read_into_pixmap(&src, info, fStorage.get(), srcImg); |
| img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior); |
| img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack, |
| behavior); |
| canvas->drawImage(img0, 100.0f, 0.0f); |
| canvas->drawImage(img1, 100.0f, 100.0f); |
| |
| if (canvas->imageInfo().colorSpace()) { |
| // Encode F16 premul |
| info = SkImageInfo::Make(srcImg->width(), srcImg->height(), kRGBA_F16_SkColorType, |
| kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear()); |
| read_into_pixmap(&src, info, fStorage.get(), srcImg); |
| img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior); |
| img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack, |
| behavior); |
| canvas->drawImage(img0, 200.0f, 0.0f); |
| canvas->drawImage(img1, 200.0f, 100.0f); |
| |
| // Encode F16 unpremul |
| info = info.makeAlphaType(kUnpremul_SkAlphaType); |
| read_into_pixmap(&src, info, fStorage.get(), srcImg); |
| img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior); |
| img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack, |
| behavior); |
| canvas->drawImage(img0, 300.0f, 0.0f); |
| canvas->drawImage(img1, 300.0f, 100.0f); |
| } |
| } |
| |
| private: |
| SkAutoTMalloc<uint8_t> fStorage; |
| |
| typedef GM INHERITED; |
| }; |
| |
| DEF_GM( return new EncodeJpegAlphaOptsGM; ) |
| |
| }; |