blob: 89c84bdda30635d53197efa22bc49b7f7922e507 [file] [log] [blame]
msarett8c8f22a2015-04-01 06:58:48 -07001/*
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 SkGifCodec_DEFINED
8#define SkGifCodec_DEFINED
msarett8c8f22a2015-04-01 06:58:48 -07009
10#include "SkCodec.h"
scroggo19b91532016-10-24 09:03:26 -070011#include "SkCodecAnimation.h"
msarettad8bcfe2016-03-07 07:09:03 -080012#include "SkColorSpace.h"
msarett10522ff2015-09-07 08:54:01 -070013#include "SkColorTable.h"
msarett8c8f22a2015-04-01 06:58:48 -070014#include "SkImageInfo.h"
msarett10522ff2015-09-07 08:54:01 -070015#include "SkSwizzler.h"
msarett8c8f22a2015-04-01 06:58:48 -070016
scroggo3d3a65c2016-10-24 12:28:30 -070017#include "SkGifImageReader.h"
msarett8c8f22a2015-04-01 06:58:48 -070018
19/*
20 *
21 * This class implements the decoding for gif images
22 *
23 */
24class SkGifCodec : public SkCodec {
25public:
scroggodb30be22015-12-08 18:54:13 -080026 static bool IsGif(const void*, size_t);
msarett8c8f22a2015-04-01 06:58:48 -070027
28 /*
29 * Assumes IsGif was called and returned true
msarett8c8f22a2015-04-01 06:58:48 -070030 * Reads enough of the stream to determine the image format
31 */
Mike Reedede7bac2017-07-23 15:30:02 -040032 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
msarett10522ff2015-09-07 08:54:01 -070033
scroggo3d3a65c2016-10-24 12:28:30 -070034 // Callback for SkGifImageReader when a row is available.
Leon Scroggins III249b8e32017-04-17 12:46:33 -040035 bool haveDecodedRow(int frameIndex, const unsigned char* rowBegin,
36 int rowNumber, int repeatCount, bool writeTransparentPixels);
msarett8c8f22a2015-04-01 06:58:48 -070037protected:
msarett438b2ad2015-04-09 12:43:10 -070038 /*
msarett10522ff2015-09-07 08:54:01 -070039 * Performs the full gif decode
msarett8c8f22a2015-04-01 06:58:48 -070040 */
41 Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&,
Leon Scroggins571b30f2017-07-11 17:35:31 +000042 int*) override;
msarett8c8f22a2015-04-01 06:58:48 -070043
Hal Canarydb683012016-11-23 08:55:18 -070044 SkEncodedImageFormat onGetEncodedFormat() const override {
45 return SkEncodedImageFormat::kGIF;
msarett8c8f22a2015-04-01 06:58:48 -070046 }
47
scroggob427db12015-08-12 07:24:13 -070048 bool onRewind() override;
49
msarettf7eb6fc2016-09-13 09:04:11 -070050 uint64_t onGetFillValue(const SkImageInfo&) const override;
msarette6dd0042015-10-09 11:07:34 -070051
Leon Scroggins III249b8e32017-04-17 12:46:33 -040052 int onGetFrameCount() override;
53 bool onGetFrameInfo(int, FrameInfo*) const override;
scroggoe71b1a12016-11-01 08:28:28 -070054 int onGetRepetitionCount() override;
scroggo19b91532016-10-24 09:03:26 -070055
56 Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
Leon Scroggins571b30f2017-07-11 17:35:31 +000057 const SkCodec::Options&) override;
scroggo19b91532016-10-24 09:03:26 -070058
59 Result onIncrementalDecode(int*) override;
msarette6dd0042015-10-09 11:07:34 -070060
Leon Scroggins III1f6af6b2017-06-12 16:41:09 -040061 const SkFrameHolder* getFrameHolder() const override {
62 return fReader.get();
63 }
64
msarett8c8f22a2015-04-01 06:58:48 -070065private:
66
67 /*
msarett10522ff2015-09-07 08:54:01 -070068 * Initializes the color table that we will use for decoding.
69 *
70 * @param dstInfo Contains the requested dst color type.
scroggo19b91532016-10-24 09:03:26 -070071 * @param frameIndex Frame whose color table to use.
msarett10522ff2015-09-07 08:54:01 -070072 */
Leon Scroggins III249b8e32017-04-17 12:46:33 -040073 void initializeColorTable(const SkImageInfo& dstInfo, int frameIndex);
msarett10522ff2015-09-07 08:54:01 -070074
75 /*
Leon Scroggins571b30f2017-07-11 17:35:31 +000076 * Does necessary setup, including setting up the color table and swizzler.
msarett10522ff2015-09-07 08:54:01 -070077 */
Leon Scroggins571b30f2017-07-11 17:35:31 +000078 Result prepareToDecode(const SkImageInfo& dstInfo, const Options& opts);
msarett10522ff2015-09-07 08:54:01 -070079
80 /*
81 * Initializes the swizzler.
82 *
scroggo19b91532016-10-24 09:03:26 -070083 * @param dstInfo Output image information. Dimensions may have been
84 * adjusted if the image frame size does not match the size
85 * indicated in the header.
86 * @param frameIndex Which frame we are decoding. This determines the frameRect
87 * to use.
msarett10522ff2015-09-07 08:54:01 -070088 */
Leon Scroggins III249b8e32017-04-17 12:46:33 -040089 void initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex);
msarett10522ff2015-09-07 08:54:01 -070090
msarette6dd0042015-10-09 11:07:34 -070091 SkSampler* getSampler(bool createIfNecessary) override {
92 SkASSERT(fSwizzler);
scroggo19b91532016-10-24 09:03:26 -070093 return fSwizzler.get();
msarette6dd0042015-10-09 11:07:34 -070094 }
scroggoe7fc14b2015-10-02 13:14:46 -070095
msarett10522ff2015-09-07 08:54:01 -070096 /*
scroggo19b91532016-10-24 09:03:26 -070097 * Recursive function to decode a frame.
msarett72261c02015-11-19 15:29:26 -080098 *
scroggo19b91532016-10-24 09:03:26 -070099 * @param firstAttempt Whether this is the first call to decodeFrame since
100 * starting. e.g. true in onGetPixels, and true in the
101 * first call to onIncrementalDecode after calling
102 * onStartIncrementalDecode.
103 * When true, this method may have to initialize the
104 * frame, for example by filling or decoding the prior
105 * frame.
106 * @param opts Options for decoding. May be different from
107 * this->options() for decoding prior frames. Specifies
108 * the frame to decode and whether the prior frame has
109 * already been decoded to fDst. If not, and the frame
110 * is not independent, this method will recursively
111 * decode the frame it depends on.
112 * @param rowsDecoded Out-parameter to report the total number of rows
113 * that have been decoded (or at least written to, if
114 * it had to fill), including rows decoded by prior
115 * calls to onIncrementalDecode.
116 * @return kSuccess if the frame is complete, kIncompleteInput
117 * otherwise.
msarett72261c02015-11-19 15:29:26 -0800118 */
scroggo19b91532016-10-24 09:03:26 -0700119 Result decodeFrame(bool firstAttempt, const Options& opts, int* rowsDecoded);
msarett8c8f22a2015-04-01 06:58:48 -0700120
121 /*
Matt Sarett61eedeb2016-11-04 13:19:48 -0400122 * Swizzles and color xforms (if necessary) into dst.
123 */
124 void applyXformRow(const SkImageInfo& dstInfo, void* dst, const uint8_t* src) const;
125
126 /*
msarett8c8f22a2015-04-01 06:58:48 -0700127 * Creates an instance of the decoder
128 * Called only by NewFromStream
scroggo3d3a65c2016-10-24 12:28:30 -0700129 * Takes ownership of the SkGifImageReader
msarett8c8f22a2015-04-01 06:58:48 -0700130 */
scroggo3d3a65c2016-10-24 12:28:30 -0700131 SkGifCodec(const SkEncodedInfo&, const SkImageInfo&, SkGifImageReader*);
msarett8c8f22a2015-04-01 06:58:48 -0700132
scroggo3d3a65c2016-10-24 12:28:30 -0700133 std::unique_ptr<SkGifImageReader> fReader;
134 std::unique_ptr<uint8_t[]> fTmpBuffer;
135 std::unique_ptr<SkSwizzler> fSwizzler;
136 sk_sp<SkColorTable> fCurrColorTable;
scroggo19b91532016-10-24 09:03:26 -0700137 // We may create a dummy table if there is not a Map in the input data. In
138 // that case, we set this value to false, and we can skip a lot of decoding
139 // work (which would not be meaningful anyway). We create a "fake"/"dummy"
140 // one in that case, so the client and the swizzler have something to draw.
scroggo3d3a65c2016-10-24 12:28:30 -0700141 bool fCurrColorTableIsReal;
scroggo19b91532016-10-24 09:03:26 -0700142 // Whether the background was filled.
scroggo3d3a65c2016-10-24 12:28:30 -0700143 bool fFilledBackground;
scroggo19b91532016-10-24 09:03:26 -0700144 // True on the first call to onIncrementalDecode. This value is passed to
145 // decodeFrame.
scroggo3d3a65c2016-10-24 12:28:30 -0700146 bool fFirstCallToIncrementalDecode;
scroggo19b91532016-10-24 09:03:26 -0700147
scroggo3d3a65c2016-10-24 12:28:30 -0700148 void* fDst;
149 size_t fDstRowBytes;
scroggo19b91532016-10-24 09:03:26 -0700150
151 // Updated inside haveDecodedRow when rows are decoded, unless we filled
152 // the background, in which case it is set once and left alone.
scroggo3d3a65c2016-10-24 12:28:30 -0700153 int fRowsDecoded;
Matt Sarett61eedeb2016-11-04 13:19:48 -0400154 std::unique_ptr<uint32_t[]> fXformBuffer;
msarett10522ff2015-09-07 08:54:01 -0700155
msarett8c8f22a2015-04-01 06:58:48 -0700156 typedef SkCodec INHERITED;
157};
Hal Canary03a7f5f2017-02-10 09:06:38 -0500158#endif // SkGifCodec_DEFINED