aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/encode-alpha-jpeg.cpp
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2017-05-09 12:46:50 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-09 18:32:04 +0000
commit2e61b182dad86e592d12c8a73ffcc7555a6e11a2 (patch)
tree323281b163e71f8058eab694c9562a2c1b007b67 /gm/encode-alpha-jpeg.cpp
parentee2d9df087c5225c9f3ba0fb98d237905f2d650c (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.cpp105
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; )
+
+};