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/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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/image-decoders/ImageDecoderTestHelpers.h" 5 #include "platform/image-decoders/ImageDecoderTestHelpers.h"
6 6
7 #include "platform/SharedBuffer.h" 7 #include "platform/SharedBuffer.h"
8 #include "platform/image-decoders/ImageDecoder.h"
9 #include "platform/image-decoders/ImageFrame.h" 8 #include "platform/image-decoders/ImageFrame.h"
10 #include "platform/testing/UnitTestHelpers.h" 9 #include "platform/testing/UnitTestHelpers.h"
11 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
12 #include "wtf/StringHasher.h" 11 #include "wtf/StringHasher.h"
13 #include "wtf/text/StringBuilder.h" 12 #include "wtf/text/StringBuilder.h"
14 #include <memory> 13 #include <memory>
15 14
16 namespace blink { 15 namespace blink {
17 16
18 PassRefPtr<SharedBuffer> readFile(const char* fileName) { 17 PassRefPtr<SharedBuffer> readFile(const char* fileName) {
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 progressiveHashes.append(0); 280 progressiveHashes.append(0);
282 continue; 281 continue;
283 } 282 }
284 progressiveHashes.append(hashBitmap(frame->bitmap())); 283 progressiveHashes.append(hashBitmap(frame->bitmap()));
285 } 284 }
286 285
287 for (size_t i = 0; i < truncatedHashes.size(); ++i) 286 for (size_t i = 0; i < truncatedHashes.size(); ++i)
288 ASSERT_EQ(truncatedHashes[i], progressiveHashes[i]); 287 ASSERT_EQ(truncatedHashes[i], progressiveHashes[i]);
289 } 288 }
290 289
290 void testUpdateRequiredPreviousFrameAfterFirstDecode(
291 DecoderCreator createDecoder,
292 SharedBuffer* fullData) {
293 std::unique_ptr<ImageDecoder> decoder = createDecoder();
294
295 // Give it data that is enough to parse but not decode in order to check the
296 // status of requiredPreviousFrameIndex before decoding.
297 size_t partialSize = 1;
298 do {
299 RefPtr<SharedBuffer> data =
300 SharedBuffer::create(fullData->data(), partialSize);
301 decoder->setData(data.get(), false);
302 ++partialSize;
303 } while (!decoder->frameCount() ||
304 decoder->frameBufferAtIndex(0)->getStatus() ==
305 ImageFrame::FrameEmpty);
306
307 EXPECT_EQ(kNotFound,
308 decoder->frameBufferAtIndex(0)->requiredPreviousFrameIndex());
309 unsigned frameCount = decoder->frameCount();
310 for (size_t i = 1; i < frameCount; ++i) {
311 EXPECT_EQ(i - 1,
312 decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex());
313 }
314
315 decoder->setData(fullData, true);
316 for (size_t i = 0; i < frameCount; ++i) {
317 EXPECT_EQ(kNotFound,
318 decoder->frameBufferAtIndex(i)->requiredPreviousFrameIndex());
319 }
320 }
321
322 void testResumePartialDecodeAfterClearFrameBufferCache(
323 DecoderCreator createDecoder,
324 SharedBuffer* fullData) {
325 Vector<unsigned> baselineHashes;
326 createDecodingBaseline(createDecoder, fullData, &baselineHashes);
327 size_t frameCount = baselineHashes.size();
328
329 std::unique_ptr<ImageDecoder> decoder = createDecoder();
330
331 // Let frame 0 be partially decoded.
332 size_t partialSize = 1;
333 do {
334 RefPtr<SharedBuffer> data =
335 SharedBuffer::create(fullData->data(), partialSize);
336 decoder->setData(data.get(), false);
337 ++partialSize;
338 } while (!decoder->frameCount() ||
339 decoder->frameBufferAtIndex(0)->getStatus() ==
340 ImageFrame::FrameEmpty);
341
342 // Skip to the last frame and clear.
343 decoder->setData(fullData, true);
344 EXPECT_EQ(frameCount, decoder->frameCount());
345 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1);
346 EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->bitmap()));
347 decoder->clearCacheExceptFrame(kNotFound);
348
349 // Resume decoding of the first frame.
350 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
351 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->getStatus());
352 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->bitmap()));
353 }
354
291 void testByteByByteDecode(DecoderCreator createDecoder, 355 void testByteByByteDecode(DecoderCreator createDecoder,
292 const char* file, 356 const char* file,
293 size_t expectedFrameCount, 357 size_t expectedFrameCount,
294 int expectedRepetitionCount) { 358 int expectedRepetitionCount) {
295 RefPtr<SharedBuffer> data = readFile(file); 359 RefPtr<SharedBuffer> data = readFile(file);
296 ASSERT_TRUE(data.get()); 360 ASSERT_TRUE(data.get());
297 testByteByByteDecode(createDecoder, data.get(), expectedFrameCount, 361 testByteByByteDecode(createDecoder, data.get(), expectedFrameCount,
298 expectedRepetitionCount); 362 expectedRepetitionCount);
299 } 363 }
300 void testByteByByteDecode(DecoderCreator createDecoder, 364 void testByteByByteDecode(DecoderCreator createDecoder,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 473
410 void testProgressiveDecoding(DecoderCreator createDecoder, 474 void testProgressiveDecoding(DecoderCreator createDecoder,
411 const char* dir, 475 const char* dir,
412 const char* file, 476 const char* file,
413 size_t increment) { 477 size_t increment) {
414 RefPtr<SharedBuffer> data = readFile(dir, file); 478 RefPtr<SharedBuffer> data = readFile(dir, file);
415 ASSERT_TRUE(data.get()); 479 ASSERT_TRUE(data.get());
416 testProgressiveDecoding(createDecoder, data.get(), increment); 480 testProgressiveDecoding(createDecoder, data.get(), increment);
417 } 481 }
418 482
483 void testUpdateRequiredPreviousFrameAfterFirstDecode(
484 DecoderCreator createDecoder,
485 const char* dir,
486 const char* file) {
487 RefPtr<SharedBuffer> data = readFile(dir, file);
488 ASSERT_TRUE(data.get());
489 testUpdateRequiredPreviousFrameAfterFirstDecode(createDecoder, data.get());
490 }
491
492 void testUpdateRequiredPreviousFrameAfterFirstDecode(
493 DecoderCreator createDecoder,
494 const char* file) {
495 RefPtr<SharedBuffer> data = readFile(file);
496 ASSERT_TRUE(data.get());
497 testUpdateRequiredPreviousFrameAfterFirstDecode(createDecoder, data.get());
498 }
499
500 void testResumePartialDecodeAfterClearFrameBufferCache(
501 DecoderCreator createDecoder,
502 const char* dir,
503 const char* file) {
504 RefPtr<SharedBuffer> data = readFile(dir, file);
505 ASSERT_TRUE(data.get());
506 testResumePartialDecodeAfterClearFrameBufferCache(createDecoder, data.get());
507 }
508
509 void testResumePartialDecodeAfterClearFrameBufferCache(
510 DecoderCreator createDecoder,
511 const char* file) {
512 RefPtr<SharedBuffer> data = readFile(file);
513 ASSERT_TRUE(data.get());
514 testResumePartialDecodeAfterClearFrameBufferCache(createDecoder, data.get());
515 }
516
517 static uint32_t premultiplyColor(uint32_t c) {
518 return SkPremultiplyARGBInline(SkGetPackedA32(c), SkGetPackedR32(c),
519 SkGetPackedG32(c), SkGetPackedB32(c));
520 }
521
522 static void verifyFramesMatch(const char* file,
523 const ImageFrame* const a,
524 const ImageFrame* const b) {
525 const SkBitmap& bitmapA = a->bitmap();
526 const SkBitmap& bitmapB = b->bitmap();
527 ASSERT_EQ(bitmapA.width(), bitmapB.width());
528 ASSERT_EQ(bitmapA.height(), bitmapB.height());
529
530 int maxDifference = 0;
531 for (int y = 0; y < bitmapA.height(); ++y) {
532 for (int x = 0; x < bitmapA.width(); ++x) {
533 uint32_t colorA = *bitmapA.getAddr32(x, y);
534 if (!a->premultiplyAlpha())
535 colorA = premultiplyColor(colorA);
536 uint32_t colorB = *bitmapB.getAddr32(x, y);
537 if (!b->premultiplyAlpha())
538 colorB = premultiplyColor(colorB);
539 uint8_t* pixelA = reinterpret_cast<uint8_t*>(&colorA);
540 uint8_t* pixelB = reinterpret_cast<uint8_t*>(&colorB);
541 for (int channel = 0; channel < 4; ++channel) {
542 const int difference = abs(pixelA[channel] - pixelB[channel]);
543 if (difference > maxDifference)
544 maxDifference = difference;
545 }
546 }
547 }
548
549 // Pre-multiplication could round the RGBA channel values. So, we declare
550 // that the frames match if the RGBA channel values differ by at most 2.
551 EXPECT_GE(2, maxDifference) << file;
552 }
553
554 // Verifies that result of alpha blending is similar for AlphaPremultiplied and
555 // AlphaNotPremultiplied cases.
556 void testAlphaBlending(DecoderCreatorWithAlpha createDecoder,
557 const char* file) {
558 RefPtr<SharedBuffer> data = readFile(file);
559 ASSERT_TRUE(data.get());
560
561 std::unique_ptr<ImageDecoder> decoderA =
562 createDecoder(ImageDecoder::AlphaPremultiplied);
563 decoderA->setData(data.get(), true);
564
565 std::unique_ptr<ImageDecoder> decoderB =
566 createDecoder(ImageDecoder::AlphaNotPremultiplied);
567 decoderB->setData(data.get(), true);
568
569 size_t frameCount = decoderA->frameCount();
570 ASSERT_EQ(frameCount, decoderB->frameCount());
571
572 for (size_t i = 0; i < frameCount; ++i) {
573 verifyFramesMatch(file, decoderA->frameBufferAtIndex(i),
574 decoderB->frameBufferAtIndex(i));
575 }
576 }
577
419 } // namespace blink 578 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698