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/SkImageInfo.h"
13 #include "include/core/SkPngChunkReader.h"
14 #include "include/core/SkRefCnt.h"
15 #include "src/codec/SkColorTable.h"
16 #include "src/codec/SkSwizzler.h"
17 
18 class SkStream;
19 
20 class SkPngCodec : public SkCodec {
21 public:
22     static bool IsPng(const char*, size_t);
23 
24     // Assume IsPng was called and returned true.
25     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
26                                                    SkPngChunkReader* = nullptr);
27 
28     // FIXME (scroggo): Temporarily needed by AutoCleanPng.
setIdatLength(size_t len)29     void setIdatLength(size_t len) { fIdatLength = len; }
30 
31     ~SkPngCodec() override;
32 
33 protected:
34     // We hold the png_ptr and info_ptr as voidp to avoid having to include png.h
35     // or forward declare their types here.  voidp auto-casts to the real pointer types.
36     struct voidp {
voidpvoidp37         voidp(void* ptr) : fPtr(ptr) {}
38 
39         template <typename T>
40         operator T*() const { return (T*)fPtr; }
41 
42         explicit operator bool() const { return fPtr != nullptr; }
43 
44         void* fPtr;
45     };
46 
47     SkPngCodec(SkEncodedInfo&&, std::unique_ptr<SkStream>, SkPngChunkReader*,
48                void* png_ptr, void* info_ptr, int bitDepth);
49 
50     Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
51             override;
onGetEncodedFormat()52     SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
53     bool onRewind() override;
54 
55     SkSampler* getSampler(bool createIfNecessary) override;
56     void applyXformRow(void* dst, const void* src);
57 
png_ptr()58     voidp png_ptr() { return fPng_ptr; }
info_ptr()59     voidp info_ptr() { return fInfo_ptr; }
60 
swizzler()61     SkSwizzler* swizzler() { return fSwizzler.get(); }
62 
63     // Initialize variables used by applyXformRow.
64     void initializeXformParams();
65 
66     /**
67      *  Pass available input to libpng to process it.
68      *
69      *  libpng will call any relevant callbacks installed. This will continue decoding
70      *  until it reaches the end of the file, or until a callback tells libpng to stop.
71      */
72     bool processData();
73 
74     Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
75             const SkCodec::Options&) override;
76     Result onIncrementalDecode(int*) override;
77 
78     sk_sp<SkPngChunkReader>     fPngChunkReader;
79     voidp                       fPng_ptr;
80     voidp                       fInfo_ptr;
81 
82     // These are stored here so they can be used both by normal decoding and scanline decoding.
83     sk_sp<SkColorTable>         fColorTable;    // May be unpremul.
84     std::unique_ptr<SkSwizzler> fSwizzler;
85     SkAutoTMalloc<uint8_t>      fStorage;
86     void*                       fColorXformSrcRow;
87     const int                   fBitDepth;
88 
89 private:
90 
91     enum XformMode {
92         // Requires only a swizzle pass.
93         kSwizzleOnly_XformMode,
94 
95         // Requires only a color xform pass.
96         kColorOnly_XformMode,
97 
98         // Requires a swizzle and a color xform.
99         kSwizzleColor_XformMode,
100     };
101 
102     bool createColorTable(const SkImageInfo& dstInfo);
103     // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
104     SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&);
105     void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
106     void allocateStorage(const SkImageInfo& dstInfo);
107     void destroyReadStruct();
108 
109     virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0;
110     virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0;
111     virtual Result decode(int* rowsDecoded) = 0;
112 
113     XformMode                      fXformMode;
114     int                            fXformWidth;
115 
116     size_t                         fIdatLength;
117     bool                           fDecodedIdat;
118 
119     typedef SkCodec INHERITED;
120 };
121 #endif  // SkPngCodec_DEFINED
122