blob: 990da5618b325a3a228e109dde5d4ce5309a3207 [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) {
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400347 if (index < 0 || index >= m_frames.count()) {
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 IIIe7503912017-08-30 10:09:42 -0400385 while (m_currentLzwBlock < m_lzwBlocks.count() && m_lzwContext->hasRemainingRows()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500386 const auto& block = m_lzwBlocks[m_currentLzwBlock];
387 const size_t len = block.blockSize;
388
389 sk_sp<SkData> data(streamBuffer->getDataAtPosition(block.blockPosition, len));
390 if (!data) {
391 return false;
392 }
393 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(data->data()), len)) {
scroggo19b91532016-10-24 09:03:26 -0700394 return false;
395 }
396 ++m_currentLzwBlock;
397 }
398
399 // If this frame is data complete then the previous loop must have completely decoded all LZW blocks.
400 // There will be no more decoding for this frame so it's time to cleanup.
401 if (isComplete()) {
402 *frameComplete = true;
403 m_lzwContext.reset();
404 }
405 return true;
406}
407
408// Decode a frame.
scroggof9acbe22016-10-25 12:43:21 -0700409// 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 -0700410// Return true if decoding has progressed. Return false if an error has occurred.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400411bool SkGifImageReader::decode(int frameIndex, bool* frameComplete)
scroggo19b91532016-10-24 09:03:26 -0700412{
scroggof9acbe22016-10-25 12:43:21 -0700413 SkGIFFrameContext* currentFrame = m_frames[frameIndex].get();
scroggo19b91532016-10-24 09:03:26 -0700414
Leon Scroggins III932efed2016-12-16 11:39:51 -0500415 return currentFrame->decode(&m_streamBuffer, m_client, frameComplete);
scroggo19b91532016-10-24 09:03:26 -0700416}
417
418// Parse incoming GIF data stream into internal data structures.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400419SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
scroggo19b91532016-10-24 09:03:26 -0700420{
421 if (m_parseCompleted) {
Leon Scroggins III588fb042017-07-14 16:32:31 -0400422 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700423 }
424
scroggoe71b1a12016-11-01 08:28:28 -0700425 if (SkGIFLoopCountQuery == query && m_loopCount != cLoopCountNotSeen) {
426 // Loop count has already been parsed.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400427 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700428 }
429
scroggof9acbe22016-10-25 12:43:21 -0700430 // SkGIFSizeQuery and SkGIFFrameCountQuery are negative, so this is only meaningful when >= 0.
scroggo19b91532016-10-24 09:03:26 -0700431 const int lastFrameToParse = (int) query;
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400432 if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse
scroggo19b91532016-10-24 09:03:26 -0700433 && m_frames[lastFrameToParse]->isComplete()) {
434 // We have already parsed this frame.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400435 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700436 }
437
438 while (true) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500439 if (!m_streamBuffer.buffer(m_bytesToConsume)) {
440 // The stream does not yet have enough data.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400441 return SkCodec::kIncompleteInput;
scroggo19b91532016-10-24 09:03:26 -0700442 }
443
444 switch (m_state) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500445 case SkGIFLZW: {
scroggo19b91532016-10-24 09:03:26 -0700446 SkASSERT(!m_frames.empty());
Leon Scroggins III932efed2016-12-16 11:39:51 -0500447 auto* frame = m_frames.back().get();
448 frame->addLzwBlock(m_streamBuffer.markPosition(), m_bytesToConsume);
scroggof9acbe22016-10-25 12:43:21 -0700449 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700450 break;
Leon Scroggins III932efed2016-12-16 11:39:51 -0500451 }
scroggof9acbe22016-10-25 12:43:21 -0700452 case SkGIFLZWStart: {
scroggo19b91532016-10-24 09:03:26 -0700453 SkASSERT(!m_frames.empty());
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500454 auto* currentFrame = m_frames.back().get();
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500455
456 currentFrame->setDataSize(this->getOneByte());
scroggof9acbe22016-10-25 12:43:21 -0700457 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700458 break;
459 }
460
scroggof9acbe22016-10-25 12:43:21 -0700461 case SkGIFType: {
scroggo19b91532016-10-24 09:03:26 -0700462 const char* currentComponent = m_streamBuffer.get();
463
464 // All GIF files begin with "GIF87a" or "GIF89a".
465 if (!memcmp(currentComponent, "GIF89a", 6))
466 m_version = 89;
467 else if (!memcmp(currentComponent, "GIF87a", 6))
468 m_version = 87;
469 else {
470 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700471 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400472 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700473 }
scroggof9acbe22016-10-25 12:43:21 -0700474 GETN(7, SkGIFGlobalHeader);
scroggo19b91532016-10-24 09:03:26 -0700475 break;
476 }
477
scroggof9acbe22016-10-25 12:43:21 -0700478 case SkGIFGlobalHeader: {
scroggo19b91532016-10-24 09:03:26 -0700479 const unsigned char* currentComponent =
480 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
481
482 // This is the height and width of the "screen" or frame into which
483 // images are rendered. The individual images can be smaller than
484 // the screen size and located with an origin anywhere within the
485 // screen.
486 // Note that we don't inform the client of the size yet, as it might
487 // change after we read the first frame's image header.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400488 fScreenWidth = GETINT16(currentComponent);
489 fScreenHeight = GETINT16(currentComponent + 2);
scroggo19b91532016-10-24 09:03:26 -0700490
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400491 const int globalColorMapColors = 2 << (currentComponent[4] & 0x07);
scroggo19b91532016-10-24 09:03:26 -0700492
493 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* global map */
494 m_globalColorMap.setNumColors(globalColorMapColors);
scroggof9acbe22016-10-25 12:43:21 -0700495 GETN(SK_BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, SkGIFGlobalColormap);
scroggo19b91532016-10-24 09:03:26 -0700496 break;
497 }
498
scroggof9acbe22016-10-25 12:43:21 -0700499 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700500 break;
501 }
502
scroggof9acbe22016-10-25 12:43:21 -0700503 case SkGIFGlobalColormap: {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500504 m_globalColorMap.setTablePosition(m_streamBuffer.markPosition());
scroggof9acbe22016-10-25 12:43:21 -0700505 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700506 break;
507 }
508
scroggof9acbe22016-10-25 12:43:21 -0700509 case SkGIFImageStart: {
scroggo19b91532016-10-24 09:03:26 -0700510 const char currentComponent = m_streamBuffer.get()[0];
511
512 if (currentComponent == '!') { // extension.
scroggof9acbe22016-10-25 12:43:21 -0700513 GETN(2, SkGIFExtension);
scroggo19b91532016-10-24 09:03:26 -0700514 break;
515 }
516
517 if (currentComponent == ',') { // image separator.
scroggof9acbe22016-10-25 12:43:21 -0700518 GETN(9, SkGIFImageHeader);
scroggo19b91532016-10-24 09:03:26 -0700519 break;
520 }
521
522 // If we get anything other than ',' (image separator), '!'
523 // (extension), or ';' (trailer), there is extraneous data
524 // between blocks. The GIF87a spec tells us to keep reading
525 // until we find an image separator, but GIF89a says such
526 // a file is corrupt. We follow Mozilla's implementation and
527 // proceed as if the file were correctly terminated, so the
528 // GIF will display.
scroggof9acbe22016-10-25 12:43:21 -0700529 GETN(0, SkGIFDone);
scroggo19b91532016-10-24 09:03:26 -0700530 break;
531 }
532
scroggof9acbe22016-10-25 12:43:21 -0700533 case SkGIFExtension: {
scroggo19b91532016-10-24 09:03:26 -0700534 const unsigned char* currentComponent =
535 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
536
537 size_t bytesInBlock = currentComponent[1];
scroggof9acbe22016-10-25 12:43:21 -0700538 SkGIFState exceptionState = SkGIFSkipBlock;
scroggo19b91532016-10-24 09:03:26 -0700539
540 switch (*currentComponent) {
541 case 0xf9:
scroggo19b91532016-10-24 09:03:26 -0700542 // The GIF spec mandates that the GIFControlExtension header block length is 4 bytes,
scroggof9acbe22016-10-25 12:43:21 -0700543 exceptionState = SkGIFControlExtension;
scroggo19b91532016-10-24 09:03:26 -0700544 // and the parser for this block reads 4 bytes, so we must enforce that the buffer
545 // contains at least this many bytes. If the GIF specifies a different length, we
546 // allow that, so long as it's larger; the additional data will simply be ignored.
547 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
548 break;
549
550 // The GIF spec also specifies the lengths of the following two extensions' headers
551 // (as 12 and 11 bytes, respectively). Because we ignore the plain text extension entirely
552 // and sanity-check the actual length of the application extension header before reading it,
553 // we allow GIFs to deviate from these values in either direction. This is important for
554 // real-world compatibility, as GIFs in the wild exist with application extension headers
555 // that are both shorter and longer than 11 bytes.
556 case 0x01:
557 // ignoring plain text extension
558 break;
559
560 case 0xff:
scroggof9acbe22016-10-25 12:43:21 -0700561 exceptionState = SkGIFApplicationExtension;
scroggo19b91532016-10-24 09:03:26 -0700562 break;
563
564 case 0xfe:
scroggof9acbe22016-10-25 12:43:21 -0700565 exceptionState = SkGIFConsumeComment;
scroggo19b91532016-10-24 09:03:26 -0700566 break;
567 }
568
569 if (bytesInBlock)
570 GETN(bytesInBlock, exceptionState);
571 else
scroggof9acbe22016-10-25 12:43:21 -0700572 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700573 break;
574 }
575
scroggof9acbe22016-10-25 12:43:21 -0700576 case SkGIFConsumeBlock: {
scroggo19b91532016-10-24 09:03:26 -0700577 const unsigned char currentComponent = this->getOneByte();
578 if (!currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700579 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700580 else
scroggof9acbe22016-10-25 12:43:21 -0700581 GETN(currentComponent, SkGIFSkipBlock);
scroggo19b91532016-10-24 09:03:26 -0700582 break;
583 }
584
scroggof9acbe22016-10-25 12:43:21 -0700585 case SkGIFSkipBlock: {
586 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700587 break;
588 }
589
scroggof9acbe22016-10-25 12:43:21 -0700590 case SkGIFControlExtension: {
scroggo19b91532016-10-24 09:03:26 -0700591 const unsigned char* currentComponent =
592 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
593
594 addFrameIfNecessary();
scroggof9acbe22016-10-25 12:43:21 -0700595 SkGIFFrameContext* currentFrame = m_frames.back().get();
scroggo19b91532016-10-24 09:03:26 -0700596 if (*currentComponent & 0x1)
597 currentFrame->setTransparentPixel(currentComponent[3]);
598
599 // We ignore the "user input" bit.
600
601 // NOTE: This relies on the values in the FrameDisposalMethod enum
602 // matching those in the GIF spec!
603 int rawDisposalMethod = ((*currentComponent) >> 2) & 0x7;
604 switch (rawDisposalMethod) {
605 case 1:
606 case 2:
607 case 3:
608 currentFrame->setDisposalMethod((SkCodecAnimation::DisposalMethod) rawDisposalMethod);
609 break;
610 case 4:
611 // Some specs say that disposal method 3 is "overwrite previous", others that setting
612 // 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 -0400613 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kRestorePrevious);
scroggo19b91532016-10-24 09:03:26 -0700614 break;
615 default:
616 // Other values use the default.
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400617 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep);
scroggo19b91532016-10-24 09:03:26 -0700618 break;
619 }
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400620 currentFrame->setDuration(GETINT16(currentComponent + 1) * 10);
scroggof9acbe22016-10-25 12:43:21 -0700621 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700622 break;
623 }
624
scroggof9acbe22016-10-25 12:43:21 -0700625 case SkGIFCommentExtension: {
scroggo19b91532016-10-24 09:03:26 -0700626 const unsigned char currentComponent = this->getOneByte();
627 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700628 GETN(currentComponent, SkGIFConsumeComment);
scroggo19b91532016-10-24 09:03:26 -0700629 else
scroggof9acbe22016-10-25 12:43:21 -0700630 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700631 break;
632 }
633
scroggof9acbe22016-10-25 12:43:21 -0700634 case SkGIFConsumeComment: {
635 GETN(1, SkGIFCommentExtension);
scroggo19b91532016-10-24 09:03:26 -0700636 break;
637 }
638
scroggof9acbe22016-10-25 12:43:21 -0700639 case SkGIFApplicationExtension: {
scroggo19b91532016-10-24 09:03:26 -0700640 // Check for netscape application extension.
Leon Scroggins III932efed2016-12-16 11:39:51 -0500641 if (m_bytesToConsume == 11) {
scroggo19b91532016-10-24 09:03:26 -0700642 const unsigned char* currentComponent =
643 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
644
645 if (!memcmp(currentComponent, "NETSCAPE2.0", 11) || !memcmp(currentComponent, "ANIMEXTS1.0", 11))
scroggof9acbe22016-10-25 12:43:21 -0700646 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700647 }
648
scroggof9acbe22016-10-25 12:43:21 -0700649 if (m_state != SkGIFNetscapeExtensionBlock)
650 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700651 break;
652 }
653
654 // Netscape-specific GIF extension: animation looping.
scroggof9acbe22016-10-25 12:43:21 -0700655 case SkGIFNetscapeExtensionBlock: {
scroggo19b91532016-10-24 09:03:26 -0700656 const int currentComponent = this->getOneByte();
scroggof9acbe22016-10-25 12:43:21 -0700657 // SkGIFConsumeNetscapeExtension always reads 3 bytes from the stream; we should at least wait for this amount.
scroggo19b91532016-10-24 09:03:26 -0700658 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700659 GETN(std::max(3, currentComponent), SkGIFConsumeNetscapeExtension);
scroggo19b91532016-10-24 09:03:26 -0700660 else
scroggof9acbe22016-10-25 12:43:21 -0700661 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700662 break;
663 }
664
665 // Parse netscape-specific application extensions
scroggof9acbe22016-10-25 12:43:21 -0700666 case SkGIFConsumeNetscapeExtension: {
scroggo19b91532016-10-24 09:03:26 -0700667 const unsigned char* currentComponent =
668 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
669
670 int netscapeExtension = currentComponent[0] & 7;
671
672 // Loop entire animation specified # of times. Only read the loop count during the first iteration.
673 if (netscapeExtension == 1) {
674 m_loopCount = GETINT16(currentComponent + 1);
675
676 // Zero loop count is infinite animation loop request.
677 if (!m_loopCount)
scroggoe71b1a12016-11-01 08:28:28 -0700678 m_loopCount = SkCodec::kRepetitionCountInfinite;
scroggo19b91532016-10-24 09:03:26 -0700679
scroggof9acbe22016-10-25 12:43:21 -0700680 GETN(1, SkGIFNetscapeExtensionBlock);
scroggoe71b1a12016-11-01 08:28:28 -0700681
682 if (SkGIFLoopCountQuery == query) {
683 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400684 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700685 }
scroggo19b91532016-10-24 09:03:26 -0700686 } else if (netscapeExtension == 2) {
687 // Wait for specified # of bytes to enter buffer.
688
689 // Don't do this, this extension doesn't exist (isn't used at all)
690 // and doesn't do anything, as our streaming/buffering takes care of it all...
691 // See: http://semmix.pl/color/exgraf/eeg24.htm
scroggof9acbe22016-10-25 12:43:21 -0700692 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700693 } else {
694 // 0,3-7 are yet to be defined netscape extension codes
695 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700696 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400697 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700698 }
699 break;
700 }
701
scroggof9acbe22016-10-25 12:43:21 -0700702 case SkGIFImageHeader: {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400703 int height, width, xOffset, yOffset;
scroggo19b91532016-10-24 09:03:26 -0700704 const unsigned char* currentComponent =
705 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
706
707 /* Get image offsets, with respect to the screen origin */
708 xOffset = GETINT16(currentComponent);
709 yOffset = GETINT16(currentComponent + 2);
710
711 /* Get image width and height. */
712 width = GETINT16(currentComponent + 4);
713 height = GETINT16(currentComponent + 6);
714
715 // Some GIF files have frames that don't fit in the specified
716 // overall image size. For the first frame, we can simply enlarge
717 // the image size to allow the frame to be visible. We can't do
718 // this on subsequent frames because the rest of the decoding
719 // infrastructure assumes the image size won't change as we
720 // continue decoding, so any subsequent frames that are even
721 // larger will be cropped.
722 // Luckily, handling just the first frame is sufficient to deal
723 // with most cases, e.g. ones where the image size is erroneously
724 // set to zero, since usually the first frame completely fills
725 // the image.
726 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400727 fScreenHeight = std::max(fScreenHeight, yOffset + height);
728 fScreenWidth = std::max(fScreenWidth, xOffset + width);
scroggo19b91532016-10-24 09:03:26 -0700729 }
730
731 // NOTE: Chromium placed this block after setHeaderDefined, down
732 // below we returned true when asked for the size. So Chromium
733 // created an image which would fail. Is this the correct behavior?
734 // We choose to return false early, so we will not create an
735 // SkCodec.
736
737 // Work around more broken GIF files that have zero image width or
738 // height.
739 if (!height || !width) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400740 height = fScreenHeight;
741 width = fScreenWidth;
scroggo19b91532016-10-24 09:03:26 -0700742 if (!height || !width) {
743 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700744 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400745 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700746 }
747 }
748
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400749 const bool isLocalColormapDefined = SkToBool(currentComponent[8] & 0x80);
scroggo19b91532016-10-24 09:03:26 -0700750 // The three low-order bits of currentComponent[8] specify the bits per pixel.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400751 const int numColors = 2 << (currentComponent[8] & 0x7);
scroggo19b91532016-10-24 09:03:26 -0700752 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400753 const int transPix = m_frames.empty() ? SkGIFColorMap::kNotFound
754 : m_frames[0]->transparentPixel();
755 if (this->hasTransparency(transPix,
756 isLocalColormapDefined, numColors))
757 {
scroggo19b91532016-10-24 09:03:26 -0700758 m_firstFrameHasAlpha = true;
scroggo19b91532016-10-24 09:03:26 -0700759 } else {
760 const bool frameIsSubset = xOffset > 0 || yOffset > 0
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400761 || width < fScreenWidth
762 || height < fScreenHeight;
scroggo19b91532016-10-24 09:03:26 -0700763 m_firstFrameHasAlpha = frameIsSubset;
scroggo19b91532016-10-24 09:03:26 -0700764 }
765 }
766
Leon Scroggins III4993b952016-12-08 11:54:04 -0500767 addFrameIfNecessary();
768 SkGIFFrameContext* currentFrame = m_frames.back().get();
769 currentFrame->setHeaderDefined();
770
scroggof9acbe22016-10-25 12:43:21 -0700771 if (query == SkGIFSizeQuery) {
scroggo19b91532016-10-24 09:03:26 -0700772 // The decoder needs to stop, so we return here, before
773 // flushing the buffer. Next time through, we'll be in the same
774 // state, requiring the same amount in the buffer.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400775 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700776 }
777
scroggo19b91532016-10-24 09:03:26 -0700778
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400779 currentFrame->setXYWH(xOffset, yOffset, width, height);
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400780 currentFrame->setInterlaced(SkToBool(currentComponent[8] & 0x40));
scroggo19b91532016-10-24 09:03:26 -0700781
782 // Overlaying interlaced, transparent GIFs over
783 // existing image data using the Haeberli display hack
784 // requires saving the underlying image in order to
785 // avoid jaggies at the transparency edges. We are
786 // unprepared to deal with that, so don't display such
787 // images progressively. Which means only the first
788 // frame can be progressively displayed.
789 // FIXME: It is possible that a non-transparent frame
790 // can be interlaced and progressively displayed.
791 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
792
793 if (isLocalColormapDefined) {
794 currentFrame->localColorMap().setNumColors(numColors);
scroggof9acbe22016-10-25 12:43:21 -0700795 GETN(SK_BYTES_PER_COLORMAP_ENTRY * numColors, SkGIFImageColormap);
scroggo19b91532016-10-24 09:03:26 -0700796 break;
797 }
798
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400799 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700800 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700801 break;
802 }
803
scroggof9acbe22016-10-25 12:43:21 -0700804 case SkGIFImageColormap: {
scroggo19b91532016-10-24 09:03:26 -0700805 SkASSERT(!m_frames.empty());
Leon Scroggins IIIe4ba1052017-01-30 13:55:14 -0500806 auto* currentFrame = m_frames.back().get();
807 auto& cmap = currentFrame->localColorMap();
Leon Scroggins III932efed2016-12-16 11:39:51 -0500808 cmap.setTablePosition(m_streamBuffer.markPosition());
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400809 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700810 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700811 break;
812 }
813
scroggof9acbe22016-10-25 12:43:21 -0700814 case SkGIFSubBlock: {
scroggo19b91532016-10-24 09:03:26 -0700815 const size_t bytesInBlock = this->getOneByte();
816 if (bytesInBlock)
scroggof9acbe22016-10-25 12:43:21 -0700817 GETN(bytesInBlock, SkGIFLZW);
scroggo19b91532016-10-24 09:03:26 -0700818 else {
819 // Finished parsing one frame; Process next frame.
820 SkASSERT(!m_frames.empty());
821 // Note that some broken GIF files do not have enough LZW blocks to fully
822 // decode all rows but we treat it as frame complete.
823 m_frames.back()->setComplete();
scroggof9acbe22016-10-25 12:43:21 -0700824 GETN(1, SkGIFImageStart);
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400825 if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse) {
scroggo19b91532016-10-24 09:03:26 -0700826 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400827 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700828 }
829 }
830 break;
831 }
832
scroggof9acbe22016-10-25 12:43:21 -0700833 case SkGIFDone: {
scroggo19b91532016-10-24 09:03:26 -0700834 m_parseCompleted = true;
Leon Scroggins III588fb042017-07-14 16:32:31 -0400835 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700836 }
837
838 default:
839 // We shouldn't ever get here.
840 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700841 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400842 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700843 break;
844 } // switch
845 m_streamBuffer.flush();
846 }
scroggo19b91532016-10-24 09:03:26 -0700847}
848
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400849bool SkGifImageReader::hasTransparency(int transparentPixel, bool isLocalColormapDefined,
850 int localColors) const {
851 const int globalColors = m_globalColorMap.numColors();
852 if (!isLocalColormapDefined && globalColors == 0) {
853 // No color table for this frame, so it is completely transparent.
854 return true;
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500855 }
856
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400857 if (transparentPixel < 0) {
858 SkASSERT(SkGIFColorMap::kNotFound == transparentPixel);
859 return false;
860 }
861
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500862 if (isLocalColormapDefined) {
863 return transparentPixel < localColors;
864 }
865
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500866 // If there is a global color table, it will be parsed before reaching
867 // here. If its numColors is set, it will be defined.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400868 SkASSERT(globalColors > 0);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500869 SkASSERT(m_globalColorMap.isDefined());
870 return transparentPixel < globalColors;
871}
872
scroggo3d3a65c2016-10-24 12:28:30 -0700873void SkGifImageReader::addFrameIfNecessary()
scroggo19b91532016-10-24 09:03:26 -0700874{
875 if (m_frames.empty() || m_frames.back()->isComplete()) {
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400876 const int i = m_frames.count();
877 m_frames.emplace_back(new SkGIFFrameContext(this, i));
scroggo19b91532016-10-24 09:03:26 -0700878 }
879}
880
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400881static SkIRect frame_rect_on_screen(SkIRect frameRect,
882 const SkIRect& screenRect) {
883 if (!frameRect.intersect(screenRect)) {
884 return SkIRect::MakeEmpty();
885 }
886
887 return frameRect;
888}
889
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400890static bool independent(const SkFrame& frame) {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400891 return frame.getRequiredFrame() == SkCodec::kNone;
892}
893
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400894static bool restore_bg(const SkFrame& frame) {
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400895 return frame.getDisposalMethod() == SkCodecAnimation::DisposalMethod::kRestoreBGColor;
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400896}
897
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400898bool SkGIFFrameContext::onReportsAlpha() const {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400899 // Note: We could correct these after decoding - i.e. some frames may turn out to be
900 // independent and opaque if they do not use the transparent pixel, but that would require
901 // checking whether each pixel used the transparent index.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400902 return m_owner->hasTransparency(this->transparentPixel(),
903 m_localColorMap.isDefined(), m_localColorMap.numColors());
904}
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400905
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400906void SkFrameHolder::setAlphaAndRequiredFrame(SkFrame* frame) {
907 const bool reportsAlpha = frame->reportsAlpha();
908 const auto screenRect = SkIRect::MakeWH(fScreenWidth, fScreenHeight);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400909 const auto frameRect = frame_rect_on_screen(frame->frameRect(), screenRect);
910
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400911 const int i = frame->frameId();
912 if (0 == i) {
913 frame->setHasAlpha(reportsAlpha || frameRect != screenRect);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500914 frame->setRequiredFrame(SkCodec::kNone);
915 return;
916 }
917
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400918
919 const bool blendWithPrevFrame = frame->getBlend() == SkCodecAnimation::Blend::kPriorFrame;
920 if ((!reportsAlpha || !blendWithPrevFrame) && frameRect == screenRect) {
921 frame->setHasAlpha(reportsAlpha);
922 frame->setRequiredFrame(SkCodec::kNone);
923 return;
924 }
925
926 const SkFrame* prevFrame = this->getFrame(i-1);
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400927 while (prevFrame->getDisposalMethod() == SkCodecAnimation::DisposalMethod::kRestorePrevious) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400928 const int prevId = prevFrame->frameId();
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400929 if (0 == prevId) {
930 frame->setHasAlpha(true);
931 frame->setRequiredFrame(SkCodec::kNone);
932 return;
933 }
934
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400935 prevFrame = this->getFrame(prevId - 1);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400936 }
937
938 const bool clearPrevFrame = restore_bg(*prevFrame);
939 auto prevFrameRect = frame_rect_on_screen(prevFrame->frameRect(), screenRect);
940
941 if (clearPrevFrame) {
942 if (prevFrameRect == screenRect || independent(*prevFrame)) {
943 frame->setHasAlpha(true);
944 frame->setRequiredFrame(SkCodec::kNone);
945 return;
946 }
947 }
948
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400949 if (reportsAlpha && blendWithPrevFrame) {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400950 // Note: We could be more aggressive here. If prevFrame clears
951 // to background color and covers its required frame (and that
952 // frame is independent), prevFrame could be marked independent.
953 // Would this extra complexity be worth it?
954 frame->setRequiredFrame(prevFrame->frameId());
955 frame->setHasAlpha(prevFrame->hasAlpha() || clearPrevFrame);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500956 return;
957 }
958
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400959 while (frameRect.contains(prevFrameRect)) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400960 const int prevRequiredFrame = prevFrame->getRequiredFrame();
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400961 if (prevRequiredFrame == SkCodec::kNone) {
962 frame->setRequiredFrame(SkCodec::kNone);
963 frame->setHasAlpha(true);
964 return;
965 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500966
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400967 prevFrame = this->getFrame(prevRequiredFrame);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400968 prevFrameRect = frame_rect_on_screen(prevFrame->frameRect(), screenRect);
969 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500970
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400971 if (restore_bg(*prevFrame)) {
972 frame->setHasAlpha(true);
973 if (prevFrameRect == screenRect || independent(*prevFrame)) {
974 frame->setRequiredFrame(SkCodec::kNone);
975 } else {
976 // Note: As above, frame could still be independent, e.g. if
977 // prevFrame covers its required frame and that frame is
978 // independent.
979 frame->setRequiredFrame(prevFrame->frameId());
980 }
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500981 return;
982 }
983
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400984 SkASSERT(prevFrame->getDisposalMethod() == SkCodecAnimation::DisposalMethod::kKeep);
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400985 frame->setRequiredFrame(prevFrame->frameId());
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400986 frame->setHasAlpha(prevFrame->hasAlpha() || (reportsAlpha && !blendWithPrevFrame));
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500987}
988
scroggo19b91532016-10-24 09:03:26 -0700989// FIXME: Move this method to close to doLZW().
Leon Scroggins III45565b62016-12-05 14:56:30 -0500990bool SkGIFLZWContext::prepareToDecode()
scroggo19b91532016-10-24 09:03:26 -0700991{
992 SkASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefined());
993
994 // Since we use a codesize of 1 more than the datasize, we need to ensure
scroggof9acbe22016-10-25 12:43:21 -0700995 // that our datasize is strictly less than the SK_MAX_DICTIONARY_ENTRY_BITS.
996 if (m_frameContext->dataSize() >= SK_MAX_DICTIONARY_ENTRY_BITS)
scroggo19b91532016-10-24 09:03:26 -0700997 return false;
998 clearCode = 1 << m_frameContext->dataSize();
999 avail = clearCode + 2;
1000 oldcode = -1;
1001 codesize = m_frameContext->dataSize() + 1;
1002 codemask = (1 << codesize) - 1;
1003 datum = bits = 0;
1004 ipass = m_frameContext->interlaced() ? 1 : 0;
1005 irow = 0;
1006
1007 // We want to know the longest sequence encodable by a dictionary with
scroggof9acbe22016-10-25 12:43:21 -07001008 // SK_MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base
scroggo19b91532016-10-24 09:03:26 -07001009 // values themselves at the beginning of the dictionary, as well as the need
1010 // for a clear code or a termination code, we could use every entry to
1011 // encode a series of multiple values. If the input value stream looked
1012 // like "AAAAA..." (a long string of just one value), the first dictionary
1013 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
scroggof9acbe22016-10-25 12:43:21 -07001014 // the longest sequence would be SK_MAX_DICTIONARY_ENTRIES + 1 values.
scroggo19b91532016-10-24 09:03:26 -07001015 //
1016 // However, we have to account for reserved entries. The first |datasize|
1017 // bits are reserved for the base values, and the next two entries are
1018 // reserved for the clear code and termination code. In theory a GIF can
1019 // set the datasize to 0, meaning we have just two reserved entries, making
scroggof9acbe22016-10-25 12:43:21 -07001020 // the longest sequence (SK_MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since
scroggo19b91532016-10-24 09:03:26 -07001021 // each value is a byte, this is also the number of bytes in the longest
1022 // encodable sequence.
scroggof9acbe22016-10-25 12:43:21 -07001023 const size_t maxBytes = SK_MAX_DICTIONARY_ENTRIES - 1;
scroggo19b91532016-10-24 09:03:26 -07001024
1025 // Now allocate the output buffer. We decode directly into this buffer
1026 // until we have at least one row worth of data, then call outputRow().
1027 // This means worst case we may have (row width - 1) bytes in the buffer
1028 // and then decode a sequence |maxBytes| long to append.
1029 rowBuffer.reset(m_frameContext->width() - 1 + maxBytes);
1030 rowIter = rowBuffer.begin();
1031 rowsRemaining = m_frameContext->height();
1032
1033 // Clearing the whole suffix table lets us be more tolerant of bad data.
1034 for (int i = 0; i < clearCode; ++i) {
1035 suffix[i] = i;
1036 suffixLength[i] = 1;
1037 }
1038 return true;
1039}
1040