• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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