• 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 SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL);
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(const SkEncodedInfo&, const SkImageInfo&, SkStream*, SkPngChunkReader*,
48             void* png_ptr, void* info_ptr, int bitDepth);
49 
50     Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*)
51             override;
onGetEncodedFormat()52     SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
53     bool onRewind() override;
54     uint64_t onGetFillValue(const SkImageInfo&) const override;
55 
56     SkSampler* getSampler(bool createIfNecessary) override;
57     void applyXformRow(void* dst, const void* src);
58 
png_ptr()59     voidp png_ptr() { return fPng_ptr; }
info_ptr()60     voidp info_ptr() { return fInfo_ptr; }
61 
swizzler()62     SkSwizzler* swizzler() { return fSwizzler.get(); }
63 
64     // Initialize variables used by applyXformRow.
65     void initializeXformParams();
66 
67     /**
68      *  Pass available input to libpng to process it.
69      *
70      *  libpng will call any relevant callbacks installed. This will continue decoding
71      *  until it reaches the end of the file, or until a callback tells libpng to stop.
72      */
73     void processData();
74 
75     Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
76             const SkCodec::Options&,
77             SkPMColor* ctable, int* ctableCount) 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, int* ctableCount);
105     // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
106     bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor* colorPtr,
107                           int* colorCount);
108     void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
109     void allocateStorage(const SkImageInfo& dstInfo);
110     void destroyReadStruct();
111 
112     virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0;
113     virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0;
114     virtual Result decode(int* rowsDecoded) = 0;
115 
116     XformMode                      fXformMode;
117     SkColorSpaceXform::ColorFormat fXformColorFormat;
118     SkAlphaType                    fXformAlphaType;
119     int                            fXformWidth;
120 
121     size_t                         fIdatLength;
122     bool                           fDecodedIdat;
123 
124     typedef SkCodec INHERITED;
125 };
126 #endif  // SkPngCodec_DEFINED
127