xref: /aosp_15_r20/external/skia/src/codec/SkPngCodec.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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