111 static const struct {
116 std::vector<int> fRequiredFrames;
118 std::vector<SkAlphaType> fAlphas;
121 std::vector<int> fDurations;
122 int fRepetitionCount;
123 std::vector<SkCodecAnimation::DisposalMethod> fDisposalMethods;
124 std::vector<bool> fAlphaWithinBounds;
125 std::vector<SkCodecAnimation::Blend> fBlends;
126 std::vector<SkIRect> fFrameRects;
128 {
"images/required.gif", 7,
129 { 0, 1, 2, 3, 4, 5 },
131 { 100, 100, 100, 100, 100, 100, 100 },
134 {
false,
true,
true,
true,
true,
true,
true },
137 { {0, 0, 100, 100}, {0, 0, 75, 75}, {0, 0, 50, 50}, {0, 0, 60, 60},
138 {0, 0, 100, 100}, {0, 0, 50, 50}, {0, 0, 75, 75}},
140 {
"images/alphabetAnim.gif", 13,
141 { kNoFrame, 0, 0, 0, 0, 5, 6, kNoFrame, kNoFrame, 9, 10, 11 },
144 { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 },
146 {
kKeep, kRestorePrev, kRestorePrev, kRestorePrev, kRestorePrev,
149 {
true,
false,
true,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true },
153 { {25, 25, 75, 75}, {25, 25, 75, 75}, {25, 25, 75, 75}, {37, 37, 62, 62},
154 {37, 37, 62, 62}, {25, 25, 75, 75}, {0, 0, 50, 50}, {0, 0, 100, 100},
155 {25, 25, 75, 75}, {25, 25, 75, 75}, {0, 0, 100, 100}, {25, 25, 75, 75},
158 {
"images/randPixelsAnim2.gif", 4,
162 { kOpaque, kOpaque, kOpaque },
164 { 0, 1000, 170, 40 },
168 {
false,
true,
false,
false },
170 { {0, 0, 8, 8}, {6, 6, 8, 8}, {4, 4, 8, 8}, {7, 0, 8, 8} },
172 {
"images/randPixelsAnim.gif", 13,
174 { 0, 1, 2, 3, 4, 3, 6, 7, 7, 7, 9, 9 },
178 { 0, 1000, 170, 40, 220, 7770, 90, 90, 90, 90, 90, 90, 90 },
182 kRestoreBG, kRestorePrev, kRestoreBG, kRestorePrev, kRestorePrev,
184 {
false,
true,
true,
false,
true,
true,
false,
false,
true,
true,
false,
false,
189 { {4, 4, 12, 12}, {4, 4, 12, 12}, {4, 4, 12, 12}, {0, 0, 8, 8}, {8, 8, 16, 16},
190 {8, 8, 16, 16}, {8, 8, 16, 16}, {2, 2, 10, 10}, {7, 7, 15, 15}, {7, 7, 15, 15},
191 {7, 7, 15, 15}, {0, 0, 8, 8}, {14, 14, 16, 16} },
193 {
"images/box.gif", 1, {}, {}, {},
SkCodec::kRepetitionCountInfinite, {
kKeep }, {}, {}, {} },
194 {
"images/color_wheel.gif", 1, {}, {}, {},
SkCodec::kRepetitionCountInfinite, {
kKeep }, {}, {}, {} },
195 {
"images/test640x479.gif", 4, { 0, 1, 2 },
196 { kOpaque, kOpaque, kOpaque },
197 { 200, 200, 200, 200 },
200 {
false,
true,
true,
true },
202 { {0, 0, 640, 479}, {0, 0, 640, 479}, {0, 0, 640, 479}, {0, 0, 640, 479} },
204 {
"images/colorTables.gif", 2, { 0 }, { kOpaque }, { 1000, 1000 }, 5,
206 { {0, 0, 640, 400}, {0, 0, 640, 200}},
209 {
"images/arrow.png", 1, {}, {}, {}, 0, {}, {}, {}, {} },
210 {
"images/google_chrome.ico", 1, {}, {}, {}, 0, {}, {}, {}, {} },
211 {
"images/brickwork-texture.jpg", 1, {}, {}, {}, 0, {}, {}, {}, {} },
212#if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32))
213 {
"images/dng_with_preview.dng", 1, {}, {}, {}, 0, {}, {}, {}, {} },
215 {
"images/mandrill.wbmp", 1, {}, {}, {}, 0, {}, {}, {}, {} },
216 {
"images/randPixels.bmp", 1, {}, {}, {}, 0, {}, {}, {}, {} },
217 {
"images/yellow_rose.webp", 1, {}, {}, {}, 0, {}, {}, {}, {} },
218 {
"images/stoplight.webp", 3, { 0, 1 }, { kOpaque, kOpaque },
222 { {0, 0, 11, 29}, {2, 10, 9, 27}, {2, 2, 9, 18}},
224 {
"images/blendBG.webp", 7,
225 { 0, kNoFrame, kNoFrame, kNoFrame, 4, 4 },
227 { 525, 500, 525, 437, 609, 729, 444 },
230 {
false,
true,
false,
true,
false,
true,
true },
232 { {0, 0, 200, 200}, {0, 0, 200, 200}, {0, 0, 200, 200}, {0, 0, 200, 200},
233 {0, 0, 200, 200}, {100, 100, 200, 200}, {100, 100, 200, 200} },
235 {
"images/required.webp", 7,
236 { 0, 1, 1, kNoFrame, 4, 4 },
238 { 100, 100, 100, 100, 100, 100, 100 },
241 {
false,
false,
false,
false,
false,
false,
false },
244 { {0, 0, 100, 100}, {0, 0, 75, 75}, {0, 0, 50, 50}, {0, 0, 60, 60},
245 {0, 0, 100, 100}, {0, 0, 50, 50}, {0, 0, 75, 75}},
249 for (
const auto& rec : gRecs) {
260 ERRORF(r,
"Failed to create an SkCodec from '%s'", rec.fName);
269 const int expected = rec.fFrameCount;
270 if (rec.fRequiredFrames.size() + 1 !=
static_cast<size_t>(expected)) {
271 ERRORF(r,
"'%s' has wrong number entries in fRequiredFrames; expected: %i\tactual: %zu",
272 rec.fName, expected - 1, rec.fRequiredFrames.size());
277 if (rec.fDurations.size() !=
static_cast<size_t>(expected)) {
278 ERRORF(r,
"'%s' has wrong number entries in fDurations; expected: %i\tactual: %zu",
279 rec.fName, expected, rec.fDurations.size());
283 if (rec.fAlphas.size() + 1 !=
static_cast<size_t>(expected)) {
284 ERRORF(r,
"'%s' has wrong number entries in fAlphas; expected: %i\tactual: %zu",
285 rec.fName, expected - 1, rec.fAlphas.size());
289 if (rec.fDisposalMethods.size() !=
static_cast<size_t>(expected)) {
290 ERRORF(r,
"'%s' has wrong number entries in fDisposalMethods; "
291 "expected %i\tactual: %zu",
292 rec.fName, expected, rec.fDisposalMethods.size());
297 enum class TestMode {
302 for (
auto mode : { TestMode::kVector, TestMode::kIndividual }) {
307 std::vector<SkCodec::FrameInfo> frameInfos;
309 case TestMode::kVector:
310 frameInfos = codec->getFrameInfo();
312 frameCount = frameInfos.empty() ? 1 : frameInfos.size();
314 case TestMode::kIndividual:
315 frameCount = codec->getFrameCount();
319 if (frameCount != expected) {
320 ERRORF(r,
"'%s' expected frame count: %i\tactual: %i",
321 rec.fName, expected, frameCount);
338 const int repetitionCount = codec->getRepetitionCount();
339 if (repetitionCount != rec.fRepetitionCount) {
340 ERRORF(r,
"%s repetition count does not match! expected: %i\tactual: %i",
341 rec.fName, rec.fRepetitionCount, repetitionCount);
345 if (1 == frameCount) {
349 for (
int i = 0; i < frameCount; i++) {
352 case TestMode::kVector:
353 frameInfo = frameInfos[i];
355 case TestMode::kIndividual:
361 if (rec.fDurations[i] != frameInfo.
fDuration) {
362 ERRORF(r,
"%s frame %i's durations do not match! expected: %i\tactual: %i",
363 rec.fName, i, rec.fDurations[i], frameInfo.
fDuration);
378 auto expectedAlpha = 0 == i ? codec->getInfo().alphaType() : rec.fAlphas[i-1];
380 if (expectedAlpha != alpha) {
381 ERRORF(r,
"%s's frame %i has wrong alpha type! expected: %s\tactual: %s",
387 }
else if (rec.fRequiredFrames[i-1] != frameInfo.
fRequiredFrame) {
388 ERRORF(r,
"%s's frame %i has wrong dependency! expected: %i\tactual: %i",
389 rec.fName, i, rec.fRequiredFrames[i-1], frameInfo.
fRequiredFrame);
394 reporter_assert_equals<bool>(r, rec.fName, i,
"alpha within bounds",
395 rec.fAlphaWithinBounds[i],
398 reporter_assert_equals(r, rec.fName, i,
"blend mode", rec.fBlends[i],
401 reporter_assert_equals(r, rec.fName, i,
"frame rect", rec.fFrameRects[i],
405 if (TestMode::kIndividual == mode) {
417 std::vector<SkBitmap> cachedFrames(frameCount);
418 const auto info = codec->getInfo().makeColorType(kN32_SkColorType);
421 auto decodeInfo =
info;
423 decodeInfo =
info.makeAlphaType(frameInfos[index].fAlphaType);
442 ERRORF(r,
"Using a kRestorePrevious frame as fPriorFrame should fail");
446 ERRORF(r,
"Failed to decode frame %i from %s when providing prior frame %i, "
447 "error %i", index, rec.fName, cachedIndex,
result);
452 for (
int i = 0; i < frameCount; i++) {
453 SkBitmap& cachedFrame = cachedFrames[i];
457 const auto reqFrame = frameInfos[i].fRequiredFrame;
462 for (
int j = reqFrame; j < i; j++) {
473 const size_t rowLen =
info.bytesPerPixel() *
info.width();
474 for (
int y = 0;
y <
info.height();
y++) {
475 const void* cachedAddr = cachedFrame.
getAddr(0,
y);
477 const void* addr =
frame.getAddr(0,
y);
479 const bool lineMatches = memcmp(cachedAddr, addr, rowLen) == 0;
485 ERRORF(r,
"%s's frame %i is different (starting from line %i) when "
486 "providing prior frame %i!", rec.fName, i,
y, j);