xref: /third_party/skia/src/codec/SkPngCodec.h (revision cb93a386)
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
18class SkStream;
19
20class SkPngCodec : public SkCodec {
21public:
22    static bool IsPng(const void*, 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.
29    void setIdatLength(size_t len) { fIdatLength = len; }
30
31    ~SkPngCodec() override;
32
33protected:
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 {
37        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;
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
58    voidp png_ptr() { return fPng_ptr; }
59    voidp info_ptr() { return fInfo_ptr; }
60
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
89private:
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    using INHERITED = SkCodec;
120};
121#endif  // SkPngCodec_DEFINED
122