diff options
author | Matt Sarett <msarett@google.com> | 2017-05-09 12:46:50 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-09 18:32:04 +0000 |
commit | 2e61b182dad86e592d12c8a73ffcc7555a6e11a2 (patch) | |
tree | 323281b163e71f8058eab694c9562a2c1b007b67 /gm/encode-alpha-jpeg.cpp | |
parent | ee2d9df087c5225c9f3ba0fb98d237905f2d650c (diff) |
Add jpeg encoder alpha handling option
This instructs us on how to encode jpegs when the src
image has alpha. The original behavior is to ignore
the alpha channel. This CL adds the option to blend
the pixels onto opaque black.
Note that kBlendOnBlack and kIgnore are identical
unless the input alpha type is kUnpremul.
Bug: 713862
Bug: skia:1501
Change-Id: I4891c70bb0ccd83f7974c359bd40a2143b5c49ac
Reviewed-on: https://skia-review.googlesource.com/15817
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'gm/encode-alpha-jpeg.cpp')
-rw-r--r-- | gm/encode-alpha-jpeg.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/gm/encode-alpha-jpeg.cpp b/gm/encode-alpha-jpeg.cpp new file mode 100644 index 0000000000..6686e78044 --- /dev/null +++ b/gm/encode-alpha-jpeg.cpp @@ -0,0 +1,105 @@ +/* + * 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 "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("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; ) + +}; |