Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 430 else | 430 else |
| 431 return false; | 431 return false; |
| 432 GETN(7, GIFGlobalHeader); | 432 GETN(7, GIFGlobalHeader); |
| 433 break; | 433 break; |
| 434 } | 434 } |
| 435 | 435 |
| 436 case GIFGlobalHeader: { | 436 case GIFGlobalHeader: { |
| 437 // This is the height and width of the "screen" or frame into which images are rendered. The | 437 // This is the height and width of the "screen" or frame into which images are rendered. The |
| 438 // individual images can be smaller than the screen size and located with an origin anywhere | 438 // individual images can be smaller than the screen size and located with an origin anywhere |
| 439 // within the screen. | 439 // within the screen. |
| 440 // Note that size is final only when the first frame is encountered. | |
| 440 m_screenWidth = GETINT16(currentComponent); | 441 m_screenWidth = GETINT16(currentComponent); |
| 441 m_screenHeight = GETINT16(currentComponent + 2); | 442 m_screenHeight = GETINT16(currentComponent + 2); |
| 442 | 443 |
| 443 // CALLBACK: Inform the decoderplugin of our size. | |
| 444 // Note: A subsequent frame might have dimensions larger than the "s creen" dimensions. | |
| 445 if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight)) | |
| 446 return false; | |
| 447 | |
| 448 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 ); | 444 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 ); |
| 449 | 445 |
| 450 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */ | 446 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */ |
| 451 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol orMapColors); | 447 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol orMapColors); |
| 452 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC olormap); | 448 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC olormap); |
| 453 break; | 449 break; |
| 454 } | 450 } |
| 455 | 451 |
| 456 GETN(1, GIFImageStart); | 452 GETN(1, GIFImageStart); |
| 457 break; | 453 break; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 unsigned height, width, xOffset, yOffset; | 621 unsigned height, width, xOffset, yOffset; |
| 626 | 622 |
| 627 /* Get image offsets, with respect to the screen origin */ | 623 /* Get image offsets, with respect to the screen origin */ |
| 628 xOffset = GETINT16(currentComponent); | 624 xOffset = GETINT16(currentComponent); |
| 629 yOffset = GETINT16(currentComponent + 2); | 625 yOffset = GETINT16(currentComponent + 2); |
| 630 | 626 |
| 631 /* Get image width and height. */ | 627 /* Get image width and height. */ |
| 632 width = GETINT16(currentComponent + 4); | 628 width = GETINT16(currentComponent + 4); |
| 633 height = GETINT16(currentComponent + 6); | 629 height = GETINT16(currentComponent + 6); |
| 634 | 630 |
| 635 /* Work around broken GIF files where the logical screen | 631 // Work around broken GIF file where the first frame has size greate r than the |
|
Peter Kasting
2015/01/08 06:56:18
Nit: files
I also wouldn't mind wrapping the comm
Alpha Left Google
2015/01/12 22:12:49
Done.
| |
| 636 * size has weird width or height. We assume that GIF87a | 632 // "screen size". |
|
Peter Kasting
2015/01/08 06:56:18
What about when subsequent frames have larger size
Alpha Left Google
2015/01/12 22:12:49
I added the std::max() code in 672 and 673 in the
| |
| 637 * files don't contain animations. | |
| 638 */ | |
| 639 if (currentFrameIsFirstFrame() | 633 if (currentFrameIsFirstFrame() |
| 640 && ((m_screenHeight < height) || (m_screenWidth < width) || (m_v ersion == 87))) { | 634 && (m_screenHeight < yOffset + height || m_screenWidth < xOffset + width)) { |
| 641 m_screenHeight = height; | 635 m_screenHeight = std::max(m_screenHeight, yOffset + height); |
| 642 m_screenWidth = width; | 636 m_screenWidth = std::max(m_screenWidth, xOffset + width); |
|
Peter Kasting
2015/01/08 06:56:18
This is a behavior change from the previous code i
Alpha Left Google
2015/01/12 22:12:49
The behavior changes unless the image is GIF87 and
| |
| 643 xOffset = 0; | |
| 644 yOffset = 0; | |
| 645 | |
| 646 // CALLBACK: Inform the decoderplugin of our size. | |
| 647 if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight )) | |
| 648 return false; | |
| 649 } | 637 } |
| 650 | 638 |
| 651 // Work around more broken GIF files that have zero image width or h eight | 639 // Inform the client of the final size. |
| 652 if (!height || !width) { | 640 if (!m_sizeFinal && m_client && !m_client->setSize(m_screenWidth, m_ screenHeight)) |
|
Peter Kasting
2015/01/08 06:56:18
Is it possible to have m_client null here but have
Alpha Left Google
2015/01/12 22:12:49
m_client is always non null. We shouldn't need to
| |
| 653 height = m_screenHeight; | 641 return false; |
| 654 width = m_screenWidth; | 642 m_sizeFinal = true; |
| 655 if (!height || !width) | |
| 656 return false; | |
| 657 } | |
| 658 | 643 |
| 659 if (query == GIFImageDecoder::GIFSizeQuery) { | 644 if (query == GIFImageDecoder::GIFSizeQuery) { |
| 660 // The decoder needs to stop. Hand back the number of bytes we c onsumed from | 645 // The decoder needs to stop. Hand back the number of bytes we c onsumed from |
| 661 // buffer minus 9 (the amount we consumed to read the header). | 646 // buffer minus 9 (the amount we consumed to read the header). |
| 662 setRemainingBytes(len + 9); | 647 setRemainingBytes(len + 9); |
| 663 GETN(9, GIFImageHeader); | 648 GETN(9, GIFImageHeader); |
| 664 return true; | 649 return true; |
| 665 } | 650 } |
| 666 | 651 |
| 667 addFrameIfNecessary(); | 652 addFrameIfNecessary(); |
| 668 GIFFrameContext* currentFrame = m_frames.last().get(); | 653 GIFFrameContext* currentFrame = m_frames.last().get(); |
| 669 | 654 |
| 670 currentFrame->setHeaderDefined(); | 655 currentFrame->setHeaderDefined(); |
| 656 | |
| 657 // Work around more broken GIF files that have zero image width or h eight. | |
| 658 if (!height || !width) { | |
| 659 height = m_screenHeight; | |
| 660 width = m_screenWidth; | |
| 661 if (!height || !width) | |
| 662 return false; | |
| 663 } | |
| 671 currentFrame->setRect(xOffset, yOffset, width, height); | 664 currentFrame->setRect(xOffset, yOffset, width, height); |
| 672 m_screenWidth = std::max(m_screenWidth, width); | |
| 673 m_screenHeight = std::max(m_screenHeight, height); | |
| 674 currentFrame->setInterlaced(currentComponent[8] & 0x40); | 665 currentFrame->setInterlaced(currentComponent[8] & 0x40); |
| 675 | 666 |
| 676 // Overlaying interlaced, transparent GIFs over | 667 // Overlaying interlaced, transparent GIFs over |
| 677 // existing image data using the Haeberli display hack | 668 // existing image data using the Haeberli display hack |
| 678 // requires saving the underlying image in order to | 669 // requires saving the underlying image in order to |
| 679 // avoid jaggies at the transparency edges. We are | 670 // avoid jaggies at the transparency edges. We are |
| 680 // unprepared to deal with that, so don't display such | 671 // unprepared to deal with that, so don't display such |
| 681 // images progressively. Which means only the first | 672 // images progressively. Which means only the first |
| 682 // frame can be progressively displayed. | 673 // frame can be progressively displayed. |
| 683 // FIXME: It is possible that a non-transparent frame | 674 // FIXME: It is possible that a non-transparent frame |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 791 rowIter = rowBuffer.begin(); | 782 rowIter = rowBuffer.begin(); |
| 792 rowsRemaining = m_frameContext->height(); | 783 rowsRemaining = m_frameContext->height(); |
| 793 | 784 |
| 794 // Clearing the whole suffix table lets us be more tolerant of bad data. | 785 // Clearing the whole suffix table lets us be more tolerant of bad data. |
| 795 for (int i = 0; i < clearCode; ++i) { | 786 for (int i = 0; i < clearCode; ++i) { |
| 796 suffix[i] = i; | 787 suffix[i] = i; |
| 797 suffixLength[i] = 1; | 788 suffixLength[i] = 1; |
| 798 } | 789 } |
| 799 return true; | 790 return true; |
| 800 } | 791 } |
| OLD | NEW |