Changeset 222910 in webkit
- Timestamp:
- Oct 5, 2017 7:00:05 AM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r222908 r222910 1 2017-10-05 Miguel Gomez <magomez@igalia.com> 2 3 [GTK][WPE] GIFImageDecoder never clears decoded frames even when told to do so 4 https://bugs.webkit.org/show_bug.cgi?id=177864 5 6 Reviewed by Carlos Garcia Campos. 7 8 Fix GIFImageDecoder::clearFrameBufferCache() so it really deletes decoded buffers, and modify 9 GIFImageDecoder to be able to decode frames that are not requested in the expected order. 10 11 Covered by existent tests. 12 13 * platform/image-decoders/gif/GIFImageDecoder.cpp: 14 (WebCore::GIFImageDecoder::findFirstRequiredFrameToDecode): 15 (WebCore::GIFImageDecoder::frameBufferAtIndex): 16 (WebCore::GIFImageDecoder::clearFrameBufferCache): 17 * platform/image-decoders/gif/GIFImageDecoder.h: 18 * platform/image-decoders/gif/GIFImageReader.cpp: 19 (GIFImageReader::decode): 20 * platform/image-decoders/gif/GIFImageReader.h: 21 (GIFImageReader::frameContext const): 22 1 23 2017-10-05 Fujii Hironori <Hironori.Fujii@sony.com> 2 24 -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
r222836 r222910 102 102 } 103 103 104 size_t GIFImageDecoder::findFirstRequiredFrameToDecode(size_t frameIndex) 105 { 106 // The first frame doesn't depend on any other. 107 if (!frameIndex) 108 return 0; 109 110 for (size_t i = frameIndex; i > 0; --i) { 111 ImageFrame& frame = m_frameBufferCache[i - 1]; 112 113 // Frames with disposal method RestoreToPrevious are useless, skip them. 114 if (frame.disposalMethod() == ImageFrame::DisposalMethod::RestoreToPrevious) 115 continue; 116 117 // At this point the disposal method can be Unspecified, DoNotDispose or RestoreToBackground. 118 // In every case, if the frame is complete we can start decoding the next one. 119 if (frame.isComplete()) 120 return i; 121 122 // If the disposal method of this frame is RestoreToBackground and it fills the whole area, 123 // the next frame's backing store is initialized to transparent, so we start decoding with it. 124 if (frame.disposalMethod() == ImageFrame::DisposalMethod::RestoreToBackground) { 125 // We cannot use frame.backingStore()->frameRect() here, because it has been cleared 126 // when the frame was removed from the cache. We need to get the values from the 127 // reader context. 128 const auto* frameContext = m_reader->frameContext(i - 1); 129 ASSERT(frameContext); 130 IntRect frameRect(frameContext->xOffset, frameContext->yOffset, frameContext->width, frameContext->height); 131 // We would need to scale frameRect and check whether it fills the whole scaledSize(). But 132 // can check whether the original frameRect fills size() instead. If the frame fills the 133 // whole area then it can be decoded without dependencies. 134 if (frameRect.contains({ { }, size() })) 135 return i; 136 } 137 } 138 139 return 0; 140 } 141 104 142 ImageFrame* GIFImageDecoder::frameBufferAtIndex(size_t index) 105 143 { … … 108 146 109 147 ImageFrame& frame = m_frameBufferCache[index]; 110 if (!frame.isComplete()) 111 decode(index + 1, GIFFullQuery, isAllDataReceived()); 148 if (!frame.isComplete()) { 149 for (auto i = findFirstRequiredFrameToDecode(index); i <= index; i++) 150 decode(i + 1, GIFFullQuery, isAllDataReceived()); 151 } 152 112 153 return &frame; 113 154 } … … 164 205 for (Vector<ImageFrame>::iterator j(m_frameBufferCache.begin()); j != i; ++j) { 165 206 ASSERT(!j->isPartial()); 166 if ( j->isInvalid())207 if (!j->isInvalid()) 167 208 j->clear(); 168 209 } -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
r222836 r222910 66 66 GIFImageDecoder(AlphaOption, GammaAndColorProfileOption); 67 67 void tryDecodeSize(bool allDataReceived) final { decode(0, GIFSizeQuery, allDataReceived); } 68 size_t findFirstRequiredFrameToDecode(size_t); 68 69 69 70 // If the query is GIFFullQuery, decodes the image up to (but not -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
r222836 r222910 366 366 // Already decoded frames can be deleted from the cache and then they require to be decoded again, so 367 367 // the haltAtFrame value we receive here may be lower than m_currentDecodingFrame. In this case 368 // we position m_currentDecodingFrame to haltAtFrame and decode from there.368 // we position m_currentDecodingFrame to haltAtFrame - 1 and decode from there. 369 369 // See bug https://bugs.webkit.org/show_bug.cgi?id=176089. 370 m_currentDecodingFrame = std::min(m_currentDecodingFrame, static_cast<size_t>(haltAtFrame) );370 m_currentDecodingFrame = std::min(m_currentDecodingFrame, static_cast<size_t>(haltAtFrame) - 1); 371 371 372 372 while (m_currentDecodingFrame < std::min(m_frames.size(), static_cast<size_t>(haltAtFrame))) { -
trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h
r206481 r222910 285 285 } 286 286 287 const GIFFrameContext* frameContext(size_t frame) const 288 { 289 return frame < m_frames.size() ? m_frames[frame].get() : nullptr; 290 } 291 287 292 private: 288 293 bool parse(size_t dataPosition, size_t len, bool parseSizeOnly);
Note: See TracChangeset
for help on using the changeset viewer.