blob: e3b225dda746d8e63d5bd948ca599da2ecbf9fad [file] [log] [blame]
scroggo19b91532016-10-24 09:03:26 -07001/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Chris Saari <saari@netscape.com>
24 * Apple Computer
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40/*
41The Graphics Interchange Format(c) is the copyright property of CompuServe
42Incorporated. Only CompuServe Incorporated is authorized to define, redefine,
43enhance, alter, modify or change in any way the definition of the format.
44
45CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free
46license for the use of the Graphics Interchange Format(sm) in computer
47software; computer software utilizing GIF(sm) must acknowledge ownership of the
48Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
49User and Technical Documentation. Computer software utilizing GIF, which is
50distributed or may be distributed without User or Technical Documentation must
51display to the screen or printer a message acknowledging ownership of the
52Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in
53this case, the acknowledgement may be displayed in an opening screen or leading
54banner, or a closing screen or trailing banner. A message such as the following
55may be used:
56
57 "The Graphics Interchange Format(c) is the Copyright property of
58 CompuServe Incorporated. GIF(sm) is a Service Mark property of
59 CompuServe Incorporated."
60
61For further information, please contact :
62
63 CompuServe Incorporated
64 Graphics Technology Department
65 5000 Arlington Center Boulevard
66 Columbus, Ohio 43220
67 U. S. A.
68
69CompuServe Incorporated maintains a mailing list with all those individuals and
70organizations who wish to receive copies of this document when it is corrected
71or revised. This service is offered free of charge; please provide us with your
72mailing address.
73*/
74
scroggo3d3a65c2016-10-24 12:28:30 -070075#include "SkGifImageReader.h"
scroggo19b91532016-10-24 09:03:26 -070076#include "SkColorPriv.h"
77#include "SkGifCodec.h"
78
79#include <algorithm>
80#include <string.h>
81
82
83// GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's'.
84//
85// Note, the hold will never need to be bigger than 256 bytes to gather up in the hold,
86// as each GIF block (except colormaps) can never be bigger than 256 bytes.
87// Colormaps are directly copied in the resp. global_colormap or dynamically allocated local_colormap.
scroggo3d3a65c2016-10-24 12:28:30 -070088// So a fixed buffer in SkGifImageReader is good enough.
scroggo19b91532016-10-24 09:03:26 -070089// This buffer is only needed to copy left-over data from one GifWrite call to the next
90#define GETN(n, s) \
91 do { \
92 m_bytesToConsume = (n); \
93 m_state = (s); \
94 } while (0)
95
96// Get a 16-bit value stored in little-endian format.
97#define GETINT16(p) ((p)[1]<<8|(p)[0])
98
99// Send the data to the display front-end.
scroggof9acbe22016-10-25 12:43:21 -0700100bool SkGIFLZWContext::outputRow(const unsigned char* rowBegin)
scroggo19b91532016-10-24 09:03:26 -0700101{
102 int drowStart = irow;
103 int drowEnd = irow;
104
105 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while
106 // displaying to diminish the "venetian-blind" effect as the image is
107 // loaded. Adjust pixel vertical positions to avoid the appearance of the
108 // image crawling up the screen as successive passes are drawn.
109 if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass < 4) {
110 unsigned rowDup = 0;
111 unsigned rowShift = 0;
112
113 switch (ipass) {
114 case 1:
115 rowDup = 7;
116 rowShift = 3;
117 break;
118 case 2:
119 rowDup = 3;
120 rowShift = 1;
121 break;
122 case 3:
123 rowDup = 1;
124 rowShift = 0;
125 break;
126 default:
127 break;
128 }
129
130 drowStart -= rowShift;
131 drowEnd = drowStart + rowDup;
132
133 // Extend if bottom edge isn't covered because of the shift upward.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400134 if ((unsigned)((m_frameContext->height() - 1) - drowEnd) <= rowShift)
scroggo19b91532016-10-24 09:03:26 -0700135 drowEnd = m_frameContext->height() - 1;
136
137 // Clamp first and last rows to upper and lower edge of image.
138 if (drowStart < 0)
139 drowStart = 0;
140
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400141 if (drowEnd >= m_frameContext->height())
scroggo19b91532016-10-24 09:03:26 -0700142 drowEnd = m_frameContext->height() - 1;
143 }
144
145 // Protect against too much image data.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400146 if (drowStart >= m_frameContext->height())
scroggo19b91532016-10-24 09:03:26 -0700147 return true;
148
149 // CALLBACK: Let the client know we have decoded a row.
Matt Sarett4ef986d2016-11-03 14:52:28 -0400150 const bool writeTransparentPixels = (SkCodec::kNone == m_frameContext->getRequiredFrame());
scroggo19b91532016-10-24 09:03:26 -0700151 if (!m_client->haveDecodedRow(m_frameContext->frameId(), rowBegin,
scroggo1285f412016-10-26 13:48:03 -0700152 drowStart, drowEnd - drowStart + 1, writeTransparentPixels))
scroggo19b91532016-10-24 09:03:26 -0700153 return false;
154
155 if (!m_frameContext->interlaced())
156 irow++;
157 else {
158 do {
159 switch (ipass) {
160 case 1:
161 irow += 8;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400162 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700163 ipass++;
164 irow = 4;
165 }
166 break;
167
168 case 2:
169 irow += 8;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400170 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700171 ipass++;
172 irow = 2;
173 }
174 break;
175
176 case 3:
177 irow += 4;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400178 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700179 ipass++;
180 irow = 1;
181 }
182 break;
183
184 case 4:
185 irow += 2;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400186 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700187 ipass++;
188 irow = 0;
189 }
190 break;
191
192 default:
193 break;
194 }
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400195 } while (irow > (unsigned) (m_frameContext->height() - 1));
scroggo19b91532016-10-24 09:03:26 -0700196 }
197 return true;
198}
199
200// Perform Lempel-Ziv-Welch decoding.
201// Returns true if decoding was successful. In this case the block will have been completely consumed and/or rowsRemaining will be 0.
scroggo3d3a65c2016-10-24 12:28:30 -0700202// Otherwise, decoding failed; returns false in this case, which will always cause the SkGifImageReader to set the "decode failed" flag.
scroggof9acbe22016-10-25 12:43:21 -0700203bool SkGIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock)
scroggo19b91532016-10-24 09:03:26 -0700204{
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400205 const int width = m_frameContext->width();
scroggo19b91532016-10-24 09:03:26 -0700206
207 if (rowIter == rowBuffer.end())
208 return true;
209
210 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) {
211 // Feed the next byte into the decoder's 32-bit input buffer.
212 datum += ((int) *ch) << bits;
213 bits += 8;
214
215 // Check for underflow of decoder's 32-bit input buffer.
216 while (bits >= codesize) {
217 // Get the leading variable-length symbol from the data stream.
218 int code = datum & codemask;
219 datum >>= codesize;
220 bits -= codesize;
221
222 // Reset the dictionary to its original state, if requested.
223 if (code == clearCode) {
224 codesize = m_frameContext->dataSize() + 1;
225 codemask = (1 << codesize) - 1;
226 avail = clearCode + 2;
227 oldcode = -1;
228 continue;
229 }
230
231 // Check for explicit end-of-stream code.
232 if (code == (clearCode + 1)) {
233 // end-of-stream should only appear after all image data.
234 if (!rowsRemaining)
235 return true;
236 return false;
237 }
238
239 const int tempCode = code;
240 unsigned short codeLength = 0;
241 if (code < avail) {
242 // This is a pre-existing code, so we already know what it
243 // encodes.
244 codeLength = suffixLength[code];
245 rowIter += codeLength;
246 } else if (code == avail && oldcode != -1) {
247 // This is a new code just being added to the dictionary.
248 // It must encode the contents of the previous code, plus
249 // the first character of the previous code again.
250 codeLength = suffixLength[oldcode] + 1;
251 rowIter += codeLength;
252 *--rowIter = firstchar;
253 code = oldcode;
254 } else {
255 // This is an invalid code. The dictionary is just initialized
256 // and the code is incomplete. We don't know how to handle
257 // this case.
258 return false;
259 }
260
261 while (code >= clearCode) {
262 *--rowIter = suffix[code];
263 code = prefix[code];
264 }
265
266 *--rowIter = firstchar = suffix[code];
267
268 // Define a new codeword in the dictionary as long as we've read
269 // more than one value from the stream.
scroggof9acbe22016-10-25 12:43:21 -0700270 if (avail < SK_MAX_DICTIONARY_ENTRIES && oldcode != -1) {
scroggo19b91532016-10-24 09:03:26 -0700271 prefix[avail] = oldcode;
272 suffix[avail] = firstchar;
273 suffixLength[avail] = suffixLength[oldcode] + 1;
274 ++avail;
275
276 // If we've used up all the codewords of a given length
277 // increase the length of codewords by one bit, but don't
278 // exceed the specified maximum codeword size.
scroggof9acbe22016-10-25 12:43:21 -0700279 if (!(avail & codemask) && avail < SK_MAX_DICTIONARY_ENTRIES) {
scroggo19b91532016-10-24 09:03:26 -0700280 ++codesize;
281 codemask += avail;
282 }
283 }
284 oldcode = tempCode;
285 rowIter += codeLength;
286
287 // Output as many rows as possible.
288 unsigned char* rowBegin = rowBuffer.begin();
289 for (; rowBegin + width <= rowIter; rowBegin += width) {
290 if (!outputRow(rowBegin))
291 return false;
292 rowsRemaining--;
293 if (!rowsRemaining)
294 return true;
295 }
296
297 if (rowBegin != rowBuffer.begin()) {
298 // Move the remaining bytes to the beginning of the buffer.
299 const size_t bytesToCopy = rowIter - rowBegin;
300 memcpy(&rowBuffer.front(), rowBegin, bytesToCopy);
301 rowIter = rowBuffer.begin() + bytesToCopy;
302 }
303 }
304 }
305 return true;
306}
307
Leon Scroggins III932efed2016-12-16 11:39:51 -0500308sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkColorType colorType,
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400309 int transparentPixel) const
scroggo19b91532016-10-24 09:03:26 -0700310{
311 if (!m_isDefined)
312 return nullptr;
313
314 const PackColorProc proc = choose_pack_color_proc(false, colorType);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500315 if (m_table && proc == m_packColorProc && m_transPixel == transparentPixel) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400316 SkASSERT(transparentPixel == kNotFound || transparentPixel > m_table->count()
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500317 || m_table->operator[](transparentPixel) == SK_ColorTRANSPARENT);
318 // This SkColorTable has already been built with the same transparent color and
319 // packing proc. Reuse it.
320 return m_table;
scroggo19b91532016-10-24 09:03:26 -0700321 }
322 m_packColorProc = proc;
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500323 m_transPixel = transparentPixel;
scroggo19b91532016-10-24 09:03:26 -0700324
Leon Scroggins III932efed2016-12-16 11:39:51 -0500325 const size_t bytes = m_colors * SK_BYTES_PER_COLORMAP_ENTRY;
326 sk_sp<SkData> rawData(streamBuffer->getDataAtPosition(m_position, bytes));
327 if (!rawData) {
328 return nullptr;
329 }
330
scroggof9acbe22016-10-25 12:43:21 -0700331 SkASSERT(m_colors <= SK_MAX_COLORS);
Leon Scroggins III932efed2016-12-16 11:39:51 -0500332 const uint8_t* srcColormap = rawData->bytes();
scroggof9acbe22016-10-25 12:43:21 -0700333 SkPMColor colorStorage[SK_MAX_COLORS];
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400334 for (int i = 0; i < m_colors; i++) {
scroggo19b91532016-10-24 09:03:26 -0700335 if (i == transparentPixel) {
336 colorStorage[i] = SK_ColorTRANSPARENT;
337 } else {
338 colorStorage[i] = proc(255, srcColormap[0], srcColormap[1], srcColormap[2]);
339 }
scroggof9acbe22016-10-25 12:43:21 -0700340 srcColormap += SK_BYTES_PER_COLORMAP_ENTRY;
scroggo19b91532016-10-24 09:03:26 -0700341 }
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400342 for (int i = m_colors; i < SK_MAX_COLORS; i++) {
scroggo19b91532016-10-24 09:03:26 -0700343 colorStorage[i] = SK_ColorTRANSPARENT;
344 }
scroggof9acbe22016-10-25 12:43:21 -0700345 m_table = sk_sp<SkColorTable>(new SkColorTable(colorStorage, SK_MAX_COLORS));
scroggo19b91532016-10-24 09:03:26 -0700346 return m_table;
347}
348
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400349sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, int index) {
350 if (index < 0 || static_cast<size_t>(index) >= m_frames.size()) {
scroggo19b91532016-10-24 09:03:26 -0700351 return nullptr;
352 }
353
scroggof9acbe22016-10-25 12:43:21 -0700354 const SkGIFFrameContext* frameContext = m_frames[index].get();
355 const SkGIFColorMap& localColorMap = frameContext->localColorMap();
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400356 const int transPix = frameContext->transparentPixel();
scroggo19b91532016-10-24 09:03:26 -0700357 if (localColorMap.isDefined()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500358 return localColorMap.buildTable(&m_streamBuffer, colorType, transPix);
scroggo19b91532016-10-24 09:03:26 -0700359 }
360 if (m_globalColorMap.isDefined()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500361 return m_globalColorMap.buildTable(&m_streamBuffer, colorType, transPix);
scroggo19b91532016-10-24 09:03:26 -0700362 }
363 return nullptr;
364}
365
366// Perform decoding for this frame. frameComplete will be true if the entire frame is decoded.
scroggo3d3a65c2016-10-24 12:28:30 -0700367// Returns false if a decoding error occurred. This is a fatal error and causes the SkGifImageReader to set the "decode failed" flag.
scroggo19b91532016-10-24 09:03:26 -0700368// Otherwise, either not enough data is available to decode further than before, or the new data has been decoded successfully; returns true in this case.
Leon Scroggins III932efed2016-12-16 11:39:51 -0500369bool SkGIFFrameContext::decode(SkStreamBuffer* streamBuffer, SkGifCodec* client,
370 bool* frameComplete)
scroggo19b91532016-10-24 09:03:26 -0700371{
372 *frameComplete = false;
373 if (!m_lzwContext) {
scroggof9acbe22016-10-25 12:43:21 -0700374 // Wait for more data to properly initialize SkGIFLZWContext.
scroggo19b91532016-10-24 09:03:26 -0700375 if (!isDataSizeDefined() || !isHeaderDefined())
376 return true;
377
scroggof9acbe22016-10-25 12:43:21 -0700378 m_lzwContext.reset(new SkGIFLZWContext(client, this));
Leon Scroggins III45565b62016-12-05 14:56:30 -0500379 if (!m_lzwContext->prepareToDecode()) {
scroggo19b91532016-10-24 09:03:26 -0700380 m_lzwContext.reset();
381 return false;
382 }
383
384 m_currentLzwBlock = 0;
385 }
386
387 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400388 while (static_cast<size_t>(m_currentLzwBlock) < m_lzwBlocks.size()
389 && m_lzwContext->hasRemainingRows()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500390 const auto& block = m_lzwBlocks[m_currentLzwBlock];
391 const size_t len = block.blockSize;
392
393 sk_sp<SkData> data(streamBuffer->getDataAtPosition(block.blockPosition, len));
394 if (!data) {
395 return false;
396 }
397 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(data->data()), len)) {
scroggo19b91532016-10-24 09:03:26 -0700398 return false;
399 }
400 ++m_currentLzwBlock;
401 }
402
403 // If this frame is data complete then the previous loop must have completely decoded all LZW blocks.
404 // There will be no more decoding for this frame so it's time to cleanup.
405 if (isComplete()) {
406 *frameComplete = true;
407 m_lzwContext.reset();
408 }
409 return true;
410}
411
412// Decode a frame.
scroggof9acbe22016-10-25 12:43:21 -0700413// This method uses SkGIFFrameContext:decode() to decode the frame; decoding error is reported to client as a critical failure.
scroggo19b91532016-10-24 09:03:26 -0700414// Return true if decoding has progressed. Return false if an error has occurred.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400415bool SkGifImageReader::decode(int frameIndex, bool* frameComplete)
scroggo19b91532016-10-24 09:03:26 -0700416{
scroggof9acbe22016-10-25 12:43:21 -0700417 SkGIFFrameContext* currentFrame = m_frames[frameIndex].get();
scroggo19b91532016-10-24 09:03:26 -0700418
Leon Scroggins III932efed2016-12-16 11:39:51 -0500419 return currentFrame->decode(&m_streamBuffer, m_client, frameComplete);
scroggo19b91532016-10-24 09:03:26 -0700420}
421
422// Parse incoming GIF data stream into internal data structures.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400423SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
scroggo19b91532016-10-24 09:03:26 -0700424{
425 if (m_parseCompleted) {
Leon Scroggins III588fb042017-07-14 16:32:31 -0400426 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700427 }
428
scroggoe71b1a12016-11-01 08:28:28 -0700429 if (SkGIFLoopCountQuery == query && m_loopCount != cLoopCountNotSeen) {
430 // Loop count has already been parsed.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400431 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700432 }
433
scroggof9acbe22016-10-25 12:43:21 -0700434 // SkGIFSizeQuery and SkGIFFrameCountQuery are negative, so this is only meaningful when >= 0.
scroggo19b91532016-10-24 09:03:26 -0700435 const int lastFrameToParse = (int) query;
436 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse
437 && m_frames[lastFrameToParse]->isComplete()) {
438 // We have already parsed this frame.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400439 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700440 }
441
442 while (true) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500443 if (!m_streamBuffer.buffer(m_bytesToConsume)) {
444 // The stream does not yet have enough data.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400445 return SkCodec::kIncompleteInput;
scroggo19b91532016-10-24 09:03:26 -0700446 }
447
448 switch (m_state) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500449 case SkGIFLZW: {
scroggo19b91532016-10-24 09:03:26 -0700450 SkASSERT(!m_frames.empty());
Leon Scroggins III932efed2016-12-16 11:39:51 -0500451 auto* frame = m_frames.back().get();
452 frame->addLzwBlock(m_streamBuffer.markPosition(), m_bytesToConsume);
scroggof9acbe22016-10-25 12:43:21 -0700453 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700454 break;
Leon Scroggins III932efed2016-12-16 11:39:51 -0500455 }
scroggof9acbe22016-10-25 12:43:21 -0700456 case SkGIFLZWStart: {
scroggo19b91532016-10-24 09:03:26 -0700457 SkASSERT(!m_frames.empty());
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500458 auto* currentFrame = m_frames.back().get();
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500459
460 currentFrame->setDataSize(this->getOneByte());
scroggof9acbe22016-10-25 12:43:21 -0700461 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700462 break;
463 }
464
scroggof9acbe22016-10-25 12:43:21 -0700465 case SkGIFType: {
scroggo19b91532016-10-24 09:03:26 -0700466 const char* currentComponent = m_streamBuffer.get();
467
468 // All GIF files begin with "GIF87a" or "GIF89a".
469 if (!memcmp(currentComponent, "GIF89a", 6))
470 m_version = 89;
471 else if (!memcmp(currentComponent, "GIF87a", 6))
472 m_version = 87;
473 else {
474 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700475 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400476 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700477 }
scroggof9acbe22016-10-25 12:43:21 -0700478 GETN(7, SkGIFGlobalHeader);
scroggo19b91532016-10-24 09:03:26 -0700479 break;
480 }
481
scroggof9acbe22016-10-25 12:43:21 -0700482 case SkGIFGlobalHeader: {
scroggo19b91532016-10-24 09:03:26 -0700483 const unsigned char* currentComponent =
484 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
485
486 // This is the height and width of the "screen" or frame into which
487 // images are rendered. The individual images can be smaller than
488 // the screen size and located with an origin anywhere within the
489 // screen.
490 // Note that we don't inform the client of the size yet, as it might
491 // change after we read the first frame's image header.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400492 fScreenWidth = GETINT16(currentComponent);
493 fScreenHeight = GETINT16(currentComponent + 2);
scroggo19b91532016-10-24 09:03:26 -0700494
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400495 const int globalColorMapColors = 2 << (currentComponent[4] & 0x07);
scroggo19b91532016-10-24 09:03:26 -0700496
497 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* global map */
498 m_globalColorMap.setNumColors(globalColorMapColors);
scroggof9acbe22016-10-25 12:43:21 -0700499 GETN(SK_BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, SkGIFGlobalColormap);
scroggo19b91532016-10-24 09:03:26 -0700500 break;
501 }
502
scroggof9acbe22016-10-25 12:43:21 -0700503 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700504 break;
505 }
506
scroggof9acbe22016-10-25 12:43:21 -0700507 case SkGIFGlobalColormap: {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500508 m_globalColorMap.setTablePosition(m_streamBuffer.markPosition());
scroggof9acbe22016-10-25 12:43:21 -0700509 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700510 break;
511 }
512
scroggof9acbe22016-10-25 12:43:21 -0700513 case SkGIFImageStart: {
scroggo19b91532016-10-24 09:03:26 -0700514 const char currentComponent = m_streamBuffer.get()[0];
515
516 if (currentComponent == '!') { // extension.
scroggof9acbe22016-10-25 12:43:21 -0700517 GETN(2, SkGIFExtension);
scroggo19b91532016-10-24 09:03:26 -0700518 break;
519 }
520
521 if (currentComponent == ',') { // image separator.
scroggof9acbe22016-10-25 12:43:21 -0700522 GETN(9, SkGIFImageHeader);
scroggo19b91532016-10-24 09:03:26 -0700523 break;
524 }
525
526 // If we get anything other than ',' (image separator), '!'
527 // (extension), or ';' (trailer), there is extraneous data
528 // between blocks. The GIF87a spec tells us to keep reading
529 // until we find an image separator, but GIF89a says such
530 // a file is corrupt. We follow Mozilla's implementation and
531 // proceed as if the file were correctly terminated, so the
532 // GIF will display.
scroggof9acbe22016-10-25 12:43:21 -0700533 GETN(0, SkGIFDone);
scroggo19b91532016-10-24 09:03:26 -0700534 break;
535 }
536
scroggof9acbe22016-10-25 12:43:21 -0700537 case SkGIFExtension: {
scroggo19b91532016-10-24 09:03:26 -0700538 const unsigned char* currentComponent =
539 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
540
541 size_t bytesInBlock = currentComponent[1];
scroggof9acbe22016-10-25 12:43:21 -0700542 SkGIFState exceptionState = SkGIFSkipBlock;
scroggo19b91532016-10-24 09:03:26 -0700543
544 switch (*currentComponent) {
545 case 0xf9:
scroggo19b91532016-10-24 09:03:26 -0700546 // The GIF spec mandates that the GIFControlExtension header block length is 4 bytes,
scroggof9acbe22016-10-25 12:43:21 -0700547 exceptionState = SkGIFControlExtension;
scroggo19b91532016-10-24 09:03:26 -0700548 // and the parser for this block reads 4 bytes, so we must enforce that the buffer
549 // contains at least this many bytes. If the GIF specifies a different length, we
550 // allow that, so long as it's larger; the additional data will simply be ignored.
551 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
552 break;
553
554 // The GIF spec also specifies the lengths of the following two extensions' headers
555 // (as 12 and 11 bytes, respectively). Because we ignore the plain text extension entirely
556 // and sanity-check the actual length of the application extension header before reading it,
557 // we allow GIFs to deviate from these values in either direction. This is important for
558 // real-world compatibility, as GIFs in the wild exist with application extension headers
559 // that are both shorter and longer than 11 bytes.
560 case 0x01:
561 // ignoring plain text extension
562 break;
563
564 case 0xff:
scroggof9acbe22016-10-25 12:43:21 -0700565 exceptionState = SkGIFApplicationExtension;
scroggo19b91532016-10-24 09:03:26 -0700566 break;
567
568 case 0xfe:
scroggof9acbe22016-10-25 12:43:21 -0700569 exceptionState = SkGIFConsumeComment;
scroggo19b91532016-10-24 09:03:26 -0700570 break;
571 }
572
573 if (bytesInBlock)
574 GETN(bytesInBlock, exceptionState);
575 else
scroggof9acbe22016-10-25 12:43:21 -0700576 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700577 break;
578 }
579
scroggof9acbe22016-10-25 12:43:21 -0700580 case SkGIFConsumeBlock: {
scroggo19b91532016-10-24 09:03:26 -0700581 const unsigned char currentComponent = this->getOneByte();
582 if (!currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700583 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700584 else
scroggof9acbe22016-10-25 12:43:21 -0700585 GETN(currentComponent, SkGIFSkipBlock);
scroggo19b91532016-10-24 09:03:26 -0700586 break;
587 }
588
scroggof9acbe22016-10-25 12:43:21 -0700589 case SkGIFSkipBlock: {
590 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700591 break;
592 }
593
scroggof9acbe22016-10-25 12:43:21 -0700594 case SkGIFControlExtension: {
scroggo19b91532016-10-24 09:03:26 -0700595 const unsigned char* currentComponent =
596 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
597
598 addFrameIfNecessary();
scroggof9acbe22016-10-25 12:43:21 -0700599 SkGIFFrameContext* currentFrame = m_frames.back().get();
scroggo19b91532016-10-24 09:03:26 -0700600 if (*currentComponent & 0x1)
601 currentFrame->setTransparentPixel(currentComponent[3]);
602
603 // We ignore the "user input" bit.
604
605 // NOTE: This relies on the values in the FrameDisposalMethod enum
606 // matching those in the GIF spec!
607 int rawDisposalMethod = ((*currentComponent) >> 2) & 0x7;
608 switch (rawDisposalMethod) {
609 case 1:
610 case 2:
611 case 3:
612 currentFrame->setDisposalMethod((SkCodecAnimation::DisposalMethod) rawDisposalMethod);
613 break;
614 case 4:
615 // Some specs say that disposal method 3 is "overwrite previous", others that setting
616 // the third bit of the field (i.e. method 4) is. We map both to the same value.
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400617 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kRestorePrevious);
scroggo19b91532016-10-24 09:03:26 -0700618 break;
619 default:
620 // Other values use the default.
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400621 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep);
scroggo19b91532016-10-24 09:03:26 -0700622 break;
623 }
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400624 currentFrame->setDuration(GETINT16(currentComponent + 1) * 10);
scroggof9acbe22016-10-25 12:43:21 -0700625 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700626 break;
627 }
628
scroggof9acbe22016-10-25 12:43:21 -0700629 case SkGIFCommentExtension: {
scroggo19b91532016-10-24 09:03:26 -0700630 const unsigned char currentComponent = this->getOneByte();
631 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700632 GETN(currentComponent, SkGIFConsumeComment);
scroggo19b91532016-10-24 09:03:26 -0700633 else
scroggof9acbe22016-10-25 12:43:21 -0700634 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700635 break;
636 }
637
scroggof9acbe22016-10-25 12:43:21 -0700638 case SkGIFConsumeComment: {
639 GETN(1, SkGIFCommentExtension);
scroggo19b91532016-10-24 09:03:26 -0700640 break;
641 }
642
scroggof9acbe22016-10-25 12:43:21 -0700643 case SkGIFApplicationExtension: {
scroggo19b91532016-10-24 09:03:26 -0700644 // Check for netscape application extension.
Leon Scroggins III932efed2016-12-16 11:39:51 -0500645 if (m_bytesToConsume == 11) {
scroggo19b91532016-10-24 09:03:26 -0700646 const unsigned char* currentComponent =
647 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
648
649 if (!memcmp(currentComponent, "NETSCAPE2.0", 11) || !memcmp(currentComponent, "ANIMEXTS1.0", 11))
scroggof9acbe22016-10-25 12:43:21 -0700650 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700651 }
652
scroggof9acbe22016-10-25 12:43:21 -0700653 if (m_state != SkGIFNetscapeExtensionBlock)
654 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700655 break;
656 }
657
658 // Netscape-specific GIF extension: animation looping.
scroggof9acbe22016-10-25 12:43:21 -0700659 case SkGIFNetscapeExtensionBlock: {
scroggo19b91532016-10-24 09:03:26 -0700660 const int currentComponent = this->getOneByte();
scroggof9acbe22016-10-25 12:43:21 -0700661 // SkGIFConsumeNetscapeExtension always reads 3 bytes from the stream; we should at least wait for this amount.
scroggo19b91532016-10-24 09:03:26 -0700662 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700663 GETN(std::max(3, currentComponent), SkGIFConsumeNetscapeExtension);
scroggo19b91532016-10-24 09:03:26 -0700664 else
scroggof9acbe22016-10-25 12:43:21 -0700665 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700666 break;
667 }
668
669 // Parse netscape-specific application extensions
scroggof9acbe22016-10-25 12:43:21 -0700670 case SkGIFConsumeNetscapeExtension: {
scroggo19b91532016-10-24 09:03:26 -0700671 const unsigned char* currentComponent =
672 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
673
674 int netscapeExtension = currentComponent[0] & 7;
675
676 // Loop entire animation specified # of times. Only read the loop count during the first iteration.
677 if (netscapeExtension == 1) {
678 m_loopCount = GETINT16(currentComponent + 1);
679
680 // Zero loop count is infinite animation loop request.
681 if (!m_loopCount)
scroggoe71b1a12016-11-01 08:28:28 -0700682 m_loopCount = SkCodec::kRepetitionCountInfinite;
scroggo19b91532016-10-24 09:03:26 -0700683
scroggof9acbe22016-10-25 12:43:21 -0700684 GETN(1, SkGIFNetscapeExtensionBlock);
scroggoe71b1a12016-11-01 08:28:28 -0700685
686 if (SkGIFLoopCountQuery == query) {
687 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400688 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700689 }
scroggo19b91532016-10-24 09:03:26 -0700690 } else if (netscapeExtension == 2) {
691 // Wait for specified # of bytes to enter buffer.
692
693 // Don't do this, this extension doesn't exist (isn't used at all)
694 // and doesn't do anything, as our streaming/buffering takes care of it all...
695 // See: http://semmix.pl/color/exgraf/eeg24.htm
scroggof9acbe22016-10-25 12:43:21 -0700696 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700697 } else {
698 // 0,3-7 are yet to be defined netscape extension codes
699 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700700 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400701 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700702 }
703 break;
704 }
705
scroggof9acbe22016-10-25 12:43:21 -0700706 case SkGIFImageHeader: {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400707 int height, width, xOffset, yOffset;
scroggo19b91532016-10-24 09:03:26 -0700708 const unsigned char* currentComponent =
709 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
710
711 /* Get image offsets, with respect to the screen origin */
712 xOffset = GETINT16(currentComponent);
713 yOffset = GETINT16(currentComponent + 2);
714
715 /* Get image width and height. */
716 width = GETINT16(currentComponent + 4);
717 height = GETINT16(currentComponent + 6);
718
719 // Some GIF files have frames that don't fit in the specified
720 // overall image size. For the first frame, we can simply enlarge
721 // the image size to allow the frame to be visible. We can't do
722 // this on subsequent frames because the rest of the decoding
723 // infrastructure assumes the image size won't change as we
724 // continue decoding, so any subsequent frames that are even
725 // larger will be cropped.
726 // Luckily, handling just the first frame is sufficient to deal
727 // with most cases, e.g. ones where the image size is erroneously
728 // set to zero, since usually the first frame completely fills
729 // the image.
730 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400731 fScreenHeight = std::max(fScreenHeight, yOffset + height);
732 fScreenWidth = std::max(fScreenWidth, xOffset + width);
scroggo19b91532016-10-24 09:03:26 -0700733 }
734
735 // NOTE: Chromium placed this block after setHeaderDefined, down
736 // below we returned true when asked for the size. So Chromium
737 // created an image which would fail. Is this the correct behavior?
738 // We choose to return false early, so we will not create an
739 // SkCodec.
740
741 // Work around more broken GIF files that have zero image width or
742 // height.
743 if (!height || !width) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400744 height = fScreenHeight;
745 width = fScreenWidth;
scroggo19b91532016-10-24 09:03:26 -0700746 if (!height || !width) {
747 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700748 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400749 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700750 }
751 }
752
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400753 const bool isLocalColormapDefined = SkToBool(currentComponent[8] & 0x80);
scroggo19b91532016-10-24 09:03:26 -0700754 // The three low-order bits of currentComponent[8] specify the bits per pixel.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400755 const int numColors = 2 << (currentComponent[8] & 0x7);
scroggo19b91532016-10-24 09:03:26 -0700756 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400757 const int transPix = m_frames.empty() ? SkGIFColorMap::kNotFound
758 : m_frames[0]->transparentPixel();
759 if (this->hasTransparency(transPix,
760 isLocalColormapDefined, numColors))
761 {
scroggo19b91532016-10-24 09:03:26 -0700762 m_firstFrameHasAlpha = true;
scroggo19b91532016-10-24 09:03:26 -0700763 } else {
764 const bool frameIsSubset = xOffset > 0 || yOffset > 0
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400765 || width < fScreenWidth
766 || height < fScreenHeight;
scroggo19b91532016-10-24 09:03:26 -0700767 m_firstFrameHasAlpha = frameIsSubset;
scroggo19b91532016-10-24 09:03:26 -0700768 }
769 }
770
Leon Scroggins III4993b952016-12-08 11:54:04 -0500771 addFrameIfNecessary();
772 SkGIFFrameContext* currentFrame = m_frames.back().get();
773 currentFrame->setHeaderDefined();
774
scroggof9acbe22016-10-25 12:43:21 -0700775 if (query == SkGIFSizeQuery) {
scroggo19b91532016-10-24 09:03:26 -0700776 // The decoder needs to stop, so we return here, before
777 // flushing the buffer. Next time through, we'll be in the same
778 // state, requiring the same amount in the buffer.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400779 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700780 }
781
scroggo19b91532016-10-24 09:03:26 -0700782
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400783 currentFrame->setXYWH(xOffset, yOffset, width, height);
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400784 currentFrame->setInterlaced(SkToBool(currentComponent[8] & 0x40));
scroggo19b91532016-10-24 09:03:26 -0700785
786 // Overlaying interlaced, transparent GIFs over
787 // existing image data using the Haeberli display hack
788 // requires saving the underlying image in order to
789 // avoid jaggies at the transparency edges. We are
790 // unprepared to deal with that, so don't display such
791 // images progressively. Which means only the first
792 // frame can be progressively displayed.
793 // FIXME: It is possible that a non-transparent frame
794 // can be interlaced and progressively displayed.
795 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
796
797 if (isLocalColormapDefined) {
798 currentFrame->localColorMap().setNumColors(numColors);
scroggof9acbe22016-10-25 12:43:21 -0700799 GETN(SK_BYTES_PER_COLORMAP_ENTRY * numColors, SkGIFImageColormap);
scroggo19b91532016-10-24 09:03:26 -0700800 break;
801 }
802
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400803 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700804 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700805 break;
806 }
807
scroggof9acbe22016-10-25 12:43:21 -0700808 case SkGIFImageColormap: {
scroggo19b91532016-10-24 09:03:26 -0700809 SkASSERT(!m_frames.empty());
Leon Scroggins IIIe4ba1052017-01-30 13:55:14 -0500810 auto* currentFrame = m_frames.back().get();
811 auto& cmap = currentFrame->localColorMap();
Leon Scroggins III932efed2016-12-16 11:39:51 -0500812 cmap.setTablePosition(m_streamBuffer.markPosition());
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400813 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700814 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700815 break;
816 }
817
scroggof9acbe22016-10-25 12:43:21 -0700818 case SkGIFSubBlock: {
scroggo19b91532016-10-24 09:03:26 -0700819 const size_t bytesInBlock = this->getOneByte();
820 if (bytesInBlock)
scroggof9acbe22016-10-25 12:43:21 -0700821 GETN(bytesInBlock, SkGIFLZW);
scroggo19b91532016-10-24 09:03:26 -0700822 else {
823 // Finished parsing one frame; Process next frame.
824 SkASSERT(!m_frames.empty());
825 // Note that some broken GIF files do not have enough LZW blocks to fully
826 // decode all rows but we treat it as frame complete.
827 m_frames.back()->setComplete();
scroggof9acbe22016-10-25 12:43:21 -0700828 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700829 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse) {
830 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400831 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700832 }
833 }
834 break;
835 }
836
scroggof9acbe22016-10-25 12:43:21 -0700837 case SkGIFDone: {
scroggo19b91532016-10-24 09:03:26 -0700838 m_parseCompleted = true;
Leon Scroggins III588fb042017-07-14 16:32:31 -0400839 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700840 }
841
842 default:
843 // We shouldn't ever get here.
844 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700845 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400846 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700847 break;
848 } // switch
849 m_streamBuffer.flush();
850 }
scroggo19b91532016-10-24 09:03:26 -0700851}
852
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400853bool SkGifImageReader::hasTransparency(int transparentPixel, bool isLocalColormapDefined,
854 int localColors) const {
855 const int globalColors = m_globalColorMap.numColors();
856 if (!isLocalColormapDefined && globalColors == 0) {
857 // No color table for this frame, so it is completely transparent.
858 return true;
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500859 }
860
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400861 if (transparentPixel < 0) {
862 SkASSERT(SkGIFColorMap::kNotFound == transparentPixel);
863 return false;
864 }
865
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500866 if (isLocalColormapDefined) {
867 return transparentPixel < localColors;
868 }
869
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500870 // If there is a global color table, it will be parsed before reaching
871 // here. If its numColors is set, it will be defined.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400872 SkASSERT(globalColors > 0);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500873 SkASSERT(m_globalColorMap.isDefined());
874 return transparentPixel < globalColors;
875}
876
scroggo3d3a65c2016-10-24 12:28:30 -0700877void SkGifImageReader::addFrameIfNecessary()
scroggo19b91532016-10-24 09:03:26 -0700878{
879 if (m_frames.empty() || m_frames.back()->isComplete()) {
880 const size_t i = m_frames.size();
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400881 std::unique_ptr<SkGIFFrameContext> frame(new SkGIFFrameContext(this, static_cast<int>(i)));
scroggo19b91532016-10-24 09:03:26 -0700882 m_frames.push_back(std::move(frame));
883 }
884}
885
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400886static SkIRect frame_rect_on_screen(SkIRect frameRect,
887 const SkIRect& screenRect) {
888 if (!frameRect.intersect(screenRect)) {
889 return SkIRect::MakeEmpty();
890 }
891
892 return frameRect;
893}
894
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400895static bool independent(const SkFrame& frame) {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400896 return frame.getRequiredFrame() == SkCodec::kNone;
897}
898
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400899static bool restore_bg(const SkFrame& frame) {
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400900 return frame.getDisposalMethod() == SkCodecAnimation::DisposalMethod::kRestoreBGColor;
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400901}
902
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400903bool SkGIFFrameContext::onReportsAlpha() const {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400904 // Note: We could correct these after decoding - i.e. some frames may turn out to be
905 // independent and opaque if they do not use the transparent pixel, but that would require
906 // checking whether each pixel used the transparent index.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400907 return m_owner->hasTransparency(this->transparentPixel(),
908 m_localColorMap.isDefined(), m_localColorMap.numColors());
909}
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400910
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400911void SkFrameHolder::setAlphaAndRequiredFrame(SkFrame* frame) {
912 const bool reportsAlpha = frame->reportsAlpha();
913 const auto screenRect = SkIRect::MakeWH(fScreenWidth, fScreenHeight);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400914 const auto frameRect = frame_rect_on_screen(frame->frameRect(), screenRect);
915
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400916 const int i = frame->frameId();
917 if (0 == i) {
918 frame->setHasAlpha(reportsAlpha || frameRect != screenRect);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500919 frame->setRequiredFrame(SkCodec::kNone);
920 return;
921 }
922
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400923
924 const bool blendWithPrevFrame = frame->getBlend() == SkCodecAnimation::Blend::kPriorFrame;
925 if ((!reportsAlpha || !blendWithPrevFrame) && frameRect == screenRect) {
926 frame->setHasAlpha(reportsAlpha);
927 frame->setRequiredFrame(SkCodec::kNone);
928 return;
929 }
930
931 const SkFrame* prevFrame = this->getFrame(i-1);
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400932 while (prevFrame->getDisposalMethod() == SkCodecAnimation::DisposalMethod::kRestorePrevious) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400933 const int prevId = prevFrame->frameId();
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400934 if (0 == prevId) {
935 frame->setHasAlpha(true);
936 frame->setRequiredFrame(SkCodec::kNone);
937 return;
938 }
939
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400940 prevFrame = this->getFrame(prevId - 1);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400941 }
942
943 const bool clearPrevFrame = restore_bg(*prevFrame);
944 auto prevFrameRect = frame_rect_on_screen(prevFrame->frameRect(), screenRect);
945
946 if (clearPrevFrame) {
947 if (prevFrameRect == screenRect || independent(*prevFrame)) {
948 frame->setHasAlpha(true);
949 frame->setRequiredFrame(SkCodec::kNone);
950 return;
951 }
952 }
953
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400954 if (reportsAlpha && blendWithPrevFrame) {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400955 // Note: We could be more aggressive here. If prevFrame clears
956 // to background color and covers its required frame (and that
957 // frame is independent), prevFrame could be marked independent.
958 // Would this extra complexity be worth it?
959 frame->setRequiredFrame(prevFrame->frameId());
960 frame->setHasAlpha(prevFrame->hasAlpha() || clearPrevFrame);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500961 return;
962 }
963
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400964 while (frameRect.contains(prevFrameRect)) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400965 const int prevRequiredFrame = prevFrame->getRequiredFrame();
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400966 if (prevRequiredFrame == SkCodec::kNone) {
967 frame->setRequiredFrame(SkCodec::kNone);
968 frame->setHasAlpha(true);
969 return;
970 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500971
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400972 prevFrame = this->getFrame(prevRequiredFrame);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400973 prevFrameRect = frame_rect_on_screen(prevFrame->frameRect(), screenRect);
974 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500975
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400976 if (restore_bg(*prevFrame)) {
977 frame->setHasAlpha(true);
978 if (prevFrameRect == screenRect || independent(*prevFrame)) {
979 frame->setRequiredFrame(SkCodec::kNone);
980 } else {
981 // Note: As above, frame could still be independent, e.g. if
982 // prevFrame covers its required frame and that frame is
983 // independent.
984 frame->setRequiredFrame(prevFrame->frameId());
985 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500986 return;
987 }
988
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400989 SkASSERT(prevFrame->getDisposalMethod() == SkCodecAnimation::DisposalMethod::kKeep);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400990 frame->setRequiredFrame(prevFrame->frameId());
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400991 frame->setHasAlpha(prevFrame->hasAlpha() || (reportsAlpha && !blendWithPrevFrame));
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500992}
993
scroggo19b91532016-10-24 09:03:26 -0700994// FIXME: Move this method to close to doLZW().
Leon Scroggins III45565b62016-12-05 14:56:30 -0500995bool SkGIFLZWContext::prepareToDecode()
scroggo19b91532016-10-24 09:03:26 -0700996{
997 SkASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefined());
998
999 // Since we use a codesize of 1 more than the datasize, we need to ensure
scroggof9acbe22016-10-25 12:43:21 -07001000 // that our datasize is strictly less than the SK_MAX_DICTIONARY_ENTRY_BITS.
1001 if (m_frameContext->dataSize() >= SK_MAX_DICTIONARY_ENTRY_BITS)
scroggo19b91532016-10-24 09:03:26 -07001002 return false;
1003 clearCode = 1 << m_frameContext->dataSize();
1004 avail = clearCode + 2;
1005 oldcode = -1;
1006 codesize = m_frameContext->dataSize() + 1;
1007 codemask = (1 << codesize) - 1;
1008 datum = bits = 0;
1009 ipass = m_frameContext->interlaced() ? 1 : 0;
1010 irow = 0;
1011
1012 // We want to know the longest sequence encodable by a dictionary with
scroggof9acbe22016-10-25 12:43:21 -07001013 // SK_MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base
scroggo19b91532016-10-24 09:03:26 -07001014 // values themselves at the beginning of the dictionary, as well as the need
1015 // for a clear code or a termination code, we could use every entry to
1016 // encode a series of multiple values. If the input value stream looked
1017 // like "AAAAA..." (a long string of just one value), the first dictionary
1018 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
scroggof9acbe22016-10-25 12:43:21 -07001019 // the longest sequence would be SK_MAX_DICTIONARY_ENTRIES + 1 values.
scroggo19b91532016-10-24 09:03:26 -07001020 //
1021 // However, we have to account for reserved entries. The first |datasize|
1022 // bits are reserved for the base values, and the next two entries are
1023 // reserved for the clear code and termination code. In theory a GIF can
1024 // set the datasize to 0, meaning we have just two reserved entries, making
scroggof9acbe22016-10-25 12:43:21 -07001025 // the longest sequence (SK_MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since
scroggo19b91532016-10-24 09:03:26 -07001026 // each value is a byte, this is also the number of bytes in the longest
1027 // encodable sequence.
scroggof9acbe22016-10-25 12:43:21 -07001028 const size_t maxBytes = SK_MAX_DICTIONARY_ENTRIES - 1;
scroggo19b91532016-10-24 09:03:26 -07001029
1030 // Now allocate the output buffer. We decode directly into this buffer
1031 // until we have at least one row worth of data, then call outputRow().
1032 // This means worst case we may have (row width - 1) bytes in the buffer
1033 // and then decode a sequence |maxBytes| long to append.
1034 rowBuffer.reset(m_frameContext->width() - 1 + maxBytes);
1035 rowIter = rowBuffer.begin();
1036 rowsRemaining = m_frameContext->height();
1037
1038 // Clearing the whole suffix table lets us be more tolerant of bad data.
1039 for (int i = 0; i < clearCode; ++i) {
1040 suffix[i] = i;
1041 suffixLength[i] = 1;
1042 }
1043 return true;
1044}
1045