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