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