blob: 6848cfc74c5566f396b75a183d9e597f0b35e8be [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"
msarettd1ec89b2016-08-03 12:59:27 -070011#include "SkColorSpaceXform.h"
scroggo05245902015-03-25 11:11:52 -070012#include "SkColorTable.h"
scroggocf98fa92015-11-23 08:14:40 -080013#include "SkPngChunkReader.h"
Hal Canarydb683012016-11-23 08:55:18 -070014#include "SkEncodedImageFormat.h"
scroggof24f2242015-03-03 08:59:20 -080015#include "SkImageInfo.h"
scroggo05245902015-03-25 11:11:52 -070016#include "SkRefCnt.h"
17#include "SkSwizzler.h"
scroggof24f2242015-03-03 08:59:20 -080018
scroggof24f2242015-03-03 08:59:20 -080019class SkStream;
20
21class SkPngCodec : public SkCodec {
22public:
scroggodb30be22015-12-08 18:54:13 -080023 static bool IsPng(const char*, size_t);
scroggo9b2cdbf42015-07-10 12:07:02 -070024
scroggo1c005e42015-08-04 09:24:45 -070025 // Assume IsPng was called and returned true.
Mike Reedede7bac2017-07-23 15:30:02 -040026 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
27 SkPngChunkReader* = nullptr);
scroggo1c005e42015-08-04 09:24:45 -070028
Leon Scroggins III83239652017-04-21 13:47:12 -040029 // FIXME (scroggo): Temporarily needed by AutoCleanPng.
30 void setIdatLength(size_t len) { fIdatLength = len; }
31
Brian Salomond3b65972017-03-22 12:05:03 -040032 ~SkPngCodec() override;
scroggo9b2cdbf42015-07-10 12:07:02 -070033
scroggof24f2242015-03-03 08:59:20 -080034protected:
mtklein6dc5b9a2016-08-24 12:22:32 -070035 // 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 {
38 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
Mike Reedede7bac2017-07-23 15:30:02 -040048 SkPngCodec(const SkEncodedInfo&, const SkImageInfo&, std::unique_ptr<SkStream>,
49 SkPngChunkReader*, void* png_ptr, void* info_ptr, int bitDepth);
scroggo8e6c7ad2016-09-16 08:20:38 -070050
Leon Scroggins571b30f2017-07-11 17:35:31 +000051 Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
mtklein36352bf2015-03-25 18:17:31 -070052 override;
Hal Canarydb683012016-11-23 08:55:18 -070053 SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
scroggob427db12015-08-12 07:24:13 -070054 bool onRewind() override;
msarettf7eb6fc2016-09-13 09:04:11 -070055 uint64_t onGetFillValue(const SkImageInfo&) const override;
scroggo46c57472015-09-30 08:57:13 -070056
msarett400a93b2016-09-01 18:32:52 -070057 SkSampler* getSampler(bool createIfNecessary) override;
scroggo8e6c7ad2016-09-16 08:20:38 -070058 void applyXformRow(void* dst, const void* src);
msarettd1ec89b2016-08-03 12:59:27 -070059
scroggo8e6c7ad2016-09-16 08:20:38 -070060 voidp png_ptr() { return fPng_ptr; }
61 voidp info_ptr() { return fInfo_ptr; }
scroggo46c57472015-09-30 08:57:13 -070062
Ben Wagner145dbcd2016-11-03 14:40:50 -040063 SkSwizzler* swizzler() { return fSwizzler.get(); }
scroggo8e6c7ad2016-09-16 08:20:38 -070064
65 // Initialize variables used by applyXformRow.
msarettc0444612016-09-16 11:45:58 -070066 void initializeXformParams();
scroggo8e6c7ad2016-09-16 08:20:38 -070067
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 */
nagarajan.ndd7ffa52017-09-29 08:23:32 +053074 bool processData();
scroggo8e6c7ad2016-09-16 08:20:38 -070075
scroggo8e6c7ad2016-09-16 08:20:38 -070076 Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
Leon Scroggins571b30f2017-07-11 17:35:31 +000077 const SkCodec::Options&) override;
scroggo8e6c7ad2016-09-16 08:20:38 -070078 Result onIncrementalDecode(int*) override;
scroggod8d68552016-06-06 11:26:17 -070079
Hal Canary67b39de2016-11-07 11:47:44 -050080 sk_sp<SkPngChunkReader> fPngChunkReader;
81 voidp fPng_ptr;
82 voidp fInfo_ptr;
scroggo05245902015-03-25 11:11:52 -070083
scroggod8d68552016-06-06 11:26:17 -070084 // These are stored here so they can be used both by normal decoding and scanline decoding.
Hal Canary67b39de2016-11-07 11:47:44 -050085 sk_sp<SkColorTable> fColorTable; // May be unpremul.
86 std::unique_ptr<SkSwizzler> fSwizzler;
87 SkAutoTMalloc<uint8_t> fStorage;
Matt Sarett379938e2017-01-12 18:34:29 -050088 void* fColorXformSrcRow;
Hal Canary67b39de2016-11-07 11:47:44 -050089 const int fBitDepth;
scroggo6f29a3c2015-07-07 06:09:08 -070090
msarettd1ec89b2016-08-03 12:59:27 -070091private:
msarett400a93b2016-09-01 18:32:52 -070092
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
Leon Scroggins571b30f2017-07-11 17:35:31 +0000104 bool createColorTable(const SkImageInfo& dstInfo);
scroggo8e6c7ad2016-09-16 08:20:38 -0700105 // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
Leon Scroggins571b30f2017-07-11 17:35:31 +0000106 SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&);
Matt Sarett379938e2017-01-12 18:34:29 -0500107 void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
scroggo8e6c7ad2016-09-16 08:20:38 -0700108 void allocateStorage(const SkImageInfo& dstInfo);
scroggo3eada2a2015-04-01 09:33:23 -0700109 void destroyReadStruct();
scroggo05245902015-03-25 11:11:52 -0700110
scroggo8e6c7ad2016-09-16 08:20:38 -0700111 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
msarettc0444612016-09-16 11:45:58 -0700115 XformMode fXformMode;
msarettc0444612016-09-16 11:45:58 -0700116 int fXformWidth;
scroggo8e6c7ad2016-09-16 08:20:38 -0700117
Leon Scroggins III83239652017-04-21 13:47:12 -0400118 size_t fIdatLength;
119 bool fDecodedIdat;
msarett400a93b2016-09-01 18:32:52 -0700120
scroggof24f2242015-03-03 08:59:20 -0800121 typedef SkCodec INHERITED;
122};
Hal Canary03a7f5f2017-02-10 09:06:38 -0500123#endif // SkPngCodec_DEFINED