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

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

Issue 2385993002: Rewrap comments to 80 columns in Source/platform/image-decoders/. (Closed)
Patch Set: Rewrite comment Created 4 years, 2 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
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK ***** 2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * 4 *
5 * The contents of this file are subject to the Mozilla Public License Version 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 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 7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/ 8 * http://www.mozilla.org/MPL/
9 * 9 *
10 * Software distributed under the License is distributed on an "AS IS" basis, 10 * Software distributed under the License is distributed on an "AS IS" basis,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 74
75 #include "platform/image-decoders/gif/GIFImageReader.h" 75 #include "platform/image-decoders/gif/GIFImageReader.h"
76 76
77 #include "platform/Histogram.h" 77 #include "platform/Histogram.h"
78 #include "wtf/PtrUtil.h" 78 #include "wtf/PtrUtil.h"
79 #include "wtf/Threading.h" 79 #include "wtf/Threading.h"
80 #include <string.h> 80 #include <string.h>
81 81
82 using blink::GIFImageDecoder; 82 using blink::GIFImageDecoder;
83 83
84 // GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's'. 84 // GETN(n, s) requests at least 'n' bytes available from 'q', at start of state
85 // 's'.
85 // 86 //
86 // Note, the hold will never need to be bigger than 256 bytes to gather up in th e hold, 87 // Note: the hold will never need to be bigger than 256 bytes, as each GIF block
87 // as each GIF block (except colormaps) can never be bigger than 256 bytes. 88 // (except colormaps) can never be bigger than 256 bytes. Colormaps are directly
88 // Colormaps are directly copied in the resp. global_colormap or dynamically all ocated local_colormap. 89 // copied in the resp. global_colormap or dynamically allocated local_colormap,
89 // So a fixed buffer in GIFImageReader is good enough. 90 // so a fixed buffer in GIFImageReader is good enough. This buffer is only
90 // This buffer is only needed to copy left-over data from one GifWrite call to t he next 91 // needed to copy left-over data from one GifWrite call to the next.
91 #define GETN(n, s) \ 92 #define GETN(n, s) \
92 do { \ 93 do { \
93 m_bytesToConsume = (n); \ 94 m_bytesToConsume = (n); \
94 m_state = (s); \ 95 m_state = (s); \
95 } while (0) 96 } while (0)
96 97
97 // Get a 16-bit value stored in little-endian format. 98 // Get a 16-bit value stored in little-endian format.
98 #define GETINT16(p) ((p)[1] << 8 | (p)[0]) 99 #define GETINT16(p) ((p)[1] << 8 | (p)[0])
99 100
100 // Send the data to the display front-end. 101 // Send the data to the display front-end.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 break; 194 break;
194 195
195 default: 196 default:
196 break; 197 break;
197 } 198 }
198 } while (irow > (m_frameContext->height() - 1)); 199 } while (irow > (m_frameContext->height() - 1));
199 } 200 }
200 return true; 201 return true;
201 } 202 }
202 203
203 // Perform Lempel-Ziv-Welch decoding. 204 // Performs Lempel-Ziv-Welch decoding. Returns whether decoding was successful.
204 // Returns true if decoding was successful. In this case the block will have bee n completely consumed and/or rowsRemaining will be 0. 205 // If successful, the block will have been completely consumed and/or
205 // Otherwise, decoding failed; returns false in this case, which will always cau se the GIFImageReader to set the "decode failed" flag. 206 // rowsRemaining will be 0.
206 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) { 207 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) {
207 const size_t width = m_frameContext->width(); 208 const size_t width = m_frameContext->width();
208 209
209 if (rowIter == rowBuffer.end()) 210 if (rowIter == rowBuffer.end())
210 return true; 211 return true;
211 212
212 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) { 213 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) {
213 // Feed the next byte into the decoder's 32-bit input buffer. 214 // Feed the next byte into the decoder's 32-bit input buffer.
214 datum += ((int)*ch) << bits; 215 datum += ((int)*ch) << bits;
215 bits += 8; 216 bits += 8;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 reinterpret_cast<const unsigned char*>(reader->getConsecutiveData( 320 reinterpret_cast<const unsigned char*>(reader->getConsecutiveData(
320 m_position, m_colors * BYTES_PER_COLORMAP_ENTRY, buffer)); 321 m_position, m_colors * BYTES_PER_COLORMAP_ENTRY, buffer));
321 m_table.resize(m_colors); 322 m_table.resize(m_colors);
322 for (Table::iterator iter = m_table.begin(); iter != m_table.end(); ++iter) { 323 for (Table::iterator iter = m_table.begin(); iter != m_table.end(); ++iter) {
323 *iter = SkPackARGB32NoCheck(255, srcColormap[0], srcColormap[1], 324 *iter = SkPackARGB32NoCheck(255, srcColormap[0], srcColormap[1],
324 srcColormap[2]); 325 srcColormap[2]);
325 srcColormap += BYTES_PER_COLORMAP_ENTRY; 326 srcColormap += BYTES_PER_COLORMAP_ENTRY;
326 } 327 }
327 } 328 }
328 329
329 // Perform decoding for this frame. frameDecoded will be true if the entire fram e is decoded. 330 // Decodes this frame. |frameDecoded| will be set to true if the entire frame is
330 // Returns false if a decoding error occurred. This is a fatal error and causes the GIFImageReader to set the "decode failed" flag. 331 // decoded. Returns true if decoding progressed further than before without
331 // 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. 332 // error, or there is insufficient new data to decode further. Otherwise, a
333 // decoding error occurred; returns false in this case.
332 bool GIFFrameContext::decode(blink::FastSharedBufferReader* reader, 334 bool GIFFrameContext::decode(blink::FastSharedBufferReader* reader,
333 blink::GIFImageDecoder* client, 335 blink::GIFImageDecoder* client,
334 bool* frameDecoded) { 336 bool* frameDecoded) {
335 m_localColorMap.buildTable(reader); 337 m_localColorMap.buildTable(reader);
336 338
337 *frameDecoded = false; 339 *frameDecoded = false;
338 if (!m_lzwContext) { 340 if (!m_lzwContext) {
339 // Wait for more data to properly initialize GIFLZWContext. 341 // Wait for more data to properly initialize GIFLZWContext.
340 if (!isDataSizeDefined() || !isHeaderDefined()) 342 if (!isDataSizeDefined() || !isHeaderDefined())
341 return true; 343 return true;
342 344
343 m_lzwContext = wrapUnique(new GIFLZWContext(client, this)); 345 m_lzwContext = wrapUnique(new GIFLZWContext(client, this));
344 if (!m_lzwContext->prepareToDecode()) { 346 if (!m_lzwContext->prepareToDecode()) {
345 m_lzwContext.reset(); 347 m_lzwContext.reset();
346 return false; 348 return false;
347 } 349 }
348 350
349 m_currentLzwBlock = 0; 351 m_currentLzwBlock = 0;
350 } 352 }
351 353
352 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode. 354 // Some bad GIFs have extra blocks beyond the last row, which we don't want to
355 // decode.
353 while (m_currentLzwBlock < m_lzwBlocks.size() && 356 while (m_currentLzwBlock < m_lzwBlocks.size() &&
354 m_lzwContext->hasRemainingRows()) { 357 m_lzwContext->hasRemainingRows()) {
355 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition; 358 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition;
356 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize; 359 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize;
357 if (blockPosition + blockSize > reader->size()) 360 if (blockPosition + blockSize > reader->size())
358 return false; 361 return false;
359 362
360 while (blockSize) { 363 while (blockSize) {
361 const char* segment = 0; 364 const char* segment = 0;
362 size_t segmentLength = reader->getSomeData(segment, blockPosition); 365 size_t segmentLength = reader->getSomeData(segment, blockPosition);
363 size_t decodeSize = std::min(segmentLength, blockSize); 366 size_t decodeSize = std::min(segmentLength, blockSize);
364 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(segment), 367 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(segment),
365 decodeSize)) 368 decodeSize))
366 return false; 369 return false;
367 blockPosition += decodeSize; 370 blockPosition += decodeSize;
368 blockSize -= decodeSize; 371 blockSize -= decodeSize;
369 } 372 }
370 ++m_currentLzwBlock; 373 ++m_currentLzwBlock;
371 } 374 }
372 375
373 // If this frame is data complete then the previous loop must have completely decoded all LZW blocks. 376 // If this frame is data complete then the previous loop must have completely
377 // decoded all LZW blocks.
374 // There will be no more decoding for this frame so it's time to cleanup. 378 // There will be no more decoding for this frame so it's time to cleanup.
375 if (isComplete()) { 379 if (isComplete()) {
376 *frameDecoded = true; 380 *frameDecoded = true;
377 m_lzwContext.reset(); 381 m_lzwContext.reset();
378 } 382 }
379 return true; 383 return true;
380 } 384 }
381 385
382 // Decode a frame. 386 // Decodes a frame using GIFFrameContext:decode(). Returns true if decoding has
383 // This method uses GIFFrameContext:decode() to decode the frame; decoding error is reported to client as a critical failure. 387 // progressed, or false if an error has occurred.
384 // Return true if decoding has progressed. Return false if an error has occurred .
385 bool GIFImageReader::decode(size_t frameIndex) { 388 bool GIFImageReader::decode(size_t frameIndex) {
386 blink::FastSharedBufferReader reader(m_data); 389 blink::FastSharedBufferReader reader(m_data);
387 m_globalColorMap.buildTable(&reader); 390 m_globalColorMap.buildTable(&reader);
388 391
389 bool frameDecoded = false; 392 bool frameDecoded = false;
390 GIFFrameContext* currentFrame = m_frames[frameIndex].get(); 393 GIFFrameContext* currentFrame = m_frames[frameIndex].get();
391 394
392 return currentFrame->decode(&reader, m_client, &frameDecoded) && 395 return currentFrame->decode(&reader, m_client, &frameDecoded) &&
393 (!frameDecoded || m_client->frameComplete(frameIndex)); 396 (!frameDecoded || m_client->frameComplete(frameIndex));
394 } 397 }
(...skipping 21 matching lines...) Expand all
416 if (!len) { 419 if (!len) {
417 // No new data has come in since the last call, just ignore this call. 420 // No new data has come in since the last call, just ignore this call.
418 return true; 421 return true;
419 } 422 }
420 423
421 if (len < m_bytesToConsume) 424 if (len < m_bytesToConsume)
422 return true; 425 return true;
423 426
424 blink::FastSharedBufferReader reader(m_data); 427 blink::FastSharedBufferReader reader(m_data);
425 428
426 // A read buffer of 16 bytes is enough to accomodate all possible reads for pa rsing. 429 // A read buffer of 16 bytes is enough to accomodate all possible reads for
430 // parsing.
427 char readBuffer[16]; 431 char readBuffer[16];
428 432
429 // This loop reads as many components from |m_data| as possible. 433 // Read as many components from |m_data| as possible. At the beginning of each
430 // At the beginning of each iteration, dataPosition will be advanced by m_byte sToConsume to 434 // iteration, |dataPosition| is advanced by m_bytesToConsume to point to the
431 // point to the next component. len will be decremented accordingly. 435 // next component. |len| is decremented accordingly.
432 while (len >= m_bytesToConsume) { 436 while (len >= m_bytesToConsume) {
433 const size_t currentComponentPosition = dataPosition; 437 const size_t currentComponentPosition = dataPosition;
434 438
435 // Mark the current component as consumed. Note that currentComponent will r emain pointed at this 439 // Mark the current component as consumed. Note that currentComponent will
436 // component until the next loop iteration. 440 // remain pointed at this component until the next loop iteration.
437 dataPosition += m_bytesToConsume; 441 dataPosition += m_bytesToConsume;
438 len -= m_bytesToConsume; 442 len -= m_bytesToConsume;
439 443
440 switch (m_state) { 444 switch (m_state) {
441 case GIFLZW: 445 case GIFLZW:
442 ASSERT(!m_frames.isEmpty()); 446 ASSERT(!m_frames.isEmpty());
443 // m_bytesToConsume is the current component size because it hasn't been updated. 447 // m_bytesToConsume is the current component size because it hasn't been
448 // updated.
444 m_frames.last()->addLzwBlock(currentComponentPosition, 449 m_frames.last()->addLzwBlock(currentComponentPosition,
445 m_bytesToConsume); 450 m_bytesToConsume);
446 GETN(1, GIFSubBlock); 451 GETN(1, GIFSubBlock);
447 break; 452 break;
448 453
449 case GIFLZWStart: { 454 case GIFLZWStart: {
450 ASSERT(!m_frames.isEmpty()); 455 ASSERT(!m_frames.isEmpty());
451 m_frames.last()->setDataSize(static_cast<unsigned char>( 456 m_frames.last()->setDataSize(static_cast<unsigned char>(
452 reader.getOneByte(currentComponentPosition))); 457 reader.getOneByte(currentComponentPosition)));
453 GETN(1, GIFSubBlock); 458 GETN(1, GIFSubBlock);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 const unsigned char* currentComponent = 538 const unsigned char* currentComponent =
534 reinterpret_cast<const unsigned char*>(reader.getConsecutiveData( 539 reinterpret_cast<const unsigned char*>(reader.getConsecutiveData(
535 currentComponentPosition, 2, readBuffer)); 540 currentComponentPosition, 2, readBuffer));
536 541
537 size_t bytesInBlock = currentComponent[1]; 542 size_t bytesInBlock = currentComponent[1];
538 GIFState exceptionState = GIFSkipBlock; 543 GIFState exceptionState = GIFSkipBlock;
539 544
540 switch (*currentComponent) { 545 switch (*currentComponent) {
541 case 0xf9: 546 case 0xf9:
542 exceptionState = GIFControlExtension; 547 exceptionState = GIFControlExtension;
543 // The GIF spec mandates that the GIFControlExtension header block l ength is 4 bytes, 548 // The GIF spec mandates that the GIFControlExtension header block
544 // and the parser for this block reads 4 bytes, so we must enforce t hat the buffer 549 // length is 4 bytes, and the parser for this block reads 4 bytes,
545 // contains at least this many bytes. If the GIF specifies a differe nt length, we 550 // so we must enforce that the buffer contains at least this many
546 // allow that, so long as it's larger; the additional data will simp ly be ignored. 551 // bytes. If the GIF specifies a different length, we allow that, so
552 // long as it's larger; the additional data will simply be ignored.
547 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4)); 553 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
548 break; 554 break;
549 555
550 // The GIF spec also specifies the lengths of the following two extens ions' headers 556 // The GIF spec also specifies the lengths of the following two
551 // (as 12 and 11 bytes, respectively). Because we ignore the plain tex t extension entirely 557 // extensions' headers (as 12 and 11 bytes, respectively). Because we
552 // and sanity-check the actual length of the application extension hea der before reading it, 558 // ignore the plain text extension entirely and sanity-check the
553 // we allow GIFs to deviate from these values in either direction. Thi s is important for 559 // actual length of the application extension header before reading
554 // real-world compatibility, as GIFs in the wild exist with applicatio n extension headers 560 // it, we allow GIFs to deviate from these values in either direction.
555 // that are both shorter and longer than 11 bytes. 561 // This is important for real-world compatibility, as GIFs in the wild
562 // exist with application extension headers that are both shorter and
563 // longer than 11 bytes.
556 case 0x01: 564 case 0x01:
557 // ignoring plain text extension 565 // ignoring plain text extension
558 break; 566 break;
559 567
560 case 0xff: 568 case 0xff:
561 exceptionState = GIFApplicationExtension; 569 exceptionState = GIFApplicationExtension;
562 break; 570 break;
563 571
564 case 0xfe: 572 case 0xfe:
565 exceptionState = GIFConsumeComment; 573 exceptionState = GIFConsumeComment;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 608
601 // We ignore the "user input" bit. 609 // We ignore the "user input" bit.
602 610
603 // NOTE: This relies on the values in the FrameDisposalMethod enum 611 // NOTE: This relies on the values in the FrameDisposalMethod enum
604 // matching those in the GIF spec! 612 // matching those in the GIF spec!
605 int disposalMethod = ((*currentComponent) >> 2) & 0x7; 613 int disposalMethod = ((*currentComponent) >> 2) & 0x7;
606 if (disposalMethod < 4) { 614 if (disposalMethod < 4) {
607 currentFrame->setDisposalMethod( 615 currentFrame->setDisposalMethod(
608 static_cast<blink::ImageFrame::DisposalMethod>(disposalMethod)); 616 static_cast<blink::ImageFrame::DisposalMethod>(disposalMethod));
609 } else if (disposalMethod == 4) { 617 } else if (disposalMethod == 4) {
610 // Some specs say that disposal method 3 is "overwrite previous", othe rs that setting 618 // Some specs say that disposal method 3 is "overwrite previous",
611 // the third bit of the field (i.e. method 4) is. We map both to the s ame value. 619 // others that setting the third bit of the field (i.e. method 4) is.
620 // We map both to the same value.
612 currentFrame->setDisposalMethod( 621 currentFrame->setDisposalMethod(
613 blink::ImageFrame::DisposeOverwritePrevious); 622 blink::ImageFrame::DisposeOverwritePrevious);
614 } 623 }
615 currentFrame->setDelayTime(GETINT16(currentComponent + 1) * 10); 624 currentFrame->setDelayTime(GETINT16(currentComponent + 1) * 10);
616 GETN(1, GIFConsumeBlock); 625 GETN(1, GIFConsumeBlock);
617 break; 626 break;
618 } 627 }
619 628
620 case GIFCommentExtension: { 629 case GIFCommentExtension: {
621 const unsigned char currentComponent = static_cast<unsigned char>( 630 const unsigned char currentComponent = static_cast<unsigned char>(
(...skipping 24 matching lines...) Expand all
646 655
647 if (m_state != GIFNetscapeExtensionBlock) 656 if (m_state != GIFNetscapeExtensionBlock)
648 GETN(1, GIFConsumeBlock); 657 GETN(1, GIFConsumeBlock);
649 break; 658 break;
650 } 659 }
651 660
652 // Netscape-specific GIF extension: animation looping. 661 // Netscape-specific GIF extension: animation looping.
653 case GIFNetscapeExtensionBlock: { 662 case GIFNetscapeExtensionBlock: {
654 const int currentComponent = static_cast<unsigned char>( 663 const int currentComponent = static_cast<unsigned char>(
655 reader.getOneByte(currentComponentPosition)); 664 reader.getOneByte(currentComponentPosition));
656 // GIFConsumeNetscapeExtension always reads 3 bytes from the stream; we should at least wait for this amount. 665 // GIFConsumeNetscapeExtension always reads 3 bytes from the stream; we
666 // should at least wait for this amount.
657 if (currentComponent) 667 if (currentComponent)
658 GETN(std::max(3, currentComponent), GIFConsumeNetscapeExtension); 668 GETN(std::max(3, currentComponent), GIFConsumeNetscapeExtension);
659 else 669 else
660 GETN(1, GIFImageStart); 670 GETN(1, GIFImageStart);
661 break; 671 break;
662 } 672 }
663 673
664 // Parse netscape-specific application extensions 674 // Parse netscape-specific application extensions
665 case GIFConsumeNetscapeExtension: { 675 case GIFConsumeNetscapeExtension: {
666 const unsigned char* currentComponent = 676 const unsigned char* currentComponent =
667 reinterpret_cast<const unsigned char*>(reader.getConsecutiveData( 677 reinterpret_cast<const unsigned char*>(reader.getConsecutiveData(
668 currentComponentPosition, 3, readBuffer)); 678 currentComponentPosition, 3, readBuffer));
669 679
670 int netscapeExtension = currentComponent[0] & 7; 680 int netscapeExtension = currentComponent[0] & 7;
671 681
672 // Loop entire animation specified # of times. Only read the loop count during the first iteration. 682 // Loop entire animation specified # of times. Only read the loop count
683 // during the first iteration.
673 if (netscapeExtension == 1) { 684 if (netscapeExtension == 1) {
674 m_loopCount = GETINT16(currentComponent + 1); 685 m_loopCount = GETINT16(currentComponent + 1);
675 686
676 // Zero loop count is infinite animation loop request. 687 // Zero loop count is infinite animation loop request.
677 if (!m_loopCount) 688 if (!m_loopCount)
678 m_loopCount = blink::cAnimationLoopInfinite; 689 m_loopCount = blink::cAnimationLoopInfinite;
679 690
680 GETN(1, GIFNetscapeExtensionBlock); 691 GETN(1, GIFNetscapeExtensionBlock);
681 } else if (netscapeExtension == 2) { 692 } else if (netscapeExtension == 2) {
682 // Wait for specified # of bytes to enter buffer. 693 // Wait for specified # of bytes to enter buffer.
683 694
684 // Don't do this, this extension doesn't exist (isn't used at all) 695 // Don't do this, this extension doesn't exist (isn't used at all)
685 // and doesn't do anything, as our streaming/buffering takes care of i t all... 696 // and doesn't do anything, as our streaming/buffering takes care of
686 // See: http://semmix.pl/color/exgraf/eeg24.htm 697 // it all. See http://semmix.pl/color/exgraf/eeg24.htm .
687 GETN(1, GIFNetscapeExtensionBlock); 698 GETN(1, GIFNetscapeExtensionBlock);
688 } else { 699 } else {
689 // 0,3-7 are yet to be defined netscape extension codes 700 // 0,3-7 are yet to be defined netscape extension codes
690 return false; 701 return false;
691 } 702 }
692 break; 703 break;
693 } 704 }
694 705
695 case GIFImageHeader: { 706 case GIFImageHeader: {
696 unsigned height, width, xOffset, yOffset; 707 unsigned height, width, xOffset, yOffset;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 m_screenWidth = std::max(m_screenWidth, xOffset + width); 766 m_screenWidth = std::max(m_screenWidth, xOffset + width);
756 } 767 }
757 768
758 // Inform the client of the final size. 769 // Inform the client of the final size.
759 if (!m_sentSizeToClient && m_client && 770 if (!m_sentSizeToClient && m_client &&
760 !m_client->setSize(m_screenWidth, m_screenHeight)) 771 !m_client->setSize(m_screenWidth, m_screenHeight))
761 return false; 772 return false;
762 m_sentSizeToClient = true; 773 m_sentSizeToClient = true;
763 774
764 if (query == GIFImageDecoder::GIFSizeQuery) { 775 if (query == GIFImageDecoder::GIFSizeQuery) {
765 // The decoder needs to stop. Hand back the number of bytes we consume d from 776 // The decoder needs to stop. Hand back the number of bytes we
766 // buffer minus 9 (the amount we consumed to read the header). 777 // consumed from the buffer minus 9 (the amount we consumed to read
778 // the header).
767 setRemainingBytes(len + 9); 779 setRemainingBytes(len + 9);
768 GETN(9, GIFImageHeader); 780 GETN(9, GIFImageHeader);
769 return true; 781 return true;
770 } 782 }
771 783
772 addFrameIfNecessary(); 784 addFrameIfNecessary();
773 GIFFrameContext* currentFrame = m_frames.last().get(); 785 GIFFrameContext* currentFrame = m_frames.last().get();
774 786
775 currentFrame->setHeaderDefined(); 787 currentFrame->setHeaderDefined();
776 788
(...skipping 14 matching lines...) Expand all
791 // avoid jaggies at the transparency edges. We are 803 // avoid jaggies at the transparency edges. We are
792 // unprepared to deal with that, so don't display such 804 // unprepared to deal with that, so don't display such
793 // images progressively. Which means only the first 805 // images progressively. Which means only the first
794 // frame can be progressively displayed. 806 // frame can be progressively displayed.
795 // FIXME: It is possible that a non-transparent frame 807 // FIXME: It is possible that a non-transparent frame
796 // can be interlaced and progressively displayed. 808 // can be interlaced and progressively displayed.
797 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame()); 809 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
798 810
799 const bool isLocalColormapDefined = currentComponent[8] & 0x80; 811 const bool isLocalColormapDefined = currentComponent[8] & 0x80;
800 if (isLocalColormapDefined) { 812 if (isLocalColormapDefined) {
801 // The three low-order bits of currentComponent[8] specify the bits pe r pixel. 813 // The three low-order bits of currentComponent[8] specify the bits
814 // per pixel.
802 const size_t numColors = 2 << (currentComponent[8] & 0x7); 815 const size_t numColors = 2 << (currentComponent[8] & 0x7);
803 currentFrame->localColorMap().setTablePositionAndSize(dataPosition, 816 currentFrame->localColorMap().setTablePositionAndSize(dataPosition,
804 numColors); 817 numColors);
805 GETN(BYTES_PER_COLORMAP_ENTRY * numColors, GIFImageColormap); 818 GETN(BYTES_PER_COLORMAP_ENTRY * numColors, GIFImageColormap);
806 break; 819 break;
807 } 820 }
808 821
809 GETN(1, GIFLZWStart); 822 GETN(1, GIFLZWStart);
810 break; 823 break;
811 } 824 }
812 825
813 case GIFImageColormap: { 826 case GIFImageColormap: {
814 ASSERT(!m_frames.isEmpty()); 827 ASSERT(!m_frames.isEmpty());
815 m_frames.last()->localColorMap().setDefined(); 828 m_frames.last()->localColorMap().setDefined();
816 GETN(1, GIFLZWStart); 829 GETN(1, GIFLZWStart);
817 break; 830 break;
818 } 831 }
819 832
820 case GIFSubBlock: { 833 case GIFSubBlock: {
821 const size_t bytesInBlock = static_cast<unsigned char>( 834 const size_t bytesInBlock = static_cast<unsigned char>(
822 reader.getOneByte(currentComponentPosition)); 835 reader.getOneByte(currentComponentPosition));
823 if (bytesInBlock) 836 if (bytesInBlock)
824 GETN(bytesInBlock, GIFLZW); 837 GETN(bytesInBlock, GIFLZW);
825 else { 838 else {
826 // Finished parsing one frame; Process next frame. 839 // Finished parsing one frame; Process next frame.
827 ASSERT(!m_frames.isEmpty()); 840 ASSERT(!m_frames.isEmpty());
828 // Note that some broken GIF files do not have enough LZW blocks to fu lly 841 // Note that some broken GIF files do not have enough LZW blocks to
829 // decode all rows but we treat it as frame complete. 842 // fully decode all rows; we treat this case as "frame complete".
830 m_frames.last()->setComplete(); 843 m_frames.last()->setComplete();
831 GETN(1, GIFImageStart); 844 GETN(1, GIFImageStart);
832 } 845 }
833 break; 846 break;
834 } 847 }
835 848
836 case GIFDone: { 849 case GIFDone: {
837 m_parseCompleted = true; 850 m_parseCompleted = true;
838 return true; 851 return true;
839 } 852 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 rowIter = rowBuffer.begin(); 916 rowIter = rowBuffer.begin();
904 rowsRemaining = m_frameContext->height(); 917 rowsRemaining = m_frameContext->height();
905 918
906 // Clearing the whole suffix table lets us be more tolerant of bad data. 919 // Clearing the whole suffix table lets us be more tolerant of bad data.
907 for (int i = 0; i < clearCode; ++i) { 920 for (int i = 0; i < clearCode; ++i) {
908 suffix[i] = i; 921 suffix[i] = i;
909 suffixLength[i] = 1; 922 suffixLength[i] = 1;
910 } 923 }
911 return true; 924 return true;
912 } 925 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698