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