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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoderTest.cpp

Issue 2490473005: Pull up equivalent image decoding tests (Closed)
Patch Set: Add repetition count test for radient.gif 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 ImageDecoder::AlphaOption alphaOption) { 49 ImageDecoder::AlphaOption alphaOption) {
50 return wrapUnique( 50 return wrapUnique(
51 new WEBPImageDecoder(alphaOption, ImageDecoder::ColorSpaceApplied, 51 new WEBPImageDecoder(alphaOption, ImageDecoder::ColorSpaceApplied,
52 ImageDecoder::noDecodedImageByteLimit)); 52 ImageDecoder::noDecodedImageByteLimit));
53 } 53 }
54 54
55 std::unique_ptr<ImageDecoder> createDecoder() { 55 std::unique_ptr<ImageDecoder> createDecoder() {
56 return createDecoder(ImageDecoder::AlphaNotPremultiplied); 56 return createDecoder(ImageDecoder::AlphaNotPremultiplied);
57 } 57 }
58 58
59 void testRandomFrameDecode(const char* webpFile) {
60 SCOPED_TRACE(webpFile);
61
62 RefPtr<SharedBuffer> fullData = readFile(webpFile);
63 ASSERT_TRUE(fullData.get());
64 Vector<unsigned> baselineHashes;
65 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes);
66 size_t frameCount = baselineHashes.size();
67
68 // Random decoding should get the same results as sequential decoding.
69 std::unique_ptr<ImageDecoder> decoder = createDecoder();
70 decoder->setData(fullData.get(), true);
71 const size_t skippingStep = 5;
72 for (size_t i = 0; i < skippingStep; ++i) {
73 for (size_t j = i; j < frameCount; j += skippingStep) {
74 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
75 ImageFrame* frame = decoder->frameBufferAtIndex(j);
76 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap()));
77 }
78 }
79
80 // Decoding in reverse order.
81 decoder = createDecoder();
82 decoder->setData(fullData.get(), true);
83 for (size_t i = frameCount; i; --i) {
84 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
85 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
86 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->bitmap()));
87 }
88 }
89
90 void testRandomDecodeAfterClearFrameBufferCache(const char* webpFile) {
91 SCOPED_TRACE(webpFile);
92
93 RefPtr<SharedBuffer> data = readFile(webpFile);
94 ASSERT_TRUE(data.get());
95 Vector<unsigned> baselineHashes;
96 createDecodingBaseline(&createDecoder, data.get(), &baselineHashes);
97 size_t frameCount = baselineHashes.size();
98
99 std::unique_ptr<ImageDecoder> decoder = createDecoder();
100 decoder->setData(data.get(), true);
101 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount;
102 ++clearExceptFrame) {
103 decoder->clearCacheExceptFrame(clearExceptFrame);
104 const size_t skippingStep = 5;
105 for (size_t i = 0; i < skippingStep; ++i) {
106 for (size_t j = 0; j < frameCount; j += skippingStep) {
107 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
108 ImageFrame* frame = decoder->frameBufferAtIndex(j);
109 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap()));
110 }
111 }
112 }
113 }
114
115 void testDecodeAfterReallocatingData(const char* webpFile) {
116 std::unique_ptr<ImageDecoder> decoder = createDecoder();
117 RefPtr<SharedBuffer> data = readFile(webpFile);
118 ASSERT_TRUE(data.get());
119
120 // Parse from 'data'.
121 decoder->setData(data.get(), true);
122 size_t frameCount = decoder->frameCount();
123
124 // ... and then decode frames from 'reallocatedData'.
125 RefPtr<SharedBuffer> reallocatedData = data.get()->copy();
126 ASSERT_TRUE(reallocatedData.get());
127 data.clear();
128 decoder->setData(reallocatedData.get(), true);
129
130 for (size_t i = 0; i < frameCount; ++i) {
131 const ImageFrame* const frame = decoder->frameBufferAtIndex(i);
132 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus());
133 }
134 }
135
136 void testByteByByteSizeAvailable(const char* webpFile,
137 size_t frameOffset,
138 bool hasColorSpace,
139 int expectedRepetitionCount) {
140 std::unique_ptr<ImageDecoder> decoder = createDecoder();
141 RefPtr<SharedBuffer> data = readFile(webpFile);
142 ASSERT_TRUE(data.get());
143 EXPECT_LT(frameOffset, data->size());
144
145 // Send data to the decoder byte-by-byte and use the provided frame offset in
146 // the data to check that isSizeAvailable() changes state only when that
147 // offset is reached. Also check other decoder state.
148 for (size_t length = 1; length <= frameOffset; ++length) {
149 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), length);
150 decoder->setData(tempData.get(), false);
151
152 if (length < frameOffset) {
153 EXPECT_FALSE(decoder->isSizeAvailable());
154 EXPECT_TRUE(decoder->size().isEmpty());
155 EXPECT_FALSE(decoder->hasEmbeddedColorSpace());
156 EXPECT_EQ(0u, decoder->frameCount());
157 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
158 EXPECT_FALSE(decoder->frameBufferAtIndex(0));
159 } else {
160 EXPECT_TRUE(decoder->isSizeAvailable());
161 EXPECT_FALSE(decoder->size().isEmpty());
162 EXPECT_EQ(decoder->hasEmbeddedColorSpace(), hasColorSpace);
163 EXPECT_EQ(1u, decoder->frameCount());
164 EXPECT_EQ(expectedRepetitionCount, decoder->repetitionCount());
165 }
166
167 EXPECT_FALSE(decoder->failed());
168 if (decoder->failed())
169 return;
170 }
171 }
172
173 // If 'parseErrorExpected' is true, error is expected during parse (frameCount() 59 // If 'parseErrorExpected' is true, error is expected during parse (frameCount()
174 // call); else error is expected during decode (frameBufferAtIndex() call). 60 // call); else error is expected during decode (frameBufferAtIndex() call).
175 void testInvalidImage(const char* webpFile, bool parseErrorExpected) { 61 void testInvalidImage(const char* webpFile, bool parseErrorExpected) {
176 std::unique_ptr<ImageDecoder> decoder = createDecoder(); 62 std::unique_ptr<ImageDecoder> decoder = createDecoder();
177 63
178 RefPtr<SharedBuffer> data = readFile(webpFile); 64 RefPtr<SharedBuffer> data = readFile(webpFile);
179 ASSERT_TRUE(data.get()); 65 ASSERT_TRUE(data.get());
180 decoder->setData(data.get(), true); 66 decoder->setData(data.get(), true);
181 67
182 if (parseErrorExpected) { 68 if (parseErrorExpected) {
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 decoder->setData(fullData.get(), true); 384 decoder->setData(fullData.get(), true);
499 EXPECT_EQ(1u, decoder->frameCount()); 385 EXPECT_EQ(1u, decoder->frameCount());
500 frame = decoder->frameBufferAtIndex(0); 386 frame = decoder->frameBufferAtIndex(0);
501 ASSERT_TRUE(frame); 387 ASSERT_TRUE(frame);
502 EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus()); 388 EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus());
503 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 389 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
504 EXPECT_TRUE(decoder->failed()); 390 EXPECT_TRUE(decoder->failed());
505 } 391 }
506 392
507 TEST(AnimatedWebPTests, progressiveDecode) { 393 TEST(AnimatedWebPTests, progressiveDecode) {
508 RefPtr<SharedBuffer> fullData = 394 testProgressiveDecoding(&createDecoder,
509 readFile("/LayoutTests/fast/images/resources/webp-animated.webp"); 395 "/LayoutTests/fast/images/resources/webp-animated.webp");
510 ASSERT_TRUE(fullData.get());
511 const size_t fullLength = fullData->size();
512
513 std::unique_ptr<ImageDecoder> decoder;
514 ImageFrame* frame;
515
516 Vector<unsigned> truncatedHashes;
517 Vector<unsigned> progressiveHashes;
518
519 // Compute hashes when the file is truncated.
520 const size_t increment = 1;
521 for (size_t i = 1; i <= fullLength; i += increment) {
522 decoder = createDecoder();
523 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
524 decoder->setData(data.get(), i == fullLength);
525 frame = decoder->frameBufferAtIndex(0);
526 if (!frame) {
527 truncatedHashes.append(0);
528 continue;
529 }
530 truncatedHashes.append(hashBitmap(frame->bitmap()));
531 }
532
533 // Compute hashes when the file is progressively decoded.
534 decoder = createDecoder();
535 for (size_t i = 1; i <= fullLength; i += increment) {
536 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
537 decoder->setData(data.get(), i == fullLength);
538 frame = decoder->frameBufferAtIndex(0);
539 if (!frame) {
540 progressiveHashes.append(0);
541 continue;
542 }
543 progressiveHashes.append(hashBitmap(frame->bitmap()));
544 }
545
546 bool match = true;
547 for (size_t i = 0; i < truncatedHashes.size(); ++i) {
548 if (truncatedHashes[i] != progressiveHashes[i]) {
549 match = false;
550 break;
551 }
552 }
553 EXPECT_TRUE(match);
554 } 396 }
555 397
556 TEST(AnimatedWebPTests, frameIsCompleteAndDuration) { 398 TEST(AnimatedWebPTests, frameIsCompleteAndDuration) {
557 std::unique_ptr<ImageDecoder> decoder = createDecoder(); 399 std::unique_ptr<ImageDecoder> decoder = createDecoder();
558 400
559 RefPtr<SharedBuffer> data = 401 RefPtr<SharedBuffer> data =
560 readFile("/LayoutTests/fast/images/resources/webp-animated.webp"); 402 readFile("/LayoutTests/fast/images/resources/webp-animated.webp");
561 ASSERT_TRUE(data.get()); 403 ASSERT_TRUE(data.get());
562 404
563 ASSERT_GE(data->size(), 10u); 405 ASSERT_GE(data->size(), 10u);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 EXPECT_EQ(i - 1, 450 EXPECT_EQ(i - 1,
609 decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex()); 451 decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex());
610 452
611 decoder->setData(fullData.get(), true); 453 decoder->setData(fullData.get(), true);
612 for (size_t i = 0; i < frameCount; ++i) 454 for (size_t i = 0; i < frameCount; ++i)
613 EXPECT_EQ(kNotFound, 455 EXPECT_EQ(kNotFound,
614 decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex()); 456 decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex());
615 } 457 }
616 458
617 TEST(AnimatedWebPTests, randomFrameDecode) { 459 TEST(AnimatedWebPTests, randomFrameDecode) {
618 testRandomFrameDecode( 460 testRandomFrameDecode(&createDecoder,
619 "/LayoutTests/fast/images/resources/webp-animated.webp"); 461 "/LayoutTests/fast/images/resources/webp-animated.webp");
620 testRandomFrameDecode( 462 testRandomFrameDecode(&createDecoder,
621 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp"); 463 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp");
622 testRandomFrameDecode( 464 testRandomFrameDecode(&createDecoder,
623 "/LayoutTests/fast/images/resources/webp-animated-large.webp"); 465 "/LayoutTests/fast/images/resources/webp-animated-large.webp");
624 testRandomFrameDecode( 466 testRandomFrameDecode(&createDecoder,
625 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 467 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp");
626 } 468 }
627 469
628 TEST(AnimatedWebPTests, randomDecodeAfterClearFrameBufferCache) { 470 TEST(AnimatedWebPTests, randomDecodeAfterClearFrameBufferCache) {
629 testRandomDecodeAfterClearFrameBufferCache( 471 testRandomDecodeAfterClearFrameBufferCache(&createDecoder,
630 "/LayoutTests/fast/images/resources/webp-animated.webp"); 472 "/LayoutTests/fast/images/resources/webp-animated.webp");
631 testRandomDecodeAfterClearFrameBufferCache( 473 testRandomDecodeAfterClearFrameBufferCache(&createDecoder,
632 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp"); 474 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp");
633 testRandomDecodeAfterClearFrameBufferCache( 475 testRandomDecodeAfterClearFrameBufferCache(&createDecoder,
634 "/LayoutTests/fast/images/resources/webp-animated-large.webp"); 476 "/LayoutTests/fast/images/resources/webp-animated-large.webp");
635 testRandomDecodeAfterClearFrameBufferCache( 477 testRandomDecodeAfterClearFrameBufferCache(&createDecoder,
636 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 478 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp");
637 } 479 }
638 480
639 TEST(AnimatedWebPTests, 481 TEST(AnimatedWebPTests,
640 DISABLED_resumePartialDecodeAfterClearFrameBufferCache) { 482 DISABLED_resumePartialDecodeAfterClearFrameBufferCache) {
641 RefPtr<SharedBuffer> fullData = 483 RefPtr<SharedBuffer> fullData =
642 readFile("/LayoutTests/fast/images/resources/webp-animated-large.webp"); 484 readFile("/LayoutTests/fast/images/resources/webp-animated-large.webp");
643 ASSERT_TRUE(fullData.get()); 485 ASSERT_TRUE(fullData.get());
644 Vector<unsigned> baselineHashes; 486 Vector<unsigned> baselineHashes;
645 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); 487 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes);
(...skipping 19 matching lines...) Expand all
665 EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->bitmap())); 507 EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->bitmap()));
666 decoder->clearCacheExceptFrame(kNotFound); 508 decoder->clearCacheExceptFrame(kNotFound);
667 509
668 // Resume decoding of the first frame. 510 // Resume decoding of the first frame.
669 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); 511 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
670 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->getStatus()); 512 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->getStatus());
671 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->bitmap())); 513 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->bitmap()));
672 } 514 }
673 515
674 TEST(AnimatedWebPTests, decodeAfterReallocatingData) { 516 TEST(AnimatedWebPTests, decodeAfterReallocatingData) {
675 testDecodeAfterReallocatingData( 517 testDecodeAfterReallocatingData(&createDecoder,
676 "/LayoutTests/fast/images/resources/webp-animated.webp"); 518 "/LayoutTests/fast/images/resources/webp-animated.webp");
677 testDecodeAfterReallocatingData( 519 testDecodeAfterReallocatingData(&createDecoder,
678 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 520 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp");
679 } 521 }
680 522
681 TEST(AnimatedWebPTests, alphaBlending) { 523 TEST(AnimatedWebPTests, alphaBlending) {
682 testAlphaBlending("/LayoutTests/fast/images/resources/webp-animated.webp"); 524 testAlphaBlending("/LayoutTests/fast/images/resources/webp-animated.webp");
683 testAlphaBlending( 525 testAlphaBlending(
684 "/LayoutTests/fast/images/resources/webp-animated-semitransparent1.webp"); 526 "/LayoutTests/fast/images/resources/webp-animated-semitransparent1.webp");
685 testAlphaBlending( 527 testAlphaBlending(
686 "/LayoutTests/fast/images/resources/webp-animated-semitransparent2.webp"); 528 "/LayoutTests/fast/images/resources/webp-animated-semitransparent2.webp");
687 testAlphaBlending( 529 testAlphaBlending(
688 "/LayoutTests/fast/images/resources/webp-animated-semitransparent3.webp"); 530 "/LayoutTests/fast/images/resources/webp-animated-semitransparent3.webp");
689 testAlphaBlending( 531 testAlphaBlending(
690 "/LayoutTests/fast/images/resources/webp-animated-semitransparent4.webp"); 532 "/LayoutTests/fast/images/resources/webp-animated-semitransparent4.webp");
691 } 533 }
692 534
693 TEST(AnimatedWebPTests, isSizeAvailable) { 535 TEST(AnimatedWebPTests, isSizeAvailable) {
694 testByteByByteSizeAvailable( 536 testByteByByteSizeAvailable(&createDecoder,
695 "/LayoutTests/fast/images/resources/webp-animated.webp", 142u, false, 537 "/LayoutTests/fast/images/resources/webp-animated.webp", 142u, false,
696 cAnimationLoopInfinite); 538 cAnimationLoopInfinite);
697 // FIXME: Add color profile support for animated webp images. 539 // FIXME: Add color profile support for animated webp images.
698 testByteByByteSizeAvailable( 540 testByteByByteSizeAvailable(&createDecoder,
699 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp", 1404u, 541 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp", 1404u,
700 false, 32000); 542 false, 32000);
701 } 543 }
702 544
703 TEST(StaticWebPTests, truncatedImage) { 545 TEST(StaticWebPTests, truncatedImage) {
704 // VP8 data is truncated. 546 // VP8 data is truncated.
705 testInvalidImage("/LayoutTests/fast/images/resources/truncated.webp", false); 547 testInvalidImage("/LayoutTests/fast/images/resources/truncated.webp", false);
706 // Chunk size in RIFF header doesn't match the file size. 548 // Chunk size in RIFF header doesn't match the file size.
707 testInvalidImage("/LayoutTests/fast/images/resources/truncated2.webp", true); 549 testInvalidImage("/LayoutTests/fast/images/resources/truncated2.webp", true);
708 } 550 }
709 551
710 // Regression test for a bug where some valid images were failing to decode 552 // Regression test for a bug where some valid images were failing to decode
711 // incrementally. 553 // incrementally.
712 TEST(StaticWebPTests, incrementalDecode) { 554 TEST(StaticWebPTests, incrementalDecode) {
713 testByteByByteDecode(&createDecoder, 555 testByteByByteDecode(&createDecoder,
714 "/LayoutTests/fast/images/resources/crbug.364830.webp", 556 "/LayoutTests/fast/images/resources/crbug.364830.webp",
715 1u, cAnimationNone); 557 1u, cAnimationNone);
716 } 558 }
717 559
718 TEST(StaticWebPTests, isSizeAvailable) { 560 TEST(StaticWebPTests, isSizeAvailable) {
719 testByteByByteSizeAvailable( 561 testByteByByteSizeAvailable(&createDecoder,
720 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp", 520u, 562 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp", 520u,
721 true, cAnimationNone); 563 true, cAnimationNone);
722 testByteByByteSizeAvailable("/LayoutTests/fast/images/resources/test.webp", 564 testByteByByteSizeAvailable(&createDecoder,
723 30u, false, cAnimationNone); 565 "/LayoutTests/fast/images/resources/test.webp", 30u, false,
566 cAnimationNone);
724 } 567 }
725 568
726 TEST(StaticWebPTests, notAnimated) { 569 TEST(StaticWebPTests, notAnimated) {
727 std::unique_ptr<ImageDecoder> decoder = createDecoder(); 570 std::unique_ptr<ImageDecoder> decoder = createDecoder();
728 RefPtr<SharedBuffer> data = readFile( 571 RefPtr<SharedBuffer> data = readFile(
729 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp"); 572 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp");
730 ASSERT_TRUE(data.get()); 573 ASSERT_TRUE(data.get());
731 decoder->setData(data.get(), true); 574 decoder->setData(data.get(), true);
732 EXPECT_EQ(1u, decoder->frameCount()); 575 EXPECT_EQ(1u, decoder->frameCount());
733 EXPECT_EQ(cAnimationNone, decoder->repetitionCount()); 576 EXPECT_EQ(cAnimationNone, decoder->repetitionCount());
734 } 577 }
735 578
736 } // namespace blink 579 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698