1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2024 Google LLC. 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 #ifndef SkPngCodecBase_DEFINED 8*c8dee2aaSAndroid Build Coastguard Worker #define SkPngCodecBase_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef> 11*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 12*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 13*c8dee2aaSAndroid Build Coastguard Worker #include <optional> 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkEncodedInfo.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h" 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker class SkColorPalette; 22*c8dee2aaSAndroid Build Coastguard Worker class SkSampler; 23*c8dee2aaSAndroid Build Coastguard Worker class SkStream; 24*c8dee2aaSAndroid Build Coastguard Worker class SkSwizzler; 25*c8dee2aaSAndroid Build Coastguard Worker enum class SkEncodedImageFormat; 26*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo; 27*c8dee2aaSAndroid Build Coastguard Worker template <typename T> class SkSpan; 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker // This class implements functionality shared between `SkPngCodec` and 30*c8dee2aaSAndroid Build Coastguard Worker // `SkPngRustCodec` (the latter is from `experimental/rust_png`). 31*c8dee2aaSAndroid Build Coastguard Worker class SkPngCodecBase : public SkCodec { 32*c8dee2aaSAndroid Build Coastguard Worker public: 33*c8dee2aaSAndroid Build Coastguard Worker ~SkPngCodecBase() override; 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker static bool isCompatibleColorProfileAndType(const SkEncodedInfo::ICCProfile* profile, 36*c8dee2aaSAndroid Build Coastguard Worker SkEncodedInfo::Color color); 37*c8dee2aaSAndroid Build Coastguard Worker protected: 38*c8dee2aaSAndroid Build Coastguard Worker SkPngCodecBase(SkEncodedInfo&&, std::unique_ptr<SkStream>); 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker // Initialize most fields needed by `applyXformRow`. 41*c8dee2aaSAndroid Build Coastguard Worker // 42*c8dee2aaSAndroid Build Coastguard Worker // Each call to `applyXformRow` will transform `frameWidth` pixels 43*c8dee2aaSAndroid Build Coastguard Worker // (which may be less than `dstInfo.width()` when decoding frames that 44*c8dee2aaSAndroid Build Coastguard Worker // depend on earlier frames). 45*c8dee2aaSAndroid Build Coastguard Worker Result initializeXforms(const SkImageInfo& dstInfo, const Options& options, int frameWidth); 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker // Initialize other fields needed by `applyXformRow`. 48*c8dee2aaSAndroid Build Coastguard Worker // 49*c8dee2aaSAndroid Build Coastguard Worker // Needs to be called *after* (i.e. outside of) `onStartIncrementalDecode`. 50*c8dee2aaSAndroid Build Coastguard Worker void initializeXformParams(); 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker // Transforms a decoded row into the `dstInfo` format that was earlier 53*c8dee2aaSAndroid Build Coastguard Worker // passed to `initializeXforms`. 54*c8dee2aaSAndroid Build Coastguard Worker // 55*c8dee2aaSAndroid Build Coastguard Worker // The first bytes/pixels of `srcRow` will be transformed into the first 56*c8dee2aaSAndroid Build Coastguard Worker // bytes/pixels of `dstRow`. In other words, the transformation ignores 57*c8dee2aaSAndroid Build Coastguard Worker // `fcTL.x_offset` field - the caller should offset `dstRow` if desired 58*c8dee2aaSAndroid Build Coastguard Worker // (it may not be desirable when working with interlaced rows which are 59*c8dee2aaSAndroid Build Coastguard Worker // first transformed into an intermediate buffer). 60*c8dee2aaSAndroid Build Coastguard Worker void applyXformRow(SkSpan<uint8_t> dstRow, SkSpan<const uint8_t> srcRow); 61*c8dee2aaSAndroid Build Coastguard Worker void applyXformRow(void* dstRow, const uint8_t* srcRow); 62*c8dee2aaSAndroid Build Coastguard Worker getEncodedRowBytes()63*c8dee2aaSAndroid Build Coastguard Worker size_t getEncodedRowBytes() const { return fEncodedRowBytes; } swizzler()64*c8dee2aaSAndroid Build Coastguard Worker const SkSwizzler* swizzler() const { return fSwizzler.get(); } 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker struct PaletteColorEntry { 67*c8dee2aaSAndroid Build Coastguard Worker uint8_t red; 68*c8dee2aaSAndroid Build Coastguard Worker uint8_t green; 69*c8dee2aaSAndroid Build Coastguard Worker uint8_t blue; 70*c8dee2aaSAndroid Build Coastguard Worker }; 71*c8dee2aaSAndroid Build Coastguard Worker virtual std::optional<SkSpan<const PaletteColorEntry>> onTryGetPlteChunk() = 0; 72*c8dee2aaSAndroid Build Coastguard Worker virtual std::optional<SkSpan<const uint8_t>> onTryGetTrnsChunk() = 0; 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker private: 75*c8dee2aaSAndroid Build Coastguard Worker // SkCodec overrides: 76*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat onGetEncodedFormat() const final; 77*c8dee2aaSAndroid Build Coastguard Worker SkSampler* getSampler(bool createIfNecessary) final; 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker void allocateStorage(const SkImageInfo& dstInfo); 80*c8dee2aaSAndroid Build Coastguard Worker Result initializeSwizzler(const SkImageInfo& dstInfo, 81*c8dee2aaSAndroid Build Coastguard Worker const Options& options, 82*c8dee2aaSAndroid Build Coastguard Worker bool skipFormatConversion, 83*c8dee2aaSAndroid Build Coastguard Worker int frameWidth); 84*c8dee2aaSAndroid Build Coastguard Worker bool createColorTable(const SkImageInfo& dstInfo); 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker enum XformMode { 87*c8dee2aaSAndroid Build Coastguard Worker // Requires only a swizzle pass. 88*c8dee2aaSAndroid Build Coastguard Worker kSwizzleOnly_XformMode, 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker // Requires only a color xform pass. 91*c8dee2aaSAndroid Build Coastguard Worker kColorOnly_XformMode, 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker // Requires a swizzle and a color xform. 94*c8dee2aaSAndroid Build Coastguard Worker kSwizzleColor_XformMode, 95*c8dee2aaSAndroid Build Coastguard Worker }; 96*c8dee2aaSAndroid Build Coastguard Worker XformMode fXformMode; 97*c8dee2aaSAndroid Build Coastguard Worker 98*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSwizzler> fSwizzler; 99*c8dee2aaSAndroid Build Coastguard Worker skia_private::AutoTMalloc<uint8_t> fStorage; 100*c8dee2aaSAndroid Build Coastguard Worker int fXformWidth = -1; 101*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorPalette> fColorTable; // May be unpremul. 102*c8dee2aaSAndroid Build Coastguard Worker 103*c8dee2aaSAndroid Build Coastguard Worker size_t fEncodedRowBytes = 0; // Size of encoded/source row in bytes. 104*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_DEBUG) 105*c8dee2aaSAndroid Build Coastguard Worker size_t fDstRowBytes = 0; // Size of destination row in bytes. 106*c8dee2aaSAndroid Build Coastguard Worker #endif 107*c8dee2aaSAndroid Build Coastguard Worker }; 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker #endif // SkPngCodecBase_DEFINED 110