Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1027)

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.cpp

Issue 2565323003: Move gif image decoder to SkCodec (Closed)
Patch Set: Add libjpeg-turbo to list of Skia library configs Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* -*- 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 /*
41 The Graphics Interchange Format(c) is the copyright property of CompuServe
42 Incorporated. Only CompuServe Incorporated is authorized to define, redefine,
43 enhance, alter, modify or change in any way the definition of the format.
44
45 CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free
46 license for the use of the Graphics Interchange Format(sm) in computer
47 software; computer software utilizing GIF(sm) must acknowledge ownership of the
48 Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
49 User and Technical Documentation. Computer software utilizing GIF, which is
50 distributed or may be distributed without User or Technical Documentation must
51 display to the screen or printer a message acknowledging ownership of the
52 Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in
53 this case, the acknowledgement may be displayed in an opening screen or leading
54 banner, or a closing screen or trailing banner. A message such as the following
55 may 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
61 For 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
69 CompuServe Incorporated maintains a mailing list with all those individuals and
70 organizations who wish to receive copies of this document when it is corrected
71 or revised. This service is offered free of charge; please provide us with your
72 mailing address.
73 */
74
75 #include "platform/image-decoders/gif/GIFImageReader.h"
76
77 #include <string.h>
78 #include "platform/wtf/PtrUtil.h"
79
80 using blink::GIFImageDecoder;
81
82 // GETN(n, s) requests at least 'n' bytes available from 'q', at start of state
83 // 's'.
84 //
85 // Note: the hold will never need to be bigger than 256 bytes, as each GIF block
86 // (except colormaps) can never be bigger than 256 bytes. Colormaps are directly
87 // copied in the resp. global_colormap or dynamically allocated local_colormap,
88 // so a fixed buffer in GIFImageReader is good enough. This buffer is only
89 // 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.
100 bool GIFLZWContext::outputRow(GIFRow::const_iterator rowBegin) {
101 int drowStart = irow;
102 int drowEnd = irow;
103
104 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while
105 // displaying to diminish the "venetian-blind" effect as the image is
106 // loaded. Adjust pixel vertical positions to avoid the appearance of the
107 // image crawling up the screen as successive passes are drawn.
108 if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() &&
109 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.
134 if (((m_frameContext->height() - 1) - drowEnd) <= rowShift)
135 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
141 if ((unsigned)drowEnd >= m_frameContext->height())
142 drowEnd = m_frameContext->height() - 1;
143 }
144
145 // Protect against too much image data.
146 if ((unsigned)drowStart >= m_frameContext->height())
147 return true;
148
149 // CALLBACK: Let the client know we have decoded a row.
150 if (!m_client->HaveDecodedRow(m_frameContext->frameId(), rowBegin,
151 m_frameContext->width(), drowStart,
152 drowEnd - drowStart + 1,
153 m_frameContext->progressiveDisplay() &&
154 m_frameContext->interlaced() && ipass > 1))
155 return false;
156
157 if (!m_frameContext->interlaced())
158 irow++;
159 else {
160 do {
161 switch (ipass) {
162 case 1:
163 irow += 8;
164 if (irow >= m_frameContext->height()) {
165 ipass++;
166 irow = 4;
167 }
168 break;
169
170 case 2:
171 irow += 8;
172 if (irow >= m_frameContext->height()) {
173 ipass++;
174 irow = 2;
175 }
176 break;
177
178 case 3:
179 irow += 4;
180 if (irow >= m_frameContext->height()) {
181 ipass++;
182 irow = 1;
183 }
184 break;
185
186 case 4:
187 irow += 2;
188 if (irow >= m_frameContext->height()) {
189 ipass++;
190 irow = 0;
191 }
192 break;
193
194 default:
195 break;
196 }
197 } while (irow > (m_frameContext->height() - 1));
198 }
199 return true;
200 }
201
202 // Performs Lempel-Ziv-Welch decoding. Returns whether decoding was successful.
203 // If successful, the block will have been completely consumed and/or
204 // rowsRemaining will be 0.
205 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) {
206 const size_t width = m_frameContext->width();
207
208 if (rowIter == rowBuffer.end())
209 return true;
210
211 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) {
212 // Feed the next byte into the decoder's 32-bit input buffer.
213 datum += ((int)*ch) << bits;
214 bits += 8;
215
216 // Check for underflow of decoder's 32-bit input buffer.
217 while (bits >= codesize) {
218 // Get the leading variable-length symbol from the data stream.
219 int code = datum & codemask;
220 datum >>= codesize;
221 bits -= codesize;
222
223 // Reset the dictionary to its original state, if requested.
224 if (code == clearCode) {
225 codesize = m_frameContext->dataSize() + 1;
226 codemask = (1 << codesize) - 1;
227 avail = clearCode + 2;
228 oldcode = -1;
229 continue;
230 }
231
232 // Check for explicit end-of-stream code.
233 if (code == (clearCode + 1)) {
234 // end-of-stream should only appear after all image data.
235 if (!rowsRemaining)
236 return true;
237 return false;
238 }
239
240 const int tempCode = code;
241 unsigned short codeLength = 0;
242 if (code < avail) {
243 // This is a pre-existing code, so we already know what it
244 // encodes.
245 codeLength = suffixLength[code];
246 rowIter += codeLength;
247 } else if (code == avail && oldcode != -1) {
248 // This is a new code just being added to the dictionary.
249 // It must encode the contents of the previous code, plus
250 // the first character of the previous code again.
251 codeLength = suffixLength[oldcode] + 1;
252 rowIter += codeLength;
253 *--rowIter = firstchar;
254 code = oldcode;
255 } else {
256 // This is an invalid code. The dictionary is just initialized
257 // and the code is incomplete. We don't know how to handle
258 // this case.
259 return false;
260 }
261
262 while (code >= clearCode) {
263 *--rowIter = suffix[code];
264 code = prefix[code];
265 }
266
267 *--rowIter = firstchar = suffix[code];
268
269 // Define a new codeword in the dictionary as long as we've read
270 // more than one value from the stream.
271 if (avail < MAX_DICTIONARY_ENTRIES && oldcode != -1) {
272 prefix[avail] = oldcode;
273 suffix[avail] = firstchar;
274 suffixLength[avail] = suffixLength[oldcode] + 1;
275 ++avail;
276
277 // If we've used up all the codewords of a given length
278 // increase the length of codewords by one bit, but don't
279 // exceed the specified maximum codeword size.
280 if (!(avail & codemask) && avail < MAX_DICTIONARY_ENTRIES) {
281 ++codesize;
282 codemask += avail;
283 }
284 }
285 oldcode = tempCode;
286 rowIter += codeLength;
287
288 // Output as many rows as possible.
289 GIFRow::iterator rowBegin = rowBuffer.begin();
290 for (; rowBegin + width <= rowIter; rowBegin += width) {
291 if (!outputRow(rowBegin))
292 return false;
293 rowsRemaining--;
294 if (!rowsRemaining)
295 return true;
296 }
297
298 if (rowBegin != rowBuffer.begin()) {
299 // Move the remaining bytes to the beginning of the buffer.
300 const size_t bytesToCopy = rowIter - rowBegin;
301 memcpy(rowBuffer.begin(), rowBegin, bytesToCopy);
302 rowIter = rowBuffer.begin() + bytesToCopy;
303 }
304 }
305 }
306 return true;
307 }
308
309 void GIFColorMap::buildTable(blink::FastSharedBufferReader* reader) {
310 if (!m_isDefined || !m_table.IsEmpty())
311 return;
312
313 CHECK_LE(m_position + m_colors * BYTES_PER_COLORMAP_ENTRY, reader->size());
314 DCHECK_LE(m_colors, MAX_COLORS);
315 char buffer[MAX_COLORS * BYTES_PER_COLORMAP_ENTRY];
316 const unsigned char* srcColormap =
317 reinterpret_cast<const unsigned char*>(reader->GetConsecutiveData(
318 m_position, m_colors * BYTES_PER_COLORMAP_ENTRY, buffer));
319 m_table.resize(m_colors);
320 for (Table::iterator iter = m_table.begin(); iter != m_table.end(); ++iter) {
321 *iter = SkPackARGB32NoCheck(255, srcColormap[0], srcColormap[1],
322 srcColormap[2]);
323 srcColormap += BYTES_PER_COLORMAP_ENTRY;
324 }
325 }
326
327 // Decodes this frame. |frameDecoded| will be set to true if the entire frame is
328 // decoded. Returns true if decoding progressed further than before without
329 // error, or there is insufficient new data to decode further. Otherwise, a
330 // decoding error occurred; returns false in this case.
331 bool GIFFrameContext::decode(blink::FastSharedBufferReader* reader,
332 blink::GIFImageDecoder* client,
333 bool* frameDecoded) {
334 m_localColorMap.buildTable(reader);
335
336 *frameDecoded = false;
337 if (!m_lzwContext) {
338 // Wait for more data to properly initialize GIFLZWContext.
339 if (!isDataSizeDefined() || !isHeaderDefined())
340 return true;
341
342 m_lzwContext = WTF::MakeUnique<GIFLZWContext>(client, this);
343 if (!m_lzwContext->prepareToDecode()) {
344 m_lzwContext.reset();
345 return false;
346 }
347
348 m_currentLzwBlock = 0;
349 }
350
351 // Some bad GIFs have extra blocks beyond the last row, which we don't want to
352 // decode.
353 while (m_currentLzwBlock < m_lzwBlocks.size() &&
354 m_lzwContext->hasRemainingRows()) {
355 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition;
356 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize;
357 if (blockPosition + blockSize > reader->size())
358 return false;
359
360 while (blockSize) {
361 const char* segment = 0;
362 size_t segmentLength = reader->GetSomeData(segment, blockPosition);
363 size_t decodeSize = std::min(segmentLength, blockSize);
364 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(segment),
365 decodeSize))
366 return false;
367 blockPosition += decodeSize;
368 blockSize -= decodeSize;
369 }
370 ++m_currentLzwBlock;
371 }
372
373 // If this frame is data complete then the previous loop must have completely
374 // decoded all LZW blocks.
375 // There will be no more decoding for this frame so it's time to cleanup.
376 if (isComplete()) {
377 *frameDecoded = true;
378 m_lzwContext.reset();
379 }
380 return true;
381 }
382
383 // Decodes a frame using GIFFrameContext:decode(). Returns true if decoding has
384 // progressed, or false if an error has occurred.
385 bool GIFImageReader::decode(size_t frameIndex) {
386 blink::FastSharedBufferReader reader(m_data);
387 m_globalColorMap.buildTable(&reader);
388
389 bool frameDecoded = false;
390 GIFFrameContext* currentFrame = m_frames[frameIndex].get();
391
392 return currentFrame->decode(&reader, m_client, &frameDecoded) &&
393 (!frameDecoded || m_client->FrameComplete(frameIndex));
394 }
395
396 bool GIFImageReader::parse(GIFImageDecoder::GIFParseQuery query) {
397 if (m_bytesRead >= m_data->size()) {
398 // This data has already been parsed. For example, in deferred
399 // decoding, a DecodingImageGenerator with more data may have already
400 // used this same ImageDecoder to decode. This can happen if two
401 // SkImages created by a DeferredImageDecoder are drawn/prerolled
402 // out of order (with respect to how much data they had at creation
403 // time).
404 return !m_client->Failed();
405 }
406
407 return parseData(m_bytesRead, m_data->size() - m_bytesRead, query);
408 }
409
410 // Parse incoming GIF data stream into internal data structures.
411 // Return true if parsing has progressed or there is not enough data.
412 // Return false if a fatal error is encountered.
413 bool GIFImageReader::parseData(size_t dataPosition,
414 size_t len,
415 GIFImageDecoder::GIFParseQuery query) {
416 if (!len) {
417 // No new data has come in since the last call, just ignore this call.
418 return true;
419 }
420
421 if (len < m_bytesToConsume)
422 return true;
423
424 blink::FastSharedBufferReader reader(m_data);
425
426 // A read buffer of 16 bytes is enough to accomodate all possible reads for
427 // parsing.
428 char readBuffer[16];
429
430 // Read as many components from |m_data| as possible. At the beginning of each
431 // iteration, |dataPosition| is advanced by m_bytesToConsume to point to the
432 // next component. |len| is decremented accordingly.
433 while (len >= m_bytesToConsume) {
434 const size_t currentComponentPosition = dataPosition;
435
436 // Mark the current component as consumed. Note that currentComponent will
437 // remain pointed at this component until the next loop iteration.
438 dataPosition += m_bytesToConsume;
439 len -= m_bytesToConsume;
440
441 switch (m_state) {
442 case GIFLZW:
443 DCHECK(!m_frames.IsEmpty());
444 // m_bytesToConsume is the current component size because it hasn't been
445 // updated.
446 m_frames.back()->addLzwBlock(currentComponentPosition,
447 m_bytesToConsume);
448 GETN(1, GIFSubBlock);
449 break;
450
451 case GIFLZWStart: {
452 DCHECK(!m_frames.IsEmpty());
453 m_frames.back()->setDataSize(static_cast<unsigned char>(
454 reader.GetOneByte(currentComponentPosition)));
455 GETN(1, GIFSubBlock);
456 break;
457 }
458
459 case GIFType: {
460 const char* currentComponent =
461 reader.GetConsecutiveData(currentComponentPosition, 6, readBuffer);
462
463 // All GIF files begin with "GIF87a" or "GIF89a".
464 if (!memcmp(currentComponent, "GIF89a", 6))
465 m_version = 89;
466 else if (!memcmp(currentComponent, "GIF87a", 6))
467 m_version = 87;
468 else
469 return false;
470 GETN(7, GIFGlobalHeader);
471 break;
472 }
473
474 case GIFGlobalHeader: {
475 const unsigned char* currentComponent =
476 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
477 currentComponentPosition, 5, readBuffer));
478
479 // This is the height and width of the "screen" or frame into which
480 // images are rendered. The individual images can be smaller than
481 // the screen size and located with an origin anywhere within the
482 // screen.
483 // Note that we don't inform the client of the size yet, as it might
484 // change after we read the first frame's image header.
485 m_screenWidth = GETINT16(currentComponent);
486 m_screenHeight = GETINT16(currentComponent + 2);
487
488 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07);
489
490 if ((currentComponent[4] & 0x80) &&
491 globalColorMapColors > 0) { /* global map */
492 m_globalColorMap.setTablePositionAndSize(dataPosition,
493 globalColorMapColors);
494 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors,
495 GIFGlobalColormap);
496 break;
497 }
498
499 GETN(1, GIFImageStart);
500 break;
501 }
502
503 case GIFGlobalColormap: {
504 m_globalColorMap.setDefined();
505 GETN(1, GIFImageStart);
506 break;
507 }
508
509 case GIFImageStart: {
510 const char currentComponent =
511 reader.GetOneByte(currentComponentPosition);
512
513 if (currentComponent == '!') { // extension.
514 GETN(2, GIFExtension);
515 break;
516 }
517
518 if (currentComponent == ',') { // image separator.
519 GETN(9, GIFImageHeader);
520 break;
521 }
522
523 // If we get anything other than ',' (image separator), '!'
524 // (extension), or ';' (trailer), there is extraneous data
525 // between blocks. The GIF87a spec tells us to keep reading
526 // until we find an image separator, but GIF89a says such
527 // a file is corrupt. We follow Mozilla's implementation and
528 // proceed as if the file were correctly terminated, so the
529 // GIF will display.
530 GETN(0, GIFDone);
531 break;
532 }
533
534 case GIFExtension: {
535 const unsigned char* currentComponent =
536 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
537 currentComponentPosition, 2, readBuffer));
538
539 size_t bytesInBlock = currentComponent[1];
540 GIFState exceptionState = GIFSkipBlock;
541
542 switch (*currentComponent) {
543 case 0xf9:
544 exceptionState = GIFControlExtension;
545 // The GIF spec mandates that the GIFControlExtension header block
546 // length is 4 bytes, and the parser for this block reads 4 bytes,
547 // so we must enforce that the buffer contains at least this many
548 // bytes. If the GIF specifies a different length, we allow that, so
549 // long as it's larger; the additional data will simply be ignored.
550 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
551 break;
552
553 // The GIF spec also specifies the lengths of the following two
554 // extensions' headers (as 12 and 11 bytes, respectively). Because we
555 // ignore the plain text extension entirely and sanity-check the
556 // actual length of the application extension header before reading
557 // it, we allow GIFs to deviate from these values in either direction.
558 // This is important for real-world compatibility, as GIFs in the wild
559 // exist with application extension headers that are both shorter and
560 // longer than 11 bytes.
561 case 0x01:
562 // ignoring plain text extension
563 break;
564
565 case 0xff:
566 exceptionState = GIFApplicationExtension;
567 break;
568
569 case 0xfe:
570 exceptionState = GIFConsumeComment;
571 break;
572 }
573
574 if (bytesInBlock)
575 GETN(bytesInBlock, exceptionState);
576 else
577 GETN(1, GIFImageStart);
578 break;
579 }
580
581 case GIFConsumeBlock: {
582 const unsigned char currentComponent = static_cast<unsigned char>(
583 reader.GetOneByte(currentComponentPosition));
584 if (!currentComponent)
585 GETN(1, GIFImageStart);
586 else
587 GETN(currentComponent, GIFSkipBlock);
588 break;
589 }
590
591 case GIFSkipBlock: {
592 GETN(1, GIFConsumeBlock);
593 break;
594 }
595
596 case GIFControlExtension: {
597 const unsigned char* currentComponent =
598 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
599 currentComponentPosition, 4, readBuffer));
600
601 addFrameIfNecessary();
602 GIFFrameContext* currentFrame = m_frames.back().get();
603 if (*currentComponent & 0x1)
604 currentFrame->setTransparentPixel(currentComponent[3]);
605
606 // We ignore the "user input" bit.
607
608 // NOTE: This relies on the values in the FrameDisposalMethod enum
609 // matching those in the GIF spec!
610 int disposalMethod = ((*currentComponent) >> 2) & 0x7;
611 if (disposalMethod < 4) {
612 currentFrame->setDisposalMethod(
613 static_cast<blink::ImageFrame::DisposalMethod>(disposalMethod));
614 } else if (disposalMethod == 4) {
615 // Some specs say that disposal method 3 is "overwrite previous",
616 // others that setting the third bit of the field (i.e. method 4) is.
617 // We map both to the same value.
618 currentFrame->setDisposalMethod(
619 blink::ImageFrame::kDisposeOverwritePrevious);
620 }
621 currentFrame->setDelayTime(GETINT16(currentComponent + 1) * 10);
622 GETN(1, GIFConsumeBlock);
623 break;
624 }
625
626 case GIFCommentExtension: {
627 const unsigned char currentComponent = static_cast<unsigned char>(
628 reader.GetOneByte(currentComponentPosition));
629 if (currentComponent)
630 GETN(currentComponent, GIFConsumeComment);
631 else
632 GETN(1, GIFImageStart);
633 break;
634 }
635
636 case GIFConsumeComment: {
637 GETN(1, GIFCommentExtension);
638 break;
639 }
640
641 case GIFApplicationExtension: {
642 // Check for netscape application extension.
643 if (m_bytesToConsume == 11) {
644 const unsigned char* currentComponent =
645 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
646 currentComponentPosition, 11, readBuffer));
647
648 if (!memcmp(currentComponent, "NETSCAPE2.0", 11) ||
649 !memcmp(currentComponent, "ANIMEXTS1.0", 11))
650 GETN(1, GIFNetscapeExtensionBlock);
651 }
652
653 if (m_state != GIFNetscapeExtensionBlock)
654 GETN(1, GIFConsumeBlock);
655 break;
656 }
657
658 // Netscape-specific GIF extension: animation looping.
659 case GIFNetscapeExtensionBlock: {
660 const int currentComponent = static_cast<unsigned char>(
661 reader.GetOneByte(currentComponentPosition));
662 // GIFConsumeNetscapeExtension always reads 3 bytes from the stream; we
663 // should at least wait for this amount.
664 if (currentComponent)
665 GETN(std::max(3, currentComponent), GIFConsumeNetscapeExtension);
666 else
667 GETN(1, GIFImageStart);
668 break;
669 }
670
671 // Parse netscape-specific application extensions
672 case GIFConsumeNetscapeExtension: {
673 const unsigned char* currentComponent =
674 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
675 currentComponentPosition, 3, readBuffer));
676
677 int netscapeExtension = currentComponent[0] & 7;
678
679 // Loop entire animation specified # of times. Only read the loop count
680 // during the first iteration.
681 if (netscapeExtension == 1) {
682 m_loopCount = GETINT16(currentComponent + 1);
683
684 // Zero loop count is infinite animation loop request.
685 if (!m_loopCount)
686 m_loopCount = blink::kCAnimationLoopInfinite;
687
688 GETN(1, GIFNetscapeExtensionBlock);
689 } else if (netscapeExtension == 2) {
690 // Wait for specified # of bytes to enter buffer.
691
692 // Don't do this, this extension doesn't exist (isn't used at all)
693 // and doesn't do anything, as our streaming/buffering takes care of
694 // it all. See http://semmix.pl/color/exgraf/eeg24.htm .
695 GETN(1, GIFNetscapeExtensionBlock);
696 } else {
697 // 0,3-7 are yet to be defined netscape extension codes
698 return false;
699 }
700 break;
701 }
702
703 case GIFImageHeader: {
704 unsigned height, width, xOffset, yOffset;
705 const unsigned char* currentComponent =
706 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
707 currentComponentPosition, 9, readBuffer));
708
709 /* Get image offsets, with respect to the screen origin */
710 xOffset = GETINT16(currentComponent);
711 yOffset = GETINT16(currentComponent + 2);
712
713 /* Get image width and height. */
714 width = GETINT16(currentComponent + 4);
715 height = GETINT16(currentComponent + 6);
716
717 // Some GIF files have frames that don't fit in the specified
718 // overall image size. For the first frame, we can simply enlarge
719 // the image size to allow the frame to be visible. We can't do
720 // this on subsequent frames because the rest of the decoding
721 // infrastructure assumes the image size won't change as we
722 // continue decoding, so any subsequent frames that are even
723 // larger will be cropped.
724 // Luckily, handling just the first frame is sufficient to deal
725 // with most cases, e.g. ones where the image size is erroneously
726 // set to zero, since usually the first frame completely fills
727 // the image.
728 if (currentFrameIsFirstFrame()) {
729 m_screenHeight = std::max(m_screenHeight, yOffset + height);
730 m_screenWidth = std::max(m_screenWidth, xOffset + width);
731 }
732
733 // Inform the client of the final size.
734 if (!m_sentSizeToClient && m_client &&
735 !m_client->SetSize(m_screenWidth, m_screenHeight))
736 return false;
737 m_sentSizeToClient = true;
738
739 if (query == GIFImageDecoder::kGIFSizeQuery) {
740 // The decoder needs to stop. Hand back the number of bytes we
741 // consumed from the buffer minus 9 (the amount we consumed to read
742 // the header).
743 setRemainingBytes(len + 9);
744 GETN(9, GIFImageHeader);
745 return true;
746 }
747
748 addFrameIfNecessary();
749 GIFFrameContext* currentFrame = m_frames.back().get();
750
751 currentFrame->setHeaderDefined();
752
753 // Work around more broken GIF files that have zero image width or
754 // height.
755 if (!height || !width) {
756 height = m_screenHeight;
757 width = m_screenWidth;
758 if (!height || !width)
759 return false;
760 }
761 currentFrame->setRect(xOffset, yOffset, width, height);
762 currentFrame->setInterlaced(currentComponent[8] & 0x40);
763
764 // Overlaying interlaced, transparent GIFs over
765 // existing image data using the Haeberli display hack
766 // requires saving the underlying image in order to
767 // avoid jaggies at the transparency edges. We are
768 // unprepared to deal with that, so don't display such
769 // images progressively. Which means only the first
770 // frame can be progressively displayed.
771 // FIXME: It is possible that a non-transparent frame
772 // can be interlaced and progressively displayed.
773 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
774
775 const bool isLocalColormapDefined = currentComponent[8] & 0x80;
776 if (isLocalColormapDefined) {
777 // The three low-order bits of currentComponent[8] specify the bits
778 // per pixel.
779 const size_t numColors = 2 << (currentComponent[8] & 0x7);
780 currentFrame->localColorMap().setTablePositionAndSize(dataPosition,
781 numColors);
782 GETN(BYTES_PER_COLORMAP_ENTRY * numColors, GIFImageColormap);
783 break;
784 }
785
786 GETN(1, GIFLZWStart);
787 break;
788 }
789
790 case GIFImageColormap: {
791 DCHECK(!m_frames.IsEmpty());
792 m_frames.back()->localColorMap().setDefined();
793 GETN(1, GIFLZWStart);
794 break;
795 }
796
797 case GIFSubBlock: {
798 const size_t bytesInBlock = static_cast<unsigned char>(
799 reader.GetOneByte(currentComponentPosition));
800 if (bytesInBlock)
801 GETN(bytesInBlock, GIFLZW);
802 else {
803 // Finished parsing one frame; Process next frame.
804 DCHECK(!m_frames.IsEmpty());
805 // Note that some broken GIF files do not have enough LZW blocks to
806 // fully decode all rows; we treat this case as "frame complete".
807 m_frames.back()->setComplete();
808 GETN(1, GIFImageStart);
809 }
810 break;
811 }
812
813 case GIFDone: {
814 m_parseCompleted = true;
815 return true;
816 }
817
818 default:
819 // We shouldn't ever get here.
820 return false;
821 break;
822 }
823 }
824
825 setRemainingBytes(len);
826 return true;
827 }
828
829 void GIFImageReader::setRemainingBytes(size_t remainingBytes) {
830 DCHECK_LE(remainingBytes, m_data->size());
831 m_bytesRead = m_data->size() - remainingBytes;
832 }
833
834 void GIFImageReader::addFrameIfNecessary() {
835 if (m_frames.IsEmpty() || m_frames.back()->isComplete())
836 m_frames.push_back(WTF::WrapUnique(new GIFFrameContext(m_frames.size())));
837 }
838
839 // FIXME: Move this method to close to doLZW().
840 bool GIFLZWContext::prepareToDecode() {
841 DCHECK(m_frameContext->isDataSizeDefined());
842 DCHECK(m_frameContext->isHeaderDefined());
843
844 // Since we use a codesize of 1 more than the datasize, we need to ensure
845 // that our datasize is strictly less than the MAX_DICTIONARY_ENTRY_BITS.
846 if (m_frameContext->dataSize() >= MAX_DICTIONARY_ENTRY_BITS)
847 return false;
848 clearCode = 1 << m_frameContext->dataSize();
849 avail = clearCode + 2;
850 oldcode = -1;
851 codesize = m_frameContext->dataSize() + 1;
852 codemask = (1 << codesize) - 1;
853 datum = bits = 0;
854 ipass = m_frameContext->interlaced() ? 1 : 0;
855 irow = 0;
856
857 // We want to know the longest sequence encodable by a dictionary with
858 // MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base
859 // values themselves at the beginning of the dictionary, as well as the need
860 // for a clear code or a termination code, we could use every entry to
861 // encode a series of multiple values. If the input value stream looked
862 // like "AAAAA..." (a long string of just one value), the first dictionary
863 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
864 // the longest sequence would be MAX_DICTIONARY_ENTRIES + 1 values.
865 //
866 // However, we have to account for reserved entries. The first |datasize|
867 // bits are reserved for the base values, and the next two entries are
868 // reserved for the clear code and termination code. In theory a GIF can
869 // set the datasize to 0, meaning we have just two reserved entries, making
870 // the longest sequence (MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since
871 // each value is a byte, this is also the number of bytes in the longest
872 // encodable sequence.
873 const size_t maxBytes = MAX_DICTIONARY_ENTRIES - 1;
874
875 // Now allocate the output buffer. We decode directly into this buffer
876 // until we have at least one row worth of data, then call outputRow().
877 // This means worst case we may have (row width - 1) bytes in the buffer
878 // and then decode a sequence |maxBytes| long to append.
879 rowBuffer.resize(m_frameContext->width() - 1 + maxBytes);
880 rowIter = rowBuffer.begin();
881 rowsRemaining = m_frameContext->height();
882
883 // Clearing the whole suffix table lets us be more tolerant of bad data.
884 for (int i = 0; i < clearCode; ++i) {
885 suffix[i] = i;
886 suffixLength[i] = 1;
887 }
888 return true;
889 }
OLDNEW
« skia/BUILD.gn ('K') | « third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698