Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp

Issue 2386453003: WIP: Implement APNG (Closed)
Patch Set: Basic frame decoding with tests, no alpha blending and disposal yet Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "platform/image-decoders/png/PNGImageDecoder.h"
6
7 #include "png.h"
8 #include "platform/image-decoders/ImageDecoderTestHelpers.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include <memory>
11
12 namespace blink {
13
14 namespace {
15
16 std::unique_ptr<ImageDecoder> createDecoder(ImageDecoder::AlphaOption alphaOptio n)
17 {
18 return wrapUnique(new PNGImageDecoder(alphaOption,
19 ImageDecoder::GammaAndColorProfileAppl ied,
20 ImageDecoder::noDecodedImageByteLimit) );
21 }
22
23 std::unique_ptr<ImageDecoder> createDecoder()
24 {
25 return createDecoder(ImageDecoder::AlphaNotPremultiplied);
26 }
27
28 std::unique_ptr<ImageDecoder> createDecoderWithPngData(const char* pngFile)
29 {
30 auto decoder = createDecoder();
31 auto data = readFile(pngFile);
32 EXPECT_FALSE(data->isEmpty());
33 decoder->setData(data.get(), true);
34 return decoder;
35 }
36
37 void testSize(const char* pngFile, IntSize expectedSize)
38 {
39 auto decoder = createDecoderWithPngData(pngFile);
40 EXPECT_TRUE(decoder->isSizeAvailable());
41 EXPECT_EQ(expectedSize, decoder->size());
42 }
43
44 void writeUint32(uint32_t val, png_byte* data)
45 {
46 data[0] = val >> 24;
47 data[1] = val >> 16;
48 data[2] = val >> 8;
49 data[3] = val;
50 }
51
52 void testRepetitionCount(const char* pngFile, int expectedRepetitionCount)
53 {
54 auto decoder = createDecoderWithPngData(pngFile);
55 // Decode frame count should see the number of repetitions as well.
56 decoder->frameCount();
57 EXPECT_FALSE(decoder->failed());
58 EXPECT_EQ(expectedRepetitionCount, decoder->repetitionCount());
59 }
60
61 // Test whether querying for the size of the image works if we present the
62 // data byte by byte.
63 void testSizeByteByByte(const char *pngFile, size_t bytesNeededToDecodeSize,
64 IntSize expectedSize)
65 {
66 auto decoder = createDecoder();
67 auto data = readFile(pngFile);
68 ASSERT_FALSE(data->isEmpty());
69 ASSERT_LT(bytesNeededToDecodeSize, data->size());
70
71 for (size_t length = 1; length <= bytesNeededToDecodeSize; length++) {
72 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(),
73 length);
74 decoder->setData(tempData.get(), false);
75
76 if (length < bytesNeededToDecodeSize) {
77 EXPECT_FALSE(decoder->isSizeAvailable());
78 EXPECT_TRUE(decoder->size().isEmpty());
79 EXPECT_FALSE(decoder->failed());
80 } else {
81 EXPECT_TRUE(decoder->isSizeAvailable());
82 EXPECT_EQ(expectedSize, decoder->size());
83 }
84 }
85 EXPECT_FALSE(decoder->failed());
86 }
87
88 struct PublicFrameInfo {
89 size_t duration;
90 IntRect frameRect;
91 ImageFrame::AlphaBlendSource alphaBlend;
92 ImageFrame::DisposalMethod disposalMethod;
93 };
94
95 // This is the frame data for the following PNG image:
96 // /LayoutTests/fast/images/resources/png-animated-idat-part-of-animation.png
97 static PublicFrameInfo pngAnimatedFrameInfo[] = {
98 {500, {IntPoint(0, 0), IntSize(5, 5)}, ImageFrame::BlendAtopBgcolor,
99 ImageFrame::DisposeKeep},
100 {900, {IntPoint(1, 1), IntSize(3, 1)}, ImageFrame::BlendAtopBgcolor,
101 ImageFrame::DisposeOverwriteBgcolor},
102 {2000, {IntPoint(1, 2), IntSize(3, 2)}, ImageFrame::BlendAtopPreviousFrame,
103 ImageFrame::DisposeKeep},
104 {1500, {IntPoint(1, 2), IntSize(3, 1)}, ImageFrame::BlendAtopBgcolor,
105 ImageFrame::DisposeKeep},
106 };
107
108 void compareFrameWithExpectation(const PublicFrameInfo& expected,
109 const ImageFrame* frame)
110 {
111 EXPECT_EQ(expected.duration, frame->duration());
112 EXPECT_EQ(expected.frameRect, frame->originalFrameRect());
113 EXPECT_EQ(expected.disposalMethod, frame->getDisposalMethod());
114 EXPECT_EQ(expected.alphaBlend, frame->getAlphaBlendSource());
115 }
116
117 // This function removes |length| bytes at |offset|, and then calls frameCount.
118 // It assumes the missing bytes should return in a failed decoding.
scroggo_chromium 2016/10/25 14:59:06 I think you mean "result" instead of "return"? (A
119 void testMissingDataBreaksDecoding(const char* pngFile, size_t offset,
120 size_t length)
121 {
122 auto decoder = createDecoder();
123 auto data = readFile(pngFile);
124 ASSERT_FALSE(data->isEmpty());
125
126 RefPtr<SharedBuffer> invalidData = SharedBuffer::create(data->data(),
127 offset);
128 invalidData->append(SharedBuffer::create(data->data() + offset + length,
129 data->size() - offset - length));
130 ASSERT_EQ(data->size() - length, invalidData->size());
131
132 decoder->setData(invalidData, true);
133 decoder->frameCount();
134 EXPECT_TRUE(decoder->failed());
135 }
136
137 // Decoding up to the indicated fcTL offset and then provide an fcTL with
138 // the wrong chunk size (20 instead of 26). It should break the decoder.
139 void testInvalidFctlSize(const char *pngFile, size_t offsetFctl,
scroggo_chromium 2016/10/25 14:59:06 * should go next to the type (although I think Mat
140 size_t expectedFrameCountBeforeFail)
141 {
142 auto data = readFile(pngFile);
143 ASSERT_FALSE(data->isEmpty());
144
145 auto decoder = createDecoder();
146 RefPtr<SharedBuffer> invalidData = SharedBuffer::create(data->data(),
147 offsetFctl);
148
149 // Test if this gives the correct frame count, before the fcTL is parsed.
150 decoder->setData(invalidData, false);
151 EXPECT_EQ(expectedFrameCountBeforeFail, decoder->frameCount());
152 ASSERT_FALSE(decoder->failed());
153
154 // Append the wrong size to the data stream
155 png_byte sizeChunk[4];
156 writeUint32(20, sizeChunk);
157 invalidData->append(const_cast<const char*>(
scroggo_chromium 2016/10/25 14:59:06 I don't think you should need a const cast to cast
158 reinterpret_cast<char*>(sizeChunk)), 4u);
159
160 // Skip the size in the original data, but provide the rest of the fcTL
161 invalidData->append(data->data() + offsetFctl + 4, 34u);
scroggo_chromium 2016/10/25 14:59:06 Where did 34u come from? Is fcTL 38 bytes?
joostouwerling 2016/10/26 15:44:17 Yes, 26 bytes of data and 12 for length, tag and c
162
163 decoder->setData(invalidData, false);
164 decoder->frameCount();
165 EXPECT_TRUE(decoder->failed());
166 }
167
168 void testDifferentActlFrameCountIsIgnored(const char* pngFile,
169 size_t offsetActl,
170 size_t injectedFrameCount,
171 size_t expectedFrameCount)
172 {
173 auto data = readFile(pngFile);
174 auto decoder = createDecoder();
175 ASSERT_FALSE(data->isEmpty());
176
177 RefPtr<SharedBuffer> diffActlData = SharedBuffer::create(data->data(),
178 offsetActl + 8);
179 // Write the injectedFrameCount to the stream
180 png_byte sizeChunk[4];
181 writeUint32(injectedFrameCount, sizeChunk);
182 diffActlData->append(const_cast<const char*>(
183 reinterpret_cast<char*>(sizeChunk)), 4u);
184 // Append the rest of the data
185 diffActlData->append(data->data() + offsetActl + 12,
scroggo_chromium 2016/10/25 14:59:06 I take it the acTL chunk is 16 bytes? It would be
186 data->size() - offsetActl - 12);
187
188 decoder->setData(diffActlData, true);
189 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
scroggo_chromium 2016/10/25 14:59:06 Maybe assert that expectedFrameCount != injectedFr
190 }
191
192 // Test if the frame bitmap hashes of truncated decoding are equal to the
193 // hashes found by incremental decoding.
194 void testProgressiveDecoding(const char *pngFile)
195 {
196 RefPtr<SharedBuffer> fullData = readFile(pngFile);
197 ASSERT_TRUE(fullData.get());
198 const size_t fullLength = fullData->size();
199
200 std::unique_ptr<ImageDecoder> decoder;
scroggo_chromium 2016/10/25 14:59:06 nit: extra space
201 ImageFrame* frame;
202
203 Vector<unsigned> truncatedHashes;
204 Vector<unsigned> progressiveHashes;
205
206 // Compute hashes when the file is truncated.
207 const size_t increment = 10;
208 for (size_t i = 1; i <= fullLength; i += increment) {
209 decoder = createDecoder();
210 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
211 decoder->setData(data.get(), i == fullLength);
212 size_t frameCount = decoder->frameCount();
213 ASSERT_FALSE(decoder->failed());
214 if (frameCount == 0) {
215 truncatedHashes.append(0);
216 continue;
217 }
218 frame = decoder->frameBufferAtIndex(frameCount - 1);
219 if (!frame) {
220 truncatedHashes.append(0);
221 continue;
222 }
223 truncatedHashes.append(hashBitmap(frame->bitmap()));
224 }
225
226 // Compute hashes when the file is progressively decoded.
227 decoder = createDecoder();
228 for (size_t i = 1; i <= fullLength; i += increment) {
229 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
230 decoder->setData(data.get(), i == fullLength);
231 ASSERT_FALSE(decoder->failed());
232 size_t frameCount = decoder->frameCount();
233 if (frameCount == 0) {
234 progressiveHashes.append(0);
235 continue;
236 }
237 frame = decoder->frameBufferAtIndex(frameCount - 1);
238 if (!frame) {
239 progressiveHashes.append(0);
240 continue;
241 }
242 progressiveHashes.append(hashBitmap(frame->bitmap()));
243 }
244
245 bool match = true;
246 for (size_t i = 0; i < truncatedHashes.size(); ++i) {
247 if (truncatedHashes[i] != progressiveHashes[i]) {
248 match = false;
scroggo_chromium 2016/10/25 14:59:06 Alternatively, could this just be something like
249 break;
250 }
251 }
252 EXPECT_TRUE(match);
253
254 }
255
256 } // Anonymous namespace
257
258 // Animated PNG Tests
259
260 TEST(AnimatedPNGTests, sizeTest)
261 {
262 testSize("/LayoutTests/fast/images/resources/png-animated-idat-part-of-anima tion.png", IntSize(5, 5));
263 testSize("/LayoutTests/fast/images/resources/png-animated-idat-not-part-of-a nimation.png", IntSize(227, 35));
264 }
265
266 TEST(AnimatedPNGTests, repetitionCountTest)
267 {
268 testRepetitionCount("/LayoutTests/fast/images/resources/png-animated-idat-pa rt-of-animation.png", 7u);
269 // This is an "animated" image with only one frame, that is, the IDAT is
270 // ignored and there is one fdAT frame. so it should be considered
271 // non-animated.
272 testRepetitionCount("/LayoutTests/fast/images/resources/png-animated-idat-no t-part-of-animation.png", cAnimationNone);
273 }
274
275 // Test if the decoded metdata corresponds to the defined expectations
276 TEST(AnimatedPNGTests, MetaDataTest)
277 {
278 const char* pngFile = "/LayoutTests/fast/images/resources/png-animated-idat- part-of-animation.png";
279 constexpr size_t expectedFrameCount = 4;
280
281 auto decoder = createDecoderWithPngData(pngFile);
282 ASSERT_EQ(expectedFrameCount, decoder->frameCount());
283 for (size_t i = 0; i < expectedFrameCount; i++)
284 compareFrameWithExpectation(pngAnimatedFrameInfo[i],
285 decoder->frameBufferAtIndex(i));
286 }
287
288 TEST(AnimatedPNGTests, ByteByByteSizeAvailable)
289 {
290 testSizeByteByByte("/LayoutTests/fast/images/resources/png-animated-idat-par t-of-animation.png",
291 141u, IntSize(5, 5));
292 testSizeByteByByte("/LayoutTests/fast/images/resources/png-animated-idat-not -part-of-animation.png",
293 79u, IntSize(227, 35));
294 }
295
296 // Test whether the frame metadata decoding also works when we provide the data
297 // byte by byte. This should cover the case when the client does not provide
298 // all data at once. At given offsets, we expect frames to become available.
299 // This test checks whether that is the case, and if so, if the frame data is
300 // equal to what we expected.
301 TEST(AnimatedPNGTests, ByteByByteMetaData)
302 {
303 const char* pngFile = "/LayoutTests/fast/images/resources/png-animated-idat- part-of-animation.png";
304 constexpr size_t expectedFrameCount = 4;
305
306 // These are the byte offsets where each frame should have been parsed.
307 // It boils down to the offset of the first fcTL / IEND after the last
308 // frame data chunk, plus 8 bytes for recognition.
309 size_t frameOffsets[expectedFrameCount] = {180, 249, 322, 430};
310
311 auto decoder = createDecoder();
312 auto data = readFile(pngFile);
313 ASSERT_FALSE(data->isEmpty());
314 size_t framesParsed = 0;
315
316 for (size_t length = 1; length <= frameOffsets[expectedFrameCount - 1]; leng th++) {
317 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(),
318 length);
319 decoder->setData(tempData.get(), false);
320 EXPECT_FALSE(decoder->failed());
321 if (length < frameOffsets[framesParsed]) {
322 EXPECT_EQ(framesParsed, decoder->frameCount());
323 } else {
324 ASSERT_EQ(framesParsed + 1, decoder->frameCount());
325 compareFrameWithExpectation(pngAnimatedFrameInfo[framesParsed],
326 decoder->frameBufferAtIndex(framesParsed ));
327 framesParsed++;
328 }
329 }
330 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
331 EXPECT_FALSE(decoder->failed());
332 }
333
334 // This tests if the frame count gets set correctly when parsing frameCount
335 // fails in one of the parsing queries.
336 //
337 // First, enough data is provided such that two frames should be registered.
338 // The decoder should at this point not be in the failed status.
339 //
340 // Then, we provide the rest of the data except for the last IEND chunk, but
341 // tell the decoder that this is all the data we have. Now, the decoder should
342 // be in the failed state since all data is provided but no IEND chunk has been
343 // seen. The frame count should be three, since one extra frame should be
344 // discovered. The fourth frame should *not* be registered since the reader
345 // should not be able to determine where the frame ends.
346 TEST(AnimatedPNGTests, FrameCountWithTruncatedData)
347 {
348 const char* pngFile = "/LayoutTests/fast/images/resources/png-animated-idat- part-of-animation.png";
349 auto decoder = createDecoder();
350 auto data = readFile(pngFile);
351 ASSERT_FALSE(data->isEmpty());
352
353 // Parse up to and including the first two frames
354 const size_t offsetTwoFrames = 249;
355 const size_t expectedFramesAfter249Bytes = 2;
356 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(),
357 offsetTwoFrames);
358 decoder->setData(tempData.get(), false);
359 EXPECT_EQ(expectedFramesAfter249Bytes, decoder->frameCount());
360 EXPECT_FALSE(decoder->failed());
361
362 // Provide the rest of the data except for the last IEND chunk.
363 const size_t expectedFramesAfterAllExpect12Bytes = 3;
364 tempData = SharedBuffer::create(data->data(), data->size() - 12);
365 decoder->setData(tempData.get(), true);
366 EXPECT_EQ(expectedFramesAfterAllExpect12Bytes, decoder->frameCount());
367 EXPECT_TRUE(decoder->failed());
368 }
369
370 TEST(AnimatedPNGTests, TestRandomFrameDecode)
371 {
372 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /png-animated-idat-part-of-animation.png");
373 ASSERT_TRUE(fullData.get());
374 Vector<unsigned> baselineHashes;
375 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes);
376 size_t frameCount = baselineHashes.size();
377
378 // Random decoding should get the same results as sequential decoding.
379 std::unique_ptr<ImageDecoder> decoder = createDecoder();
380 decoder->setData(fullData.get(), true);
381 const size_t skippingStep = 2;
382 for (size_t i = 0; i < skippingStep; ++i) {
383 for (size_t j = i; j < frameCount; j += skippingStep) {
384 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
385 ImageFrame* frame = decoder->frameBufferAtIndex(j);
386 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap()));
387 }
388 }
389
390 // Decoding in reverse order.
391 decoder = createDecoder();
392 decoder->setData(fullData.get(), true);
393 for (size_t i = frameCount; i; --i) {
394 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
395 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
396 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->bitmap()));
397 }
398
399 }
400
401 TEST(AnimatedPNGTests, TestDecodeAfterReallocation)
402 {
403 std::unique_ptr<ImageDecoder> decoder = createDecoder();
404 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/png -animated-idat-part-of-animation.png");
405 ASSERT_TRUE(data.get());
406
407 // Parse from |data|.
408 decoder->setData(data.get(), true);
409 size_t frameCount = decoder->frameCount();
410
411 // ... and then decode frames from |reallocatedData|.
scroggo_chromium 2016/10/25 14:59:06 What is interesting about this test? (Will PNGIma
joostouwerling 2016/10/26 15:44:17 It should have the frame meta data cached, not the
scroggo_chromium 2016/10/26 18:25:58 Ok, that makes sense. You asked me a question in p
joostouwerling 2016/10/31 18:40:19 I will consolidate the tests when this CL is done,
412 RefPtr<SharedBuffer> reallocatedData = data.get()->copy();
413 ASSERT_TRUE(reallocatedData.get());
414 data.clear();
415 decoder->setData(reallocatedData.get(), true);
416
417 for (size_t i = 0; i < frameCount; ++i) {
418 const ImageFrame* const frame = decoder->frameBufferAtIndex(i);
419 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus());
420 }
421 }
422
423 TEST(AnimatedPNGTests, ProgressiveDecode)
424 {
425 testProgressiveDecoding("/LayoutTests/fast/images/resources/png-animated-ida t-part-of-animation.png");
426 }
427
428 TEST(AnimatedPNGTests, ParseAndDecodeByteByByte)
429 {
430 testByteByByteDecode(&createDecoder,
431 "/LayoutTests/fast/images/resources/png-animated-idat-p art-of-animation.png",
432 4u, 7u);
433 }
434
435 TEST(AnimatedPNGTests, FctlWrongSizeBreaksDecoding)
436 {
437 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
438 auto data = readFile(pngFile);
439 ASSERT_FALSE(data->isEmpty());
440
441 // Test the first fcTL in the stream. Because no frame data has been set
442 // at this point, the expected frame count is zero.
443 testInvalidFctlSize("//LayoutTests/fast/images/resources/png-animated-idat-p art-of-animation.png",
444 95u, 0u);
445
446 // Test for the third fcTL in the stream. This should be tested as well,
447 // since the first fcTL is parsed in PNGImageReader::parseSize() whereas
448 // later fcTLs are parsed in PNGImageReader::parse() as part of framecount.
449 // The expected frame count before the fcTL chunk is 1u, since the second
450 // frame is registered when the third fcTL (or IEND) is seen.
451 testInvalidFctlSize("//LayoutTests/fast/images/resources/png-animated-idat-p art-of-animation.png",
452 241u, 1u);
453
454 }
455
456 TEST(AnimatedPNGTests, MissingFctlDataBreaksDecoding)
457 {
458 // The fcTL chunk starts at 95u, add 10u to get to the content data, and
459 // remove 5 bytes of data.
460 testMissingDataBreaksDecoding(
461 "//LayoutTests/fast/images/resources/png-animated-idat-part-of-animation .png",
462 105u, 5u);
463 }
464
465 TEST(AnimatedPNGTests, MissingActlResultsInNonAnimated)
466 {
467 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
468 auto data = readFile(pngFile);
469 auto decoder = createDecoder();
470 ASSERT_FALSE(data->isEmpty());
471
472 // Remove the acTL chunk from the stream.
473 size_t offsetActl = 33;
474 RefPtr<SharedBuffer> noActlData = SharedBuffer::create(data->data(),
475 offsetActl);
476 noActlData->append(data->data() + offsetActl + 20,
477 data->size() - offsetActl - 20);
478
479 decoder->setData(noActlData, true);
480 EXPECT_EQ(1u, decoder->frameCount());
481 EXPECT_FALSE(decoder->failed());
482 }
483
484 // Test if the indicated frame count by the acTL is ignored if the actual
485 // number of frames is different. Test for higher and lower indicated number.
486 TEST(AnimatedPNGTests, differentActlFrameCountIsIgnored)
487 {
488 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
489 testDifferentActlFrameCountIsIgnored(pngFile, 33u, 2u, 4u);
490 testDifferentActlFrameCountIsIgnored(pngFile, 33u, 8u, 4u);
491 }
492
493 // Check if a frame rectangle, that is larger than the image width, gets
494 // clipped correctly.
495 TEST(AnimatedPNGTests, frameRectIsClipped)
496 {
497 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
498 auto data = readFile(pngFile);
499 auto decoder = createDecoder();
500 ASSERT_FALSE(data->isEmpty());
501
502 // Change the width and height of the frame so it falls outside the image.
503 size_t offsetThirdFctl = 241 + 12;
504 RefPtr<SharedBuffer> modifiedData = SharedBuffer::create(data->data(),
505 offsetThirdFctl);
506 png_byte sizeChunk[8];
507 writeUint32(10, sizeChunk);
508 writeUint32(15, sizeChunk + 4);
509 modifiedData->append(const_cast<const char*>(
510 reinterpret_cast<char*>(sizeChunk)), 8u);
511 modifiedData->append(data->data() + offsetThirdFctl + 8,
512 data->size() - offsetThirdFctl - 8);
513
514 decoder->setData(modifiedData, true);
515
516 IntSize expectedSize(5, 5);
517 size_t expectedFrameCount = 4;
518 IntRect expectedFrameRect(IntPoint(1, 2), IntSize(4, 3));
519
520 EXPECT_TRUE(decoder->isSizeAvailable());
521 EXPECT_EQ(expectedSize, decoder->size());
522 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
523 ASSERT_FALSE(decoder->failed());
524 EXPECT_EQ(expectedFrameRect,
525 decoder->frameBufferAtIndex(2)->originalFrameRect());
526
527 }
528
529 // Static PNG tests
530
531 TEST(StaticPNGTests, repetitionCountTest)
532 {
533 testRepetitionCount("/LayoutTests/fast/images/resources/png-simple.png",
534 cAnimationNone);
535 }
536
537 TEST(StaticPNGTests, sizeTest)
538 {
539 testSize("/LayoutTests/fast/images/resources/png-simple.png",
540 IntSize(111, 29));
541 }
542
543 TEST(StaticPNGTests, MetaDataTest)
544 {
545 const size_t expectedFrameCount = 1;
546 const size_t expectedDuration = 0;
547 auto decoder = createDecoderWithPngData("/LayoutTests/fast/images/resources/ png-simple.png");
548 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
549 EXPECT_EQ(expectedDuration, decoder->frameDurationAtIndex(0));
550 }
551
552 // This test removes two random byets from the IHDR chunk. The decoder should
553 // fail on this since all IHDR data is necessary to decode a PNG image.
554 TEST(StaticPNGTests, InvalidIHDRChunk)
555 {
556 testMissingDataBreaksDecoding(
557 "//LayoutTests/fast/images/resources/png-simple.png", 20u, 2u);
558 }
559
560 TEST(StaticPNGTests, ProgressiveDecoding)
561 {
562 testProgressiveDecoding("/LayoutTests/fast/images/resources/png-simple.png") ;
563 }
564
565 }; // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698