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
CheckFrameAnimatorBlendResults(const ImageTestCase & aTestCase,RasterImage * aImage)18 static void CheckFrameAnimatorBlendResults(const ImageTestCase& aTestCase,
19 RasterImage* aImage) {
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
27 RefPtr<SourceSurface> surface =
28 aImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE);
29 ASSERT_TRUE(surface != nullptr);
30
31 CheckGeneratedSurface(surface, IntRect(0, 0, 50, 50),
32 BGRAColor::Transparent(),
33 aTestCase.ChooseColor(BGRAColor::Red()));
34
35 // Advance to the next/final frame.
36 now = TimeStamp::Now() + TimeDuration::FromMilliseconds(500);
37 aImage->RequestRefresh(now);
38
39 surface =
40 aImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE);
41 ASSERT_TRUE(surface != nullptr);
42 CheckGeneratedSurface(surface, IntRect(0, 0, 50, 50),
43 aTestCase.ChooseColor(BGRAColor::Green()),
44 aTestCase.ChooseColor(BGRAColor::Red()));
45 }
46
47 template <typename Func>
WithFrameAnimatorDecode(const ImageTestCase & aTestCase,Func aResultChecker)48 static void WithFrameAnimatorDecode(const ImageTestCase& aTestCase,
49 Func aResultChecker) {
50 // Create an image.
51 RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
52 nsDependentCString(aTestCase.mMimeType));
53 ASSERT_TRUE(!image->HasError());
54
55 NotNull<RefPtr<RasterImage>> rasterImage =
56 WrapNotNull(static_cast<RasterImage*>(image.get()));
57
58 nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
59 ASSERT_TRUE(inputStream != nullptr);
60
61 // Figure out how much data we have.
62 uint64_t length;
63 nsresult rv = inputStream->Available(&length);
64 ASSERT_TRUE(NS_SUCCEEDED(rv));
65
66 // Write the data into a SourceBuffer.
67 NotNull<RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull(new SourceBuffer());
68 sourceBuffer->ExpectLength(length);
69 rv = sourceBuffer->AppendFromInputStream(inputStream, length);
70 ASSERT_TRUE(NS_SUCCEEDED(rv));
71 sourceBuffer->Complete(NS_OK);
72
73 // Create a metadata decoder first, because otherwise RasterImage will get
74 // unhappy about finding out the image is animated during a full decode.
75 DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
76 RefPtr<IDecodingTask> task = DecoderFactory::CreateMetadataDecoder(
77 decoderType, rasterImage, sourceBuffer);
78 ASSERT_TRUE(task != nullptr);
79
80 // Run the metadata decoder synchronously.
81 task->Run();
82 task = nullptr;
83
84 // Create an AnimationSurfaceProvider which will manage the decoding process
85 // and make this decoder's output available in the surface cache.
86 DecoderFlags decoderFlags = DefaultDecoderFlags();
87 SurfaceFlags surfaceFlags = aTestCase.mSurfaceFlags;
88 rv = DecoderFactory::CreateAnimationDecoder(
89 decoderType, rasterImage, sourceBuffer, aTestCase.mSize, decoderFlags,
90 surfaceFlags, 0, getter_AddRefs(task));
91 EXPECT_EQ(rv, NS_OK);
92 ASSERT_TRUE(task != nullptr);
93
94 // Run the full decoder synchronously.
95 task->Run();
96
97 // Call the lambda to verify the expected results.
98 aResultChecker(rasterImage.get());
99 }
100
CheckFrameAnimatorBlend(const ImageTestCase & aTestCase)101 static void CheckFrameAnimatorBlend(const ImageTestCase& aTestCase) {
102 WithFrameAnimatorDecode(aTestCase, [&](RasterImage* aImage) {
103 CheckFrameAnimatorBlendResults(aTestCase, aImage);
104 });
105 }
106
107 class ImageFrameAnimator : public ::testing::Test {
108 protected:
109 AutoInitializeImageLib mInit;
110 };
111
TEST_F(ImageFrameAnimator,BlendGIFWithFilter)112 TEST_F(ImageFrameAnimator, BlendGIFWithFilter) {
113 CheckFrameAnimatorBlend(BlendAnimatedGIFTestCase());
114 }
115
TEST_F(ImageFrameAnimator,BlendPNGWithFilter)116 TEST_F(ImageFrameAnimator, BlendPNGWithFilter) {
117 CheckFrameAnimatorBlend(BlendAnimatedPNGTestCase());
118 }
119
TEST_F(ImageFrameAnimator,BlendWebPWithFilter)120 TEST_F(ImageFrameAnimator, BlendWebPWithFilter) {
121 CheckFrameAnimatorBlend(BlendAnimatedWebPTestCase());
122 }
123