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