| 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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 // Mark the current component as consumed. Note that currentComponent will | 439 // Mark the current component as consumed. Note that currentComponent will |
| 440 // remain pointed at this component until the next loop iteration. | 440 // remain pointed at this component until the next loop iteration. |
| 441 dataPosition += m_bytesToConsume; | 441 dataPosition += m_bytesToConsume; |
| 442 len -= m_bytesToConsume; | 442 len -= m_bytesToConsume; |
| 443 | 443 |
| 444 switch (m_state) { | 444 switch (m_state) { |
| 445 case GIFLZW: | 445 case GIFLZW: |
| 446 ASSERT(!m_frames.isEmpty()); | 446 ASSERT(!m_frames.isEmpty()); |
| 447 // m_bytesToConsume is the current component size because it hasn't been | 447 // m_bytesToConsume is the current component size because it hasn't been |
| 448 // updated. | 448 // updated. |
| 449 m_frames.last()->addLzwBlock(currentComponentPosition, | 449 m_frames.back()->addLzwBlock(currentComponentPosition, |
| 450 m_bytesToConsume); | 450 m_bytesToConsume); |
| 451 GETN(1, GIFSubBlock); | 451 GETN(1, GIFSubBlock); |
| 452 break; | 452 break; |
| 453 | 453 |
| 454 case GIFLZWStart: { | 454 case GIFLZWStart: { |
| 455 ASSERT(!m_frames.isEmpty()); | 455 ASSERT(!m_frames.isEmpty()); |
| 456 m_frames.last()->setDataSize(static_cast<unsigned char>( | 456 m_frames.back()->setDataSize(static_cast<unsigned char>( |
| 457 reader.getOneByte(currentComponentPosition))); | 457 reader.getOneByte(currentComponentPosition))); |
| 458 GETN(1, GIFSubBlock); | 458 GETN(1, GIFSubBlock); |
| 459 break; | 459 break; |
| 460 } | 460 } |
| 461 | 461 |
| 462 case GIFType: { | 462 case GIFType: { |
| 463 const char* currentComponent = | 463 const char* currentComponent = |
| 464 reader.getConsecutiveData(currentComponentPosition, 6, readBuffer); | 464 reader.getConsecutiveData(currentComponentPosition, 6, readBuffer); |
| 465 | 465 |
| 466 // All GIF files begin with "GIF87a" or "GIF89a". | 466 // All GIF files begin with "GIF87a" or "GIF89a". |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 GETN(1, GIFConsumeBlock); | 595 GETN(1, GIFConsumeBlock); |
| 596 break; | 596 break; |
| 597 } | 597 } |
| 598 | 598 |
| 599 case GIFControlExtension: { | 599 case GIFControlExtension: { |
| 600 const unsigned char* currentComponent = | 600 const unsigned char* currentComponent = |
| 601 reinterpret_cast<const unsigned char*>(reader.getConsecutiveData( | 601 reinterpret_cast<const unsigned char*>(reader.getConsecutiveData( |
| 602 currentComponentPosition, 4, readBuffer)); | 602 currentComponentPosition, 4, readBuffer)); |
| 603 | 603 |
| 604 addFrameIfNecessary(); | 604 addFrameIfNecessary(); |
| 605 GIFFrameContext* currentFrame = m_frames.last().get(); | 605 GIFFrameContext* currentFrame = m_frames.back().get(); |
| 606 if (*currentComponent & 0x1) | 606 if (*currentComponent & 0x1) |
| 607 currentFrame->setTransparentPixel(currentComponent[3]); | 607 currentFrame->setTransparentPixel(currentComponent[3]); |
| 608 | 608 |
| 609 // We ignore the "user input" bit. | 609 // We ignore the "user input" bit. |
| 610 | 610 |
| 611 // NOTE: This relies on the values in the FrameDisposalMethod enum | 611 // NOTE: This relies on the values in the FrameDisposalMethod enum |
| 612 // matching those in the GIF spec! | 612 // matching those in the GIF spec! |
| 613 int disposalMethod = ((*currentComponent) >> 2) & 0x7; | 613 int disposalMethod = ((*currentComponent) >> 2) & 0x7; |
| 614 if (disposalMethod < 4) { | 614 if (disposalMethod < 4) { |
| 615 currentFrame->setDisposalMethod( | 615 currentFrame->setDisposalMethod( |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 if (query == GIFImageDecoder::GIFSizeQuery) { | 775 if (query == GIFImageDecoder::GIFSizeQuery) { |
| 776 // The decoder needs to stop. Hand back the number of bytes we | 776 // The decoder needs to stop. Hand back the number of bytes we |
| 777 // consumed from the buffer minus 9 (the amount we consumed to read | 777 // consumed from the buffer minus 9 (the amount we consumed to read |
| 778 // the header). | 778 // the header). |
| 779 setRemainingBytes(len + 9); | 779 setRemainingBytes(len + 9); |
| 780 GETN(9, GIFImageHeader); | 780 GETN(9, GIFImageHeader); |
| 781 return true; | 781 return true; |
| 782 } | 782 } |
| 783 | 783 |
| 784 addFrameIfNecessary(); | 784 addFrameIfNecessary(); |
| 785 GIFFrameContext* currentFrame = m_frames.last().get(); | 785 GIFFrameContext* currentFrame = m_frames.back().get(); |
| 786 | 786 |
| 787 currentFrame->setHeaderDefined(); | 787 currentFrame->setHeaderDefined(); |
| 788 | 788 |
| 789 // Work around more broken GIF files that have zero image width or | 789 // Work around more broken GIF files that have zero image width or |
| 790 // height. | 790 // height. |
| 791 if (!height || !width) { | 791 if (!height || !width) { |
| 792 height = m_screenHeight; | 792 height = m_screenHeight; |
| 793 width = m_screenWidth; | 793 width = m_screenWidth; |
| 794 if (!height || !width) | 794 if (!height || !width) |
| 795 return false; | 795 return false; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 818 GETN(BYTES_PER_COLORMAP_ENTRY * numColors, GIFImageColormap); | 818 GETN(BYTES_PER_COLORMAP_ENTRY * numColors, GIFImageColormap); |
| 819 break; | 819 break; |
| 820 } | 820 } |
| 821 | 821 |
| 822 GETN(1, GIFLZWStart); | 822 GETN(1, GIFLZWStart); |
| 823 break; | 823 break; |
| 824 } | 824 } |
| 825 | 825 |
| 826 case GIFImageColormap: { | 826 case GIFImageColormap: { |
| 827 ASSERT(!m_frames.isEmpty()); | 827 ASSERT(!m_frames.isEmpty()); |
| 828 m_frames.last()->localColorMap().setDefined(); | 828 m_frames.back()->localColorMap().setDefined(); |
| 829 GETN(1, GIFLZWStart); | 829 GETN(1, GIFLZWStart); |
| 830 break; | 830 break; |
| 831 } | 831 } |
| 832 | 832 |
| 833 case GIFSubBlock: { | 833 case GIFSubBlock: { |
| 834 const size_t bytesInBlock = static_cast<unsigned char>( | 834 const size_t bytesInBlock = static_cast<unsigned char>( |
| 835 reader.getOneByte(currentComponentPosition)); | 835 reader.getOneByte(currentComponentPosition)); |
| 836 if (bytesInBlock) | 836 if (bytesInBlock) |
| 837 GETN(bytesInBlock, GIFLZW); | 837 GETN(bytesInBlock, GIFLZW); |
| 838 else { | 838 else { |
| 839 // Finished parsing one frame; Process next frame. | 839 // Finished parsing one frame; Process next frame. |
| 840 ASSERT(!m_frames.isEmpty()); | 840 ASSERT(!m_frames.isEmpty()); |
| 841 // Note that some broken GIF files do not have enough LZW blocks to | 841 // Note that some broken GIF files do not have enough LZW blocks to |
| 842 // fully decode all rows; we treat this case as "frame complete". | 842 // fully decode all rows; we treat this case as "frame complete". |
| 843 m_frames.last()->setComplete(); | 843 m_frames.back()->setComplete(); |
| 844 GETN(1, GIFImageStart); | 844 GETN(1, GIFImageStart); |
| 845 } | 845 } |
| 846 break; | 846 break; |
| 847 } | 847 } |
| 848 | 848 |
| 849 case GIFDone: { | 849 case GIFDone: { |
| 850 m_parseCompleted = true; | 850 m_parseCompleted = true; |
| 851 return true; | 851 return true; |
| 852 } | 852 } |
| 853 | 853 |
| 854 default: | 854 default: |
| 855 // We shouldn't ever get here. | 855 // We shouldn't ever get here. |
| 856 return false; | 856 return false; |
| 857 break; | 857 break; |
| 858 } | 858 } |
| 859 } | 859 } |
| 860 | 860 |
| 861 setRemainingBytes(len); | 861 setRemainingBytes(len); |
| 862 return true; | 862 return true; |
| 863 } | 863 } |
| 864 | 864 |
| 865 void GIFImageReader::setRemainingBytes(size_t remainingBytes) { | 865 void GIFImageReader::setRemainingBytes(size_t remainingBytes) { |
| 866 ASSERT(remainingBytes <= m_data->size()); | 866 ASSERT(remainingBytes <= m_data->size()); |
| 867 m_bytesRead = m_data->size() - remainingBytes; | 867 m_bytesRead = m_data->size() - remainingBytes; |
| 868 } | 868 } |
| 869 | 869 |
| 870 void GIFImageReader::addFrameIfNecessary() { | 870 void GIFImageReader::addFrameIfNecessary() { |
| 871 if (m_frames.isEmpty() || m_frames.last()->isComplete()) | 871 if (m_frames.isEmpty() || m_frames.back()->isComplete()) |
| 872 m_frames.append(wrapUnique(new GIFFrameContext(m_frames.size()))); | 872 m_frames.append(wrapUnique(new GIFFrameContext(m_frames.size()))); |
| 873 } | 873 } |
| 874 | 874 |
| 875 // FIXME: Move this method to close to doLZW(). | 875 // FIXME: Move this method to close to doLZW(). |
| 876 bool GIFLZWContext::prepareToDecode() { | 876 bool GIFLZWContext::prepareToDecode() { |
| 877 ASSERT(m_frameContext->isDataSizeDefined() && | 877 ASSERT(m_frameContext->isDataSizeDefined() && |
| 878 m_frameContext->isHeaderDefined()); | 878 m_frameContext->isHeaderDefined()); |
| 879 | 879 |
| 880 // Since we use a codesize of 1 more than the datasize, we need to ensure | 880 // Since we use a codesize of 1 more than the datasize, we need to ensure |
| 881 // that our datasize is strictly less than the MAX_DICTIONARY_ENTRY_BITS. | 881 // that our datasize is strictly less than the MAX_DICTIONARY_ENTRY_BITS. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 rowIter = rowBuffer.begin(); | 916 rowIter = rowBuffer.begin(); |
| 917 rowsRemaining = m_frameContext->height(); | 917 rowsRemaining = m_frameContext->height(); |
| 918 | 918 |
| 919 // 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. |
| 920 for (int i = 0; i < clearCode; ++i) { | 920 for (int i = 0; i < clearCode; ++i) { |
| 921 suffix[i] = i; | 921 suffix[i] = i; |
| 922 suffixLength[i] = 1; | 922 suffixLength[i] = 1; |
| 923 } | 923 } |
| 924 return true; | 924 return true; |
| 925 } | 925 } |
| OLD | NEW |