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

Unified Diff: Source/WebKit/chromium/tests/ImageDecoderTest.cpp

Issue 15350006: Decode GIF image frames on demand. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Don't preserve the last frame and frames at intervals Created 7 years, 7 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/WebKit/chromium/tests/ImageDecoderTest.cpp
diff --git a/Source/WebKit/chromium/tests/ImageDecoderTest.cpp b/Source/WebKit/chromium/tests/ImageDecoderTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2665421016d70e3c521015b993837198f0c4ed07
--- /dev/null
+++ b/Source/WebKit/chromium/tests/ImageDecoderTest.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/platform/image-decoders/ImageDecoder.h"
+
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+class TestImageDecoder : public ImageDecoder {
+public:
+ TestImageDecoder()
+ : ImageDecoder(ImageSource::AlphaNotPremultiplied, ImageSource::GammaAndColorProfileApplied)
+ {
+ }
+
+ virtual String filenameExtension() const OVERRIDE { return ""; }
+ virtual ImageFrame* frameBufferAtIndex(size_t) OVERRIDE { return 0; }
+
+ size_t findRequiredPreviousFrame(size_t frameIndex)
+ {
+ return ImageDecoder::findRequiredPreviousFrame(frameIndex);
+ }
+
+ Vector<ImageFrame, 1>& frameBufferCache()
+ {
+ return m_frameBufferCache;
+ }
+
+ void resetRequiredPreviousFrames()
+ {
+ for (size_t i = 0; i < m_frameBufferCache.size(); ++i)
+ m_frameBufferCache[i].setRequiredPreviousFrameIndex(findRequiredPreviousFrame(i));
+ }
+};
+
+TEST(ImageDecoderTest, findRequiredPreviousFrame)
+{
+ OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
+ Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache();
+
+ const size_t numFrames = 6;
+ const unsigned defaultWidth = 100;
+ const unsigned defaultHeight = 100;
+ decoder->setSize(defaultWidth, defaultHeight);
+ decoderFrameBufferCache.resize(numFrames);
+ for (size_t i = 0; i < numFrames; ++i)
+ decoderFrameBufferCache[i].setOriginalFrameRect(IntRect(0, 0, defaultWidth, defaultHeight));
+
+ decoderFrameBufferCache[1].setDisposalMethod(ImageFrame::DisposeKeep);
+ decoderFrameBufferCache[2].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ decoderFrameBufferCache[3].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ decoderFrameBufferCache[4].setDisposalMethod(ImageFrame::DisposeKeep);
+
+ // The first frame doesn't require any previous frame.
+ EXPECT_EQ(notFound, decoder->findRequiredPreviousFrame(0));
+ // The previous DisposeNotSpecified frame is required.
+ EXPECT_EQ(0u, decoder->findRequiredPreviousFrame(1));
+ // DisposeKeep is treated as DisposeNotSpecified.
+ EXPECT_EQ(1u, decoder->findRequiredPreviousFrame(2));
+ // Previous DisposeOverwritePrevious frames are skipped.
+ EXPECT_EQ(1u, decoder->findRequiredPreviousFrame(3));
+ EXPECT_EQ(1u, decoder->findRequiredPreviousFrame(4));
+ EXPECT_EQ(4u, decoder->findRequiredPreviousFrame(5));
+
+ // Fully covering DisposeOverwriteBgcolor previous frame resets the starting state.
+ decoderFrameBufferCache[1].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
Alpha Left Google 2013/05/22 20:18:09 I suggest this be a separate test case.
Xianzhu 2013/05/22 23:43:29 Done.
+ EXPECT_EQ(notFound, decoder->findRequiredPreviousFrame(2));
+
+ // DisposeOverwritePrevious of the first frame is treated as DisposeOverwriteBgcolor.
Alpha Left Google 2013/05/22 20:18:09 I suggest this be a separate test case.
Xianzhu 2013/05/22 23:43:29 Done.
+ decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ EXPECT_EQ(notFound, decoder->findRequiredPreviousFrame(1));
+ decoderFrameBufferCache[0].setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
+ EXPECT_EQ(notFound, decoder->findRequiredPreviousFrame(1));
+
+ // Partially converting DisposeOverriteBgcolor previous frame is treated DisposeKeep.
Alpha Left Google 2013/05/22 20:18:09 nit: I can't parse this sentence please rewrite it
Xianzhu 2013/05/22 23:43:29 Done.
+ decoderFrameBufferCache[1].setOriginalFrameRect(IntRect(50, 50, 50, 50));
Alpha Left Google 2013/05/22 20:18:09 I suggest this be a separate test case.
Xianzhu 2013/05/22 23:43:29 Done.
+ EXPECT_EQ(1u, decoder->findRequiredPreviousFrame(2));
+
Alpha Left Google 2013/05/22 20:18:09 Please add a condition that a DisposeKeep or Dispo
Xianzhu 2013/05/22 23:43:29 This will be tested in GIFImageDecoderTest because
+ // The above rule doesn't apply if the previous frame is the first frame.
+ decoderFrameBufferCache[0].setOriginalFrameRect(IntRect(50, 50, 50, 50));
+ EXPECT_EQ(notFound, decoder->findRequiredPreviousFrame(1));
+}
+
+TEST(ImageDecoderTest, clearFrameBufferCache)
+{
+ OwnPtr<TestImageDecoder> decoder(adoptPtr(new TestImageDecoder()));
+ Vector<ImageFrame, 1>& decoderFrameBufferCache = decoder->frameBufferCache();
+
+ const unsigned defaultWidth = 100;
+ const unsigned defaultHeight = 100;
+ decoder->setSize(defaultWidth, defaultHeight);
+
+ // This should no nothing.
Alpha Left Google 2013/05/22 20:18:09 nit: do
Xianzhu 2013/05/22 23:43:29 Done.
+ decoder->clearFrameBufferCache(0);
+
+ const size_t numFrames = 20;
+ decoderFrameBufferCache.resize(numFrames);
+ for (size_t i = 0; i < numFrames; ++i) {
+ decoderFrameBufferCache[i].setOriginalFrameRect(IntRect(0, 0, defaultWidth, defaultHeight));
+ decoderFrameBufferCache[i].setStatus(ImageFrame::FrameComplete);
+ }
+
+ decoderFrameBufferCache[9].setStatus(ImageFrame::FramePartial);
+ decoder->resetRequiredPreviousFrames();
+
+ decoder->clearFrameBufferCache(7);
+ // Should preserve the the clearExceptFrame.
+ EXPECT_EQ(ImageFrame::FrameComplete, decoderFrameBufferCache[7].status());
+ // Should preserve non-completed frames.
+ EXPECT_EQ(ImageFrame::FramePartial, decoderFrameBufferCache[9].status());
Alpha Left Google 2013/05/22 20:18:09 The test only clear (7) which doesn't cover 9 anyw
Xianzhu 2013/05/22 23:43:29 Done.
+ // All other frames should be cleared.
+ for (size_t i = 0; i < numFrames; ++i) {
+ if (i != 7 && i != 9)
+ EXPECT_EQ(ImageFrame::FrameEmpty, decoderFrameBufferCache[i].status());
Alpha Left Google 2013/05/22 20:18:09 nit: If this expect fails it's not clear from the
Xianzhu 2013/05/22 23:43:29 Done.
+ }
+
+ // Repeated clearFrameBufferCache should not change the state.
Alpha Left Google 2013/05/22 20:18:09 This should be a separate test case.
Xianzhu 2013/05/22 23:43:29 Done.
+ decoder->resetRequiredPreviousFrames();
+ Vector<ImageFrame, 1> oldFrameBufferCache = decoderFrameBufferCache;
+ decoder->clearFrameBufferCache(7);
+ for (size_t i = 0; i < numFrames; ++i)
+ EXPECT_EQ(oldFrameBufferCache[i].status(), decoderFrameBufferCache[i].status());
+
+ decoderFrameBufferCache[5].setStatus(ImageFrame::FrameComplete);
+ decoderFrameBufferCache[7].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ decoderFrameBufferCache[8].setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
+ decoderFrameBufferCache[9].clearPixelData();
+ decoder->resetRequiredPreviousFrames();
+
+ decoder->clearFrameBufferCache(9);
+ // Should preserve the frame that is required to decode the clearExceptFrame.
+ EXPECT_EQ(ImageFrame::FrameComplete, decoderFrameBufferCache[5].status());
+
+ // This should not crash.
+ decoder->clearFrameBufferCache(notFound);
Alpha Left Google 2013/05/22 20:18:09 This should be a separate test case.
Xianzhu 2013/05/22 23:43:29 Done.
+}

Powered by Google App Engine
This is Rietveld 408576698