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

Unified Diff: Source/core/platform/image-decoders/ImageDecoderTest.cpp

Issue 23068027: Animated WebP: Optimize decoding in case of seeking (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@add_noblend_image
Patch Set: Fix assert fail on debug Created 7 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: Source/core/platform/image-decoders/ImageDecoderTest.cpp
diff --git a/Source/core/platform/image-decoders/ImageDecoderTest.cpp b/Source/core/platform/image-decoders/ImageDecoderTest.cpp
index 65dfe4d76f810462e5ab3899fdfb28820ce4b7fc..f916b8a7d9ed6bb358d69050f630b07b09baec7e 100644
--- a/Source/core/platform/image-decoders/ImageDecoderTest.cpp
+++ b/Source/core/platform/image-decoders/ImageDecoderTest.cpp
@@ -54,10 +54,10 @@ public:
return m_frameBufferCache;
}
- void resetRequiredPreviousFrames()
+ void resetRequiredPreviousFrames(bool knownOpaque = false)
{
for (size_t i = 0; i < m_frameBufferCache.size(); ++i)
- m_frameBufferCache[i].setRequiredPreviousFrameIndex(findRequiredPreviousFrame(i));
+ m_frameBufferCache[i].setRequiredPreviousFrameIndex(findRequiredPreviousFrame(i, knownOpaque));
}
void initFrames(size_t numFrames, unsigned width = 100, unsigned height = 100)
@@ -73,71 +73,120 @@ TEST(ImageDecoderTest, requiredPreviousFrameIndex)
{
OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
decoder->initFrames(6);
- Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache();
+ Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
- decoderFrameBufferCache[1].setDisposalMethod(ImageFrame::DisposeKeep);
- decoderFrameBufferCache[2].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
- decoderFrameBufferCache[3].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
- decoderFrameBufferCache[4].setDisposalMethod(ImageFrame::DisposeKeep);
+ frameBuffers[1].setDisposalMethod(ImageFrame::DisposeKeep);
+ frameBuffers[2].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ frameBuffers[3].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ frameBuffers[4].setDisposalMethod(ImageFrame::DisposeKeep);
decoder->resetRequiredPreviousFrames();
// The first frame doesn't require any previous frame.
- EXPECT_EQ(notFound, decoderFrameBufferCache[0].requiredPreviousFrameIndex());
+ EXPECT_EQ(notFound, frameBuffers[0].requiredPreviousFrameIndex());
// The previous DisposeNotSpecified frame is required.
- EXPECT_EQ(0u, decoderFrameBufferCache[1].requiredPreviousFrameIndex());
+ EXPECT_EQ(0u, frameBuffers[1].requiredPreviousFrameIndex());
// DisposeKeep is treated as DisposeNotSpecified.
- EXPECT_EQ(1u, decoderFrameBufferCache[2].requiredPreviousFrameIndex());
+ EXPECT_EQ(1u, frameBuffers[2].requiredPreviousFrameIndex());
// Previous DisposeOverwritePrevious frames are skipped.
- EXPECT_EQ(1u, decoderFrameBufferCache[3].requiredPreviousFrameIndex());
- EXPECT_EQ(1u, decoderFrameBufferCache[4].requiredPreviousFrameIndex());
- EXPECT_EQ(4u, decoderFrameBufferCache[5].requiredPreviousFrameIndex());
+ EXPECT_EQ(1u, frameBuffers[3].requiredPreviousFrameIndex());
+ EXPECT_EQ(1u, frameBuffers[4].requiredPreviousFrameIndex());
+ EXPECT_EQ(4u, frameBuffers[5].requiredPreviousFrameIndex());
}
TEST(ImageDecoderTest, requiredPreviousFrameIndexDisposeOverwriteBgcolor)
{
OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
decoder->initFrames(3);
- Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache();
+ Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
// Fully covering DisposeOverwriteBgcolor previous frame resets the starting state.
- decoderFrameBufferCache[1].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
+ frameBuffers[1].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
decoder->resetRequiredPreviousFrames();
- EXPECT_EQ(notFound, decoderFrameBufferCache[2].requiredPreviousFrameIndex());
+ EXPECT_EQ(notFound, frameBuffers[2].requiredPreviousFrameIndex());
// Partially covering DisposeOverwriteBgcolor previous frame is required by this frame.
- decoderFrameBufferCache[1].setOriginalFrameRect(IntRect(50, 50, 50, 50));
+ frameBuffers[1].setOriginalFrameRect(IntRect(50, 50, 50, 50));
decoder->resetRequiredPreviousFrames();
- EXPECT_EQ(1u, decoderFrameBufferCache[2].requiredPreviousFrameIndex());
+ EXPECT_EQ(1u, frameBuffers[2].requiredPreviousFrameIndex());
}
TEST(ImageDecoderTest, requiredPreviousFrameIndexForFrame1)
{
OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
decoder->initFrames(2);
- Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache();
+ Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
decoder->resetRequiredPreviousFrames();
- EXPECT_EQ(0u, decoderFrameBufferCache[1].requiredPreviousFrameIndex());
+ EXPECT_EQ(0u, frameBuffers[1].requiredPreviousFrameIndex());
// The first frame with DisposeOverwritePrevious or DisposeOverwriteBgcolor
// resets the starting state.
- decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
decoder->resetRequiredPreviousFrames();
- EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex());
- decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
+ EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex());
+ frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
decoder->resetRequiredPreviousFrames();
- EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex());
+ EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex());
// ... even if it partially covers.
- decoderFrameBufferCache[0].setOriginalFrameRect(IntRect(50, 50, 50, 50));
+ frameBuffers[0].setOriginalFrameRect(IntRect(50, 50, 50, 50));
- decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
decoder->resetRequiredPreviousFrames();
- EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex());
- decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
+ EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex());
+ frameBuffers[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
decoder->resetRequiredPreviousFrames();
- EXPECT_EQ(notFound, decoderFrameBufferCache[1].requiredPreviousFrameIndex());
+ EXPECT_EQ(notFound, frameBuffers[1].requiredPreviousFrameIndex());
+}
+
+TEST(ImageDecoderTest, requiredPreviousFrameIndexBlendAtopBgcolor)
+{
+ OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
+ decoder->initFrames(3);
+ Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
+
+ frameBuffers[1].setOriginalFrameRect(IntRect(25, 25, 50, 50));
+ frameBuffers[2].setAlphaBlendSource(ImageFrame::BlendAtopBgcolor);
+
+ // A full frame with 'blending method == BlendAtopBgcolor' doesn't depend on any prior frames.
+ for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
+ frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
+ decoder->resetRequiredPreviousFrames();
+ EXPECT_EQ(notFound, frameBuffers[2].requiredPreviousFrameIndex());
+ }
+
+ // A non-full frame with 'blending method == BlendAtopBgcolor' does depend on a prior frame.
+ frameBuffers[2].setOriginalFrameRect(IntRect(50, 50, 50, 50));
+ for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
+ frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
+ decoder->resetRequiredPreviousFrames();
+ EXPECT_NE(notFound, frameBuffers[2].requiredPreviousFrameIndex());
+ }
+}
+
+TEST(ImageDecoderTest, requiredPreviousFrameIndexKnownOpaque)
+{
+ OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
+ decoder->initFrames(3);
+ Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
+
+ frameBuffers[1].setOriginalFrameRect(IntRect(25, 25, 50, 50));
+
+ // A full frame that is known to be opaque doesn't depend on any prior frames.
+ for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
+ frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
+ decoder->resetRequiredPreviousFrames(true);
+ EXPECT_EQ(notFound, frameBuffers[2].requiredPreviousFrameIndex());
+ }
+
+ // A non-full frame that is known to be opaque does depend on a prior frame.
+ frameBuffers[2].setOriginalFrameRect(IntRect(50, 50, 50, 50));
+ for (int disposeMethod = ImageFrame::DisposeNotSpecified; disposeMethod <= ImageFrame::DisposeOverwritePrevious; ++disposeMethod) {
+ frameBuffers[1].setDisposalMethod(static_cast<ImageFrame::DisposalMethod>(disposeMethod));
+ decoder->resetRequiredPreviousFrames(true);
+ EXPECT_NE(notFound, frameBuffers[2].requiredPreviousFrameIndex());
+ }
}
TEST(ImageDecoderTest, clearCacheExceptFrameDoNothing)
@@ -155,15 +204,15 @@ TEST(ImageDecoderTest, clearCacheExceptFrameAll)
const size_t numFrames = 10;
OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
decoder->initFrames(numFrames);
- Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache();
+ Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
for (size_t i = 0; i < numFrames; ++i)
- decoderFrameBufferCache[i].setStatus(i % 2 ? ImageFrame::FramePartial : ImageFrame::FrameComplete);
+ frameBuffers[i].setStatus(i % 2 ? ImageFrame::FramePartial : ImageFrame::FrameComplete);
decoder->clearCacheExceptFrame(notFound);
for (size_t i = 0; i < numFrames; ++i) {
SCOPED_TRACE(testing::Message() << i);
- EXPECT_EQ(ImageFrame::FrameEmpty, decoderFrameBufferCache[i].status());
+ EXPECT_EQ(ImageFrame::FrameEmpty, frameBuffers[i].status());
}
}
@@ -172,17 +221,17 @@ TEST(ImageDecoderTest, clearCacheExceptFramePreverveClearExceptFrame)
const size_t numFrames = 10;
OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
decoder->initFrames(numFrames);
- Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache();
+ Vector<ImageFrame, 1>& frameBuffers = decoder->frameBufferCache();
for (size_t i = 0; i < numFrames; ++i)
- decoderFrameBufferCache[i].setStatus(ImageFrame::FrameComplete);
+ frameBuffers[i].setStatus(ImageFrame::FrameComplete);
decoder->resetRequiredPreviousFrames();
decoder->clearCacheExceptFrame(5);
for (size_t i = 0; i < numFrames; ++i) {
SCOPED_TRACE(testing::Message() << i);
if (i == 5)
- EXPECT_EQ(ImageFrame::FrameComplete, decoderFrameBufferCache[i].status());
+ EXPECT_EQ(ImageFrame::FrameComplete, frameBuffers[i].status());
else
- EXPECT_EQ(ImageFrame::FrameEmpty, decoderFrameBufferCache[i].status());
+ EXPECT_EQ(ImageFrame::FrameEmpty, frameBuffers[i].status());
}
}
« no previous file with comments | « Source/core/platform/image-decoders/ImageDecoder.cpp ('k') | Source/core/platform/image-decoders/ImageFrame.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698