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/private/base/SkAPI.h" 14 15 // TODO(kjlubick) update clients to directly include this 16 #include "include/encode/SkEncoder.h" // IWYU pragma: keep 17 18 #include <memory> 19 20 class GrDirectContext; 21 class SkData; 22 class SkImage; 23 class SkPixmap; 24 class SkWStream; 25 struct skcms_ICCProfile; 26 struct SkGainmapInfo; 27 28 namespace SkPngEncoder { 29 30 enum class FilterFlag : int { 31 kZero = 0x00, 32 kNone = 0x08, 33 kSub = 0x10, 34 kUp = 0x20, 35 kAvg = 0x40, 36 kPaeth = 0x80, 37 kAll = kNone | kSub | kUp | kAvg | kPaeth, 38 }; 39 40 inline FilterFlag operator|(FilterFlag x, FilterFlag y) { return (FilterFlag)((int)x | (int)y); } 41 42 struct Options { 43 /** 44 * Selects which filtering strategies to use. 45 * 46 * If a single filter is chosen, libpng will use that filter for every row. 47 * 48 * If multiple filters are chosen, libpng will use a heuristic to guess which filter 49 * will encode smallest, then apply that filter. This happens on a per row basis, 50 * different rows can use different filters. 51 * 52 * Using a single filter (or less filters) is typically faster. Trying all of the 53 * filters may help minimize the output file size. 54 * 55 * Our default value matches libpng's default. 56 */ 57 FilterFlag fFilterFlags = FilterFlag::kAll; 58 59 /** 60 * Must be in [0, 9] where 9 corresponds to maximal compression. This value is passed 61 * directly to zlib. 0 is a special case to skip zlib entirely, creating dramatically 62 * larger pngs. 63 * 64 * Our default value matches libpng's default. 65 */ 66 int fZLibLevel = 6; 67 68 /** 69 * Represents comments in the tEXt ancillary chunk of the png. 70 * The 2i-th entry is the keyword for the i-th comment, 71 * and the (2i + 1)-th entry is the text for the i-th comment. 72 */ 73 sk_sp<SkDataTable> fComments; 74 75 /** 76 * An optional ICC profile to override the default behavior. 77 * 78 * The default behavior is to generate an ICC profile using a primary matrix and 79 * analytic transfer function. If the color space of |src| cannot be represented 80 * in this way (e.g, it is HLG or PQ), then no profile will be embedded. 81 */ 82 const skcms_ICCProfile* fICCProfile = nullptr; 83 const char* fICCProfileDescription = nullptr; 84 85 /** 86 * If non-null, then a gainmap and its metadata will be encoded as png chunks. 87 * The gainmap will be encoded in a gmAP chunk as a full PNG container. The 88 * gainmap info will be encoded in a gdAT chunk inside of the gmAP chunk. 89 * This effectively is Option B proposed in this discussion for adding gainmaps 90 * into PNG: https://github.com/w3c/png/issues/380#issuecomment-2325163149. 91 * 92 * Note that if fGainmapInfo is null, then fGainmap will fail to encode, as the 93 * gainmap metadata is required to correctly interpret the encoded gainmap. 94 */ 95 const SkPixmap* fGainmap = nullptr; 96 const SkGainmapInfo* fGainmapInfo = nullptr; 97 }; 98 99 /** 100 * Encode the |src| pixels to the |dst| stream. 101 * |options| may be used to control the encoding behavior. 102 * 103 * Returns true on success. Returns false on an invalid or unsupported |src|. 104 */ 105 SK_API bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options); 106 107 /** 108 * Encode the provided image and return the resulting bytes. If the image was created as 109 * a texture-backed image on a GPU context, that |ctx| must be provided so the pixels 110 * can be read before being encoded. For raster-backed images, |ctx| can be nullptr. 111 * |options| may be used to control the encoding behavior. 112 * 113 * Returns nullptr if the pixels could not be read or encoding otherwise fails. 114 */ 115 SK_API sk_sp<SkData> Encode(GrDirectContext* ctx, const SkImage* img, const Options& options); 116 117 /** 118 * Create a png encoder that will encode the |src| pixels to the |dst| stream. 119 * |options| may be used to control the encoding behavior. 120 * 121 * The primary use of this is incremental encoding of the pixels. 122 * 123 * |dst| is unowned but must remain valid for the lifetime of the object. 124 * 125 * This returns nullptr on an invalid or unsupported |src|. 126 */ 127 SK_API std::unique_ptr<SkEncoder> Make(SkWStream* dst, const SkPixmap& src, const Options& options); 128 129 } // namespace SkPngEncoder 130 131 #endif 132