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