xref: /third_party/skia/gm/encode_platform.cpp (revision cb93a386)
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/core/SkBitmap.h"
10#include "include/core/SkCanvas.h"
11#include "include/core/SkData.h"
12#include "include/core/SkEncodedImageFormat.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/Resources.h"
26
27#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) || defined(SK_BUILD_FOR_WIN) \
28 || defined(SK_ENABLE_NDK_IMAGES)
29#include "src/images/SkImageEncoderPriv.h"
30#endif
31
32namespace {
33
34static const struct {
35    SkEncodedImageFormat format;
36    int                  quality;
37} gRecs[] = {
38#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
39    { SkEncodedImageFormat::kPNG,  100},
40    { SkEncodedImageFormat::kJPEG, 100},
41    { SkEncodedImageFormat::kGIF,  100},
42    { SkEncodedImageFormat::kBMP,  100},
43    { SkEncodedImageFormat::kICO,  100},
44#elif defined(SK_BUILD_FOR_WIN)
45    // Our WIC encoder does not support GIF, BMP, or ICO.
46    { SkEncodedImageFormat::kPNG,  100},
47    { SkEncodedImageFormat::kJPEG, 100},
48    { SkEncodedImageFormat::kPNG,  100},
49    { SkEncodedImageFormat::kPNG,  100},
50    { SkEncodedImageFormat::kPNG,  100},
51#else
52    // We don't support GIF, BMP, or ICO. This applies to both NDK and SkEncoder.
53    { SkEncodedImageFormat::kPNG,  100},
54    { SkEncodedImageFormat::kJPEG, 100},
55    { SkEncodedImageFormat::kWEBP, 100}, // Lossless
56    { SkEncodedImageFormat::kWEBP,  80}, // Lossy
57    { SkEncodedImageFormat::kPNG,  100},
58#endif
59};
60
61} // anonymous namespace
62
63static sk_sp<SkData> encode_data(SkEncodedImageFormat type, const SkBitmap& bitmap, int quality) {
64    SkPixmap src;
65    if (!bitmap.peekPixels(&src)) {
66        return nullptr;
67    }
68    SkDynamicMemoryWStream buf;
69    #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
70        return SkEncodeImageWithCG(&buf, src, type) ? buf.detachAsData() : nullptr;
71    #elif defined(SK_BUILD_FOR_WIN)
72        return SkEncodeImageWithWIC(&buf, src, type, quality) ? buf.detachAsData() : nullptr;
73    #elif defined(SK_ENABLE_NDK_IMAGES)
74        return SkEncodeImageWithNDK(&buf, src, type, quality) ? buf.detachAsData() : nullptr;
75    #else
76        switch (type) {
77            case SkEncodedImageFormat::kPNG: {
78                bool success = SkPngEncoder::Encode(&buf, src, SkPngEncoder::Options());
79                return success ? buf.detachAsData() : nullptr;
80            }
81            case SkEncodedImageFormat::kJPEG: {
82                bool success = SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options());
83                return success ? buf.detachAsData() : nullptr;
84            }
85            case SkEncodedImageFormat::kWEBP: {
86                bool success = SkWebpEncoder::Encode(&buf, src, SkWebpEncoder::Options());
87                return success ? buf.detachAsData() : nullptr;
88            }
89            default:
90                SkUNREACHABLE;
91        }
92    #endif
93}
94
95namespace skiagm {
96
97class EncodePlatformGM : public GM {
98public:
99    EncodePlatformGM() {}
100
101protected:
102    SkString onShortName() override {
103        return SkString("encode-platform");
104    }
105
106    SkISize onISize() override {
107        return SkISize::Make(256 * SK_ARRAY_COUNT(gRecs), 256 * 3);
108    }
109
110    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
111        SkBitmap opaqueBm, premulBm, unpremulBm;
112
113        if (!GetResourceAsBitmap("images/mandrill_256.png", &opaqueBm)) {
114            *errorMsg = "Could not load images/mandrill_256.png.png. "
115                        "Did you forget to set the resourcePath?";
116            return DrawResult::kFail;
117        }
118        SkBitmap tmp;
119        if (!GetResourceAsBitmap("images/yellow_rose.png", &tmp)) {
120            *errorMsg = "Could not load images/yellow_rose.png. "
121                        "Did you forget to set the resourcePath?";
122            return DrawResult::kFail;
123        }
124        tmp.extractSubset(&premulBm, SkIRect::MakeWH(256, 256));
125        tmp.reset();
126        unpremulBm.allocPixels(premulBm.info().makeAlphaType(kUnpremul_SkAlphaType));
127        SkAssertResult(premulBm.readPixels(unpremulBm.pixmap()));
128
129        for (const auto& rec : gRecs) {
130            auto fmt = rec.format; int q = rec.quality;
131            auto opaqueImage   = SkImage::MakeFromEncoded(encode_data(fmt, opaqueBm,   q));
132            auto premulImage   = SkImage::MakeFromEncoded(encode_data(fmt, premulBm,   q));
133            auto unpremulImage = SkImage::MakeFromEncoded(encode_data(fmt, unpremulBm, q));
134
135            canvas->drawImage(opaqueImage.get(), 0.0f, 0.0f);
136            canvas->drawImage(premulImage.get(), 0.0f, 256.0f);
137            canvas->drawImage(unpremulImage.get(), 0.0f, 512.0f);
138
139            canvas->translate(256.0f, 0.0f);
140        }
141        return DrawResult::kOk;
142    }
143
144private:
145    using INHERITED = GM;
146};
147
148DEF_GM( return new EncodePlatformGM; )
149}  // namespace skiagm
150