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

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

Issue 2386453003: WIP: Implement APNG (Closed)
Patch Set: Processed feedback patch 6 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 result in a failed decode.
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,
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(reinterpret_cast<char*>(sizeChunk), 4u);
158
159 // Skip the size in the original data, but provide the rest of the fcTL,
160 // which is 4B of tag, 26B of data and 4B of CRC, totalling 34B.
161 invalidData->append(data->data() + offsetFctl + 4, 34u);
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 // First make sure that this tests makes sense.
174 ASSERT(injectedFrameCount != expectedFrameCount);
scroggo_chromium 2016/10/26 18:25:58 Sorry, I meant ASSERT_NE(injectedFrameCount, ex
scroggo_chromium 2016/10/28 14:20:32 (It is helpful if you respond to comments that rec
joostouwerling 2016/10/28 18:41:25 Acknowledged.
175
176 auto data = readFile(pngFile);
177 auto decoder = createDecoder();
178 ASSERT_FALSE(data->isEmpty());
179
180 RefPtr<SharedBuffer> diffActlData = SharedBuffer::create(data->data(),
181 offsetActl + 8);
182 // Write the injectedFrameCount to the stream
183 png_byte sizeChunk[4];
184 writeUint32(injectedFrameCount, sizeChunk);
185 diffActlData->append(reinterpret_cast<char*>(sizeChunk), 4u);
186 // Append the rest of the data. The first |offsetActl + 12| bytes that are
187 // already in diffActlData should not be appended again.
188 diffActlData->append(data->data() + offsetActl + 12,
189 data->size() - offsetActl - 12);
190
191 decoder->setData(diffActlData, true);
192 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
193 }
194
195 // Test if the frame bitmap hashes of truncated decoding are equal to the
196 // hashes found by incremental decoding.
197 void testProgressiveDecoding(const char *pngFile)
198 {
199 RefPtr<SharedBuffer> fullData = readFile(pngFile);
200 ASSERT_TRUE(fullData.get());
201 const size_t fullLength = fullData->size();
202
203 std::unique_ptr<ImageDecoder> decoder;
204 ImageFrame* frame;
205
206 Vector<unsigned> truncatedHashes;
207 Vector<unsigned> progressiveHashes;
208
209 // Compute hashes when the file is truncated.
210 const size_t increment = 10;
211 for (size_t i = 1; i <= fullLength; i += increment) {
212 decoder = createDecoder();
213 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
214 decoder->setData(data.get(), i == fullLength);
215 size_t frameCount = decoder->frameCount();
216 ASSERT_FALSE(decoder->failed());
217 if (frameCount == 0) {
218 truncatedHashes.append(0);
219 continue;
220 }
221 frame = decoder->frameBufferAtIndex(frameCount - 1);
222 if (!frame) {
223 truncatedHashes.append(0);
224 continue;
225 }
226 truncatedHashes.append(hashBitmap(frame->bitmap()));
227 }
228
229 // Compute hashes when the file is progressively decoded.
230 decoder = createDecoder();
231 for (size_t i = 1; i <= fullLength; i += increment) {
232 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
233 decoder->setData(data.get(), i == fullLength);
234 ASSERT_FALSE(decoder->failed());
235 size_t frameCount = decoder->frameCount();
236 if (frameCount == 0) {
237 progressiveHashes.append(0);
238 continue;
239 }
240 frame = decoder->frameBufferAtIndex(frameCount - 1);
241 if (!frame) {
242 progressiveHashes.append(0);
243 continue;
244 }
245 progressiveHashes.append(hashBitmap(frame->bitmap()));
246 }
247
248 for (size_t i = 0; i < truncatedHashes.size(); ++i)
249 ASSERT_EQ(truncatedHashes[i], progressiveHashes[i]);
250 }
251
252 } // Anonymous namespace
253
254 // Animated PNG Tests
255
256 TEST(AnimatedPNGTests, sizeTest)
257 {
258 testSize("/LayoutTests/fast/images/resources/png-animated-idat-part-of-anima tion.png", IntSize(5, 5));
259 testSize("/LayoutTests/fast/images/resources/png-animated-idat-not-part-of-a nimation.png", IntSize(227, 35));
260 }
261
262 TEST(AnimatedPNGTests, repetitionCountTest)
263 {
264 testRepetitionCount("/LayoutTests/fast/images/resources/png-animated-idat-pa rt-of-animation.png", 7u);
265 // This is an "animated" image with only one frame, that is, the IDAT is
266 // ignored and there is one fdAT frame. so it should be considered
267 // non-animated.
268 testRepetitionCount("/LayoutTests/fast/images/resources/png-animated-idat-no t-part-of-animation.png", cAnimationNone);
269 }
270
271 // Test if the decoded metdata corresponds to the defined expectations
272 TEST(AnimatedPNGTests, MetaDataTest)
273 {
274 const char* pngFile = "/LayoutTests/fast/images/resources/png-animated-idat- part-of-animation.png";
275 constexpr size_t expectedFrameCount = 4;
276
277 auto decoder = createDecoderWithPngData(pngFile);
278 ASSERT_EQ(expectedFrameCount, decoder->frameCount());
279 for (size_t i = 0; i < expectedFrameCount; i++)
280 compareFrameWithExpectation(pngAnimatedFrameInfo[i],
281 decoder->frameBufferAtIndex(i));
282 }
283
284 TEST(AnimatedPNGTests, ByteByByteSizeAvailable)
285 {
286 testSizeByteByByte("/LayoutTests/fast/images/resources/png-animated-idat-par t-of-animation.png",
287 141u, IntSize(5, 5));
288 testSizeByteByByte("/LayoutTests/fast/images/resources/png-animated-idat-not -part-of-animation.png",
289 79u, IntSize(227, 35));
290 }
291
292 // Test whether the frame metadata decoding also works when we provide the data
293 // byte by byte. This should cover the case when the client does not provide
294 // all data at once. At given offsets, we expect frames to become available.
295 // This test checks whether that is the case, and if so, if the frame data is
296 // equal to what we expected.
297 TEST(AnimatedPNGTests, ByteByByteMetaData)
298 {
299 const char* pngFile = "/LayoutTests/fast/images/resources/png-animated-idat- part-of-animation.png";
300 constexpr size_t expectedFrameCount = 4;
301
302 // These are the byte offsets where each frame should have been parsed.
303 // It boils down to the offset of the first fcTL / IEND after the last
304 // frame data chunk, plus 8 bytes for recognition.
305 size_t frameOffsets[expectedFrameCount] = {180, 249, 322, 430};
306
307 auto decoder = createDecoder();
308 auto data = readFile(pngFile);
309 ASSERT_FALSE(data->isEmpty());
310 size_t framesParsed = 0;
311
312 for (size_t length = 1; length <= frameOffsets[expectedFrameCount - 1]; leng th++) {
313 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(),
314 length);
315 decoder->setData(tempData.get(), false);
316 EXPECT_FALSE(decoder->failed());
317 if (length < frameOffsets[framesParsed]) {
318 EXPECT_EQ(framesParsed, decoder->frameCount());
319 } else {
320 ASSERT_EQ(framesParsed + 1, decoder->frameCount());
321 compareFrameWithExpectation(pngAnimatedFrameInfo[framesParsed],
322 decoder->frameBufferAtIndex(framesParsed ));
323 framesParsed++;
324 }
325 }
326 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
327 EXPECT_FALSE(decoder->failed());
328 }
329
330 // This tests if the frame count gets set correctly when parsing frameCount
331 // fails in one of the parsing queries.
332 //
333 // First, enough data is provided such that two frames should be registered.
334 // The decoder should at this point not be in the failed status.
335 //
336 // Then, we provide the rest of the data except for the last IEND chunk, but
337 // tell the decoder that this is all the data we have. Now, the decoder should
338 // be in the failed state since all data is provided but no IEND chunk has been
339 // seen. The frame count should be three, since one extra frame should be
340 // discovered. The fourth frame should *not* be registered since the reader
341 // should not be able to determine where the frame ends.
342 TEST(AnimatedPNGTests, FrameCountWithTruncatedData)
343 {
344 const char* pngFile = "/LayoutTests/fast/images/resources/png-animated-idat- part-of-animation.png";
345 auto decoder = createDecoder();
346 auto data = readFile(pngFile);
347 ASSERT_FALSE(data->isEmpty());
348
349 // Parse up to and including the first two frames
350 const size_t offsetTwoFrames = 249;
351 const size_t expectedFramesAfter249Bytes = 2;
352 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(),
353 offsetTwoFrames);
354 decoder->setData(tempData.get(), false);
355 EXPECT_EQ(expectedFramesAfter249Bytes, decoder->frameCount());
356 EXPECT_FALSE(decoder->failed());
357
358 // Provide the rest of the data except for the last IEND chunk.
359 const size_t expectedFramesAfterAllExpect12Bytes = 3;
360 tempData = SharedBuffer::create(data->data(), data->size() - 12);
361 decoder->setData(tempData.get(), true);
362 EXPECT_EQ(expectedFramesAfterAllExpect12Bytes, decoder->frameCount());
363 EXPECT_TRUE(decoder->failed());
364 }
365
366 TEST(AnimatedPNGTests, TestRandomFrameDecode)
367 {
368 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /png-animated-idat-part-of-animation.png");
369 ASSERT_TRUE(fullData.get());
370 Vector<unsigned> baselineHashes;
371 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes);
372 size_t frameCount = baselineHashes.size();
373
374 // Random decoding should get the same results as sequential decoding.
375 std::unique_ptr<ImageDecoder> decoder = createDecoder();
376 decoder->setData(fullData.get(), true);
377 const size_t skippingStep = 2;
378 for (size_t i = 0; i < skippingStep; ++i) {
379 for (size_t j = i; j < frameCount; j += skippingStep) {
380 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
381 ImageFrame* frame = decoder->frameBufferAtIndex(j);
382 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap()));
383 }
384 }
385
386 // Decoding in reverse order.
387 decoder = createDecoder();
388 decoder->setData(fullData.get(), true);
389 for (size_t i = frameCount; i; --i) {
390 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
391 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
392 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->bitmap()));
393 }
394
395 }
396
397 TEST(AnimatedPNGTests, TestDecodeAfterReallocation)
398 {
399 std::unique_ptr<ImageDecoder> decoder = createDecoder();
400 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/png -animated-idat-part-of-animation.png");
401 ASSERT_TRUE(data.get());
402
403 // Parse from |data|.
404 decoder->setData(data.get(), true);
405 size_t frameCount = decoder->frameCount();
406
407 // ... and then decode frames from |reallocatedData|.
408 RefPtr<SharedBuffer> reallocatedData = data.get()->copy();
409 ASSERT_TRUE(reallocatedData.get());
410 data.clear();
411 decoder->setData(reallocatedData.get(), true);
412
413 for (size_t i = 0; i < frameCount; ++i) {
414 const ImageFrame* const frame = decoder->frameBufferAtIndex(i);
415 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus());
416 }
417 }
418
419 TEST(AnimatedPNGTests, ProgressiveDecode)
420 {
421 testProgressiveDecoding("/LayoutTests/fast/images/resources/png-animated-ida t-part-of-animation.png");
422 }
423
424 TEST(AnimatedPNGTests, ParseAndDecodeByteByByte)
425 {
426 testByteByByteDecode(&createDecoder,
427 "/LayoutTests/fast/images/resources/png-animated-idat-p art-of-animation.png",
428 4u, 7u);
429 }
430
431 TEST(AnimatedPNGTests, FctlWrongSizeBreaksDecoding)
432 {
433 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
434 auto data = readFile(pngFile);
435 ASSERT_FALSE(data->isEmpty());
436
437 // Test the first fcTL in the stream. Because no frame data has been set
438 // at this point, the expected frame count is zero.
439 testInvalidFctlSize("//LayoutTests/fast/images/resources/png-animated-idat-p art-of-animation.png",
440 95u, 0u);
441
442 // Test for the third fcTL in the stream. This should be tested as well,
443 // since the first fcTL is parsed in PNGImageReader::parseSize() whereas
444 // later fcTLs are parsed in PNGImageReader::parse() as part of framecount.
445 // The expected frame count before the fcTL chunk is 1u, since the second
446 // frame is registered when the third fcTL (or IEND) is seen.
447 testInvalidFctlSize("//LayoutTests/fast/images/resources/png-animated-idat-p art-of-animation.png",
448 241u, 1u);
449
450 }
451
452 TEST(AnimatedPNGTests, MissingFctlDataBreaksDecoding)
453 {
454 // The fcTL chunk starts at 95u, add 10u to get to the content data, and
455 // remove 5 bytes of data.
456 testMissingDataBreaksDecoding(
457 "//LayoutTests/fast/images/resources/png-animated-idat-part-of-animation .png",
458 105u, 5u);
459 }
460
461 TEST(AnimatedPNGTests, MissingActlResultsInNonAnimated)
462 {
463 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
464 auto data = readFile(pngFile);
465 auto decoder = createDecoder();
466 ASSERT_FALSE(data->isEmpty());
467
468 // Remove the acTL chunk from the stream.
469 size_t offsetActl = 33;
470 RefPtr<SharedBuffer> noActlData = SharedBuffer::create(data->data(),
471 offsetActl);
472 noActlData->append(data->data() + offsetActl + 20,
473 data->size() - offsetActl - 20);
474
475 decoder->setData(noActlData, true);
476 EXPECT_EQ(1u, decoder->frameCount());
477 EXPECT_FALSE(decoder->failed());
478 }
479
480 // Test if the indicated frame count by the acTL is ignored if the actual
481 // number of frames is different. Test for higher and lower indicated number.
482 TEST(AnimatedPNGTests, differentActlFrameCountIsIgnored)
483 {
484 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
485 testDifferentActlFrameCountIsIgnored(pngFile, 33u, 2u, 4u);
486 testDifferentActlFrameCountIsIgnored(pngFile, 33u, 8u, 4u);
487 }
488
489 // Check if a frame rectangle, that is larger than the image width, gets
490 // clipped correctly.
491 TEST(AnimatedPNGTests, frameRectIsClipped)
492 {
493 const char* pngFile = "//LayoutTests/fast/images/resources/png-animated-idat -part-of-animation.png";
494 auto data = readFile(pngFile);
495 auto decoder = createDecoder();
496 ASSERT_FALSE(data->isEmpty());
497
498 // Change the width and height of the frame so it falls outside the image.
scroggo_chromium 2016/10/26 18:25:58 I don't think this is a realistic test. Although y
scroggo_chromium 2016/10/28 14:20:32 Maybe it's silly of me to say "this is what a brok
joostouwerling 2016/10/28 18:41:25 I don't completely understand what you mean with "
scroggo_chromium 2016/10/31 13:35:11 My original comment was that I would expect a brok
joostouwerling 2016/10/31 18:40:19 I could not find any explicit tests for corrupt PN
499 size_t offsetThirdFctl = 241 + 12;
500 RefPtr<SharedBuffer> modifiedData = SharedBuffer::create(data->data(),
501 offsetThirdFctl);
502 png_byte sizeChunk[8];
503 writeUint32(10, sizeChunk);
504 writeUint32(15, sizeChunk + 4);
505 modifiedData->append(const_cast<const char*>(
506 reinterpret_cast<char*>(sizeChunk)), 8u);
507 modifiedData->append(data->data() + offsetThirdFctl + 8,
508 data->size() - offsetThirdFctl - 8);
509
510 decoder->setData(modifiedData, true);
511
512 IntSize expectedSize(5, 5);
513 size_t expectedFrameCount = 4;
514 IntRect expectedFrameRect(IntPoint(1, 2), IntSize(4, 3));
515
516 EXPECT_TRUE(decoder->isSizeAvailable());
517 EXPECT_EQ(expectedSize, decoder->size());
518 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
519 ASSERT_FALSE(decoder->failed());
520 EXPECT_EQ(expectedFrameRect,
521 decoder->frameBufferAtIndex(2)->originalFrameRect());
522
523 }
524
525 // Static PNG tests
526
527 TEST(StaticPNGTests, repetitionCountTest)
528 {
529 testRepetitionCount("/LayoutTests/fast/images/resources/png-simple.png",
530 cAnimationNone);
531 }
532
533 TEST(StaticPNGTests, sizeTest)
534 {
535 testSize("/LayoutTests/fast/images/resources/png-simple.png",
536 IntSize(111, 29));
537 }
538
539 TEST(StaticPNGTests, MetaDataTest)
540 {
541 const size_t expectedFrameCount = 1;
542 const size_t expectedDuration = 0;
543 auto decoder = createDecoderWithPngData("/LayoutTests/fast/images/resources/ png-simple.png");
544 EXPECT_EQ(expectedFrameCount, decoder->frameCount());
545 EXPECT_EQ(expectedDuration, decoder->frameDurationAtIndex(0));
546 }
547
548 // This test removes two random byets from the IHDR chunk. The decoder should
549 // fail on this since all IHDR data is necessary to decode a PNG image.
550 TEST(StaticPNGTests, InvalidIHDRChunk)
551 {
552 testMissingDataBreaksDecoding(
553 "//LayoutTests/fast/images/resources/png-simple.png", 20u, 2u);
554 }
555
556 TEST(StaticPNGTests, ProgressiveDecoding)
557 {
558 testProgressiveDecoding("/LayoutTests/fast/images/resources/png-simple.png") ;
559 }
560
561 }; // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698