1 /*
2 * Copyright 2016 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/gm.h"
9 #include "include/codec/SkEncodedImageFormat.h"
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkImage.h"
14 #include "include/core/SkImageInfo.h"
15 #include "include/core/SkPixmap.h"
16 #include "include/core/SkRect.h"
17 #include "include/core/SkRefCnt.h"
18 #include "include/core/SkSize.h"
19 #include "include/core/SkStream.h"
20 #include "include/core/SkString.h"
21 #include "include/core/SkTypes.h"
22 #include "include/encode/SkJpegEncoder.h"
23 #include "include/encode/SkPngEncoder.h"
24 #include "include/encode/SkWebpEncoder.h"
25 #include "tools/DecodeUtils.h"
26 #include "tools/Resources.h"
27
28 namespace {
29
30 static const struct {
31 SkEncodedImageFormat format;
32 int quality;
33 } gRecs[] = {
34 // We don't support GIF, BMP, or ICO. This applies to both NDK and SkEncoder.
35 { SkEncodedImageFormat::kPNG, 100},
36 { SkEncodedImageFormat::kJPEG, 100},
37 { SkEncodedImageFormat::kWEBP, 100}, // Lossless
38 { SkEncodedImageFormat::kWEBP, 80}, // Lossy
39 { SkEncodedImageFormat::kPNG, 100},
40 };
41
42 } // anonymous namespace
43
encode_data(SkEncodedImageFormat type,const SkBitmap & bitmap,int quality)44 static sk_sp<SkData> encode_data(SkEncodedImageFormat type, const SkBitmap& bitmap, int quality) {
45 SkPixmap src;
46 if (!bitmap.peekPixels(&src)) {
47 return nullptr;
48 }
49 SkDynamicMemoryWStream buf;
50 switch (type) {
51 case SkEncodedImageFormat::kPNG: {
52 bool success = SkPngEncoder::Encode(&buf, src, {});
53 return success ? buf.detachAsData() : nullptr;
54 }
55 case SkEncodedImageFormat::kJPEG: {
56 SkJpegEncoder::Options opts;
57 opts.fQuality = quality;
58 bool success = SkJpegEncoder::Encode(&buf, src, opts);
59 return success ? buf.detachAsData() : nullptr;
60 }
61 case SkEncodedImageFormat::kWEBP: {
62 SkWebpEncoder::Options opts;
63 opts.fQuality = quality;
64 bool success = SkWebpEncoder::Encode(&buf, src, opts);
65 return success ? buf.detachAsData() : nullptr;
66 }
67 default:
68 SkUNREACHABLE;
69 }
70 }
71
72 namespace skiagm {
73
74 class EncodePlatformGM : public GM {
75 public:
EncodePlatformGM()76 EncodePlatformGM() {}
77
78 protected:
getName() const79 SkString getName() const override { return SkString("encode-platform"); }
80
getISize()81 SkISize getISize() override { return SkISize::Make(256 * std::size(gRecs), 256 * 3); }
82
onDraw(SkCanvas * canvas,SkString * errorMsg)83 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
84 SkBitmap opaqueBm, premulBm, unpremulBm;
85
86 if (!ToolUtils::GetResourceAsBitmap("images/mandrill_256.png", &opaqueBm)) {
87 *errorMsg = "Could not load images/mandrill_256.png.png. "
88 "Did you forget to set the resourcePath?";
89 return DrawResult::kFail;
90 }
91 SkBitmap tmp;
92 if (!ToolUtils::GetResourceAsBitmap("images/yellow_rose.png", &tmp)) {
93 *errorMsg = "Could not load images/yellow_rose.png. "
94 "Did you forget to set the resourcePath?";
95 return DrawResult::kFail;
96 }
97 tmp.extractSubset(&premulBm, SkIRect::MakeWH(256, 256));
98 tmp.reset();
99 unpremulBm.allocPixels(premulBm.info().makeAlphaType(kUnpremul_SkAlphaType));
100 SkAssertResult(premulBm.readPixels(unpremulBm.pixmap()));
101
102 for (const auto& rec : gRecs) {
103 auto fmt = rec.format; int q = rec.quality;
104 auto opaqueImage = SkImages::DeferredFromEncodedData(encode_data(fmt, opaqueBm, q));
105 auto premulImage = SkImages::DeferredFromEncodedData(encode_data(fmt, premulBm, q));
106 auto unpremulImage = SkImages::DeferredFromEncodedData(encode_data(fmt, unpremulBm, q));
107
108 canvas->drawImage(opaqueImage.get(), 0.0f, 0.0f);
109 canvas->drawImage(premulImage.get(), 0.0f, 256.0f);
110 canvas->drawImage(unpremulImage.get(), 0.0f, 512.0f);
111
112 canvas->translate(256.0f, 0.0f);
113 }
114 return DrawResult::kOk;
115 }
116
117 private:
118 using INHERITED = GM;
119 };
120
121 DEF_GM( return new EncodePlatformGM; )
122 } // namespace skiagm
123