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 typedef SkCodec INHERITED;
120};
121#endif // SkPngCodec_DEFINED
122