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

Unified Diff: third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp

Issue 2520753002: Pull up tests for WebP and GIF image decoders. (Closed)
Patch Set: Use braces for multi-line loops, fix alphabetical sorting Created 4 years, 1 month 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: third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp
index 63c062687e16c6666dedca1da6eed3b053ff0e26..c6dd3fb2c438a3d9c7065a60cefb1b04832fd052 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp
@@ -5,7 +5,6 @@
#include "platform/image-decoders/ImageDecoderTestHelpers.h"
#include "platform/SharedBuffer.h"
-#include "platform/image-decoders/ImageDecoder.h"
#include "platform/image-decoders/ImageFrame.h"
#include "platform/testing/UnitTestHelpers.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -288,6 +287,71 @@ static void testProgressiveDecoding(DecoderCreator createDecoder,
ASSERT_EQ(truncatedHashes[i], progressiveHashes[i]);
}
+void testUpdateRequiredPreviousFrameAfterFirstDecode(
+ DecoderCreator createDecoder,
+ SharedBuffer* fullData) {
+ std::unique_ptr<ImageDecoder> decoder = createDecoder();
+
+ // Give it data that is enough to parse but not decode in order to check the
+ // status of requiredPreviousFrameIndex before decoding.
+ size_t partialSize = 1;
+ do {
+ RefPtr<SharedBuffer> data =
+ SharedBuffer::create(fullData->data(), partialSize);
+ decoder->setData(data.get(), false);
+ ++partialSize;
+ } while (!decoder->frameCount() ||
+ decoder->frameBufferAtIndex(0)->getStatus() ==
+ ImageFrame::FrameEmpty);
+
+ EXPECT_EQ(kNotFound,
+ decoder->frameBufferAtIndex(0)->requiredPreviousFrameIndex());
+ unsigned frameCount = decoder->frameCount();
+ for (size_t i = 1; i < frameCount; ++i) {
+ EXPECT_EQ(i - 1,
+ decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex());
+ }
+
+ decoder->setData(fullData, true);
+ for (size_t i = 0; i < frameCount; ++i) {
+ EXPECT_EQ(kNotFound,
+ decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex());
+ }
+}
+
+void testResumePartialDecodeAfterClearFrameBufferCache(
+ DecoderCreator createDecoder,
+ SharedBuffer* fullData) {
+ Vector<unsigned> baselineHashes;
+ createDecodingBaseline(createDecoder, fullData, &baselineHashes);
+ size_t frameCount = baselineHashes.size();
+
+ std::unique_ptr<ImageDecoder> decoder = createDecoder();
+
+ // Let frame 0 be partially decoded.
+ size_t partialSize = 1;
+ do {
+ RefPtr<SharedBuffer> data =
+ SharedBuffer::create(fullData->data(), partialSize);
+ decoder->setData(data.get(), false);
+ ++partialSize;
+ } while (!decoder->frameCount() ||
+ decoder->frameBufferAtIndex(0)->getStatus() ==
+ ImageFrame::FrameEmpty);
+
+ // Skip to the last frame and clear.
+ decoder->setData(fullData, true);
+ EXPECT_EQ(frameCount, decoder->frameCount());
+ ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1);
+ EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->bitmap()));
+ decoder->clearCacheExceptFrame(kNotFound);
+
+ // Resume decoding of the first frame.
+ ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
+ EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->getStatus());
+ EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->bitmap()));
+}
+
void testByteByByteDecode(DecoderCreator createDecoder,
const char* file,
size_t expectedFrameCount,
@@ -416,4 +480,99 @@ void testProgressiveDecoding(DecoderCreator createDecoder,
testProgressiveDecoding(createDecoder, data.get(), increment);
}
+void testUpdateRequiredPreviousFrameAfterFirstDecode(
+ DecoderCreator createDecoder,
+ const char* dir,
+ const char* file) {
+ RefPtr<SharedBuffer> data = readFile(dir, file);
+ ASSERT_TRUE(data.get());
+ testUpdateRequiredPreviousFrameAfterFirstDecode(createDecoder, data.get());
+}
+
+void testUpdateRequiredPreviousFrameAfterFirstDecode(
+ DecoderCreator createDecoder,
+ const char* file) {
+ RefPtr<SharedBuffer> data = readFile(file);
+ ASSERT_TRUE(data.get());
+ testUpdateRequiredPreviousFrameAfterFirstDecode(createDecoder, data.get());
+}
+
+void testResumePartialDecodeAfterClearFrameBufferCache(
+ DecoderCreator createDecoder,
+ const char* dir,
+ const char* file) {
+ RefPtr<SharedBuffer> data = readFile(dir, file);
+ ASSERT_TRUE(data.get());
+ testResumePartialDecodeAfterClearFrameBufferCache(createDecoder, data.get());
+}
+
+void testResumePartialDecodeAfterClearFrameBufferCache(
+ DecoderCreator createDecoder,
+ const char* file) {
+ RefPtr<SharedBuffer> data = readFile(file);
+ ASSERT_TRUE(data.get());
+ testResumePartialDecodeAfterClearFrameBufferCache(createDecoder, data.get());
+}
+
+static uint32_t premultiplyColor(uint32_t c) {
+ return SkPremultiplyARGBInline(SkGetPackedA32(c), SkGetPackedR32(c),
+ SkGetPackedG32(c), SkGetPackedB32(c));
+}
+
+static void verifyFramesMatch(const char* file,
+ const ImageFrame* const a,
+ const ImageFrame* const b) {
+ const SkBitmap& bitmapA = a->bitmap();
+ const SkBitmap& bitmapB = b->bitmap();
+ ASSERT_EQ(bitmapA.width(), bitmapB.width());
+ ASSERT_EQ(bitmapA.height(), bitmapB.height());
+
+ int maxDifference = 0;
+ for (int y = 0; y < bitmapA.height(); ++y) {
+ for (int x = 0; x < bitmapA.width(); ++x) {
+ uint32_t colorA = *bitmapA.getAddr32(x, y);
+ if (!a->premultiplyAlpha())
+ colorA = premultiplyColor(colorA);
+ uint32_t colorB = *bitmapB.getAddr32(x, y);
+ if (!b->premultiplyAlpha())
+ colorB = premultiplyColor(colorB);
+ uint8_t* pixelA = reinterpret_cast<uint8_t*>(&colorA);
+ uint8_t* pixelB = reinterpret_cast<uint8_t*>(&colorB);
+ for (int channel = 0; channel < 4; ++channel) {
+ const int difference = abs(pixelA[channel] - pixelB[channel]);
+ if (difference > maxDifference)
+ maxDifference = difference;
+ }
+ }
+ }
+
+ // Pre-multiplication could round the RGBA channel values. So, we declare
+ // that the frames match if the RGBA channel values differ by at most 2.
+ EXPECT_GE(2, maxDifference) << file;
+}
+
+// Verifies that result of alpha blending is similar for AlphaPremultiplied and
+// AlphaNotPremultiplied cases.
+void testAlphaBlending(DecoderCreatorWithAlpha createDecoder,
+ const char* file) {
+ RefPtr<SharedBuffer> data = readFile(file);
+ ASSERT_TRUE(data.get());
+
+ std::unique_ptr<ImageDecoder> decoderA =
+ createDecoder(ImageDecoder::AlphaPremultiplied);
+ decoderA->setData(data.get(), true);
+
+ std::unique_ptr<ImageDecoder> decoderB =
+ createDecoder(ImageDecoder::AlphaNotPremultiplied);
+ decoderB->setData(data.get(), true);
+
+ size_t frameCount = decoderA->frameCount();
+ ASSERT_EQ(frameCount, decoderB->frameCount());
+
+ for (size_t i = 0; i < frameCount; ++i) {
+ verifyFramesMatch(file, decoderA->frameBufferAtIndex(i),
+ decoderB->frameBufferAtIndex(i));
+ }
+}
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698