1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "gm.h" 9 #include "SkImage.h" 10 #include "SkJpegEncoder.h" 11 12 #include "Resources.h" 13 14 namespace skiagm { 15 16 static inline void read_into_pixmap(SkPixmap* dst, SkImageInfo dstInfo, void* dstPixels, 17 sk_sp<SkImage> src) { 18 dst->reset(dstInfo, dstPixels, dstInfo.minRowBytes()); 19 src->readPixels(*dst, 0, 0, SkImage::CachingHint::kDisallow_CachingHint); 20 } 21 22 static inline sk_sp<SkImage> encode_pixmap_and_make_image(const SkPixmap& src, 23 SkJpegEncoder::AlphaOption alphaOption, SkTransferFunctionBehavior blendBehavior) { 24 SkDynamicMemoryWStream dst; 25 SkJpegEncoder::Options options; 26 options.fAlphaOption = alphaOption; 27 options.fBlendBehavior = blendBehavior; 28 SkJpegEncoder::Encode(&dst, src, options); 29 return SkImage::MakeFromEncoded(dst.detachAsData()); 30 } 31 32 class EncodeJpegAlphaOptsGM : public GM { 33 public: 34 EncodeJpegAlphaOptsGM() {} 35 36 protected: 37 SkString onShortName() override { 38 return SkString("encode-alpha-jpeg"); 39 } 40 41 SkISize onISize() override { 42 return SkISize::Make(400, 200); 43 } 44 45 void onDraw(SkCanvas* canvas) override { 46 sk_sp<SkImage> srcImg = GetResourceAsImage("rainbow-gradient.png"); 47 fStorage.reset(srcImg->width() * srcImg->height() * 48 SkColorTypeBytesPerPixel(kRGBA_F16_SkColorType)); 49 50 SkPixmap src; 51 SkImageInfo info = SkImageInfo::MakeN32Premul(srcImg->width(), srcImg->height(), 52 canvas->imageInfo().colorSpace() ? SkColorSpace::MakeSRGB() : nullptr); 53 read_into_pixmap(&src, info, fStorage.get(), srcImg); 54 55 SkTransferFunctionBehavior behavior = canvas->imageInfo().colorSpace() ? 56 SkTransferFunctionBehavior::kRespect : SkTransferFunctionBehavior::kIgnore; 57 58 // Encode 8888 premul. 59 sk_sp<SkImage> img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, 60 behavior); 61 sk_sp<SkImage> img1 = encode_pixmap_and_make_image(src, 62 SkJpegEncoder::AlphaOption::kBlendOnBlack, behavior); 63 canvas->drawImage(img0, 0.0f, 0.0f); 64 canvas->drawImage(img1, 0.0f, 100.0f); 65 66 // Encode 8888 unpremul 67 info = info.makeAlphaType(kUnpremul_SkAlphaType); 68 read_into_pixmap(&src, info, fStorage.get(), srcImg); 69 img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior); 70 img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack, 71 behavior); 72 canvas->drawImage(img0, 100.0f, 0.0f); 73 canvas->drawImage(img1, 100.0f, 100.0f); 74 75 if (canvas->imageInfo().colorSpace()) { 76 // Encode F16 premul 77 info = SkImageInfo::Make(srcImg->width(), srcImg->height(), kRGBA_F16_SkColorType, 78 kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear()); 79 read_into_pixmap(&src, info, fStorage.get(), srcImg); 80 img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior); 81 img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack, 82 behavior); 83 canvas->drawImage(img0, 200.0f, 0.0f); 84 canvas->drawImage(img1, 200.0f, 100.0f); 85 86 // Encode F16 unpremul 87 info = info.makeAlphaType(kUnpremul_SkAlphaType); 88 read_into_pixmap(&src, info, fStorage.get(), srcImg); 89 img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior); 90 img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack, 91 behavior); 92 canvas->drawImage(img0, 300.0f, 0.0f); 93 canvas->drawImage(img1, 300.0f, 100.0f); 94 } 95 } 96 97 private: 98 SkAutoTMalloc<uint8_t> fStorage; 99 100 typedef GM INHERITED; 101 }; 102 103 DEF_GM( return new EncodeJpegAlphaOptsGM; ) 104 105 }; 106