1/*
2 * Copyright 2009 The Android Open Source Project
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 "include/encode/SkJpegEncoder.h"
9#include "include/encode/SkPngEncoder.h"
10#include "include/encode/SkWebpEncoder.h"
11#include "src/images/SkImageEncoderPriv.h"
12
13#ifndef SK_ENCODE_JPEG
14bool SkJpegEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; }
15std::unique_ptr<SkEncoder> SkJpegEncoder::Make(SkWStream*, const SkPixmap&, const Options&) {
16 return nullptr;
17}
18#endif
19
20#ifndef SK_ENCODE_PNG
21bool SkPngEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; }
22std::unique_ptr<SkEncoder> SkPngEncoder::Make(SkWStream*, const SkPixmap&, const Options&) {
23 return nullptr;
24}
25#endif
26
27#ifndef SK_ENCODE_WEBP
28bool SkWebpEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; }
29#endif
30
31bool SkEncodeImage(SkWStream* dst, const SkPixmap& src,
32 SkEncodedImageFormat format, int quality) {
33 #ifdef SK_USE_CG_ENCODER
34 (void)quality;
35 return SkEncodeImageWithCG(dst, src, format);
36 #elif SK_USE_WIC_ENCODER
37 return SkEncodeImageWithWIC(dst, src, format, quality);
38 #elif SK_ENABLE_NDK_IMAGES
39 return SkEncodeImageWithNDK(dst, src, format, quality);
40 #else
41 switch(format) {
42 case SkEncodedImageFormat::kJPEG: {
43 SkJpegEncoder::Options opts;
44 opts.fQuality = quality;
45 return SkJpegEncoder::Encode(dst, src, opts);
46 }
47 case SkEncodedImageFormat::kPNG: {
48 SkPngEncoder::Options opts;
49 return SkPngEncoder::Encode(dst, src, opts);
50 }
51 case SkEncodedImageFormat::kWEBP: {
52 SkWebpEncoder::Options opts;
53 if (quality == 100) {
54 opts.fCompression = SkWebpEncoder::Compression::kLossless;
55 // Note: SkEncodeImage treats 0 quality as the lowest quality
56 // (greatest compression) and 100 as the highest quality (least
57 // compression). For kLossy, this matches libwebp's
58 // interpretation, so it is passed directly to libwebp. But
59 // with kLossless, libwebp always creates the highest quality
60 // image. In this case, fQuality is reinterpreted as how much
61 // effort (time) to put into making a smaller file. This API
62 // does not provide a way to specify this value (though it can
63 // be specified by using SkWebpEncoder::Encode) so we have to
64 // pick one arbitrarily. This value matches that chosen by
65 // blink::ImageEncoder::ComputeWebpOptions as well
66 // WebPConfigInit.
67 opts.fQuality = 75;
68 } else {
69 opts.fCompression = SkWebpEncoder::Compression::kLossy;
70 opts.fQuality = quality;
71 }
72 return SkWebpEncoder::Encode(dst, src, opts);
73 }
74 default:
75 return false;
76 }
77 #endif
78}
79
80bool SkEncoder::encodeRows(int numRows) {
81 SkASSERT(numRows > 0 && fCurrRow < fSrc.height());
82 if (numRows <= 0 || fCurrRow >= fSrc.height()) {
83 return false;
84 }
85
86 if (fCurrRow + numRows > fSrc.height()) {
87 numRows = fSrc.height() - fCurrRow;
88 }
89
90 if (!this->onEncodeRows(numRows)) {
91 // If we fail, short circuit any future calls.
92 fCurrRow = fSrc.height();
93 return false;
94 }
95
96 return true;
97}
98
99sk_sp<SkData> SkEncodePixmap(const SkPixmap& src, SkEncodedImageFormat format, int quality) {
100 SkDynamicMemoryWStream stream;
101 return SkEncodeImage(&stream, src, format, quality) ? stream.detachAsData() : nullptr;
102}
103
104sk_sp<SkData> SkEncodeBitmap(const SkBitmap& src, SkEncodedImageFormat format, int quality) {
105 SkPixmap pixmap;
106 return src.peekPixels(&pixmap) ? SkEncodePixmap(pixmap, format, quality) : nullptr;
107}
108