OLD | NEW |
| (Empty) |
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 | |
8 #include "SkCodec.h" | |
9 #include "SkColorTable.h" | |
10 #include "SkImageInfo.h" | |
11 #include "SkSwizzler.h" | |
12 | |
13 #include "gif_lib.h" | |
14 | |
15 /* | |
16 * | |
17 * This class implements the decoding for gif images | |
18 * | |
19 */ | |
20 class SkGifCodec : public SkCodec { | |
21 public: | |
22 static bool IsGif(const void*, size_t); | |
23 | |
24 /* | |
25 * Assumes IsGif was called and returned true | |
26 * Creates a gif decoder | |
27 * Reads enough of the stream to determine the image format | |
28 */ | |
29 static SkCodec* NewFromStream(SkStream*); | |
30 | |
31 protected: | |
32 | |
33 /* | |
34 * Read enough of the stream to initialize the SkGifCodec. | |
35 * Returns a bool representing success or failure. | |
36 * | |
37 * @param codecOut | |
38 * If it returned true, and codecOut was not nullptr, | |
39 * codecOut will be set to a new SkGifCodec. | |
40 * | |
41 * @param gifOut | |
42 * If it returned true, and codecOut was nullptr, | |
43 * gifOut must be non-nullptr and gifOut will be set to a new | |
44 * GifFileType pointer. | |
45 * | |
46 * @param stream | |
47 * Deleted on failure. | |
48 * codecOut will take ownership of it in the case where we created a codec. | |
49 * Ownership is unchanged when we returned a gifOut. | |
50 * | |
51 */ | |
52 static bool ReadHeader(SkStream* stream, SkCodec** codecOut, | |
53 GifFileType** gifOut); | |
54 | |
55 /* | |
56 * Performs the full gif decode | |
57 */ | |
58 Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, | |
59 SkPMColor*, int*, int*) override; | |
60 | |
61 SkEncodedFormat onGetEncodedFormat() const override { | |
62 return kGIF_SkEncodedFormat; | |
63 } | |
64 | |
65 bool onRewind() override; | |
66 | |
67 uint32_t onGetFillValue(SkColorType colorType, SkAlphaType alphaType) const
override; | |
68 | |
69 int onOutputScanline(int inputScanline) const override; | |
70 | |
71 private: | |
72 | |
73 /* | |
74 * A gif can contain multiple image frames. We will only decode the first | |
75 * frame. This function reads up to the first image frame, processing | |
76 * transparency and/or animation information that comes before the image | |
77 * data. | |
78 * | |
79 * @param gif Pointer to the library type that manages the gif decode | |
80 * @param transIndex This call will set the transparent index based on the | |
81 * extension data. | |
82 */ | |
83 static Result ReadUpToFirstImage(GifFileType* gif, uint32_t* transIndex); | |
84 | |
85 /* | |
86 * A gif may contain many image frames, all of different sizes. | |
87 * This function checks if the gif dimensions are valid, based on the frame | |
88 * dimensions, and corrects the gif dimensions if necessary. | |
89 * | |
90 * @param gif Pointer to the library type that manages the gif decode | |
91 * @param size Size of the image that we will decode. | |
92 * Will be set by this function if the return value is tru
e. | |
93 * @param frameRect Contains the dimenions and offset of the first image fr
ame. | |
94 * Will be set by this function if the return value is tru
e. | |
95 * | |
96 * @return true on success, false otherwise | |
97 */ | |
98 static bool GetDimensions(GifFileType* gif, SkISize* size, SkIRect* frameRe
ct); | |
99 | |
100 /* | |
101 * Initializes the color table that we will use for decoding. | |
102 * | |
103 * @param dstInfo Contains the requested dst color type. | |
104 * @param inputColorPtr Copies the encoded color table to the client's | |
105 * input color table if the client requests kIndex8. | |
106 * @param inputColorCount If the client requests kIndex8, sets | |
107 * inputColorCount to 256. Since gifs always | |
108 * contain 8-bit indices, we need a 256 entry color | |
109 * table to ensure that indexing is always in | |
110 * bounds. | |
111 */ | |
112 void initializeColorTable(const SkImageInfo& dstInfo, SkPMColor* colorPtr, | |
113 int* inputColorCount); | |
114 | |
115 /* | |
116 * Checks for invalid inputs and calls setFrameDimensions(), and | |
117 * initializeColorTable() in the proper sequence. | |
118 */ | |
119 Result prepareToDecode(const SkImageInfo& dstInfo, SkPMColor* inputColorPtr, | |
120 int* inputColorCount, const Options& opts); | |
121 | |
122 /* | |
123 * Initializes the swizzler. | |
124 * | |
125 * @param dstInfo Output image information. Dimensions may have been | |
126 * adjusted if the image frame size does not match the size | |
127 * indicated in the header. | |
128 * @param options Informs the swizzler if destination memory is zero initia
lized. | |
129 * Contains subset information. | |
130 */ | |
131 Result initializeSwizzler(const SkImageInfo& dstInfo, | |
132 const Options& options); | |
133 | |
134 SkSampler* getSampler(bool createIfNecessary) override { | |
135 SkASSERT(fSwizzler); | |
136 return fSwizzler; | |
137 } | |
138 | |
139 /* | |
140 * @return true if the read is successful and false if the read fails. | |
141 */ | |
142 bool readRow(); | |
143 | |
144 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opts
, | |
145 SkPMColor inputColorPtr[], int* inputColorCount) override; | |
146 | |
147 int onGetScanlines(void* dst, int count, size_t rowBytes) override; | |
148 | |
149 bool onSkipScanlines(int count) override; | |
150 | |
151 /* | |
152 * For a scanline decode of "count" lines, this function indicates how | |
153 * many of the "count" lines should be skipped until we reach the top of | |
154 * the image frame and how many of the "count" lines are actually inside | |
155 * the image frame. | |
156 * | |
157 * @param count The number of scanlines requested. | |
158 * @param rowsBeforeFrame Output variable. The number of lines before | |
159 * we reach the top of the image frame. | |
160 * @param rowsInFrame Output variable. The number of lines to decode | |
161 * inside the image frame. | |
162 */ | |
163 void handleScanlineFrame(int count, int* rowsBeforeFrame, int* rowsInFrame); | |
164 | |
165 SkScanlineOrder onGetScanlineOrder() const override; | |
166 | |
167 /* | |
168 * This function cleans up the gif object after the decode completes | |
169 * It is used in a SkAutoTCallIProc template | |
170 */ | |
171 static void CloseGif(GifFileType* gif); | |
172 | |
173 /* | |
174 * Frees any extension data used in the decode | |
175 * Used in a SkAutoTCallVProc | |
176 */ | |
177 static void FreeExtension(SavedImage* image); | |
178 | |
179 /* | |
180 * Creates an instance of the decoder | |
181 * Called only by NewFromStream | |
182 * | |
183 * @param srcInfo contains the source width and height | |
184 * @param stream the stream of image data | |
185 * @param gif pointer to library type that manages gif decode | |
186 * takes ownership | |
187 * @param transIndex The transparent index. An invalid value | |
188 * indicates that there is no transparent index. | |
189 */ | |
190 SkGifCodec(const SkImageInfo& srcInfo, SkStream* stream, GifFileType* gif, u
int32_t transIndex, | |
191 const SkIRect& frameRect, bool frameIsSubset); | |
192 | |
193 SkAutoTCallVProc<GifFileType, CloseGif> fGif; // owned | |
194 SkAutoTDeleteArray<uint8_t> fSrcBuffer; | |
195 const SkIRect fFrameRect; | |
196 const uint32_t fTransIndex; | |
197 uint32_t fFillIndex; | |
198 const bool fFrameIsSubset; | |
199 SkAutoTDelete<SkSwizzler> fSwizzler; | |
200 SkAutoTUnref<SkColorTable> fColorTable; | |
201 | |
202 typedef SkCodec INHERITED; | |
203 }; | |
OLD | NEW |