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