Index: Source/core/platform/image-decoders/ImageDecoder.h |
diff --git a/Source/core/platform/image-decoders/ImageDecoder.h b/Source/core/platform/image-decoders/ImageDecoder.h |
index 724e27c918dc3e3c7a5dcd00f2ef98bfa3cd2aeb..591548dc1b66be8314bbdbc14affef93a64acc24 100644 |
--- a/Source/core/platform/image-decoders/ImageDecoder.h |
+++ b/Source/core/platform/image-decoders/ImageDecoder.h |
@@ -115,6 +115,14 @@ namespace WebCore { |
FrameDisposalMethod disposalMethod() const { return m_disposalMethod; } |
bool premultiplyAlpha() const { return m_premultiplyAlpha; } |
void reportMemoryUsage(MemoryObjectInfo*) const; |
+ size_t requiredPreviousFrameIndex() const |
+ { |
+ ASSERT(m_requiredPreviousFrameIndexValid); |
+ return m_requiredPreviousFrameIndex; |
+ } |
+#if !ASSERT_DISABLED |
+ bool requiredPreviousFrameIndexValid() const { return m_requiredPreviousFrameIndexValid; } |
+#endif |
void setHasAlpha(bool alpha); |
void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; } |
@@ -122,6 +130,13 @@ namespace WebCore { |
void setDuration(unsigned duration) { m_duration = duration; } |
void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; } |
void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; } |
+ void setRequiredPreviousFrameIndex(size_t previousFrameIndex) |
+ { |
+ m_requiredPreviousFrameIndex = previousFrameIndex; |
+#if !ASSERT_DISABLED |
+ m_requiredPreviousFrameIndexValid = true; |
+#endif |
+ } |
inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a) |
{ |
@@ -200,6 +215,15 @@ namespace WebCore { |
unsigned m_duration; |
FrameDisposalMethod m_disposalMethod; |
bool m_premultiplyAlpha; |
+ |
+ // The frame that must be decoded before this frame can be decoded. |
+ // WTF::notFound if this frame doesn't require any previous frame. |
+ // This is used by ImageDecoder::clearCacheExceptFrame(), and will never |
+ // be read for image formats that do not have multiple frames. |
+ size_t m_requiredPreviousFrameIndex; |
+#if !ASSERT_DISABLED |
+ bool m_requiredPreviousFrameIndexValid; |
+#endif |
}; |
// ImageDecoder is a base for all format-specific decoders |
@@ -358,10 +382,13 @@ namespace WebCore { |
bool failed() const { return m_failed; } |
- // Clears decoded pixel data from before the provided frame unless that |
- // data may be needed to decode future frames (e.g. due to GIF frame |
- // compositing). |
- virtual void clearFrameBufferCache(size_t) { } |
+ // Clears decoded pixel data from all frames except the provided frame, |
+ // unless that frame has status FrameEmpty, in which case we instead |
+ // preserve the most recent frame whose data is required in order to |
+ // decode this frame. Callers may pass WTF::notFound to clear all frames. |
+ // |
+ // Returns the number of bytes of frame data actually cleared. |
+ size_t clearCacheExceptFrame(size_t); |
// If the image has a cursor hot-spot, stores it in the argument |
// and returns true. Otherwise returns false. |
@@ -378,6 +405,25 @@ namespace WebCore { |
} |
protected: |
+ // Calculates the most recent frame whose image data may be needed in |
+ // order to decode frame |frameIndex|, based on frame disposal methods. |
+ // If no previous frame's data is required, returns WTF::notFound. |
+ // |
+ // This function requires that the previous frame's |
+ // |m_requiredPreviousFrameIndex| member has been set correctly. The |
+ // easiest way to ensure this is for subclasses to call this method and |
+ // store the result on the frame via setRequiredPreviousFrameIndex() |
+ // as soon as the frame has been created and parsed sufficiently to |
+ // determine the disposal method; assuming this happens for all frames |
+ // in order, the required invariant will hold. |
+ // |
+ // Image formats which do not use more than one frame do not need to |
+ // worry about this; see comments on |
+ // ImageFrame::m_requiredPreviousFrameIndex. |
+ size_t findRequiredPreviousFrame(size_t frameIndex); |
+ |
+ virtual void clearFrameBuffer(size_t frameIndex); |
+ |
RefPtr<SharedBuffer> m_data; // The encoded data. |
Vector<ImageFrame, 1> m_frameBufferCache; |
bool m_premultiplyAlpha; |