blob: 0cb77bab79213da5dca3e7a0b7cb00dbbe6b5e3d [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
Chris Blume0b5e7d12017-09-27 13:23:41 -070099namespace {
100 bool is_palette_index_valid(int transparentIndex) {
101 // -1 is a signal that there is no transparent index.
102 // Otherwise, it is encoded in 8 bits, and all 256 values are considered
103 // valid since a GIF may use an index outside of the palette to be
104 // transparent.
105 return transparentIndex >= 0;
106 }
107} // anonymous namespace
108
scroggo19b91532016-10-24 09:03:26 -0700109// Send the data to the display front-end.
Leon Scroggins III223ec292017-08-22 14:13:15 -0400110void SkGIFLZWContext::outputRow(const unsigned char* rowBegin)
scroggo19b91532016-10-24 09:03:26 -0700111{
112 int drowStart = irow;
113 int drowEnd = irow;
114
115 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while
116 // displaying to diminish the "venetian-blind" effect as the image is
117 // loaded. Adjust pixel vertical positions to avoid the appearance of the
118 // image crawling up the screen as successive passes are drawn.
119 if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass < 4) {
120 unsigned rowDup = 0;
121 unsigned rowShift = 0;
122
123 switch (ipass) {
124 case 1:
125 rowDup = 7;
126 rowShift = 3;
127 break;
128 case 2:
129 rowDup = 3;
130 rowShift = 1;
131 break;
132 case 3:
133 rowDup = 1;
134 rowShift = 0;
135 break;
136 default:
137 break;
138 }
139
140 drowStart -= rowShift;
141 drowEnd = drowStart + rowDup;
142
143 // Extend if bottom edge isn't covered because of the shift upward.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400144 if ((unsigned)((m_frameContext->height() - 1) - drowEnd) <= rowShift)
scroggo19b91532016-10-24 09:03:26 -0700145 drowEnd = m_frameContext->height() - 1;
146
147 // Clamp first and last rows to upper and lower edge of image.
148 if (drowStart < 0)
149 drowStart = 0;
150
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400151 if (drowEnd >= m_frameContext->height())
scroggo19b91532016-10-24 09:03:26 -0700152 drowEnd = m_frameContext->height() - 1;
153 }
154
155 // Protect against too much image data.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400156 if (drowStart >= m_frameContext->height())
Leon Scroggins III223ec292017-08-22 14:13:15 -0400157 return;
scroggo19b91532016-10-24 09:03:26 -0700158
159 // CALLBACK: Let the client know we have decoded a row.
Nigel Tao66bc5242018-08-22 10:56:03 +1000160 const bool writeTransparentPixels =
161 SkCodec::kNoFrame == m_frameContext->getRequiredFrame();
Leon Scroggins III223ec292017-08-22 14:13:15 -0400162 m_client->haveDecodedRow(m_frameContext->frameId(), rowBegin,
163 drowStart, drowEnd - drowStart + 1, writeTransparentPixels);
scroggo19b91532016-10-24 09:03:26 -0700164
165 if (!m_frameContext->interlaced())
166 irow++;
167 else {
168 do {
169 switch (ipass) {
170 case 1:
171 irow += 8;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400172 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700173 ipass++;
174 irow = 4;
175 }
176 break;
177
178 case 2:
179 irow += 8;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400180 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700181 ipass++;
182 irow = 2;
183 }
184 break;
185
186 case 3:
187 irow += 4;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400188 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700189 ipass++;
190 irow = 1;
191 }
192 break;
193
194 case 4:
195 irow += 2;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400196 if (irow >= (unsigned) m_frameContext->height()) {
scroggo19b91532016-10-24 09:03:26 -0700197 ipass++;
198 irow = 0;
199 }
200 break;
201
202 default:
203 break;
204 }
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400205 } while (irow > (unsigned) (m_frameContext->height() - 1));
scroggo19b91532016-10-24 09:03:26 -0700206 }
scroggo19b91532016-10-24 09:03:26 -0700207}
208
209// Perform Lempel-Ziv-Welch decoding.
210// 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 -0700211// 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 -0700212bool SkGIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock)
scroggo19b91532016-10-24 09:03:26 -0700213{
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400214 const int width = m_frameContext->width();
scroggo19b91532016-10-24 09:03:26 -0700215
216 if (rowIter == rowBuffer.end())
217 return true;
218
219 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) {
220 // Feed the next byte into the decoder's 32-bit input buffer.
221 datum += ((int) *ch) << bits;
222 bits += 8;
223
224 // Check for underflow of decoder's 32-bit input buffer.
225 while (bits >= codesize) {
226 // Get the leading variable-length symbol from the data stream.
227 int code = datum & codemask;
228 datum >>= codesize;
229 bits -= codesize;
230
231 // Reset the dictionary to its original state, if requested.
232 if (code == clearCode) {
233 codesize = m_frameContext->dataSize() + 1;
234 codemask = (1 << codesize) - 1;
235 avail = clearCode + 2;
236 oldcode = -1;
237 continue;
238 }
239
240 // Check for explicit end-of-stream code.
241 if (code == (clearCode + 1)) {
242 // end-of-stream should only appear after all image data.
243 if (!rowsRemaining)
244 return true;
245 return false;
246 }
247
248 const int tempCode = code;
249 unsigned short codeLength = 0;
250 if (code < avail) {
251 // This is a pre-existing code, so we already know what it
252 // encodes.
253 codeLength = suffixLength[code];
254 rowIter += codeLength;
255 } else if (code == avail && oldcode != -1) {
256 // This is a new code just being added to the dictionary.
257 // It must encode the contents of the previous code, plus
258 // the first character of the previous code again.
259 codeLength = suffixLength[oldcode] + 1;
260 rowIter += codeLength;
261 *--rowIter = firstchar;
262 code = oldcode;
263 } else {
264 // This is an invalid code. The dictionary is just initialized
265 // and the code is incomplete. We don't know how to handle
266 // this case.
267 return false;
268 }
269
270 while (code >= clearCode) {
271 *--rowIter = suffix[code];
272 code = prefix[code];
273 }
274
275 *--rowIter = firstchar = suffix[code];
276
277 // Define a new codeword in the dictionary as long as we've read
278 // more than one value from the stream.
scroggof9acbe22016-10-25 12:43:21 -0700279 if (avail < SK_MAX_DICTIONARY_ENTRIES && oldcode != -1) {
scroggo19b91532016-10-24 09:03:26 -0700280 prefix[avail] = oldcode;
281 suffix[avail] = firstchar;
282 suffixLength[avail] = suffixLength[oldcode] + 1;
283 ++avail;
284
285 // If we've used up all the codewords of a given length
286 // increase the length of codewords by one bit, but don't
287 // exceed the specified maximum codeword size.
scroggof9acbe22016-10-25 12:43:21 -0700288 if (!(avail & codemask) && avail < SK_MAX_DICTIONARY_ENTRIES) {
scroggo19b91532016-10-24 09:03:26 -0700289 ++codesize;
290 codemask += avail;
291 }
292 }
293 oldcode = tempCode;
294 rowIter += codeLength;
295
296 // Output as many rows as possible.
297 unsigned char* rowBegin = rowBuffer.begin();
298 for (; rowBegin + width <= rowIter; rowBegin += width) {
Leon Scroggins III223ec292017-08-22 14:13:15 -0400299 outputRow(rowBegin);
scroggo19b91532016-10-24 09:03:26 -0700300 rowsRemaining--;
301 if (!rowsRemaining)
302 return true;
303 }
304
305 if (rowBegin != rowBuffer.begin()) {
306 // Move the remaining bytes to the beginning of the buffer.
307 const size_t bytesToCopy = rowIter - rowBegin;
308 memcpy(&rowBuffer.front(), rowBegin, bytesToCopy);
309 rowIter = rowBuffer.begin() + bytesToCopy;
310 }
311 }
312 }
313 return true;
314}
315
Leon Scroggins III932efed2016-12-16 11:39:51 -0500316sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkColorType colorType,
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400317 int transparentPixel) const
scroggo19b91532016-10-24 09:03:26 -0700318{
319 if (!m_isDefined)
320 return nullptr;
321
322 const PackColorProc proc = choose_pack_color_proc(false, colorType);
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500323 if (m_table && proc == m_packColorProc && m_transPixel == transparentPixel) {
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400324 SkASSERT(transparentPixel == kNotFound || transparentPixel > m_table->count()
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500325 || m_table->operator[](transparentPixel) == SK_ColorTRANSPARENT);
326 // This SkColorTable has already been built with the same transparent color and
327 // packing proc. Reuse it.
328 return m_table;
scroggo19b91532016-10-24 09:03:26 -0700329 }
330 m_packColorProc = proc;
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500331 m_transPixel = transparentPixel;
scroggo19b91532016-10-24 09:03:26 -0700332
Leon Scroggins III932efed2016-12-16 11:39:51 -0500333 const size_t bytes = m_colors * SK_BYTES_PER_COLORMAP_ENTRY;
334 sk_sp<SkData> rawData(streamBuffer->getDataAtPosition(m_position, bytes));
335 if (!rawData) {
336 return nullptr;
337 }
338
scroggof9acbe22016-10-25 12:43:21 -0700339 SkASSERT(m_colors <= SK_MAX_COLORS);
Leon Scroggins III932efed2016-12-16 11:39:51 -0500340 const uint8_t* srcColormap = rawData->bytes();
scroggof9acbe22016-10-25 12:43:21 -0700341 SkPMColor colorStorage[SK_MAX_COLORS];
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400342 for (int i = 0; i < m_colors; i++) {
scroggo19b91532016-10-24 09:03:26 -0700343 if (i == transparentPixel) {
344 colorStorage[i] = SK_ColorTRANSPARENT;
345 } else {
346 colorStorage[i] = proc(255, srcColormap[0], srcColormap[1], srcColormap[2]);
347 }
scroggof9acbe22016-10-25 12:43:21 -0700348 srcColormap += SK_BYTES_PER_COLORMAP_ENTRY;
scroggo19b91532016-10-24 09:03:26 -0700349 }
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400350 for (int i = m_colors; i < SK_MAX_COLORS; i++) {
scroggo19b91532016-10-24 09:03:26 -0700351 colorStorage[i] = SK_ColorTRANSPARENT;
352 }
scroggof9acbe22016-10-25 12:43:21 -0700353 m_table = sk_sp<SkColorTable>(new SkColorTable(colorStorage, SK_MAX_COLORS));
scroggo19b91532016-10-24 09:03:26 -0700354 return m_table;
355}
356
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400357sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, int index) {
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400358 if (index < 0 || index >= m_frames.count()) {
scroggo19b91532016-10-24 09:03:26 -0700359 return nullptr;
360 }
361
scroggof9acbe22016-10-25 12:43:21 -0700362 const SkGIFFrameContext* frameContext = m_frames[index].get();
363 const SkGIFColorMap& localColorMap = frameContext->localColorMap();
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400364 const int transPix = frameContext->transparentPixel();
scroggo19b91532016-10-24 09:03:26 -0700365 if (localColorMap.isDefined()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500366 return localColorMap.buildTable(&m_streamBuffer, colorType, transPix);
scroggo19b91532016-10-24 09:03:26 -0700367 }
368 if (m_globalColorMap.isDefined()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500369 return m_globalColorMap.buildTable(&m_streamBuffer, colorType, transPix);
scroggo19b91532016-10-24 09:03:26 -0700370 }
371 return nullptr;
372}
373
374// Perform decoding for this frame. frameComplete will be true if the entire frame is decoded.
scroggo3d3a65c2016-10-24 12:28:30 -0700375// 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 -0700376// 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 -0500377bool SkGIFFrameContext::decode(SkStreamBuffer* streamBuffer, SkGifCodec* client,
378 bool* frameComplete)
scroggo19b91532016-10-24 09:03:26 -0700379{
380 *frameComplete = false;
381 if (!m_lzwContext) {
scroggof9acbe22016-10-25 12:43:21 -0700382 // Wait for more data to properly initialize SkGIFLZWContext.
scroggo19b91532016-10-24 09:03:26 -0700383 if (!isDataSizeDefined() || !isHeaderDefined())
384 return true;
385
scroggof9acbe22016-10-25 12:43:21 -0700386 m_lzwContext.reset(new SkGIFLZWContext(client, this));
Leon Scroggins III45565b62016-12-05 14:56:30 -0500387 if (!m_lzwContext->prepareToDecode()) {
scroggo19b91532016-10-24 09:03:26 -0700388 m_lzwContext.reset();
389 return false;
390 }
391
392 m_currentLzwBlock = 0;
393 }
394
395 // 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 -0400396 while (m_currentLzwBlock < m_lzwBlocks.count() && m_lzwContext->hasRemainingRows()) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500397 const auto& block = m_lzwBlocks[m_currentLzwBlock];
398 const size_t len = block.blockSize;
399
400 sk_sp<SkData> data(streamBuffer->getDataAtPosition(block.blockPosition, len));
401 if (!data) {
402 return false;
403 }
404 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(data->data()), len)) {
scroggo19b91532016-10-24 09:03:26 -0700405 return false;
406 }
407 ++m_currentLzwBlock;
408 }
409
410 // If this frame is data complete then the previous loop must have completely decoded all LZW blocks.
411 // There will be no more decoding for this frame so it's time to cleanup.
412 if (isComplete()) {
413 *frameComplete = true;
414 m_lzwContext.reset();
415 }
416 return true;
417}
418
419// Decode a frame.
scroggof9acbe22016-10-25 12:43:21 -0700420// 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 -0700421// Return true if decoding has progressed. Return false if an error has occurred.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400422bool SkGifImageReader::decode(int frameIndex, bool* frameComplete)
scroggo19b91532016-10-24 09:03:26 -0700423{
scroggof9acbe22016-10-25 12:43:21 -0700424 SkGIFFrameContext* currentFrame = m_frames[frameIndex].get();
scroggo19b91532016-10-24 09:03:26 -0700425
Leon Scroggins III932efed2016-12-16 11:39:51 -0500426 return currentFrame->decode(&m_streamBuffer, m_client, frameComplete);
scroggo19b91532016-10-24 09:03:26 -0700427}
428
429// Parse incoming GIF data stream into internal data structures.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400430SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
scroggo19b91532016-10-24 09:03:26 -0700431{
432 if (m_parseCompleted) {
Leon Scroggins III588fb042017-07-14 16:32:31 -0400433 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700434 }
435
scroggoe71b1a12016-11-01 08:28:28 -0700436 if (SkGIFLoopCountQuery == query && m_loopCount != cLoopCountNotSeen) {
437 // Loop count has already been parsed.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400438 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700439 }
440
scroggof9acbe22016-10-25 12:43:21 -0700441 // SkGIFSizeQuery and SkGIFFrameCountQuery are negative, so this is only meaningful when >= 0.
scroggo19b91532016-10-24 09:03:26 -0700442 const int lastFrameToParse = (int) query;
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400443 if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse
scroggo19b91532016-10-24 09:03:26 -0700444 && m_frames[lastFrameToParse]->isComplete()) {
445 // We have already parsed this frame.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400446 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700447 }
448
449 while (true) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500450 if (!m_streamBuffer.buffer(m_bytesToConsume)) {
451 // The stream does not yet have enough data.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400452 return SkCodec::kIncompleteInput;
scroggo19b91532016-10-24 09:03:26 -0700453 }
454
455 switch (m_state) {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500456 case SkGIFLZW: {
scroggo19b91532016-10-24 09:03:26 -0700457 SkASSERT(!m_frames.empty());
Leon Scroggins III932efed2016-12-16 11:39:51 -0500458 auto* frame = m_frames.back().get();
459 frame->addLzwBlock(m_streamBuffer.markPosition(), m_bytesToConsume);
scroggof9acbe22016-10-25 12:43:21 -0700460 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700461 break;
Leon Scroggins III932efed2016-12-16 11:39:51 -0500462 }
scroggof9acbe22016-10-25 12:43:21 -0700463 case SkGIFLZWStart: {
scroggo19b91532016-10-24 09:03:26 -0700464 SkASSERT(!m_frames.empty());
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500465 auto* currentFrame = m_frames.back().get();
Leon Scroggins IIIb0b625b2016-12-22 16:40:24 -0500466
467 currentFrame->setDataSize(this->getOneByte());
scroggof9acbe22016-10-25 12:43:21 -0700468 GETN(1, SkGIFSubBlock);
scroggo19b91532016-10-24 09:03:26 -0700469 break;
470 }
471
scroggof9acbe22016-10-25 12:43:21 -0700472 case SkGIFType: {
scroggo19b91532016-10-24 09:03:26 -0700473 const char* currentComponent = m_streamBuffer.get();
474
475 // All GIF files begin with "GIF87a" or "GIF89a".
476 if (!memcmp(currentComponent, "GIF89a", 6))
477 m_version = 89;
478 else if (!memcmp(currentComponent, "GIF87a", 6))
479 m_version = 87;
480 else {
481 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700482 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400483 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700484 }
scroggof9acbe22016-10-25 12:43:21 -0700485 GETN(7, SkGIFGlobalHeader);
scroggo19b91532016-10-24 09:03:26 -0700486 break;
487 }
488
scroggof9acbe22016-10-25 12:43:21 -0700489 case SkGIFGlobalHeader: {
scroggo19b91532016-10-24 09:03:26 -0700490 const unsigned char* currentComponent =
491 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
492
493 // This is the height and width of the "screen" or frame into which
494 // images are rendered. The individual images can be smaller than
495 // the screen size and located with an origin anywhere within the
496 // screen.
497 // Note that we don't inform the client of the size yet, as it might
498 // change after we read the first frame's image header.
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400499 fScreenWidth = GETINT16(currentComponent);
500 fScreenHeight = GETINT16(currentComponent + 2);
scroggo19b91532016-10-24 09:03:26 -0700501
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400502 const int globalColorMapColors = 2 << (currentComponent[4] & 0x07);
scroggo19b91532016-10-24 09:03:26 -0700503
504 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* global map */
505 m_globalColorMap.setNumColors(globalColorMapColors);
scroggof9acbe22016-10-25 12:43:21 -0700506 GETN(SK_BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, SkGIFGlobalColormap);
scroggo19b91532016-10-24 09:03:26 -0700507 break;
508 }
509
scroggof9acbe22016-10-25 12:43:21 -0700510 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700511 break;
512 }
513
scroggof9acbe22016-10-25 12:43:21 -0700514 case SkGIFGlobalColormap: {
Leon Scroggins III932efed2016-12-16 11:39:51 -0500515 m_globalColorMap.setTablePosition(m_streamBuffer.markPosition());
scroggof9acbe22016-10-25 12:43:21 -0700516 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700517 break;
518 }
519
scroggof9acbe22016-10-25 12:43:21 -0700520 case SkGIFImageStart: {
scroggo19b91532016-10-24 09:03:26 -0700521 const char currentComponent = m_streamBuffer.get()[0];
522
523 if (currentComponent == '!') { // extension.
scroggof9acbe22016-10-25 12:43:21 -0700524 GETN(2, SkGIFExtension);
scroggo19b91532016-10-24 09:03:26 -0700525 break;
526 }
527
528 if (currentComponent == ',') { // image separator.
scroggof9acbe22016-10-25 12:43:21 -0700529 GETN(9, SkGIFImageHeader);
scroggo19b91532016-10-24 09:03:26 -0700530 break;
531 }
532
533 // If we get anything other than ',' (image separator), '!'
534 // (extension), or ';' (trailer), there is extraneous data
535 // between blocks. The GIF87a spec tells us to keep reading
536 // until we find an image separator, but GIF89a says such
537 // a file is corrupt. We follow Mozilla's implementation and
538 // proceed as if the file were correctly terminated, so the
539 // GIF will display.
scroggof9acbe22016-10-25 12:43:21 -0700540 GETN(0, SkGIFDone);
scroggo19b91532016-10-24 09:03:26 -0700541 break;
542 }
543
scroggof9acbe22016-10-25 12:43:21 -0700544 case SkGIFExtension: {
scroggo19b91532016-10-24 09:03:26 -0700545 const unsigned char* currentComponent =
546 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
547
548 size_t bytesInBlock = currentComponent[1];
scroggof9acbe22016-10-25 12:43:21 -0700549 SkGIFState exceptionState = SkGIFSkipBlock;
scroggo19b91532016-10-24 09:03:26 -0700550
551 switch (*currentComponent) {
552 case 0xf9:
scroggo19b91532016-10-24 09:03:26 -0700553 // The GIF spec mandates that the GIFControlExtension header block length is 4 bytes,
scroggof9acbe22016-10-25 12:43:21 -0700554 exceptionState = SkGIFControlExtension;
scroggo19b91532016-10-24 09:03:26 -0700555 // and the parser for this block reads 4 bytes, so we must enforce that the buffer
556 // contains at least this many bytes. If the GIF specifies a different length, we
557 // allow that, so long as it's larger; the additional data will simply be ignored.
558 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
559 break;
560
561 // The GIF spec also specifies the lengths of the following two extensions' headers
562 // (as 12 and 11 bytes, respectively). Because we ignore the plain text extension entirely
563 // and sanity-check the actual length of the application extension header before reading it,
564 // we allow GIFs to deviate from these values in either direction. This is important for
565 // real-world compatibility, as GIFs in the wild exist with application extension headers
566 // that are both shorter and longer than 11 bytes.
567 case 0x01:
568 // ignoring plain text extension
569 break;
570
571 case 0xff:
scroggof9acbe22016-10-25 12:43:21 -0700572 exceptionState = SkGIFApplicationExtension;
scroggo19b91532016-10-24 09:03:26 -0700573 break;
574
575 case 0xfe:
scroggof9acbe22016-10-25 12:43:21 -0700576 exceptionState = SkGIFConsumeComment;
scroggo19b91532016-10-24 09:03:26 -0700577 break;
578 }
579
580 if (bytesInBlock)
581 GETN(bytesInBlock, exceptionState);
582 else
scroggof9acbe22016-10-25 12:43:21 -0700583 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700584 break;
585 }
586
scroggof9acbe22016-10-25 12:43:21 -0700587 case SkGIFConsumeBlock: {
scroggo19b91532016-10-24 09:03:26 -0700588 const unsigned char currentComponent = this->getOneByte();
589 if (!currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700590 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700591 else
scroggof9acbe22016-10-25 12:43:21 -0700592 GETN(currentComponent, SkGIFSkipBlock);
scroggo19b91532016-10-24 09:03:26 -0700593 break;
594 }
595
scroggof9acbe22016-10-25 12:43:21 -0700596 case SkGIFSkipBlock: {
597 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700598 break;
599 }
600
scroggof9acbe22016-10-25 12:43:21 -0700601 case SkGIFControlExtension: {
scroggo19b91532016-10-24 09:03:26 -0700602 const unsigned char* currentComponent =
603 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
604
605 addFrameIfNecessary();
scroggof9acbe22016-10-25 12:43:21 -0700606 SkGIFFrameContext* currentFrame = m_frames.back().get();
scroggo19b91532016-10-24 09:03:26 -0700607 if (*currentComponent & 0x1)
608 currentFrame->setTransparentPixel(currentComponent[3]);
609
610 // We ignore the "user input" bit.
611
612 // NOTE: This relies on the values in the FrameDisposalMethod enum
613 // matching those in the GIF spec!
614 int rawDisposalMethod = ((*currentComponent) >> 2) & 0x7;
615 switch (rawDisposalMethod) {
616 case 1:
617 case 2:
618 case 3:
619 currentFrame->setDisposalMethod((SkCodecAnimation::DisposalMethod) rawDisposalMethod);
620 break;
621 case 4:
622 // Some specs say that disposal method 3 is "overwrite previous", others that setting
623 // 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 -0400624 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kRestorePrevious);
scroggo19b91532016-10-24 09:03:26 -0700625 break;
626 default:
627 // Other values use the default.
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400628 currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep);
scroggo19b91532016-10-24 09:03:26 -0700629 break;
630 }
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400631 currentFrame->setDuration(GETINT16(currentComponent + 1) * 10);
scroggof9acbe22016-10-25 12:43:21 -0700632 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700633 break;
634 }
635
scroggof9acbe22016-10-25 12:43:21 -0700636 case SkGIFCommentExtension: {
scroggo19b91532016-10-24 09:03:26 -0700637 const unsigned char currentComponent = this->getOneByte();
638 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700639 GETN(currentComponent, SkGIFConsumeComment);
scroggo19b91532016-10-24 09:03:26 -0700640 else
scroggof9acbe22016-10-25 12:43:21 -0700641 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700642 break;
643 }
644
scroggof9acbe22016-10-25 12:43:21 -0700645 case SkGIFConsumeComment: {
646 GETN(1, SkGIFCommentExtension);
scroggo19b91532016-10-24 09:03:26 -0700647 break;
648 }
649
scroggof9acbe22016-10-25 12:43:21 -0700650 case SkGIFApplicationExtension: {
scroggo19b91532016-10-24 09:03:26 -0700651 // Check for netscape application extension.
Leon Scroggins III932efed2016-12-16 11:39:51 -0500652 if (m_bytesToConsume == 11) {
scroggo19b91532016-10-24 09:03:26 -0700653 const unsigned char* currentComponent =
654 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
655
656 if (!memcmp(currentComponent, "NETSCAPE2.0", 11) || !memcmp(currentComponent, "ANIMEXTS1.0", 11))
scroggof9acbe22016-10-25 12:43:21 -0700657 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700658 }
659
scroggof9acbe22016-10-25 12:43:21 -0700660 if (m_state != SkGIFNetscapeExtensionBlock)
661 GETN(1, SkGIFConsumeBlock);
scroggo19b91532016-10-24 09:03:26 -0700662 break;
663 }
664
665 // Netscape-specific GIF extension: animation looping.
scroggof9acbe22016-10-25 12:43:21 -0700666 case SkGIFNetscapeExtensionBlock: {
scroggo19b91532016-10-24 09:03:26 -0700667 const int currentComponent = this->getOneByte();
scroggof9acbe22016-10-25 12:43:21 -0700668 // SkGIFConsumeNetscapeExtension always reads 3 bytes from the stream; we should at least wait for this amount.
scroggo19b91532016-10-24 09:03:26 -0700669 if (currentComponent)
scroggof9acbe22016-10-25 12:43:21 -0700670 GETN(std::max(3, currentComponent), SkGIFConsumeNetscapeExtension);
scroggo19b91532016-10-24 09:03:26 -0700671 else
scroggof9acbe22016-10-25 12:43:21 -0700672 GETN(1, SkGIFImageStart);
scroggo19b91532016-10-24 09:03:26 -0700673 break;
674 }
675
676 // Parse netscape-specific application extensions
scroggof9acbe22016-10-25 12:43:21 -0700677 case SkGIFConsumeNetscapeExtension: {
scroggo19b91532016-10-24 09:03:26 -0700678 const unsigned char* currentComponent =
679 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
680
681 int netscapeExtension = currentComponent[0] & 7;
682
683 // Loop entire animation specified # of times. Only read the loop count during the first iteration.
684 if (netscapeExtension == 1) {
685 m_loopCount = GETINT16(currentComponent + 1);
686
687 // Zero loop count is infinite animation loop request.
688 if (!m_loopCount)
scroggoe71b1a12016-11-01 08:28:28 -0700689 m_loopCount = SkCodec::kRepetitionCountInfinite;
scroggo19b91532016-10-24 09:03:26 -0700690
scroggof9acbe22016-10-25 12:43:21 -0700691 GETN(1, SkGIFNetscapeExtensionBlock);
scroggoe71b1a12016-11-01 08:28:28 -0700692
693 if (SkGIFLoopCountQuery == query) {
694 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400695 return SkCodec::kSuccess;
scroggoe71b1a12016-11-01 08:28:28 -0700696 }
scroggo19b91532016-10-24 09:03:26 -0700697 } else if (netscapeExtension == 2) {
698 // Wait for specified # of bytes to enter buffer.
699
700 // Don't do this, this extension doesn't exist (isn't used at all)
701 // and doesn't do anything, as our streaming/buffering takes care of it all...
702 // See: http://semmix.pl/color/exgraf/eeg24.htm
scroggof9acbe22016-10-25 12:43:21 -0700703 GETN(1, SkGIFNetscapeExtensionBlock);
scroggo19b91532016-10-24 09:03:26 -0700704 } else {
705 // 0,3-7 are yet to be defined netscape extension codes
706 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700707 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400708 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700709 }
710 break;
711 }
712
scroggof9acbe22016-10-25 12:43:21 -0700713 case SkGIFImageHeader: {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400714 int height, width, xOffset, yOffset;
scroggo19b91532016-10-24 09:03:26 -0700715 const unsigned char* currentComponent =
716 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
717
718 /* Get image offsets, with respect to the screen origin */
719 xOffset = GETINT16(currentComponent);
720 yOffset = GETINT16(currentComponent + 2);
721
722 /* Get image width and height. */
723 width = GETINT16(currentComponent + 4);
724 height = GETINT16(currentComponent + 6);
725
726 // Some GIF files have frames that don't fit in the specified
727 // overall image size. For the first frame, we can simply enlarge
728 // the image size to allow the frame to be visible. We can't do
729 // this on subsequent frames because the rest of the decoding
730 // infrastructure assumes the image size won't change as we
731 // continue decoding, so any subsequent frames that are even
732 // larger will be cropped.
733 // Luckily, handling just the first frame is sufficient to deal
734 // with most cases, e.g. ones where the image size is erroneously
735 // set to zero, since usually the first frame completely fills
736 // the image.
737 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400738 fScreenHeight = std::max(fScreenHeight, yOffset + height);
739 fScreenWidth = std::max(fScreenWidth, xOffset + width);
scroggo19b91532016-10-24 09:03:26 -0700740 }
741
742 // NOTE: Chromium placed this block after setHeaderDefined, down
743 // below we returned true when asked for the size. So Chromium
744 // created an image which would fail. Is this the correct behavior?
745 // We choose to return false early, so we will not create an
746 // SkCodec.
747
748 // Work around more broken GIF files that have zero image width or
749 // height.
750 if (!height || !width) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400751 height = fScreenHeight;
752 width = fScreenWidth;
scroggo19b91532016-10-24 09:03:26 -0700753 if (!height || !width) {
754 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700755 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400756 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700757 }
758 }
759
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400760 const bool isLocalColormapDefined = SkToBool(currentComponent[8] & 0x80);
scroggo19b91532016-10-24 09:03:26 -0700761 // The three low-order bits of currentComponent[8] specify the bits per pixel.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400762 const int numColors = 2 << (currentComponent[8] & 0x7);
scroggo19b91532016-10-24 09:03:26 -0700763 if (currentFrameIsFirstFrame()) {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400764 const int transPix = m_frames.empty() ? SkGIFColorMap::kNotFound
765 : m_frames[0]->transparentPixel();
Chris Blume0b5e7d12017-09-27 13:23:41 -0700766 if (is_palette_index_valid(transPix)) {
scroggo19b91532016-10-24 09:03:26 -0700767 m_firstFrameHasAlpha = true;
scroggo19b91532016-10-24 09:03:26 -0700768 } else {
769 const bool frameIsSubset = xOffset > 0 || yOffset > 0
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400770 || width < fScreenWidth
771 || height < fScreenHeight;
scroggo19b91532016-10-24 09:03:26 -0700772 m_firstFrameHasAlpha = frameIsSubset;
scroggo19b91532016-10-24 09:03:26 -0700773 }
774 }
775
Leon Scroggins III4993b952016-12-08 11:54:04 -0500776 addFrameIfNecessary();
777 SkGIFFrameContext* currentFrame = m_frames.back().get();
778 currentFrame->setHeaderDefined();
779
scroggof9acbe22016-10-25 12:43:21 -0700780 if (query == SkGIFSizeQuery) {
scroggo19b91532016-10-24 09:03:26 -0700781 // The decoder needs to stop, so we return here, before
782 // flushing the buffer. Next time through, we'll be in the same
783 // state, requiring the same amount in the buffer.
Leon Scroggins III588fb042017-07-14 16:32:31 -0400784 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700785 }
786
scroggo19b91532016-10-24 09:03:26 -0700787
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400788 currentFrame->setXYWH(xOffset, yOffset, width, height);
Jim Van Verth3cfdf6c2016-10-26 09:45:23 -0400789 currentFrame->setInterlaced(SkToBool(currentComponent[8] & 0x40));
scroggo19b91532016-10-24 09:03:26 -0700790
791 // Overlaying interlaced, transparent GIFs over
792 // existing image data using the Haeberli display hack
793 // requires saving the underlying image in order to
794 // avoid jaggies at the transparency edges. We are
795 // unprepared to deal with that, so don't display such
796 // images progressively. Which means only the first
797 // frame can be progressively displayed.
798 // FIXME: It is possible that a non-transparent frame
799 // can be interlaced and progressively displayed.
800 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
801
802 if (isLocalColormapDefined) {
803 currentFrame->localColorMap().setNumColors(numColors);
scroggof9acbe22016-10-25 12:43:21 -0700804 GETN(SK_BYTES_PER_COLORMAP_ENTRY * numColors, SkGIFImageColormap);
scroggo19b91532016-10-24 09:03:26 -0700805 break;
806 }
807
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400808 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700809 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700810 break;
811 }
812
scroggof9acbe22016-10-25 12:43:21 -0700813 case SkGIFImageColormap: {
scroggo19b91532016-10-24 09:03:26 -0700814 SkASSERT(!m_frames.empty());
Leon Scroggins IIIe4ba1052017-01-30 13:55:14 -0500815 auto* currentFrame = m_frames.back().get();
816 auto& cmap = currentFrame->localColorMap();
Leon Scroggins III932efed2016-12-16 11:39:51 -0500817 cmap.setTablePosition(m_streamBuffer.markPosition());
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400818 setAlphaAndRequiredFrame(currentFrame);
scroggof9acbe22016-10-25 12:43:21 -0700819 GETN(1, SkGIFLZWStart);
scroggo19b91532016-10-24 09:03:26 -0700820 break;
821 }
822
scroggof9acbe22016-10-25 12:43:21 -0700823 case SkGIFSubBlock: {
scroggo19b91532016-10-24 09:03:26 -0700824 const size_t bytesInBlock = this->getOneByte();
825 if (bytesInBlock)
scroggof9acbe22016-10-25 12:43:21 -0700826 GETN(bytesInBlock, SkGIFLZW);
scroggo19b91532016-10-24 09:03:26 -0700827 else {
828 // Finished parsing one frame; Process next frame.
829 SkASSERT(!m_frames.empty());
830 // Note that some broken GIF files do not have enough LZW blocks to fully
831 // decode all rows but we treat it as frame complete.
832 m_frames.back()->setComplete();
scroggof9acbe22016-10-25 12:43:21 -0700833 GETN(1, SkGIFImageStart);
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400834 if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse) {
scroggo19b91532016-10-24 09:03:26 -0700835 m_streamBuffer.flush();
Leon Scroggins III588fb042017-07-14 16:32:31 -0400836 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700837 }
838 }
839 break;
840 }
841
scroggof9acbe22016-10-25 12:43:21 -0700842 case SkGIFDone: {
scroggo19b91532016-10-24 09:03:26 -0700843 m_parseCompleted = true;
Leon Scroggins III588fb042017-07-14 16:32:31 -0400844 return SkCodec::kSuccess;
scroggo19b91532016-10-24 09:03:26 -0700845 }
846
847 default:
848 // We shouldn't ever get here.
849 // This prevents attempting to continue reading this invalid stream.
scroggof9acbe22016-10-25 12:43:21 -0700850 GETN(0, SkGIFDone);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400851 return SkCodec::kInvalidInput;
scroggo19b91532016-10-24 09:03:26 -0700852 break;
853 } // switch
854 m_streamBuffer.flush();
855 }
scroggo19b91532016-10-24 09:03:26 -0700856}
857
scroggo3d3a65c2016-10-24 12:28:30 -0700858void SkGifImageReader::addFrameIfNecessary()
scroggo19b91532016-10-24 09:03:26 -0700859{
860 if (m_frames.empty() || m_frames.back()->isComplete()) {
Leon Scroggins IIIe7503912017-08-30 10:09:42 -0400861 const int i = m_frames.count();
Chris Blume6c08b7b2017-09-28 10:23:26 -0700862 m_frames.emplace_back(new SkGIFFrameContext(i));
scroggo19b91532016-10-24 09:03:26 -0700863 }
864}
865
Leon Scroggins IIIc8037dc2017-12-05 13:55:24 -0500866SkEncodedInfo::Alpha SkGIFFrameContext::onReportedAlpha() const {
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400867 // Note: We could correct these after decoding - i.e. some frames may turn out to be
868 // independent and opaque if they do not use the transparent pixel, but that would require
869 // checking whether each pixel used the transparent index.
Leon Scroggins IIIc8037dc2017-12-05 13:55:24 -0500870 return is_palette_index_valid(this->transparentPixel()) ? SkEncodedInfo::kBinary_Alpha
871 : SkEncodedInfo::kOpaque_Alpha;
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400872}
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400873
scroggo19b91532016-10-24 09:03:26 -0700874// FIXME: Move this method to close to doLZW().
Leon Scroggins III45565b62016-12-05 14:56:30 -0500875bool SkGIFLZWContext::prepareToDecode()
scroggo19b91532016-10-24 09:03:26 -0700876{
877 SkASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefined());
878
879 // Since we use a codesize of 1 more than the datasize, we need to ensure
scroggof9acbe22016-10-25 12:43:21 -0700880 // that our datasize is strictly less than the SK_MAX_DICTIONARY_ENTRY_BITS.
881 if (m_frameContext->dataSize() >= SK_MAX_DICTIONARY_ENTRY_BITS)
scroggo19b91532016-10-24 09:03:26 -0700882 return false;
883 clearCode = 1 << m_frameContext->dataSize();
884 avail = clearCode + 2;
885 oldcode = -1;
886 codesize = m_frameContext->dataSize() + 1;
887 codemask = (1 << codesize) - 1;
888 datum = bits = 0;
889 ipass = m_frameContext->interlaced() ? 1 : 0;
890 irow = 0;
891
892 // We want to know the longest sequence encodable by a dictionary with
scroggof9acbe22016-10-25 12:43:21 -0700893 // SK_MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base
scroggo19b91532016-10-24 09:03:26 -0700894 // values themselves at the beginning of the dictionary, as well as the need
895 // for a clear code or a termination code, we could use every entry to
896 // encode a series of multiple values. If the input value stream looked
897 // like "AAAAA..." (a long string of just one value), the first dictionary
898 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
scroggof9acbe22016-10-25 12:43:21 -0700899 // the longest sequence would be SK_MAX_DICTIONARY_ENTRIES + 1 values.
scroggo19b91532016-10-24 09:03:26 -0700900 //
901 // However, we have to account for reserved entries. The first |datasize|
902 // bits are reserved for the base values, and the next two entries are
903 // reserved for the clear code and termination code. In theory a GIF can
904 // set the datasize to 0, meaning we have just two reserved entries, making
scroggof9acbe22016-10-25 12:43:21 -0700905 // the longest sequence (SK_MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since
scroggo19b91532016-10-24 09:03:26 -0700906 // each value is a byte, this is also the number of bytes in the longest
907 // encodable sequence.
scroggof9acbe22016-10-25 12:43:21 -0700908 const size_t maxBytes = SK_MAX_DICTIONARY_ENTRIES - 1;
scroggo19b91532016-10-24 09:03:26 -0700909
910 // Now allocate the output buffer. We decode directly into this buffer
911 // until we have at least one row worth of data, then call outputRow().
912 // This means worst case we may have (row width - 1) bytes in the buffer
913 // and then decode a sequence |maxBytes| long to append.
914 rowBuffer.reset(m_frameContext->width() - 1 + maxBytes);
915 rowIter = rowBuffer.begin();
916 rowsRemaining = m_frameContext->height();
917
918 // Clearing the whole suffix table lets us be more tolerant of bad data.
919 for (int i = 0; i < clearCode; ++i) {
920 suffix[i] = i;
921 suffixLength[i] = 1;
922 }
923 return true;
924}
925