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