blob: bf068eafdf9e00316168b005a814732025519377 [file] [log] [blame]
scroggof24f2242015-03-03 08:59:20 -08001/*
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 */
Hal Canary03a7f5f2017-02-10 09:06:38 -05007#ifndef SkPngCodec_DEFINED
8#define SkPngCodec_DEFINED
scroggof24f2242015-03-03 08:59:20 -08009
10#include "SkCodec.h"
scroggo05245902015-03-25 11:11:52 -070011#include "SkColorTable.h"
scroggocf98fa92015-11-23 08:14:40 -080012#include "SkPngChunkReader.h"
Hal Canarydb683012016-11-23 08:55:18 -070013#include "SkEncodedImageFormat.h"
scroggof24f2242015-03-03 08:59:20 -080014#include "SkImageInfo.h"
scroggo05245902015-03-25 11:11:52 -070015#include "SkRefCnt.h"
16#include "SkSwizzler.h"
scroggof24f2242015-03-03 08:59:20 -080017
scroggof24f2242015-03-03 08:59:20 -080018class SkStream;
19
20class SkPngCodec : public SkCodec {
21public:
scroggodb30be22015-12-08 18:54:13 -080022 static bool IsPng(const char*, size_t);
scroggo9b2cdbf2015-07-10 12:07:02 -070023
scroggo1c005e42015-08-04 09:24:45 -070024 // Assume IsPng was called and returned true.
Mike Reedede7bac2017-07-23 15:30:02 -040025 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
26 SkPngChunkReader* = nullptr);
scroggo1c005e42015-08-04 09:24:45 -070027
Leon Scroggins III83239652017-04-21 13:47:12 -040028 // FIXME (scroggo): Temporarily needed by AutoCleanPng.
29 void setIdatLength(size_t len) { fIdatLength = len; }
30
Brian Salomond3b65972017-03-22 12:05:03 -040031 ~SkPngCodec() override;
scroggo9b2cdbf2015-07-10 12:07:02 -070032
scroggof24f2242015-03-03 08:59:20 -080033protected:
mtklein6dc5b9a2016-08-24 12:22:32 -070034 // 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
Leon Scroggins III36f7e322018-08-27 11:55:46 -040047 SkPngCodec(SkEncodedInfo&&, std::unique_ptr<SkStream>, SkPngChunkReader*,
48 void* png_ptr, void* info_ptr, int bitDepth);
scroggo8e6c7ad2016-09-16 08:20:38 -070049
Leon Scroggins571b30f2017-07-11 17:35:31 +000050 Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
mtklein36352bf2015-03-25 18:17:31 -070051 override;
Hal Canarydb683012016-11-23 08:55:18 -070052 SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
scroggob427db12015-08-12 07:24:13 -070053 bool onRewind() override;
scroggo46c57472015-09-30 08:57:13 -070054
msarett400a93b2016-09-01 18:32:52 -070055 SkSampler* getSampler(bool createIfNecessary) override;
scroggo8e6c7ad2016-09-16 08:20:38 -070056 void applyXformRow(void* dst, const void* src);
msarettd1ec89b2016-08-03 12:59:27 -070057
scroggo8e6c7ad2016-09-16 08:20:38 -070058 voidp png_ptr() { return fPng_ptr; }
59 voidp info_ptr() { return fInfo_ptr; }
scroggo46c57472015-09-30 08:57:13 -070060
Ben Wagner145dbcd2016-11-03 14:40:50 -040061 SkSwizzler* swizzler() { return fSwizzler.get(); }
scroggo8e6c7ad2016-09-16 08:20:38 -070062
63 // Initialize variables used by applyXformRow.
msarettc0444612016-09-16 11:45:58 -070064 void initializeXformParams();
scroggo8e6c7ad2016-09-16 08:20:38 -070065
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 */
nagarajan.ndd7ffa52017-09-29 08:23:32 +053072 bool processData();
scroggo8e6c7ad2016-09-16 08:20:38 -070073
scroggo8e6c7ad2016-09-16 08:20:38 -070074 Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
Leon Scroggins571b30f2017-07-11 17:35:31 +000075 const SkCodec::Options&) override;
scroggo8e6c7ad2016-09-16 08:20:38 -070076 Result onIncrementalDecode(int*) override;
scroggod8d68552016-06-06 11:26:17 -070077
Hal Canary67b39de2016-11-07 11:47:44 -050078 sk_sp<SkPngChunkReader> fPngChunkReader;
79 voidp fPng_ptr;
80 voidp fInfo_ptr;
scroggo05245902015-03-25 11:11:52 -070081
scroggod8d68552016-06-06 11:26:17 -070082 // These are stored here so they can be used both by normal decoding and scanline decoding.
Hal Canary67b39de2016-11-07 11:47:44 -050083 sk_sp<SkColorTable> fColorTable; // May be unpremul.
84 std::unique_ptr<SkSwizzler> fSwizzler;
85 SkAutoTMalloc<uint8_t> fStorage;
Matt Sarett379938e2017-01-12 18:34:29 -050086 void* fColorXformSrcRow;
Hal Canary67b39de2016-11-07 11:47:44 -050087 const int fBitDepth;
scroggo6f29a3c2015-07-07 06:09:08 -070088
msarettd1ec89b2016-08-03 12:59:27 -070089private:
msarett400a93b2016-09-01 18:32:52 -070090
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
Leon Scroggins571b30f2017-07-11 17:35:31 +0000102 bool createColorTable(const SkImageInfo& dstInfo);
scroggo8e6c7ad2016-09-16 08:20:38 -0700103 // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
Leon Scroggins571b30f2017-07-11 17:35:31 +0000104 SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&);
Matt Sarett379938e2017-01-12 18:34:29 -0500105 void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
scroggo8e6c7ad2016-09-16 08:20:38 -0700106 void allocateStorage(const SkImageInfo& dstInfo);
scroggo3eada2a2015-04-01 09:33:23 -0700107 void destroyReadStruct();
scroggo05245902015-03-25 11:11:52 -0700108
scroggo8e6c7ad2016-09-16 08:20:38 -0700109 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
msarettc0444612016-09-16 11:45:58 -0700113 XformMode fXformMode;
msarettc0444612016-09-16 11:45:58 -0700114 int fXformWidth;
scroggo8e6c7ad2016-09-16 08:20:38 -0700115
Leon Scroggins III83239652017-04-21 13:47:12 -0400116 size_t fIdatLength;
117 bool fDecodedIdat;
msarett400a93b2016-09-01 18:32:52 -0700118
scroggof24f2242015-03-03 08:59:20 -0800119 typedef SkCodec INHERITED;
120};
Hal Canary03a7f5f2017-02-10 09:06:38 -0500121#endif // SkPngCodec_DEFINED