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.h"
9 
10 #include "Resources.h"
11 #include "SkCanvas.h"
12 #include "SkData.h"
13 #include "SkImage.h"
14 #include "SkImageEncoderPriv.h"
15 #include "SkJpegEncoder.h"
16 #include "SkPngEncoder.h"
17 #include "SkWebpEncoder.h"
18 
19 namespace skiagm {
20 
21 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
22 static SkEncodedImageFormat kTypes[] {
23         SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kJPEG, SkEncodedImageFormat::kGIF,
24         SkEncodedImageFormat::kBMP, SkEncodedImageFormat::kICO,
25 };
26 #elif defined(SK_BUILD_FOR_WIN)
27 // Use PNG multiple times because our WIC encoder does not support GIF, BMP, or ICO.
28 static SkEncodedImageFormat kTypes[] {
29         SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kJPEG, SkEncodedImageFormat::kPNG,
30         SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kPNG,
31 };
32 #else
33 // Use WEBP in place of GIF.  Use PNG two extra times.  We don't support GIF, BMP, or ICO.
34 static SkEncodedImageFormat kTypes[] {
35         SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kJPEG, SkEncodedImageFormat::kWEBP,
36         SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kPNG,
37 };
38 #endif
39 
encode_data(SkEncodedImageFormat type,const SkBitmap & bitmap)40 static sk_sp<SkData> encode_data(SkEncodedImageFormat type, const SkBitmap& bitmap) {
41     SkPixmap src;
42     if (!bitmap.peekPixels(&src)) {
43         return nullptr;
44     }
45     SkDynamicMemoryWStream buf;
46     #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
47         return SkEncodeImageWithCG(&buf, src, type) ? buf.detachAsData() : nullptr;
48     #elif defined(SK_BUILD_FOR_WIN)
49         return SkEncodeImageWithWIC(&buf, src, type, 100) ? buf.detachAsData() : nullptr;
50     #else
51         switch (type) {
52             case SkEncodedImageFormat::kPNG: {
53                 bool success = SkPngEncoder::Encode(&buf, src, SkPngEncoder::Options());
54                 return success ? buf.detachAsData() : nullptr;
55             }
56             case SkEncodedImageFormat::kJPEG: {
57                 bool success = SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options());
58                 return success ? buf.detachAsData() : nullptr;
59             }
60             case SkEncodedImageFormat::kWEBP: {
61                 bool success = SkWebpEncoder::Encode(&buf, src, SkWebpEncoder::Options());
62                 return success ? buf.detachAsData() : nullptr;
63             }
64             default:
65                 SkASSERT(false);
66                 return nullptr;
67         }
68     #endif
69 }
70 
71 class EncodePlatformGM : public GM {
72 public:
EncodePlatformGM()73     EncodePlatformGM() {}
74 
75 protected:
onShortName()76     SkString onShortName() override {
77         return SkString("encode-platform");
78     }
79 
onISize()80     SkISize onISize() override {
81         return SkISize::Make(256 * SK_ARRAY_COUNT(kTypes), 256 * 3);
82     }
83 
onDraw(SkCanvas * canvas)84     void onDraw(SkCanvas* canvas) override {
85         SkBitmap opaqueBm, premulBm, unpremulBm;
86 
87         if (!GetResourceAsBitmap("images/mandrill_256.png", &opaqueBm)) {
88             return;
89         }
90         SkBitmap tmp;
91         if (!GetResourceAsBitmap("images/yellow_rose.png", &tmp)) {
92             return;
93         }
94         tmp.extractSubset(&premulBm, SkIRect::MakeWH(256, 256));
95         tmp.reset();
96         unpremulBm.allocPixels(premulBm.info().makeAlphaType(kUnpremul_SkAlphaType));
97         SkAssertResult(premulBm.readPixels(unpremulBm.pixmap()));
98 
99         for (SkEncodedImageFormat type : kTypes) {
100             auto opaqueImage = SkImage::MakeFromEncoded(encode_data(type, opaqueBm));
101             auto premulImage = SkImage::MakeFromEncoded(encode_data(type, premulBm));
102             auto unpremulImage = SkImage::MakeFromEncoded(encode_data(type, unpremulBm));
103 
104             canvas->drawImage(opaqueImage.get(), 0.0f, 0.0f);
105             canvas->drawImage(premulImage.get(), 0.0f, 256.0f);
106             canvas->drawImage(unpremulImage.get(), 0.0f, 512.0f);
107 
108             canvas->translate(256.0f, 0.0f);
109         }
110     }
111 
112 private:
113     typedef GM INHERITED;
114 };
115 
116 DEF_GM( return new EncodePlatformGM; )
117 }
118