blob: ed20af017b2d9e429d3c6443de02a4316d961506 [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.
Leon Scroggins III223ec292017-08-22 14:13:15 -0400100void 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())
Leon Scroggins III223ec292017-08-22 14:13:15 -0400147 return;
scroggo19b91532016-10-24 09:03:26 -0700148
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());
Leon Scroggins III223ec292017-08-22 14:13:15 -0400151 m_client->haveDecodedRow(m_frameContext->frameId(), rowBegin,
152 drowStart, drowEnd - drowStart + 1, writeTransparentPixels);
scroggo19b91532016-10-24 09:03:26 -0700153
154 if (!m_frameContext->interlaced())
155 irow++;
156 else {
157 do {
158 switch (ipass) {
159 case 1:
160 irow += 8;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400161 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700162 ipass++;
163 irow = 4;
164 }
165 break;
166
167 case 2:
168 irow += 8;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400169 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700170 ipass++;
171 irow = 2;
172 }
173 break;
174
175 case 3:
176 irow += 4;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400177 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700178 ipass++;
179 irow = 1;
180 }
181 break;
182
183 case 4:
184 irow += 2;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400185 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700186 ipass++;
187 irow = 0;
188 }
189 break;
190
191 default:
192 break;
193 }
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400194 } while (irow > (unsigned) (m_frameContext->height() - 1));
scroggo19b91532016-10-24 09:03:26 -0700195 }
scroggo19b91532016-10-24 09:03:26 -0700196}
197
198// Perform Lempel-Ziv-Welch decoding.
199// 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 -0700200// 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 -0700201bool SkGIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock)
scroggo19b91532016-10-24 09:03:26 -0700202{
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400203 const int width = m_frameContext->width();
scroggo19b91532016-10-24 09:03:26 -0700204
205 if (rowIter == rowBuffer.end())
206 return true;
207
208 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) {
209 // Feed the next byte into the decoder's 32-bit input buffer.
210 datum += ((int) *ch) << bits;
211 bits += 8;
212
213 // Check for underflow of decoder's 32-bit input buffer.
214 while (bits >= codesize) {
215 // Get the leading variable-length symbol from the data stream.
216 int code = datum & codemask;
217 datum >>= codesize;
218 bits -= codesize;
219
220 // Reset the dictionary to its original state, if requested.
221 if (code == clearCode) {
222 codesize = m_frameContext->dataSize() + 1;
223 codemask = (1 << codesize) - 1;
224 avail = clearCode + 2;
225 oldcode = -1;
226 continue;
227 }
228
229 // Check for explicit end-of-stream code.
230 if (code == (clearCode + 1)) {
231 // end-of-stream should only appear after all image data.
232 if (!rowsRemaining)
233 return true;
234 return false;
235 }
236
237 const int tempCode = code;
238 unsigned short codeLength = 0;
239 if (code < avail) {
240 // This is a pre-existing code, so we already know what it
241 // encodes.
242 codeLength = suffixLength[code];
243 rowIter += codeLength;
244 } else if (code == avail && oldcode != -1) {
245 // This is a new code just being added to the dictionary.
246 // It must encode the contents of the previous code, plus
247 // the first character of the previous code again.
248 codeLength = suffixLength[oldcode] + 1;
249 rowIter += codeLength;
250 *--rowIter = firstchar;
251 code = oldcode;
252 } else {
253 // This is an invalid code. The dictionary is just initialized
254 // and the code is incomplete. We don't know how to handle
255 // this case.
256 return false;
257 }
258
259 while (code >= clearCode) {
260 *--rowIter = suffix[code];
261 code = prefix[code];
262 }
263
264 *--rowIter = firstchar = suffix[code];
265
266 // Define a new codeword in the dictionary as long as we've read
267 // more than one value from the stream.
scroggof9acbe22016-10-25 12:43:21 -0700268 if (avail < SK_MAX_DICTIONARY_ENTRIES && oldcode != -1) {
scroggo19b91532016-10-24 09:03:26 -0700269 prefix[avail] = oldcode;
270 suffix[avail] = firstchar;
271 suffixLength[avail] = suffixLength[oldcode] + 1;
272 ++avail;
273
274 // If we've used up all the codewords of a given length
275 // increase the length of codewords by one bit, but don't
276 // exceed the specified maximum codeword size.
scroggof9acbe22016-10-25 12:43:21 -0700277 if (!(avail & codemask) && avail < SK_MAX_DICTIONARY_ENTRIES) {
scroggo19b91532016-10-24 09:03:26 -0700278 ++codesize;
279 codemask += avail;
280 }
281 }
282 oldcode = tempCode;
283 rowIter += codeLength;
284
285 // Output as many rows as possible.
286 unsigned char* rowBegin = rowBuffer.begin();
287 for (; rowBegin + width <= rowIter; rowBegin += width) {
Leon Scroggins III223ec292017-08-22 14:13:15 -0400288 outputRow(rowBegin);
scroggo19b91532016-10-24 09:03:26 -0700289 rowsRemaining--;
290 if (!rowsRemaining)
291 return true;
292 }
293
294 if (rowBegin != rowBuffer.begin()) {
295 // Move the remaining bytes to the beginning of the buffer.
296 const size_t bytesToCopy = rowIter - rowBegin;
297 memcpy(&rowBuffer.front(), rowBegin, bytesToCopy);
298 rowIter = rowBuffer.begin() + bytesToCopy;
299 }
300 }
301 }
302 return true;
303}
304
Leon Scroggins III932efed2016-12-16 11:39:51 -0500305sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkColorType colorType,
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400306 int transparentPixel) const
scroggo19b91532016-10-24 09:03:26 -0700307{
308 if (!m_isDefined)
309 return nullptr;
310
311 const PackColorProc proc = choose_pack_color_proc(false, colorType);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500312 if (m_table && proc == m_packColorProc && m_transPixel == transparentPixel) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400313 SkASSERT(transparentPixel == kNotFound || transparentPixel > m_table->count()
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500314 || m_table->operator[](transparentPixel) == SK_ColorTRANSPARENT);
315 // This SkColorTable has already been built with the same transparent color and
316 // packing proc. Reuse it.
317 return m_table;
scroggo19b91532016-10-24 09:03:26 -0700318 }
319 m_packColorProc = proc;
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500320 m_transPixel = transparentPixel;
scroggo19b91532016-10-24 09:03:26 -0700321
Leon Scroggins III932efed2016-12-16 11:39:51 -0500322 const size_t bytes = m_colors * SK_BYTES_PER_COLORMAP_ENTRY;
323 sk_sp<SkData> rawData(streamBuffer->getDataAtPosition(m_position, bytes));
324 if (!rawData) {
325 return nullptr;
326 }
327
scroggof9acbe22016-10-25 12:43:21 -0700328 SkASSERT(m_colors <= SK_MAX_COLORS);
Leon Scroggins III932efed2016-12-16 11:39:51 -0500329 const uint8_t* srcColormap = rawData->bytes();
scroggof9acbe22016-10-25 12:43:21 -0700330 SkPMColor colorStorage[SK_MAX_COLORS];
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400331 for (int i = 0; i < m_colors; i++) {
scroggo19b91532016-10-24 09:03:26 -0700332 if (i == transparentPixel) {
333 colorStorage[i] = SK_ColorTRANSPARENT;
334 } else {
335 colorStorage[i] = proc(255, srcColormap[0], srcColormap[1], srcColormap[2]);
336 }
scroggof9acbe22016-10-25 12:43:21 -0700337 srcColormap += SK_BYTES_PER_COLORMAP_ENTRY;
scroggo19b91532016-10-24 09:03:26 -0700338 }
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400339 for (int i = m_colors; i < SK_MAX_COLORS; i++) {
scroggo19b91532016-10-24 09:03:26 -0700340 colorStorage[i] = SK_ColorTRANSPARENT;
341 }
scroggof9acbe22016-10-25 12:43:21 -0700342 m_table = sk_sp<SkColorTable>(new SkColorTable(colorStorage, SK_MAX_COLORS));
scroggo19b91532016-10-24 09:03:26 -0700343 return m_table;
344}
345
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400346sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, int index) {
347 if (index < 0 || static_cast<size_t>(index) >= m_frames.size()) {
scroggo19b91532016-10-24 09:03:26 -0700348 return nullptr;
349 }
350
scroggof9acbe22016-10-25 12:43:21 -0700351 const SkGIFFrameContext* frameContext = m_frames[index].get();
352 const SkGIFColorMap& localColorMap = frameContext->localColorMap();
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400353 const int transPix = frameContext->transparentPixel();
scroggo19b91532016-10-24 09:03:26 -0700354 if (localColorMap.isDefined()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500355 return localColorMap.buildTable(&m_streamBuffer, colorType, transPix);
scroggo19b91532016-10-24 09:03:26 -0700356 }
357 if (m_globalColorMap.isDefined()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500358 return m_globalColorMap.buildTable(&m_streamBuffer, colorType, transPix);
scroggo19b91532016-10-24 09:03:26 -0700359 }
360 return nullptr;
361}
362
363// Perform decoding for this frame. frameComplete will be true if the entire frame is decoded.
scroggo3d3a65c2016-10-24 12:28:30 -0700364// 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 -0700365// 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 -0500366bool SkGIFFrameContext::decode(SkStreamBuffer* streamBuffer, SkGifCodec* client,
367 bool* frameComplete)
scroggo19b91532016-10-24 09:03:26 -0700368{
369 *frameComplete = false;
370 if (!m_lzwContext) {
scroggof9acbe22016-10-25 12:43:21 -0700371 // Wait for more data to properly initialize SkGIFLZWContext.
scroggo19b91532016-10-24 09:03:26 -0700372 if (!isDataSizeDefined() || !isHeaderDefined())
373 return true;
374
scroggof9acbe22016-10-25 12:43:21 -0700375 m_lzwContext.reset(new SkGIFLZWContext(client, this));
Leon Scroggins III45565b62016-12-05 14:56:30 -0500376 if (!m_lzwContext->prepareToDecode()) {
scroggo19b91532016-10-24 09:03:26 -0700377 m_lzwContext.reset();
378 return false;
379 }
380
381 m_currentLzwBlock = 0;
382 }
383
384 // 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 -0400385 while (static_cast<size_t>(m_currentLzwBlock) < m_lzwBlocks.size()
386 && m_lzwContext->hasRemainingRows()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500387 const auto& block = m_lzwBlocks[m_currentLzwBlock];
388 const size_t len = block.blockSize;
389
390 sk_sp<SkData> data(streamBuffer->getDataAtPosition(block.blockPosition, len));
391 if (!data) {
392 return false;
393 }
394 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(data->data()), len)) {
scroggo19b91532016-10-24 09:03:26 -0700395 return false;
396 }
397 ++m_currentLzwBlock;
398 }
399
400 // If this frame is data complete then the previous loop must have completely decoded all LZW blocks.
401 // There will be no more decoding for this frame so it's time to cleanup.
402 if (isComplete()) {
403 *frameComplete = true;
404 m_lzwContext.reset();
405 }
406 return true;
407}
408
409// Decode a frame.
scroggof9acbe22016-10-25 12:43:21 -0700410// 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 -0700411// Return true if decoding has progressed. Return false if an error has occurred.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400412bool SkGifImageReader::decode(int frameIndex, bool* frameComplete)
scroggo19b91532016-10-24 09:03:26 -0700413{
scroggof9acbe22016-10-25 12:43:21 -0700414 SkGIFFrameContext* currentFrame = m_frames[frameIndex].get();
scroggo19b91532016-10-24 09:03:26 -0700415
Leon Scroggins III932efed2016-12-16 11:39:51 -0500416 return currentFrame->decode(&m_streamBuffer, m_client, frameComplete);
scroggo19b91532016-10-24 09:03:26 -0700417}
418
419// Parse incoming GIF data stream into internal data structures.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400420SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
scroggo19b91532016-10-24 09:03:26 -0700421{
422 if (m_parseCompleted) {
Leon Scroggins III588fb042017-07-14 16:32:31 -0400423 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700424 }
425
scroggoe71b1a12016-11-01 08:28:28 -0700426 if (SkGIFLoopCountQuery == query && m_loopCount != cLoopCountNotSeen) {
427 // Loop count has already been parsed.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400428 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700429 }
430
scroggof9acbe22016-10-25 12:43:21 -0700431 // SkGIFSizeQuery and SkGIFFrameCountQuery are negative, so this is only meaningful when >= 0.
scroggo19b91532016-10-24 09:03:26 -0700432 const int lastFrameToParse = (int) query;
433 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse
434 && m_frames[lastFrameToParse]->isComplete()) {
435 // We have already parsed this frame.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400436 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700437 }
438
439 while (true) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500440 if (!m_streamBuffer.buffer(m_bytesToConsume)) {
441 // The stream does not yet have enough data.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400442 return SkCodec::kIncompleteInput;
scroggo19b91532016-10-24 09:03:26 -0700443 }
444
445 switch (m_state) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500446 case SkGIFLZW: {
scroggo19b91532016-10-24 09:03:26 -0700447 SkASSERT(!m_frames.empty());
Leon Scroggins III932efed2016-12-16 11:39:51 -0500448 auto* frame = m_frames.back().get();
449 frame->addLzwBlock(m_streamBuffer.markPosition(), m_bytesToConsume);
scroggof9acbe22016-10-25 12:43:21 -0700450 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700451 break;
Leon Scroggins III932efed2016-12-16 11:39:51 -0500452 }
scroggof9acbe22016-10-25 12:43:21 -0700453 case SkGIFLZWStart: {
scroggo19b91532016-10-24 09:03:26 -0700454 SkASSERT(!m_frames.empty());
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500455 auto* currentFrame = m_frames.back().get();
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500456
457 currentFrame->setDataSize(this->getOneByte());
scroggof9acbe22016-10-25 12:43:21 -0700458 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700459 break;
460 }
461
scroggof9acbe22016-10-25 12:43:21 -0700462 case SkGIFType: {
scroggo19b91532016-10-24 09:03:26 -0700463 const char* currentComponent = m_streamBuffer.get();
464
465 // All GIF files begin with "GIF87a" or "GIF89a".
466 if (!memcmp(currentComponent, "GIF89a", 6))
467 m_version = 89;
468 else if (!memcmp(currentComponent, "GIF87a", 6))
469 m_version = 87;
470 else {
471 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700472 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400473 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700474 }
scroggof9acbe22016-10-25 12:43:21 -0700475 GETN(7, SkGIFGlobalHeader);
scroggo19b91532016-10-24 09:03:26 -0700476 break;
477 }
478
scroggof9acbe22016-10-25 12:43:21 -0700479 case SkGIFGlobalHeader: {
scroggo19b91532016-10-24 09:03:26 -0700480 const unsigned char* currentComponent =
481 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
482
483 // This is the height and width of the "screen" or frame into which
484 // images are rendered. The individual images can be smaller than
485 // the screen size and located with an origin anywhere within the
486 // screen.
487 // Note that we don't inform the client of the size yet, as it might
488 // change after we read the first frame's image header.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400489 fScreenWidth = GETINT16(currentComponent);
490 fScreenHeight = GETINT16(currentComponent + 2);
scroggo19b91532016-10-24 09:03:26 -0700491
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400492 const int globalColorMapColors = 2 << (currentComponent[4] & 0x07);
scroggo19b91532016-10-24 09:03:26 -0700493
494 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* global map */
495 m_globalColorMap.setNumColors(globalColorMapColors);
scroggof9acbe22016-10-25 12:43:21 -0700496 GETN(SK_BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, SkGIFGlobalColormap);
scroggo19b91532016-10-24 09:03:26 -0700497 break;
498 }
499
scroggof9acbe22016-10-25 12:43:21 -0700500 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700501 break;
502 }
503
scroggof9acbe22016-10-25 12:43:21 -0700504 case SkGIFGlobalColormap: {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500505 m_globalColorMap.setTablePosition(m_streamBuffer.markPosition());
scroggof9acbe22016-10-25 12:43:21 -0700506 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700507 break;
508 }
509
scroggof9acbe22016-10-25 12:43:21 -0700510 case SkGIFImageStart: {
scroggo19b91532016-10-24 09:03:26 -0700511 const char currentComponent = m_streamBuffer.get()[0];
512
513 if (currentComponent == '!') { // extension.
scroggof9acbe22016-10-25 12:43:21 -0700514 GETN(2, SkGIFExtension);
scroggo19b91532016-10-24 09:03:26 -0700515 break;
516 }
517
518 if (currentComponent == ',') { // image separator.
scroggof9acbe22016-10-25 12:43:21 -0700519 GETN(9, SkGIFImageHeader);
scroggo19b91532016-10-24 09:03:26 -0700520 break;
521 }
522
523 // If we get anything other than ',' (image separator), '!'
524 // (extension), or ';' (trailer), there is extraneous data
525 // between blocks. The GIF87a spec tells us to keep reading
526 // until we find an image separator, but GIF89a says such
527 // a file is corrupt. We follow Mozilla's implementation and
528 // proceed as if the file were correctly terminated, so the
529 // GIF will display.
scroggof9acbe22016-10-25 12:43:21 -0700530 GETN(0, SkGIFDone);
scroggo19b91532016-10-24 09:03:26 -0700531 break;
532 }
533
scroggof9acbe22016-10-25 12:43:21 -0700534 case SkGIFExtension: {
scroggo19b91532016-10-24 09:03:26 -0700535 const unsigned char* currentComponent =
536 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
537
538 size_t bytesInBlock = currentComponent[1];
scroggof9acbe22016-10-25 12:43:21 -0700539 SkGIFState exceptionState = SkGIFSkipBlock;
scroggo19b91532016-10-24 09:03:26 -0700540
541 switch (*currentComponent) {
542 case 0xf9:
scroggo19b91532016-10-24 09:03:26 -0700543 // The GIF spec mandates that the GIFControlExtension header block length is 4 bytes,
scroggof9acbe22016-10-25 12:43:21 -0700544 exceptionState = SkGIFControlExtension;
scroggo19b91532016-10-24 09:03:26 -0700545 // and the parser for this block reads 4 bytes, so we must enforce that the buffer
546 // contains at least this many bytes. If the GIF specifies a different length, we
547 // allow that, so long as it's larger; the additional data will simply be ignored.
548 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
549 break;
550
551 // The GIF spec also specifies the lengths of the following two extensions' headers
552 // (as 12 and 11 bytes, respectively). Because we ignore the plain text extension entirely
553 // and sanity-check the actual length of the application extension header before reading it,
554 // we allow GIFs to deviate from these values in either direction. This is important for
555 // real-world compatibility, as GIFs in the wild exist with application extension headers
556 // that are both shorter and longer than 11 bytes.
557 case 0x01:
558 // ignoring plain text extension
559 break;
560
561 case 0xff:
scroggof9acbe22016-10-25 12:43:21 -0700562 exceptionState = SkGIFApplicationExtension;
scroggo19b91532016-10-24 09:03:26 -0700563 break;
564
565 case 0xfe:
scroggof9acbe22016-10-25 12:43:21 -0700566 exceptionState = SkGIFConsumeComment;
scroggo19b91532016-10-24 09:03:26 -0700567 break;
568 }
569
570 if (bytesInBlock)
571 GETN(bytesInBlock, exceptionState);
572 else
scroggof9acbe22016-10-25 12:43:21 -0700573 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700574 break;
575 }
576
scroggof9acbe22016-10-25 12:43:21 -0700577 case SkGIFConsumeBlock: {
scroggo19b91532016-10-24 09:03:26 -0700578 const unsigned char currentComponent = this->getOneByte();
579 if (!currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700580 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700581 else
scroggof9acbe22016-10-25 12:43:21 -0700582 GETN(currentComponent, SkGIFSkipBlock);
scroggo19b91532016-10-24 09:03:26 -0700583 break;
584 }
585
scroggof9acbe22016-10-25 12:43:21 -0700586 case SkGIFSkipBlock: {
587 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700588 break;
589 }
590
scroggof9acbe22016-10-25 12:43:21 -0700591 case SkGIFControlExtension: {
scroggo19b91532016-10-24 09:03:26 -0700592 const unsigned char* currentComponent =
593 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
594
595 addFrameIfNecessary();
scroggof9acbe22016-10-25 12:43:21 -0700596 SkGIFFrameContext* currentFrame = m_frames.back().get();
scroggo19b91532016-10-24 09:03:26 -0700597 if (*currentComponent & 0x1)
598 currentFrame->setTransparentPixel(currentComponent[3]);
599
600 // We ignore the "user input" bit.
601
602 // NOTE: This relies on the values in the FrameDisposalMethod enum
603 // matching those in the GIF spec!
604 int rawDisposalMethod = ((*currentComponent) >> 2) & 0x7;
605 switch (rawDisposalMethod) {
606 case 1:
607 case 2:
608 case 3:
609 currentFrame->setDisposalMethod((SkCodecAnimation::DisposalMethod) rawDisposalMethod);
610 break;
611 case 4:
612 // Some specs say that disposal method 3 is "overwrite previous", others that setting
613 // 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 -0400614 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kRestorePrevious);
scroggo19b91532016-10-24 09:03:26 -0700615 break;
616 default:
617 // Other values use the default.
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400618 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep);
scroggo19b91532016-10-24 09:03:26 -0700619 break;
620 }
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400621 currentFrame->setDuration(GETINT16(currentComponent + 1) * 10);
scroggof9acbe22016-10-25 12:43:21 -0700622 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700623 break;
624 }
625
scroggof9acbe22016-10-25 12:43:21 -0700626 case SkGIFCommentExtension: {
scroggo19b91532016-10-24 09:03:26 -0700627 const unsigned char currentComponent = this->getOneByte();
628 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700629 GETN(currentComponent, SkGIFConsumeComment);
scroggo19b91532016-10-24 09:03:26 -0700630 else
scroggof9acbe22016-10-25 12:43:21 -0700631 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700632 break;
633 }
634
scroggof9acbe22016-10-25 12:43:21 -0700635 case SkGIFConsumeComment: {
636 GETN(1, SkGIFCommentExtension);
scroggo19b91532016-10-24 09:03:26 -0700637 break;
638 }
639
scroggof9acbe22016-10-25 12:43:21 -0700640 case SkGIFApplicationExtension: {
scroggo19b91532016-10-24 09:03:26 -0700641 // Check for netscape application extension.
Leon Scroggins III932efed2016-12-16 11:39:51 -0500642 if (m_bytesToConsume == 11) {
scroggo19b91532016-10-24 09:03:26 -0700643 const unsigned char* currentComponent =
644 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
645
646 if (!memcmp(currentComponent, "NETSCAPE2.0", 11) || !memcmp(currentComponent, "ANIMEXTS1.0", 11))
scroggof9acbe22016-10-25 12:43:21 -0700647 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700648 }
649
scroggof9acbe22016-10-25 12:43:21 -0700650 if (m_state != SkGIFNetscapeExtensionBlock)
651 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700652 break;
653 }
654
655 // Netscape-specific GIF extension: animation looping.
scroggof9acbe22016-10-25 12:43:21 -0700656 case SkGIFNetscapeExtensionBlock: {
scroggo19b91532016-10-24 09:03:26 -0700657 const int currentComponent = this->getOneByte();
scroggof9acbe22016-10-25 12:43:21 -0700658 // SkGIFConsumeNetscapeExtension always reads 3 bytes from the stream; we should at least wait for this amount.
scroggo19b91532016-10-24 09:03:26 -0700659 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700660 GETN(std::max(3, currentComponent), SkGIFConsumeNetscapeExtension);
scroggo19b91532016-10-24 09:03:26 -0700661 else
scroggof9acbe22016-10-25 12:43:21 -0700662 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700663 break;
664 }
665
666 // Parse netscape-specific application extensions
scroggof9acbe22016-10-25 12:43:21 -0700667 case SkGIFConsumeNetscapeExtension: {
scroggo19b91532016-10-24 09:03:26 -0700668 const unsigned char* currentComponent =
669 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
670
671 int netscapeExtension = currentComponent[0] & 7;
672
673 // Loop entire animation specified # of times. Only read the loop count during the first iteration.
674 if (netscapeExtension == 1) {
675 m_loopCount = GETINT16(currentComponent + 1);
676
677 // Zero loop count is infinite animation loop request.
678 if (!m_loopCount)
scroggoe71b1a12016-11-01 08:28:28 -0700679 m_loopCount = SkCodec::kRepetitionCountInfinite;
scroggo19b91532016-10-24 09:03:26 -0700680
scroggof9acbe22016-10-25 12:43:21 -0700681 GETN(1, SkGIFNetscapeExtensionBlock);
scroggoe71b1a12016-11-01 08:28:28 -0700682
683 if (SkGIFLoopCountQuery == query) {
684 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400685 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700686 }
scroggo19b91532016-10-24 09:03:26 -0700687 } else if (netscapeExtension == 2) {
688 // Wait for specified # of bytes to enter buffer.
689
690 // Don't do this, this extension doesn't exist (isn't used at all)
691 // and doesn't do anything, as our streaming/buffering takes care of it all...
692 // See: http://semmix.pl/color/exgraf/eeg24.htm
scroggof9acbe22016-10-25 12:43:21 -0700693 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700694 } else {
695 // 0,3-7 are yet to be defined netscape extension codes
696 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700697 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400698 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700699 }
700 break;
701 }
702
scroggof9acbe22016-10-25 12:43:21 -0700703 case SkGIFImageHeader: {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400704 int height, width, xOffset, yOffset;
scroggo19b91532016-10-24 09:03:26 -0700705 const unsigned char* currentComponent =
706 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
707
708 /* Get image offsets, with respect to the screen origin */
709 xOffset = GETINT16(currentComponent);
710 yOffset = GETINT16(currentComponent + 2);
711
712 /* Get image width and height. */
713 width = GETINT16(currentComponent + 4);
714 height = GETINT16(currentComponent + 6);
715
716 // Some GIF files have frames that don't fit in the specified
717 // overall image size. For the first frame, we can simply enlarge
718 // the image size to allow the frame to be visible. We can't do
719 // this on subsequent frames because the rest of the decoding
720 // infrastructure assumes the image size won't change as we
721 // continue decoding, so any subsequent frames that are even
722 // larger will be cropped.
723 // Luckily, handling just the first frame is sufficient to deal
724 // with most cases, e.g. ones where the image size is erroneously
725 // set to zero, since usually the first frame completely fills
726 // the image.
727 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400728 fScreenHeight = std::max(fScreenHeight, yOffset + height);
729 fScreenWidth = std::max(fScreenWidth, xOffset + width);
scroggo19b91532016-10-24 09:03:26 -0700730 }
731
732 // NOTE: Chromium placed this block after setHeaderDefined, down
733 // below we returned true when asked for the size. So Chromium
734 // created an image which would fail. Is this the correct behavior?
735 // We choose to return false early, so we will not create an
736 // SkCodec.
737
738 // Work around more broken GIF files that have zero image width or
739 // height.
740 if (!height || !width) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400741 height = fScreenHeight;
742 width = fScreenWidth;
scroggo19b91532016-10-24 09:03:26 -0700743 if (!height || !width) {
744 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700745 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400746 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700747 }
748 }
749
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400750 const bool isLocalColormapDefined = SkToBool(currentComponent[8] & 0x80);
scroggo19b91532016-10-24 09:03:26 -0700751 // The three low-order bits of currentComponent[8] specify the bits per pixel.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400752 const int numColors = 2 << (currentComponent[8] & 0x7);
scroggo19b91532016-10-24 09:03:26 -0700753 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400754 const int transPix = m_frames.empty() ? SkGIFColorMap::kNotFound
755 : m_frames[0]->transparentPixel();
756 if (this->hasTransparency(transPix,
757 isLocalColormapDefined, numColors))
758 {
scroggo19b91532016-10-24 09:03:26 -0700759 m_firstFrameHasAlpha = true;
scroggo19b91532016-10-24 09:03:26 -0700760 } else {
761 const bool frameIsSubset = xOffset > 0 || yOffset > 0
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400762 || width < fScreenWidth
763 || height < fScreenHeight;
scroggo19b91532016-10-24 09:03:26 -0700764 m_firstFrameHasAlpha = frameIsSubset;
scroggo19b91532016-10-24 09:03:26 -0700765 }
766 }
767
Leon Scroggins III4993b952016-12-08 11:54:04 -0500768 addFrameIfNecessary();
769 SkGIFFrameContext* currentFrame = m_frames.back().get();
770 currentFrame->setHeaderDefined();
771
scroggof9acbe22016-10-25 12:43:21 -0700772 if (query == SkGIFSizeQuery) {
scroggo19b91532016-10-24 09:03:26 -0700773 // The decoder needs to stop, so we return here, before
774 // flushing the buffer. Next time through, we'll be in the same
775 // state, requiring the same amount in the buffer.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400776 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700777 }
778
scroggo19b91532016-10-24 09:03:26 -0700779
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400780 currentFrame->setXYWH(xOffset, yOffset, width, height);
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400781 currentFrame->setInterlaced(SkToBool(currentComponent[8] & 0x40));
scroggo19b91532016-10-24 09:03:26 -0700782
783 // Overlaying interlaced, transparent GIFs over
784 // existing image data using the Haeberli display hack
785 // requires saving the underlying image in order to
786 // avoid jaggies at the transparency edges. We are
787 // unprepared to deal with that, so don't display such
788 // images progressively. Which means only the first
789 // frame can be progressively displayed.
790 // FIXME: It is possible that a non-transparent frame
791 // can be interlaced and progressively displayed.
792 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
793
794 if (isLocalColormapDefined) {
795 currentFrame->localColorMap().setNumColors(numColors);
scroggof9acbe22016-10-25 12:43:21 -0700796 GETN(SK_BYTES_PER_COLORMAP_ENTRY * numColors, SkGIFImageColormap);
scroggo19b91532016-10-24 09:03:26 -0700797 break;
798 }
799
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400800 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700801 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700802 break;
803 }
804
scroggof9acbe22016-10-25 12:43:21 -0700805 case SkGIFImageColormap: {
scroggo19b91532016-10-24 09:03:26 -0700806 SkASSERT(!m_frames.empty());
Leon Scroggins IIIe4ba1052017-01-30 13:55:14 -0500807 auto* currentFrame = m_frames.back().get();
808 auto& cmap = currentFrame->localColorMap();
Leon Scroggins III932efed2016-12-16 11:39:51 -0500809 cmap.setTablePosition(m_streamBuffer.markPosition());
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400810 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700811 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700812 break;
813 }
814
scroggof9acbe22016-10-25 12:43:21 -0700815 case SkGIFSubBlock: {
scroggo19b91532016-10-24 09:03:26 -0700816 const size_t bytesInBlock = this->getOneByte();
817 if (bytesInBlock)
scroggof9acbe22016-10-25 12:43:21 -0700818 GETN(bytesInBlock, SkGIFLZW);
scroggo19b91532016-10-24 09:03:26 -0700819 else {
820 // Finished parsing one frame; Process next frame.
821 SkASSERT(!m_frames.empty());
822 // Note that some broken GIF files do not have enough LZW blocks to fully
823 // decode all rows but we treat it as frame complete.
824 m_frames.back()->setComplete();
scroggof9acbe22016-10-25 12:43:21 -0700825 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700826 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse) {
827 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400828 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700829 }
830 }
831 break;
832 }
833
scroggof9acbe22016-10-25 12:43:21 -0700834 case SkGIFDone: {
scroggo19b91532016-10-24 09:03:26 -0700835 m_parseCompleted = true;
Leon Scroggins III588fb042017-07-14 16:32:31 -0400836 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700837 }
838
839 default:
840 // We shouldn't ever get here.
841 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700842 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400843 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700844 break;
845 } // switch
846 m_streamBuffer.flush();
847 }
scroggo19b91532016-10-24 09:03:26 -0700848}
849
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400850bool SkGifImageReader::hasTransparency(int transparentPixel, bool isLocalColormapDefined,
851 int localColors) const {
852 const int globalColors = m_globalColorMap.numColors();
853 if (!isLocalColormapDefined && globalColors == 0) {
854 // No color table for this frame, so it is completely transparent.
855 return true;
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500856 }
857
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400858 if (transparentPixel < 0) {
859 SkASSERT(SkGIFColorMap::kNotFound == transparentPixel);
860 return false;
861 }
862
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500863 if (isLocalColormapDefined) {
864 return transparentPixel < localColors;
865 }
866
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500867 // If there is a global color table, it will be parsed before reaching
868 // here. If its numColors is set, it will be defined.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400869 SkASSERT(globalColors > 0);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500870 SkASSERT(m_globalColorMap.isDefined());
871 return transparentPixel < globalColors;
872}
873
scroggo3d3a65c2016-10-24 12:28:30 -0700874void SkGifImageReader::addFrameIfNecessary()
scroggo19b91532016-10-24 09:03:26 -0700875{
876 if (m_frames.empty() || m_frames.back()->isComplete()) {
877 const size_t i = m_frames.size();
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400878 std::unique_ptr<SkGIFFrameContext> frame(new SkGIFFrameContext(this, static_cast<int>(i)));
scroggo19b91532016-10-24 09:03:26 -0700879 m_frames.push_back(std::move(frame));
880 }
881}
882
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400883static SkIRect frame_rect_on_screen(SkIRect frameRect,
884 const SkIRect& screenRect) {
885 if (!frameRect.intersect(screenRect)) {
886 return SkIRect::MakeEmpty();
887 }
888
889 return frameRect;
890}
891
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400892static bool independent(const SkFrame& frame) {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400893 return frame.getRequiredFrame() == SkCodec::kNone;
894}
895
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400896static bool restore_bg(const SkFrame& frame) {
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400897 return frame.getDisposalMethod() == SkCodecAnimation::DisposalMethod::kRestoreBGColor;
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400898}
899
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400900bool SkGIFFrameContext::onReportsAlpha() const {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400901 // Note: We could correct these after decoding - i.e. some frames may turn out to be
902 // independent and opaque if they do not use the transparent pixel, but that would require
903 // checking whether each pixel used the transparent index.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400904 return m_owner->hasTransparency(this->transparentPixel(),
905 m_localColorMap.isDefined(), m_localColorMap.numColors());
906}
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400907
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400908void SkFrameHolder::setAlphaAndRequiredFrame(SkFrame* frame) {
909 const bool reportsAlpha = frame->reportsAlpha();
910 const auto screenRect = SkIRect::MakeWH(fScreenWidth, fScreenHeight);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400911 const auto frameRect = frame_rect_on_screen(frame->frameRect(), screenRect);
912
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400913 const int i = frame->frameId();
914 if (0 == i) {
915 frame->setHasAlpha(reportsAlpha || frameRect != screenRect);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500916 frame->setRequiredFrame(SkCodec::kNone);
917 return;
918 }
919
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400920
921 const bool blendWithPrevFrame = frame->getBlend() == SkCodecAnimation::Blend::kPriorFrame;
922 if ((!reportsAlpha || !blendWithPrevFrame) && frameRect == screenRect) {
923 frame->setHasAlpha(reportsAlpha);
924 frame->setRequiredFrame(SkCodec::kNone);
925 return;
926 }
927
928 const SkFrame* prevFrame = this->getFrame(i-1);
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400929 while (prevFrame->getDisposalMethod() == SkCodecAnimation::DisposalMethod::kRestorePrevious) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400930 const int prevId = prevFrame->frameId();
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400931 if (0 == prevId) {
932 frame->setHasAlpha(true);
933 frame->setRequiredFrame(SkCodec::kNone);
934 return;
935 }
936
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400937 prevFrame = this->getFrame(prevId - 1);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400938 }
939
940 const bool clearPrevFrame = restore_bg(*prevFrame);
941 auto prevFrameRect = frame_rect_on_screen(prevFrame->frameRect(), screenRect);
942
943 if (clearPrevFrame) {
944 if (prevFrameRect == screenRect || independent(*prevFrame)) {
945 frame->setHasAlpha(true);
946 frame->setRequiredFrame(SkCodec::kNone);
947 return;
948 }
949 }
950
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400951 if (reportsAlpha && blendWithPrevFrame) {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400952 // Note: We could be more aggressive here. If prevFrame clears
953 // to background color and covers its required frame (and that
954 // frame is independent), prevFrame could be marked independent.
955 // Would this extra complexity be worth it?
956 frame->setRequiredFrame(prevFrame->frameId());
957 frame->setHasAlpha(prevFrame->hasAlpha() || clearPrevFrame);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500958 return;
959 }
960
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400961 while (frameRect.contains(prevFrameRect)) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400962 const int prevRequiredFrame = prevFrame->getRequiredFrame();
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400963 if (prevRequiredFrame == SkCodec::kNone) {
964 frame->setRequiredFrame(SkCodec::kNone);
965 frame->setHasAlpha(true);
966 return;
967 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500968
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400969 prevFrame = this->getFrame(prevRequiredFrame);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400970 prevFrameRect = frame_rect_on_screen(prevFrame->frameRect(), screenRect);
971 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500972
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400973 if (restore_bg(*prevFrame)) {
974 frame->setHasAlpha(true);
975 if (prevFrameRect == screenRect || independent(*prevFrame)) {
976 frame->setRequiredFrame(SkCodec::kNone);
977 } else {
978 // Note: As above, frame could still be independent, e.g. if
979 // prevFrame covers its required frame and that frame is
980 // independent.
981 frame->setRequiredFrame(prevFrame->frameId());
982 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500983 return;
984 }
985
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400986 SkASSERT(prevFrame->getDisposalMethod() == SkCodecAnimation::DisposalMethod::kKeep);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400987 frame->setRequiredFrame(prevFrame->frameId());
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400988 frame->setHasAlpha(prevFrame->hasAlpha() || (reportsAlpha && !blendWithPrevFrame));
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500989}
990
scroggo19b91532016-10-24 09:03:26 -0700991// FIXME: Move this method to close to doLZW().
Leon Scroggins III45565b62016-12-05 14:56:30 -0500992bool SkGIFLZWContext::prepareToDecode()
scroggo19b91532016-10-24 09:03:26 -0700993{
994 SkASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefined());
995
996 // Since we use a codesize of 1 more than the datasize, we need to ensure
scroggof9acbe22016-10-25 12:43:21 -0700997 // that our datasize is strictly less than the SK_MAX_DICTIONARY_ENTRY_BITS.
998 if (m_frameContext->dataSize() >= SK_MAX_DICTIONARY_ENTRY_BITS)
scroggo19b91532016-10-24 09:03:26 -0700999 return false;
1000 clearCode = 1 << m_frameContext->dataSize();
1001 avail = clearCode + 2;
1002 oldcode = -1;
1003 codesize = m_frameContext->dataSize() + 1;
1004 codemask = (1 << codesize) - 1;
1005 datum = bits = 0;
1006 ipass = m_frameContext->interlaced() ? 1 : 0;
1007 irow = 0;
1008
1009 // We want to know the longest sequence encodable by a dictionary with
scroggof9acbe22016-10-25 12:43:21 -07001010 // SK_MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base
scroggo19b91532016-10-24 09:03:26 -07001011 // values themselves at the beginning of the dictionary, as well as the need
1012 // for a clear code or a termination code, we could use every entry to
1013 // encode a series of multiple values. If the input value stream looked
1014 // like "AAAAA..." (a long string of just one value), the first dictionary
1015 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
scroggof9acbe22016-10-25 12:43:21 -07001016 // the longest sequence would be SK_MAX_DICTIONARY_ENTRIES + 1 values.
scroggo19b91532016-10-24 09:03:26 -07001017 //
1018 // However, we have to account for reserved entries. The first |datasize|
1019 // bits are reserved for the base values, and the next two entries are
1020 // reserved for the clear code and termination code. In theory a GIF can
1021 // set the datasize to 0, meaning we have just two reserved entries, making
scroggof9acbe22016-10-25 12:43:21 -07001022 // the longest sequence (SK_MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since
scroggo19b91532016-10-24 09:03:26 -07001023 // each value is a byte, this is also the number of bytes in the longest
1024 // encodable sequence.
scroggof9acbe22016-10-25 12:43:21 -07001025 const size_t maxBytes = SK_MAX_DICTIONARY_ENTRIES - 1;
scroggo19b91532016-10-24 09:03:26 -07001026
1027 // Now allocate the output buffer. We decode directly into this buffer
1028 // until we have at least one row worth of data, then call outputRow().
1029 // This means worst case we may have (row width - 1) bytes in the buffer
1030 // and then decode a sequence |maxBytes| long to append.
1031 rowBuffer.reset(m_frameContext->width() - 1 + maxBytes);
1032 rowIter = rowBuffer.begin();
1033 rowsRemaining = m_frameContext->height();
1034
1035 // Clearing the whole suffix table lets us be more tolerant of bad data.
1036 for (int i = 0; i < clearCode; ++i) {
1037 suffix[i] = i;
1038 suffixLength[i] = 1;
1039 }
1040 return true;
1041}
1042