1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 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 #ifndef SkPngCodec_DEFINED 8*c8dee2aaSAndroid Build Coastguard Worker #define SkPngCodec_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/SkGainmapInfo.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkPngCodecBase.h" 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker class SkPngChunkReader; 21*c8dee2aaSAndroid Build Coastguard Worker class SkStream; 22*c8dee2aaSAndroid Build Coastguard Worker struct SkEncodedInfo; 23*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo; 24*c8dee2aaSAndroid Build Coastguard Worker template <typename T> class SkSpan; 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker class SkPngCodec : public SkPngCodecBase { 27*c8dee2aaSAndroid Build Coastguard Worker public: 28*c8dee2aaSAndroid Build Coastguard Worker static bool IsPng(const void*, size_t); 29*c8dee2aaSAndroid Build Coastguard Worker 30*c8dee2aaSAndroid Build Coastguard Worker // Assume IsPng was called and returned true. 31*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, 32*c8dee2aaSAndroid Build Coastguard Worker SkPngChunkReader* = nullptr); 33*c8dee2aaSAndroid Build Coastguard Worker 34*c8dee2aaSAndroid Build Coastguard Worker // FIXME (scroggo): Temporarily needed by AutoCleanPng. setIdatLength(size_t len)35*c8dee2aaSAndroid Build Coastguard Worker void setIdatLength(size_t len) { fIdatLength = len; } 36*c8dee2aaSAndroid Build Coastguard Worker 37*c8dee2aaSAndroid Build Coastguard Worker bool onGetGainmapCodec(SkGainmapInfo*, std::unique_ptr<SkCodec>*) override; 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker bool onGetGainmapInfo(SkGainmapInfo*) override; 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker ~SkPngCodec() override; 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker protected: 44*c8dee2aaSAndroid Build Coastguard Worker // We hold the png_ptr and info_ptr as voidp to avoid having to include png.h 45*c8dee2aaSAndroid Build Coastguard Worker // or forward declare their types here. voidp auto-casts to the real pointer types. 46*c8dee2aaSAndroid Build Coastguard Worker struct voidp { voidpvoidp47*c8dee2aaSAndroid Build Coastguard Worker voidp(void* ptr) : fPtr(ptr) {} 48*c8dee2aaSAndroid Build Coastguard Worker 49*c8dee2aaSAndroid Build Coastguard Worker template <typename T> 50*c8dee2aaSAndroid Build Coastguard Worker operator T*() const { return (T*)fPtr; } 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker explicit operator bool() const { return fPtr != nullptr; } 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker void* fPtr; 55*c8dee2aaSAndroid Build Coastguard Worker }; 56*c8dee2aaSAndroid Build Coastguard Worker 57*c8dee2aaSAndroid Build Coastguard Worker SkPngCodec(SkEncodedInfo&&, 58*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStream>, 59*c8dee2aaSAndroid Build Coastguard Worker SkPngChunkReader*, 60*c8dee2aaSAndroid Build Coastguard Worker void* png_ptr, 61*c8dee2aaSAndroid Build Coastguard Worker void* info_ptr, 62*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStream>, 63*c8dee2aaSAndroid Build Coastguard Worker std::optional<SkGainmapInfo>); 64*c8dee2aaSAndroid Build Coastguard Worker 65*c8dee2aaSAndroid Build Coastguard Worker Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*) 66*c8dee2aaSAndroid Build Coastguard Worker override; 67*c8dee2aaSAndroid Build Coastguard Worker bool onRewind() override; 68*c8dee2aaSAndroid Build Coastguard Worker png_ptr()69*c8dee2aaSAndroid Build Coastguard Worker voidp png_ptr() { return fPng_ptr; } info_ptr()70*c8dee2aaSAndroid Build Coastguard Worker voidp info_ptr() { return fInfo_ptr; } 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker /** 73*c8dee2aaSAndroid Build Coastguard Worker * Pass available input to libpng to process it. 74*c8dee2aaSAndroid Build Coastguard Worker * 75*c8dee2aaSAndroid Build Coastguard Worker * libpng will call any relevant callbacks installed. This will continue decoding 76*c8dee2aaSAndroid Build Coastguard Worker * until it reaches the end of the file, or until a callback tells libpng to stop. 77*c8dee2aaSAndroid Build Coastguard Worker */ 78*c8dee2aaSAndroid Build Coastguard Worker bool processData(); 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes, 81*c8dee2aaSAndroid Build Coastguard Worker const SkCodec::Options&) override; 82*c8dee2aaSAndroid Build Coastguard Worker Result onIncrementalDecode(int*) override; 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPngChunkReader> fPngChunkReader; 85*c8dee2aaSAndroid Build Coastguard Worker voidp fPng_ptr; 86*c8dee2aaSAndroid Build Coastguard Worker voidp fInfo_ptr; 87*c8dee2aaSAndroid Build Coastguard Worker 88*c8dee2aaSAndroid Build Coastguard Worker private: 89*c8dee2aaSAndroid Build Coastguard Worker // SkPngCodecBase overrides: 90*c8dee2aaSAndroid Build Coastguard Worker std::optional<SkSpan<const PaletteColorEntry>> onTryGetPlteChunk() override; 91*c8dee2aaSAndroid Build Coastguard Worker std::optional<SkSpan<const uint8_t>> onTryGetTrnsChunk() override; 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker // Thin wrapper around `SkPngCodecBase::initializeXforms` that also sets up 94*c8dee2aaSAndroid Build Coastguard Worker // some `libpng`-specific state. 95*c8dee2aaSAndroid Build Coastguard Worker Result initializeXforms(const SkImageInfo& dstInfo, const Options&); 96*c8dee2aaSAndroid Build Coastguard Worker 97*c8dee2aaSAndroid Build Coastguard Worker void destroyReadStruct(); 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0; 100*c8dee2aaSAndroid Build Coastguard Worker virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0; 101*c8dee2aaSAndroid Build Coastguard Worker virtual Result decode(int* rowsDecoded) = 0; 102*c8dee2aaSAndroid Build Coastguard Worker 103*c8dee2aaSAndroid Build Coastguard Worker size_t fIdatLength; 104*c8dee2aaSAndroid Build Coastguard Worker bool fDecodedIdat; 105*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStream> fGainmapStream; 106*c8dee2aaSAndroid Build Coastguard Worker std::optional<SkGainmapInfo> fGainmapInfo; 107*c8dee2aaSAndroid Build Coastguard Worker }; 108*c8dee2aaSAndroid Build Coastguard Worker #endif // SkPngCodec_DEFINED 109