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