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