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/. */
5 #include "gtest/gtest.h"
8 #include "AnimationSurfaceProvider.h"
10 #include "ImageFactory.h"
11 #include "nsIInputStream.h"
12 #include "RasterImage.h"
14 using namespace mozilla
;
15 using namespace mozilla::gfx
;
16 using namespace mozilla::image
;
18 static void CheckFrameAnimatorBlendResults(const ImageTestCase
& aTestCase
,
19 RasterImage
* aImage
, uint8_t aFuzz
) {
20 // Allow the animation to actually begin.
21 aImage
->IncrementAnimationConsumers();
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);
28 RefPtr
<SourceSurface
> surface
=
29 aImage
->GetFrame(imgIContainer::FRAME_CURRENT
, imgIContainer::FLAG_NONE
);
30 ASSERT_TRUE(surface
!= nullptr);
32 CheckGeneratedSurface(surface
, IntRect(0, 0, 50, 50),
33 BGRAColor::Transparent(),
34 aTestCase
.ChooseColor(BGRAColor::Red()), aFuzz
);
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);
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
);
49 template <typename Func
>
50 static void WithFrameAnimatorDecode(const ImageTestCase
& aTestCase
,
51 Func aResultChecker
) {
53 RefPtr
<Image
> image
= ImageFactory::CreateAnonymousImage(
54 nsDependentCString(aTestCase
.mMimeType
));
55 ASSERT_TRUE(!image
->HasError());
57 NotNull
<RefPtr
<RasterImage
>> rasterImage
=
58 WrapNotNull(static_cast<RasterImage
*>(image
.get()));
60 nsCOMPtr
<nsIInputStream
> inputStream
= LoadFile(aTestCase
.mPath
);
61 ASSERT_TRUE(inputStream
!= nullptr);
63 // Figure out how much data we have.
65 nsresult rv
= inputStream
->Available(&length
);
66 ASSERT_NS_SUCCEEDED(rv
);
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
);
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);
84 // Run the metadata decoder synchronously.
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
));
95 ASSERT_TRUE(task
!= nullptr);
97 // Run the full decoder synchronously.
100 // Call the lambda to verify the expected results.
101 aResultChecker(rasterImage
.get());
104 static void CheckFrameAnimatorBlend(const ImageTestCase
& aTestCase
,
106 WithFrameAnimatorDecode(aTestCase
, [&](RasterImage
* aImage
) {
107 CheckFrameAnimatorBlendResults(aTestCase
, aImage
, aFuzz
);
111 class ImageFrameAnimator
: public ::testing::Test
{
113 AutoInitializeImageLib mInit
;
116 TEST_F(ImageFrameAnimator
, BlendGIFWithFilter
) {
117 CheckFrameAnimatorBlend(BlendAnimatedGIFTestCase());
120 TEST_F(ImageFrameAnimator
, BlendPNGWithFilter
) {
121 CheckFrameAnimatorBlend(BlendAnimatedPNGTestCase());
124 TEST_F(ImageFrameAnimator
, BlendWebPWithFilter
) {
125 CheckFrameAnimatorBlend(BlendAnimatedWebPTestCase());
128 TEST_F(ImageFrameAnimator
, BlendAVIFWithFilter
) {
129 CheckFrameAnimatorBlend(BlendAnimatedAVIFTestCase(), 1);