blob: 2e1f7d731ad229d4a20262782bd9ed4b4e915b78 [file] [log] [blame]
Matt Sarettc367d032017-05-05 11:13:26 -04001/*
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 "SkEncoder.h"
Yuqian Lid0dbee62017-06-09 11:35:58 -040012#include "SkDataTable.h"
Matt Sarettc367d032017-05-05 11:13:26 -040013
14class SkPngEncoderMgr;
15class SkWStream;
16
Matt Sarett94fd06f2017-05-08 17:31:00 -040017class SK_API SkPngEncoder : public SkEncoder {
Matt Sarettc367d032017-05-05 11:13:26 -040018public:
19
Matt Sarettbe4c9b02017-05-08 12:11:44 -040020 enum class FilterFlag : int {
21 kZero = 0x00,
22 kNone = 0x08,
23 kSub = 0x10,
24 kUp = 0x20,
25 kAvg = 0x40,
26 kPaeth = 0x80,
27 kAll = kNone | kSub | kUp | kAvg | kPaeth,
28 };
Matt Sarettc367d032017-05-05 11:13:26 -040029
30 struct Options {
Matt Sarett04c37312017-05-05 14:02:13 -040031 /**
Matt Sarettbe4c9b02017-05-08 12:11:44 -040032 * Selects which filtering strategies to use.
33 *
34 * If a single filter is chosen, libpng will use that filter for every row.
35 *
36 * If multiple filters are chosen, libpng will use a heuristic to guess which filter
37 * will encode smallest, then apply that filter. This happens on a per row basis,
38 * different rows can use different filters.
39 *
40 * Using a single filter (or less filters) is typically faster. Trying all of the
41 * filters may help minimize the output file size.
42 *
43 * Our default value matches libpng's default.
44 */
45 FilterFlag fFilterFlags = FilterFlag::kAll;
46
47 /**
48 * Must be in [0, 9] where 9 corresponds to maximal compression. This value is passed
49 * directly to zlib. 0 is a special case to skip zlib entirely, creating dramatically
50 * larger pngs.
51 *
52 * Our default value matches libpng's default.
53 */
54 int fZLibLevel = 6;
55
56 /**
Yuqian Lid0dbee62017-06-09 11:35:58 -040057 * Represents comments in the tEXt ancillary chunk of the png.
58 * The 2i-th entry is the keyword for the i-th comment,
59 * and the (2i + 1)-th entry is the text for the i-th comment.
60 */
61 sk_sp<SkDataTable> fComments;
Matt Sarettc367d032017-05-05 11:13:26 -040062 };
63
64 /**
65 * Encode the |src| pixels to the |dst| stream.
66 * |options| may be used to control the encoding behavior.
67 *
68 * Returns true on success. Returns false on an invalid or unsupported |src|.
69 */
70 static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
71
72 /**
73 * Create a png encoder that will encode the |src| pixels to the |dst| stream.
74 * |options| may be used to control the encoding behavior.
75 *
76 * |dst| is unowned but must remain valid for the lifetime of the object.
77 *
78 * This returns nullptr on an invalid or unsupported |src|.
79 */
Matt Sarett6a4dc662017-05-11 09:32:59 -040080 static std::unique_ptr<SkEncoder> Make(SkWStream* dst, const SkPixmap& src,
81 const Options& options);
Matt Sarettc367d032017-05-05 11:13:26 -040082
83 ~SkPngEncoder() override;
84
85protected:
86 bool onEncodeRows(int numRows) override;
87
88 SkPngEncoder(std::unique_ptr<SkPngEncoderMgr>, const SkPixmap& src);
89
90 std::unique_ptr<SkPngEncoderMgr> fEncoderMgr;
91 typedef SkEncoder INHERITED;
92};
93
Matt Sarettbe4c9b02017-05-08 12:11:44 -040094static inline SkPngEncoder::FilterFlag operator|(SkPngEncoder::FilterFlag x,
95 SkPngEncoder::FilterFlag y) {
96 return (SkPngEncoder::FilterFlag)((int)x | (int)y);
97}
98
Matt Sarettc367d032017-05-05 11:13:26 -040099#endif