• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 Google Inc.
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 #ifndef SkPngEncoder_DEFINED
9 #define SkPngEncoder_DEFINED
10 
11 #include "include/core/SkDataTable.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/encode/SkEncoder.h"
14 #include "include/private/base/SkAPI.h"
15 
16 #include <memory>
17 
18 class SkPixmap;
19 class SkPngEncoderMgr;
20 class SkWStream;
21 struct skcms_ICCProfile;
22 
23 class SK_API SkPngEncoder : public SkEncoder {
24 public:
25 
26     enum class FilterFlag : int {
27         kZero  = 0x00,
28         kNone  = 0x08,
29         kSub   = 0x10,
30         kUp    = 0x20,
31         kAvg   = 0x40,
32         kPaeth = 0x80,
33         kAll   = kNone | kSub | kUp | kAvg | kPaeth,
34     };
35 
36     struct Options {
37         /**
38          *  Selects which filtering strategies to use.
39          *
40          *  If a single filter is chosen, libpng will use that filter for every row.
41          *
42          *  If multiple filters are chosen, libpng will use a heuristic to guess which filter
43          *  will encode smallest, then apply that filter.  This happens on a per row basis,
44          *  different rows can use different filters.
45          *
46          *  Using a single filter (or less filters) is typically faster.  Trying all of the
47          *  filters may help minimize the output file size.
48          *
49          *  Our default value matches libpng's default.
50          */
51         FilterFlag fFilterFlags = FilterFlag::kAll;
52 
53         /**
54          *  Must be in [0, 9] where 9 corresponds to maximal compression.  This value is passed
55          *  directly to zlib.  0 is a special case to skip zlib entirely, creating dramatically
56          *  larger pngs.
57          *
58          *  Our default value matches libpng's default.
59          */
60         int fZLibLevel = 6;
61 
62         /**
63          *  Represents comments in the tEXt ancillary chunk of the png.
64          *  The 2i-th entry is the keyword for the i-th comment,
65          *  and the (2i + 1)-th entry is the text for the i-th comment.
66          */
67         sk_sp<SkDataTable> fComments;
68 
69         /**
70          * An optional ICC profile to override the default behavior.
71          *
72          * The default behavior is to generate an ICC profile using a primary matrix and
73          * analytic transfer function. If the color space of |src| cannot be represented
74          * in this way (e.g, it is HLG or PQ), then no profile will be embedded.
75          */
76         const skcms_ICCProfile* fICCProfile = nullptr;
77         const char* fICCProfileDescription = nullptr;
78     };
79 
80     /**
81      *  Encode the |src| pixels to the |dst| stream.
82      *  |options| may be used to control the encoding behavior.
83      *
84      *  Returns true on success.  Returns false on an invalid or unsupported |src|.
85      */
86     static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
87 
88     /**
89      *  Create a png encoder that will encode the |src| pixels to the |dst| stream.
90      *  |options| may be used to control the encoding behavior.
91      *
92      *  |dst| is unowned but must remain valid for the lifetime of the object.
93      *
94      *  This returns nullptr on an invalid or unsupported |src|.
95      */
96     static std::unique_ptr<SkEncoder> Make(SkWStream* dst, const SkPixmap& src,
97                                            const Options& options);
98 
99     ~SkPngEncoder() override;
100 
101 protected:
102     bool onEncodeRows(int numRows) override;
103 
104     SkPngEncoder(std::unique_ptr<SkPngEncoderMgr>, const SkPixmap& src);
105 
106     std::unique_ptr<SkPngEncoderMgr> fEncoderMgr;
107     using INHERITED = SkEncoder;
108 };
109 
110 static inline SkPngEncoder::FilterFlag operator|(SkPngEncoder::FilterFlag x,
111                                                  SkPngEncoder::FilterFlag y) {
112     return (SkPngEncoder::FilterFlag)((int)x | (int)y);
113 }
114 
115 #endif
116