diff options
Diffstat (limited to 'tests/AnimatedImageTest.cpp')
-rw-r--r-- | tests/AnimatedImageTest.cpp | 115 |
1 files changed, 97 insertions, 18 deletions
diff --git a/tests/AnimatedImageTest.cpp b/tests/AnimatedImageTest.cpp index 6c7b0e5a55..13ea80804c 100644 --- a/tests/AnimatedImageTest.cpp +++ b/tests/AnimatedImageTest.cpp @@ -72,6 +72,102 @@ DEF_TEST(AnimatedImage_scaled, r) { } } +static bool compare_bitmaps(skiatest::Reporter* r, + const char* file, + int expectedFrame, + const SkBitmap& expectedBm, + const SkBitmap& actualBm) { + REPORTER_ASSERT(r, expectedBm.colorType() == actualBm.colorType()); + REPORTER_ASSERT(r, expectedBm.dimensions() == actualBm.dimensions()); + for (int i = 0; i < actualBm.width(); ++i) + for (int j = 0; j < actualBm.height(); ++j) { + SkColor expected = SkUnPreMultiply::PMColorToColor(*expectedBm.getAddr32(i, j)); + SkColor actual = SkUnPreMultiply::PMColorToColor(*actualBm .getAddr32(i, j)); + if (expected != actual) { + ERRORF(r, "frame %i of %s does not match at pixel %i, %i!" + " expected %x\tactual: %x", + expectedFrame, file, i, j, expected, actual); + SkString expected_name = SkStringPrintf("expected_%c", '0' + expectedFrame); + SkString actual_name = SkStringPrintf("actual_%c", '0' + expectedFrame); + write_bm(expected_name.c_str(), expectedBm); + write_bm(actual_name.c_str(), actualBm); + return false; + } + } + return true; +} + +DEF_TEST(AnimatedImage_copyOnWrite, r) { + if (GetResourcePath().isEmpty()) { + return; + } + for (const char* file : { "images/alphabetAnim.gif", + "images/colorTables.gif", + "images/webp-animated.webp", + "images/required.webp", + }) { + auto data = GetResourceAsData(file); + if (!data) { + ERRORF(r, "Could not get %s", file); + continue; + } + + auto codec = SkCodec::MakeFromData(data); + if (!codec) { + ERRORF(r, "Could not create codec for %s", file); + continue; + } + + const auto imageInfo = codec->getInfo().makeAlphaType(kPremul_SkAlphaType); + const int frameCount = codec->getFrameCount(); + auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec)); + if (!androidCodec) { + ERRORF(r, "Could not create androidCodec for %s", file); + continue; + } + + auto animatedImage = SkAnimatedImage::Make(std::move(androidCodec)); + if (!animatedImage) { + ERRORF(r, "Could not create animated image for %s", file); + continue; + } + animatedImage->setRepetitionCount(0); + + std::vector<SkBitmap> expected(frameCount); + std::vector<sk_sp<SkPicture>> pictures(frameCount); + for (int i = 0; i < frameCount; i++) { + SkBitmap& bm = expected[i]; + bm.allocPixels(imageInfo); + bm.eraseColor(SK_ColorTRANSPARENT); + SkCanvas canvas(bm); + + pictures[i].reset(animatedImage->newPictureSnapshot()); + canvas.drawPicture(pictures[i]); + + const auto duration = animatedImage->decodeNextFrame(); + // We're attempting to decode i + 1, so decodeNextFrame will return + // kFinished if that is the last frame (or we attempt to decode one + // more). + if (i >= frameCount - 2) { + REPORTER_ASSERT(r, duration == SkAnimatedImage::kFinished); + } else { + REPORTER_ASSERT(r, duration != SkAnimatedImage::kFinished); + } + } + + for (int i = 0; i < frameCount; i++) { + SkBitmap test; + test.allocPixels(imageInfo); + test.eraseColor(SK_ColorTRANSPARENT); + SkCanvas canvas(test); + + canvas.drawPicture(pictures[i]); + + compare_bitmaps(r, file, i, expected[i], test); + } + } +} + DEF_TEST(AnimatedImage, r) { if (GetResourcePath().isEmpty()) { return; @@ -147,24 +243,7 @@ DEF_TEST(AnimatedImage, r) { animatedImage->draw(&c); const SkBitmap& frame = frames[expectedFrame]; - REPORTER_ASSERT(r, frame.colorType() == test.colorType()); - REPORTER_ASSERT(r, frame.dimensions() == test.dimensions()); - for (int i = 0; i < test.width(); ++i) - for (int j = 0; j < test.height(); ++j) { - SkColor expected = SkUnPreMultiply::PMColorToColor(*frame.getAddr32(i, j)); - SkColor actual = SkUnPreMultiply::PMColorToColor(*test .getAddr32(i, j)); - if (expected != actual) { - ERRORF(r, "frame %i of %s does not match at pixel %i, %i!" - " expected %x\tactual: %x", - expectedFrame, file, i, j, expected, actual); - SkString expected_name = SkStringPrintf("expected_%c", '0' + expectedFrame); - SkString actual_name = SkStringPrintf("actual_%c", '0' + expectedFrame); - write_bm(expected_name.c_str(), frame); - write_bm(actual_name.c_str(), test); - return false; - } - } - return true; + return compare_bitmaps(r, file, expectedFrame, frame, test); }; REPORTER_ASSERT(r, animatedImage->currentFrameDuration() == frameInfos[0].fDuration); |