TestFrameAnimator.cpp (4668B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "gtest/gtest.h" 6 7 #include "Common.h" 8 #include "AnimationSurfaceProvider.h" 9 #include "Decoder.h" 10 #include "ImageFactory.h" 11 #include "nsIInputStream.h" 12 #include "RasterImage.h" 13 14 using namespace mozilla; 15 using namespace mozilla::gfx; 16 using namespace mozilla::image; 17 18 static void CheckFrameAnimatorBlendResults(const ImageTestCase& aTestCase, 19 RasterImage* aImage, uint8_t aFuzz) { 20 // Allow the animation to actually begin. 21 aImage->IncrementAnimationConsumers(); 22 23 // Initialize for the first frame so we can advance. 24 TimeStamp now = TimeStamp::Now(); 25 aImage->RequestRefresh(now); 26 EXPECT_EQ(aImage->GetFrameIndex(imgIContainer::FRAME_CURRENT), 0); 27 28 RefPtr<SourceSurface> surface = 29 aImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE); 30 ASSERT_TRUE(surface != nullptr); 31 32 CheckGeneratedSurface(surface, IntRect(0, 0, 50, 50), 33 BGRAColor::Transparent(), 34 aTestCase.ChooseColor(BGRAColor::Red()), aFuzz); 35 36 // Advance to the next/final frame. 37 now = TimeStamp::Now() + TimeDuration::FromMilliseconds(500); 38 aImage->RequestRefresh(now); 39 EXPECT_EQ(aImage->GetFrameIndex(imgIContainer::FRAME_CURRENT), 1); 40 41 surface = 42 aImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE); 43 ASSERT_TRUE(surface != nullptr); 44 CheckGeneratedSurface(surface, IntRect(0, 0, 50, 50), 45 aTestCase.ChooseColor(BGRAColor::Green()), 46 aTestCase.ChooseColor(BGRAColor::Red()), aFuzz); 47 } 48 49 template <typename Func> 50 static void WithFrameAnimatorDecode(const ImageTestCase& aTestCase, 51 Func aResultChecker) { 52 // Create an image. 53 RefPtr<Image> image = ImageFactory::CreateAnonymousImage( 54 nsDependentCString(aTestCase.mMimeType)); 55 ASSERT_TRUE(!image->HasError()); 56 57 NotNull<RefPtr<RasterImage>> rasterImage = 58 WrapNotNull(static_cast<RasterImage*>(image.get())); 59 60 nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath); 61 ASSERT_TRUE(inputStream != nullptr); 62 63 // Figure out how much data we have. 64 uint64_t length; 65 nsresult rv = inputStream->Available(&length); 66 ASSERT_NS_SUCCEEDED(rv); 67 68 // Write the data into a SourceBuffer. 69 NotNull<RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull(new SourceBuffer()); 70 sourceBuffer->ExpectLength(length); 71 rv = sourceBuffer->AppendFromInputStream(inputStream, length); 72 ASSERT_NS_SUCCEEDED(rv); 73 sourceBuffer->Complete(NS_OK); 74 75 // Create a metadata decoder first, because otherwise RasterImage will get 76 // unhappy about finding out the image is animated during a full decode. 77 DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType); 78 DecoderFlags decoderFlags = 79 DecoderFactory::GetDefaultDecoderFlagsForType(decoderType); 80 RefPtr<IDecodingTask> task = DecoderFactory::CreateMetadataDecoder( 81 decoderType, rasterImage, decoderFlags, sourceBuffer); 82 ASSERT_TRUE(task != nullptr); 83 84 // Run the metadata decoder synchronously. 85 task->Run(); 86 task = nullptr; 87 88 // Create an AnimationSurfaceProvider which will manage the decoding process 89 // and make this decoder's output available in the surface cache. 90 SurfaceFlags surfaceFlags = aTestCase.mSurfaceFlags; 91 rv = DecoderFactory::CreateAnimationDecoder( 92 decoderType, rasterImage, sourceBuffer, aTestCase.mSize, decoderFlags, 93 surfaceFlags, 0, getter_AddRefs(task)); 94 EXPECT_EQ(rv, NS_OK); 95 ASSERT_TRUE(task != nullptr); 96 97 // Run the full decoder synchronously. 98 task->Run(); 99 100 // Call the lambda to verify the expected results. 101 aResultChecker(rasterImage.get()); 102 } 103 104 static void CheckFrameAnimatorBlend(const ImageTestCase& aTestCase, 105 uint8_t aFuzz = 0) { 106 WithFrameAnimatorDecode(aTestCase, [&](RasterImage* aImage) { 107 CheckFrameAnimatorBlendResults(aTestCase, aImage, aFuzz); 108 }); 109 } 110 111 class ImageFrameAnimator : public ::testing::Test { 112 protected: 113 AutoInitializeImageLib mInit; 114 }; 115 116 TEST_F(ImageFrameAnimator, BlendGIFWithFilter) { 117 CheckFrameAnimatorBlend(BlendAnimatedGIFTestCase()); 118 } 119 120 TEST_F(ImageFrameAnimator, BlendPNGWithFilter) { 121 CheckFrameAnimatorBlend(BlendAnimatedPNGTestCase()); 122 } 123 124 TEST_F(ImageFrameAnimator, BlendWebPWithFilter) { 125 CheckFrameAnimatorBlend(BlendAnimatedWebPTestCase()); 126 } 127 128 TEST_F(ImageFrameAnimator, BlendAVIFWithFilter) { 129 CheckFrameAnimatorBlend(BlendAnimatedAVIFTestCase(), 2); 130 }