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