• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 Google Inc.
2 // Use of this source code is governed by the BSD-3-Clause license that can be
3 // found in the LICENSE.md file.
4 #ifndef SkLibGifCodec_DEFINED
5 #define SkLibGifCodec_DEFINED
6 
7 #include "SkGifImageReader.h"
8 
9 #include "include/codec/SkCodec.h"
10 #include "include/codec/SkCodecAnimation.h"
11 #include "include/core/SkColorSpace.h"
12 #include "include/core/SkImageInfo.h"
13 #include "src/codec/SkColorTable.h"
14 #include "src/codec/SkSwizzler.h"
15 
16 /*
17  *
18  * This class implements the decoding for gif images
19  *
20  */
21 class SkLibGifCodec : public SkCodec {
22 public:
23     static bool IsGif(const void*, size_t);
24 
25     /*
26      * Assumes IsGif was called and returned true
27      * Reads enough of the stream to determine the image format
28      */
29     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
30 
31     // Callback for SkGifImageReader when a row is available.
32     void haveDecodedRow(int frameIndex, const unsigned char* rowBegin,
33                         int rowNumber, int repeatCount, bool writeTransparentPixels);
34     /*
35      * Creates an instance of the decoder
36      * Called only by NewFromStream
37      * Takes ownership of the SkGifImageReader
38      */
39     SkLibGifCodec(SkEncodedInfo&&, SkGifImageReader*);
40 
41 protected:
42     /*
43      * Performs the full gif decode
44      */
45     Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&,
46             int*) override;
47 
onGetEncodedFormat()48     SkEncodedImageFormat onGetEncodedFormat() const override {
49         return SkEncodedImageFormat::kGIF;
50     }
51 
52     bool onRewind() override;
53 
54     int onGetFrameCount() override;
55     bool onGetFrameInfo(int, FrameInfo*) const override;
56     int onGetRepetitionCount() override;
57 
58     Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
59             const SkCodec::Options&) override;
60 
61     Result onIncrementalDecode(int*) override;
62 
getFrameHolder()63     const SkFrameHolder* getFrameHolder() const override {
64         return fReader.get();
65     }
66 
67 private:
68 
69     /*
70      * Initializes the color table that we will use for decoding.
71      *
72      * @param dstInfo         Contains the requested dst color type.
73      * @param frameIndex      Frame whose color table to use.
74      */
75     void initializeColorTable(const SkImageInfo& dstInfo, int frameIndex);
76 
77    /*
78     * Does necessary setup, including setting up the color table and swizzler.
79     */
80     Result prepareToDecode(const SkImageInfo& dstInfo, const Options& opts);
81 
82     /*
83      * Initializes the swizzler.
84      *
85      * @param dstInfo    Output image information.  Dimensions may have been
86      *                   adjusted if the image frame size does not match the size
87      *                   indicated in the header.
88      * @param frameIndex Which frame we are decoding. This determines the frameRect
89      *                   to use.
90      */
91     void initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex);
92 
getSampler(bool createIfNecessary)93     SkSampler* getSampler(bool createIfNecessary) override {
94         SkASSERT(fSwizzler);
95         return fSwizzler.get();
96     }
97 
98     /*
99      * Recursive function to decode a frame.
100      *
101      * @param firstAttempt Whether this is the first call to decodeFrame since
102      *                     starting. e.g. true in onGetPixels, and true in the
103      *                     first call to onIncrementalDecode after calling
104      *                     onStartIncrementalDecode.
105      *                     When true, this method may have to initialize the
106      *                     frame, for example by filling or decoding the prior
107      *                     frame.
108      * @param opts         Options for decoding. May be different from
109      *                     this->options() for decoding prior frames. Specifies
110      *                     the frame to decode and whether the prior frame has
111      *                     already been decoded to fDst. If not, and the frame
112      *                     is not independent, this method will recursively
113      *                     decode the frame it depends on.
114      * @param rowsDecoded  Out-parameter to report the total number of rows
115      *                     that have been decoded (or at least written to, if
116      *                     it had to fill), including rows decoded by prior
117      *                     calls to onIncrementalDecode.
118      * @return             kSuccess if the frame is complete, kIncompleteInput
119      *                     otherwise.
120      */
121     Result decodeFrame(bool firstAttempt, const Options& opts, int* rowsDecoded);
122 
123     /*
124      *  Swizzles and color xforms (if necessary) into dst.
125      */
126     void applyXformRow(const SkImageInfo& dstInfo, void* dst, const uint8_t* src) const;
127 
128     std::unique_ptr<SkGifImageReader>   fReader;
129     std::unique_ptr<uint8_t[]>          fTmpBuffer;
130     std::unique_ptr<SkSwizzler>         fSwizzler;
131     sk_sp<SkColorTable>                 fCurrColorTable;
132     // We may create a dummy table if there is not a Map in the input data. In
133     // that case, we set this value to false, and we can skip a lot of decoding
134     // work (which would not be meaningful anyway). We create a "fake"/"dummy"
135     // one in that case, so the client and the swizzler have something to draw.
136     bool                                fCurrColorTableIsReal;
137     // Whether the background was filled.
138     bool                                fFilledBackground;
139     // True on the first call to onIncrementalDecode. This value is passed to
140     // decodeFrame.
141     bool                                fFirstCallToIncrementalDecode;
142 
143     void*                               fDst;
144     size_t                              fDstRowBytes;
145 
146     // Updated inside haveDecodedRow when rows are decoded, unless we filled
147     // the background, in which case it is set once and left alone.
148     int                                 fRowsDecoded;
149     std::unique_ptr<uint32_t[]>         fXformBuffer;
150 
151     typedef SkCodec INHERITED;
152 };
153 #endif  // SkLibGifCodec_DEFINED
154