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

Side by Side Diff: Source/core/platform/image-decoders/gif/GIFImageDecoderTest.cpp

Issue 15350006: Decode GIF image frames on demand. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased Created 7 years, 6 months 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
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 14 matching lines...) Expand all
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 32
33 #include "core/platform/image-decoders/gif/GIFImageDecoder.h" 33 #include "core/platform/image-decoders/gif/GIFImageDecoder.h"
34 34
35 #include <gtest/gtest.h>
36 #include "core/platform/FileSystem.h" 35 #include "core/platform/FileSystem.h"
37 #include "core/platform/SharedBuffer.h" 36 #include "core/platform/SharedBuffer.h"
37 #include "wtf/OwnPtr.h"
38 #include "wtf/PassOwnPtr.h"
39 #include "wtf/StringHasher.h"
40 #include "wtf/Vector.h"
41 #include <gtest/gtest.h>
38 #include <public/Platform.h> 42 #include <public/Platform.h>
39 #include <public/WebData.h> 43 #include <public/WebData.h>
40 #include <public/WebSize.h> 44 #include <public/WebSize.h>
41 #include <public/WebUnitTestSupport.h> 45 #include <public/WebUnitTestSupport.h>
42 #include <wtf/OwnPtr.h>
43 #include <wtf/PassOwnPtr.h>
44 #include <wtf/StringHasher.h>
45 #include <wtf/Vector.h>
46 46
47 using namespace WebCore; 47 using namespace WebCore;
48 using namespace WebKit; 48 using namespace WebKit;
49 49
50 namespace { 50 namespace {
51 51
52 #if !OS(ANDROID) 52 #if !OS(ANDROID)
53 53
54 static PassRefPtr<SharedBuffer> readFile(const char* fileName) 54 static PassRefPtr<SharedBuffer> readFile(const char* fileName)
55 { 55 {
(...skipping 15 matching lines...) Expand all
71 static PassOwnPtr<GIFImageDecoder> createDecoder() 71 static PassOwnPtr<GIFImageDecoder> createDecoder()
72 { 72 {
73 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag eSource::GammaAndColorProfileApplied)); 73 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag eSource::GammaAndColorProfileApplied));
74 } 74 }
75 75
76 static unsigned hashSkBitmap(const SkBitmap& bitmap) 76 static unsigned hashSkBitmap(const SkBitmap& bitmap)
77 { 77 {
78 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); 78 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize());
79 } 79 }
80 80
81 static void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselin eHashes)
82 {
83 OwnPtr<GIFImageDecoder> decoder = createDecoder();
84 decoder->setData(data, true);
85 size_t frameCount = decoder->frameCount();
86 for (size_t i = 0; i < frameCount; ++i) {
87 ImageFrame* frame = decoder->frameBufferAtIndex(i);
88 baselineHashes->append(hashSkBitmap(frame->getSkBitmap()));
89 }
90 }
91
81 TEST(GIFImageDecoderTest, decodeTwoFrames) 92 TEST(GIFImageDecoderTest, decodeTwoFrames)
82 { 93 {
83 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 94 OwnPtr<GIFImageDecoder> decoder = createDecoder();
84 95
85 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 96 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
86 ASSERT_TRUE(data.get()); 97 ASSERT_TRUE(data.get());
87 decoder->setData(data.get(), true); 98 decoder->setData(data.get(), true);
88 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 99 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
89 100
90 ImageFrame* frame = decoder->frameBufferAtIndex(0); 101 ImageFrame* frame = decoder->frameBufferAtIndex(0);
91 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 102 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
92 EXPECT_EQ(16, frame->getSkBitmap().width()); 103 EXPECT_EQ(16, frame->getSkBitmap().width());
93 EXPECT_EQ(16, frame->getSkBitmap().height()); 104 EXPECT_EQ(16, frame->getSkBitmap().height());
94 105
95 frame = decoder->frameBufferAtIndex(1); 106 frame = decoder->frameBufferAtIndex(1);
96 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 107 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
97 EXPECT_EQ(16, frame->getSkBitmap().width()); 108 EXPECT_EQ(16, frame->getSkBitmap().width());
98 EXPECT_EQ(16, frame->getSkBitmap().height()); 109 EXPECT_EQ(16, frame->getSkBitmap().height());
99 110
100 EXPECT_EQ(2u, decoder->frameCount()); 111 EXPECT_EQ(2u, decoder->frameCount());
101 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 112 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
102 } 113 }
103 114
104 TEST(GIFImageDecoderTest, parseAndDecode) 115 TEST(GIFImageDecoderTest, parseAndDecode)
105 { 116 {
106 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 117 OwnPtr<GIFImageDecoder> decoder = createDecoder();
107 118
108 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 119 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
109 ASSERT_TRUE(data.get()); 120 ASSERT_TRUE(data.get());
110 decoder->setData(data.get(), true); 121 decoder->setData(data.get(), true);
111 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 122 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
112 123
113 // This call will parse the entire file. 124 // This call will parse the entire file.
114 EXPECT_EQ(2u, decoder->frameCount()); 125 EXPECT_EQ(2u, decoder->frameCount());
115 126
116 ImageFrame* frame = decoder->frameBufferAtIndex(0); 127 ImageFrame* frame = decoder->frameBufferAtIndex(0);
117 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 128 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
118 EXPECT_EQ(16, frame->getSkBitmap().width()); 129 EXPECT_EQ(16, frame->getSkBitmap().width());
119 EXPECT_EQ(16, frame->getSkBitmap().height()); 130 EXPECT_EQ(16, frame->getSkBitmap().height());
120 131
121 frame = decoder->frameBufferAtIndex(1); 132 frame = decoder->frameBufferAtIndex(1);
122 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 133 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
123 EXPECT_EQ(16, frame->getSkBitmap().width()); 134 EXPECT_EQ(16, frame->getSkBitmap().width());
124 EXPECT_EQ(16, frame->getSkBitmap().height()); 135 EXPECT_EQ(16, frame->getSkBitmap().height());
125 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 136 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
126 } 137 }
127 138
128 TEST(GIFImageDecoderTest, parseByteByByte) 139 TEST(GIFImageDecoderTest, parseByteByByte)
129 { 140 {
130 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 141 OwnPtr<GIFImageDecoder> decoder = createDecoder();
131 142
132 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 143 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
133 ASSERT_TRUE(data.get()); 144 ASSERT_TRUE(data.get());
134 145
135 size_t frameCount = 0; 146 size_t frameCount = 0;
136 147
137 // Pass data to decoder byte by byte. 148 // Pass data to decoder byte by byte.
138 for (unsigned length = 1; length <= data->size(); ++length) { 149 for (size_t length = 1; length <= data->size(); ++length) {
139 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 150 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
140 decoder->setData(tempData.get(), length == data->size()); 151 decoder->setData(tempData.get(), length == data->size());
141 152
142 EXPECT_LE(frameCount, decoder->frameCount()); 153 EXPECT_LE(frameCount, decoder->frameCount());
143 frameCount = decoder->frameCount(); 154 frameCount = decoder->frameCount();
144 } 155 }
145 156
146 EXPECT_EQ(2u, decoder->frameCount()); 157 EXPECT_EQ(2u, decoder->frameCount());
147 158
148 decoder->frameBufferAtIndex(0); 159 decoder->frameBufferAtIndex(0);
149 decoder->frameBufferAtIndex(1); 160 decoder->frameBufferAtIndex(1);
150 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 161 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
151 } 162 }
152 163
153 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) 164 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte)
154 { 165 {
155 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 166 OwnPtr<GIFImageDecoder> decoder = createDecoder();
156 167
157 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated-gif-with-offsets.gif"); 168 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated-gif-with-offsets.gif");
158 ASSERT_TRUE(data.get()); 169 ASSERT_TRUE(data.get());
159 170
160 size_t frameCount = 0; 171 size_t frameCount = 0;
161 size_t framesDecoded = 0; 172 size_t framesDecoded = 0;
162 173
163 // Pass data to decoder byte by byte. 174 // Pass data to decoder byte by byte.
164 for (unsigned length = 1; length <= data->size(); ++length) { 175 for (size_t length = 1; length <= data->size(); ++length) {
165 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 176 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
166 decoder->setData(tempData.get(), length == data->size()); 177 decoder->setData(tempData.get(), length == data->size());
167 178
168 EXPECT_LE(frameCount, decoder->frameCount()); 179 EXPECT_LE(frameCount, decoder->frameCount());
169 frameCount = decoder->frameCount(); 180 frameCount = decoder->frameCount();
170 181
171 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); 182 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1);
172 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount) 183 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount)
173 ++framesDecoded; 184 ++framesDecoded;
174 } 185 }
175 186
176 EXPECT_EQ(5u, decoder->frameCount()); 187 EXPECT_EQ(5u, decoder->frameCount());
177 EXPECT_EQ(5u, framesDecoded); 188 EXPECT_EQ(5u, framesDecoded);
178 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 189 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
179 } 190 }
180 191
181 TEST(GIFImageDecoderTest, brokenSecondFrame) 192 TEST(GIFImageDecoderTest, brokenSecondFrame)
182 { 193 {
183 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 194 OwnPtr<GIFImageDecoder> decoder = createDecoder();
184 195
185 RefPtr<SharedBuffer> data = readFile("/Source/WebKit/chromium/tests/data/bro ken.gif"); 196 RefPtr<SharedBuffer> data = readFile("/Source/WebKit/chromium/tests/data/bro ken.gif");
186 ASSERT_TRUE(data.get()); 197 ASSERT_TRUE(data.get());
187 decoder->setData(data.get(), true); 198 decoder->setData(data.get(), true);
188 199
189 // One frame is detected but cannot be decoded. 200 // One frame is detected but cannot be decoded.
190 EXPECT_EQ(1u, decoder->frameCount()); 201 EXPECT_EQ(1u, decoder->frameCount());
191 ImageFrame* frame = decoder->frameBufferAtIndex(1); 202 ImageFrame* frame = decoder->frameBufferAtIndex(1);
192 EXPECT_FALSE(frame); 203 EXPECT_FALSE(frame);
193 } 204 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 if (truncatedHashes[i] != progressiveHashes[i]) { 247 if (truncatedHashes[i] != progressiveHashes[i]) {
237 match = false; 248 match = false;
238 break; 249 break;
239 } 250 }
240 } 251 }
241 EXPECT_TRUE(match); 252 EXPECT_TRUE(match);
242 } 253 }
243 254
244 TEST(GIFImageDecoderTest, allDataReceivedTruncation) 255 TEST(GIFImageDecoderTest, allDataReceivedTruncation)
245 { 256 {
246 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 257 OwnPtr<GIFImageDecoder> decoder = createDecoder();
247 258
248 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 259 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
249 ASSERT_TRUE(data.get()); 260 ASSERT_TRUE(data.get());
250 261
251 ASSERT_GE(data->size(), 10u); 262 ASSERT_GE(data->size(), 10u);
252 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 263 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
253 decoder->setData(tempData.get(), true); 264 decoder->setData(tempData.get(), true);
254 265
255 EXPECT_EQ(2u, decoder->frameCount()); 266 EXPECT_EQ(2u, decoder->frameCount());
256 EXPECT_FALSE(decoder->failed()); 267 EXPECT_FALSE(decoder->failed());
257 268
258 decoder->frameBufferAtIndex(0); 269 decoder->frameBufferAtIndex(0);
259 EXPECT_FALSE(decoder->failed()); 270 EXPECT_FALSE(decoder->failed());
260 decoder->frameBufferAtIndex(1); 271 decoder->frameBufferAtIndex(1);
261 EXPECT_TRUE(decoder->failed()); 272 EXPECT_TRUE(decoder->failed());
262 } 273 }
263 274
264 TEST(GIFImageDecoderTest, frameIsComplete) 275 TEST(GIFImageDecoderTest, frameIsComplete)
265 { 276 {
266 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 277 OwnPtr<GIFImageDecoder> decoder = createDecoder();
267 278
268 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 279 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
269 ASSERT_TRUE(data.get()); 280 ASSERT_TRUE(data.get());
270 decoder->setData(data.get(), true); 281 decoder->setData(data.get(), true);
271 282
272 EXPECT_EQ(2u, decoder->frameCount()); 283 EXPECT_EQ(2u, decoder->frameCount());
273 EXPECT_FALSE(decoder->failed()); 284 EXPECT_FALSE(decoder->failed());
274 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 285 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
275 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 286 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
276 } 287 }
277 288
278 TEST(GIFImageDecoderTest, frameIsCompleteLoading) 289 TEST(GIFImageDecoderTest, frameIsCompleteLoading)
279 { 290 {
280 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 291 OwnPtr<GIFImageDecoder> decoder = createDecoder();
281 292
282 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 293 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
283 ASSERT_TRUE(data.get()); 294 ASSERT_TRUE(data.get());
284 295
285 ASSERT_GE(data->size(), 10u); 296 ASSERT_GE(data->size(), 10u);
286 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 297 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
287 decoder->setData(tempData.get(), false); 298 decoder->setData(tempData.get(), false);
288 299
289 EXPECT_EQ(2u, decoder->frameCount()); 300 EXPECT_EQ(2u, decoder->frameCount());
290 EXPECT_FALSE(decoder->failed()); 301 EXPECT_FALSE(decoder->failed());
(...skipping 21 matching lines...) Expand all
312 323
313 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); 324 OwnPtr<GIFImageDecoder> testDecoder(createDecoder());
314 testDecoder->setData(testData.get(), true); 325 testDecoder->setData(testData.get(), true);
315 EXPECT_EQ(1u, testDecoder->frameCount()); 326 EXPECT_EQ(1u, testDecoder->frameCount());
316 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); 327 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0);
317 ASSERT(testFrame); 328 ASSERT(testFrame);
318 329
319 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram e->getSkBitmap())); 330 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram e->getSkBitmap()));
320 } 331 }
321 332
333 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode)
334 {
335 OwnPtr<GIFImageDecoder> decoder = createDecoder();
336
337 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /animated-10color.gif");
338 ASSERT_TRUE(fullData.get());
339
340 // Give it data that is enough to parse but not decode in order to check the status
341 // of requiredPreviousFrameIndex before decoding.
342 size_t partialSize = 1;
343 do {
344 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize);
345 decoder->setData(data.get(), false);
346 ++partialSize;
347 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty);
348
349 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameInd ex());
350 unsigned frameCount = decoder->frameCount();
351 for (size_t i = 1; i < frameCount; ++i)
352 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex());
353
354 decoder->setData(fullData.get(), true);
355 for (size_t i = 0; i < frameCount; ++i)
356 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(i)->requiredPreviousFram eIndex());
357 }
358
359 void testRandomFrameDecode(const char* gifFile)
360 {
361 SCOPED_TRACE(gifFile);
362
363 RefPtr<SharedBuffer> fullData = readFile(gifFile);
364 ASSERT_TRUE(fullData.get());
365 Vector<unsigned> baselineHashes;
366 createDecodingBaseline(fullData.get(), &baselineHashes);
367 size_t frameCount = baselineHashes.size();
368
369 // Random decoding should get the same results as sequential decoding.
370 OwnPtr<GIFImageDecoder> decoder = createDecoder();
371 decoder->setData(fullData.get(), true);
372 const size_t skippingStep = 5;
373 for (size_t i = 0; i < skippingStep; ++i) {
374 for (size_t j = i; j < frameCount; j += skippingStep) {
375 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
376 ImageFrame* frame = decoder->frameBufferAtIndex(j);
377 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap()));
378 }
379 }
380
381 // Decoding in reverse order.
382 decoder = createDecoder();
383 decoder->setData(fullData.get(), true);
384 for (size_t i = frameCount; i; --i) {
385 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
386 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
387 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap()));
388 }
389 }
390
391 TEST(GIFImageDecoderTest, randomFrameDecode)
392 {
393 // Single frame image.
394 testRandomFrameDecode("/Source/WebKit/chromium/tests/data/radient.gif");
395 // Multiple frame image.
396 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-gif-with- offsets.gif");
397 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-10color.g if");
398 }
399
400 void testRandomDecodeAfterClearFrameBufferCache(const char* gifFile)
401 {
402 SCOPED_TRACE(gifFile);
403
404 RefPtr<SharedBuffer> data = readFile(gifFile);
405 ASSERT_TRUE(data.get());
406 Vector<unsigned> baselineHashes;
407 createDecodingBaseline(data.get(), &baselineHashes);
408 size_t frameCount = baselineHashes.size();
409
410 OwnPtr<GIFImageDecoder> decoder = createDecoder();
411 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) {
412 decoder->clearCacheExceptFrame(clearExceptFrame);
413 const size_t skippingStep = 5;
414 for (size_t i = 0; i < skippingStep; ++i) {
415 for (size_t j = 0; j < frameCount; j += skippingStep) {
416 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
417 ImageFrame* frame = decoder->frameBufferAtIndex(j);
418 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())) ;
419 }
420 }
421 }
422 }
423
424 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache)
425 {
426 // Single frame image.
427 testRandomFrameDecode("/Source/WebKit/chromium/tests/data/radient.gif");
428 // Multiple frame image.
429 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-gif-with- offsets.gif");
430 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-10color.g if");
431 }
432
433 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache)
434 {
435 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /animated-10color.gif");
436 ASSERT_TRUE(fullData.get());
437 Vector<unsigned> baselineHashes;
438 createDecodingBaseline(fullData.get(), &baselineHashes);
439 size_t frameCount = baselineHashes.size();
440
441 OwnPtr<GIFImageDecoder> decoder = createDecoder();
442
443 // Let frame 0 be partially decoded.
444 size_t partialSize = 1;
445 do {
446 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize);
447 decoder->setData(data.get(), false);
448 ++partialSize;
449 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty);
450
451 // Skip to the last frame and clear.
452 decoder->setData(fullData.get(), true);
453 EXPECT_EQ(frameCount, decoder->frameCount());
454 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1);
455 EXPECT_EQ(baselineHashes[frameCount - 1], hashSkBitmap(lastFrame->getSkBitma p()));
456 decoder->clearCacheExceptFrame(notFound);
457
458 // Resume decoding of the first frame.
459 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
460 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status());
461 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap()));
462 }
463
322 #endif 464 #endif
323 465
324 } // namespace 466 } // namespace
OLDNEW
« no previous file with comments | « Source/core/platform/image-decoders/gif/GIFImageDecoder.cpp ('k') | Source/core/platform/image-decoders/gif/GIFImageReader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698