• 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 "include/codec/SkCodec.h"
11 #include "include/core/SkEncodedImageFormat.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/private/base/SkTemplates.h"
14 
15 #include <cstddef>
16 #include <cstdint>
17 #include <memory>
18 
19 class SkColorTable;
20 class SkPngChunkReader;
21 class SkSampler;
22 class SkStream;
23 class SkSwizzler;
24 struct SkEncodedInfo;
25 struct SkImageInfo;
26 
27 class SkPngCodec : public SkCodec {
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     ~SkPngCodec() override;
39 
40 protected:
41     // We hold the png_ptr and info_ptr as voidp to avoid having to include png.h
42     // or forward declare their types here.  voidp auto-casts to the real pointer types.
43     struct voidp {
voidpvoidp44         voidp(void* ptr) : fPtr(ptr) {}
45 
46         template <typename T>
47         operator T*() const { return (T*)fPtr; }
48 
49         explicit operator bool() const { return fPtr != nullptr; }
50 
51         void* fPtr;
52     };
53 
54     SkPngCodec(SkEncodedInfo&&, std::unique_ptr<SkStream>, SkPngChunkReader*,
55                void* png_ptr, void* info_ptr, int bitDepth);
56 
57     Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
58             override;
onGetEncodedFormat()59     SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
60     bool onRewind() override;
61 
62     SkSampler* getSampler(bool createIfNecessary) override;
63     void applyXformRow(void* dst, const void* src);
64 
png_ptr()65     voidp png_ptr() { return fPng_ptr; }
info_ptr()66     voidp info_ptr() { return fInfo_ptr; }
67 
swizzler()68     SkSwizzler* swizzler() { return fSwizzler.get(); }
69 
70     // Initialize variables used by applyXformRow.
71     void initializeXformParams();
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<SkPngChunkReader>     fPngChunkReader;
86     voidp                       fPng_ptr;
87     voidp                       fInfo_ptr;
88 
89     // These are stored here so they can be used both by normal decoding and scanline decoding.
90     sk_sp<SkColorTable>         fColorTable;    // May be unpremul.
91     std::unique_ptr<SkSwizzler> fSwizzler;
92     skia_private::AutoTMalloc<uint8_t>      fStorage;
93     void*                       fColorXformSrcRow;
94     const int                   fBitDepth;
95 
96 private:
97 
98     enum XformMode {
99         // Requires only a swizzle pass.
100         kSwizzleOnly_XformMode,
101 
102         // Requires only a color xform pass.
103         kColorOnly_XformMode,
104 
105         // Requires a swizzle and a color xform.
106         kSwizzleColor_XformMode,
107     };
108 
109     bool createColorTable(const SkImageInfo& dstInfo);
110     // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
111     SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&);
112     void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
113     void allocateStorage(const SkImageInfo& dstInfo);
114     void destroyReadStruct();
115 
116     virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0;
117     virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0;
118     virtual Result decode(int* rowsDecoded) = 0;
119 
120     XformMode                      fXformMode;
121     int                            fXformWidth;
122 
123     size_t                         fIdatLength;
124     bool                           fDecodedIdat;
125 
126     using INHERITED = SkCodec;
127 };
128 #endif  // SkPngCodec_DEFINED
129