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