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

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: Fixed feedback on patch 1 and ran WebKit formnatting 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(
509 readFile("/LayoutTests/fast/images/resources/webp-animated.webp"); 395 &createDecoder, "/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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(
619 "/LayoutTests/fast/images/resources/webp-animated.webp"); 461 &createDecoder, "/LayoutTests/fast/images/resources/webp-animated.webp");
620 testRandomFrameDecode( 462 testRandomFrameDecode(
463 &createDecoder,
621 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp"); 464 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp");
622 testRandomFrameDecode( 465 testRandomFrameDecode(
466 &createDecoder,
623 "/LayoutTests/fast/images/resources/webp-animated-large.webp"); 467 "/LayoutTests/fast/images/resources/webp-animated-large.webp");
624 testRandomFrameDecode( 468 testRandomFrameDecode(
469 &createDecoder,
625 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 470 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp");
626 } 471 }
627 472
628 TEST(AnimatedWebPTests, randomDecodeAfterClearFrameBufferCache) { 473 TEST(AnimatedWebPTests, randomDecodeAfterClearFrameBufferCache) {
629 testRandomDecodeAfterClearFrameBufferCache( 474 testRandomDecodeAfterClearFrameBufferCache(
630 "/LayoutTests/fast/images/resources/webp-animated.webp"); 475 &createDecoder, "/LayoutTests/fast/images/resources/webp-animated.webp");
631 testRandomDecodeAfterClearFrameBufferCache( 476 testRandomDecodeAfterClearFrameBufferCache(
477 &createDecoder,
632 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp"); 478 "/LayoutTests/fast/images/resources/webp-animated-opaque.webp");
633 testRandomDecodeAfterClearFrameBufferCache( 479 testRandomDecodeAfterClearFrameBufferCache(
480 &createDecoder,
634 "/LayoutTests/fast/images/resources/webp-animated-large.webp"); 481 "/LayoutTests/fast/images/resources/webp-animated-large.webp");
635 testRandomDecodeAfterClearFrameBufferCache( 482 testRandomDecodeAfterClearFrameBufferCache(
483 &createDecoder,
636 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 484 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp");
637 } 485 }
638 486
639 TEST(AnimatedWebPTests, 487 TEST(AnimatedWebPTests,
640 DISABLED_resumePartialDecodeAfterClearFrameBufferCache) { 488 DISABLED_resumePartialDecodeAfterClearFrameBufferCache) {
641 RefPtr<SharedBuffer> fullData = 489 RefPtr<SharedBuffer> fullData =
642 readFile("/LayoutTests/fast/images/resources/webp-animated-large.webp"); 490 readFile("/LayoutTests/fast/images/resources/webp-animated-large.webp");
643 ASSERT_TRUE(fullData.get()); 491 ASSERT_TRUE(fullData.get());
644 Vector<unsigned> baselineHashes; 492 Vector<unsigned> baselineHashes;
645 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); 493 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes);
(...skipping 20 matching lines...) Expand all
666 decoder->clearCacheExceptFrame(kNotFound); 514 decoder->clearCacheExceptFrame(kNotFound);
667 515
668 // Resume decoding of the first frame. 516 // Resume decoding of the first frame.
669 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); 517 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
670 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->getStatus()); 518 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->getStatus());
671 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->bitmap())); 519 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->bitmap()));
672 } 520 }
673 521
674 TEST(AnimatedWebPTests, decodeAfterReallocatingData) { 522 TEST(AnimatedWebPTests, decodeAfterReallocatingData) {
675 testDecodeAfterReallocatingData( 523 testDecodeAfterReallocatingData(
676 "/LayoutTests/fast/images/resources/webp-animated.webp"); 524 &createDecoder, "/LayoutTests/fast/images/resources/webp-animated.webp");
677 testDecodeAfterReallocatingData( 525 testDecodeAfterReallocatingData(
526 &createDecoder,
678 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp"); 527 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp");
679 } 528 }
680 529
681 TEST(AnimatedWebPTests, alphaBlending) { 530 TEST(AnimatedWebPTests, alphaBlending) {
682 testAlphaBlending("/LayoutTests/fast/images/resources/webp-animated.webp"); 531 testAlphaBlending("/LayoutTests/fast/images/resources/webp-animated.webp");
683 testAlphaBlending( 532 testAlphaBlending(
684 "/LayoutTests/fast/images/resources/webp-animated-semitransparent1.webp"); 533 "/LayoutTests/fast/images/resources/webp-animated-semitransparent1.webp");
685 testAlphaBlending( 534 testAlphaBlending(
686 "/LayoutTests/fast/images/resources/webp-animated-semitransparent2.webp"); 535 "/LayoutTests/fast/images/resources/webp-animated-semitransparent2.webp");
687 testAlphaBlending( 536 testAlphaBlending(
688 "/LayoutTests/fast/images/resources/webp-animated-semitransparent3.webp"); 537 "/LayoutTests/fast/images/resources/webp-animated-semitransparent3.webp");
689 testAlphaBlending( 538 testAlphaBlending(
690 "/LayoutTests/fast/images/resources/webp-animated-semitransparent4.webp"); 539 "/LayoutTests/fast/images/resources/webp-animated-semitransparent4.webp");
691 } 540 }
692 541
693 TEST(AnimatedWebPTests, isSizeAvailable) { 542 TEST(AnimatedWebPTests, isSizeAvailable) {
694 testByteByByteSizeAvailable( 543 testByteByByteSizeAvailable(
695 "/LayoutTests/fast/images/resources/webp-animated.webp", 142u, false, 544 &createDecoder, "/LayoutTests/fast/images/resources/webp-animated.webp",
696 cAnimationLoopInfinite); 545 142u, false, cAnimationLoopInfinite);
697 // FIXME: Add color profile support for animated webp images. 546 // FIXME: Add color profile support for animated webp images.
698 testByteByByteSizeAvailable( 547 testByteByByteSizeAvailable(
548 &createDecoder,
699 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp", 1404u, 549 "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp", 1404u,
700 false, 32000); 550 false, 32000);
701 } 551 }
702 552
703 TEST(StaticWebPTests, truncatedImage) { 553 TEST(StaticWebPTests, truncatedImage) {
704 // VP8 data is truncated. 554 // VP8 data is truncated.
705 testInvalidImage("/LayoutTests/fast/images/resources/truncated.webp", false); 555 testInvalidImage("/LayoutTests/fast/images/resources/truncated.webp", false);
706 // Chunk size in RIFF header doesn't match the file size. 556 // Chunk size in RIFF header doesn't match the file size.
707 testInvalidImage("/LayoutTests/fast/images/resources/truncated2.webp", true); 557 testInvalidImage("/LayoutTests/fast/images/resources/truncated2.webp", true);
708 } 558 }
709 559
710 // Regression test for a bug where some valid images were failing to decode 560 // Regression test for a bug where some valid images were failing to decode
711 // incrementally. 561 // incrementally.
712 TEST(StaticWebPTests, incrementalDecode) { 562 TEST(StaticWebPTests, incrementalDecode) {
713 testByteByByteDecode(&createDecoder, 563 testByteByByteDecode(&createDecoder,
714 "/LayoutTests/fast/images/resources/crbug.364830.webp", 564 "/LayoutTests/fast/images/resources/crbug.364830.webp",
715 1u, cAnimationNone); 565 1u, cAnimationNone);
716 } 566 }
717 567
718 TEST(StaticWebPTests, isSizeAvailable) { 568 TEST(StaticWebPTests, isSizeAvailable) {
719 testByteByByteSizeAvailable( 569 testByteByByteSizeAvailable(
570 &createDecoder,
720 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp", 520u, 571 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp", 520u,
721 true, cAnimationNone); 572 true, cAnimationNone);
722 testByteByByteSizeAvailable("/LayoutTests/fast/images/resources/test.webp", 573 testByteByByteSizeAvailable(&createDecoder,
574 "/LayoutTests/fast/images/resources/test.webp",
723 30u, false, cAnimationNone); 575 30u, false, cAnimationNone);
724 } 576 }
725 577
726 TEST(StaticWebPTests, notAnimated) { 578 TEST(StaticWebPTests, notAnimated) {
727 std::unique_ptr<ImageDecoder> decoder = createDecoder(); 579 std::unique_ptr<ImageDecoder> decoder = createDecoder();
728 RefPtr<SharedBuffer> data = readFile( 580 RefPtr<SharedBuffer> data = readFile(
729 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp"); 581 "/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp");
730 ASSERT_TRUE(data.get()); 582 ASSERT_TRUE(data.get());
731 decoder->setData(data.get(), true); 583 decoder->setData(data.get(), true);
732 EXPECT_EQ(1u, decoder->frameCount()); 584 EXPECT_EQ(1u, decoder->frameCount());
733 EXPECT_EQ(cAnimationNone, decoder->repetitionCount()); 585 EXPECT_EQ(cAnimationNone, decoder->repetitionCount());
734 } 586 }
735 587
736 } // namespace blink 588 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698