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

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

Issue 813943003: Fix handling of broken GIFs with weird frame sizes (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: comments Created 5 years, 11 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
« no previous file with comments | « no previous file | Source/platform/image-decoders/gif/GIFImageReader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 29 matching lines...) Expand all
40 #include "wtf/OwnPtr.h" 40 #include "wtf/OwnPtr.h"
41 #include "wtf/PassOwnPtr.h" 41 #include "wtf/PassOwnPtr.h"
42 #include "wtf/StringHasher.h" 42 #include "wtf/StringHasher.h"
43 #include "wtf/Vector.h" 43 #include "wtf/Vector.h"
44 #include <gtest/gtest.h> 44 #include <gtest/gtest.h>
45 45
46 using namespace blink; 46 using namespace blink;
47 47
48 namespace { 48 namespace {
49 49
50 PassRefPtr<SharedBuffer> readFile(const char* fileName) 50 const char decodersTestingDir[] = "Source/platform/image-decoders/testing";
51 const char layoutTestResourcesDir[] = "LayoutTests/fast/images/resources";
52 const char webTestsDataDir[] = "Source/web/tests/data";
53
54 PassRefPtr<SharedBuffer> readFile(const char* dir, const char* fileName)
51 { 55 {
52 String filePath = Platform::current()->unitTestSupport()->webKitRootDir(); 56 String filePath = Platform::current()->unitTestSupport()->webKitRootDir();
57 filePath.append("/");
58 filePath.append(dir);
59 filePath.append("/");
53 filePath.append(fileName); 60 filePath.append(fileName);
54 61
55 return Platform::current()->unitTestSupport()->readFromFile(filePath); 62 return Platform::current()->unitTestSupport()->readFromFile(filePath);
56 } 63 }
57 64
58 PassOwnPtr<GIFImageDecoder> createDecoder() 65 PassOwnPtr<GIFImageDecoder> createDecoder()
59 { 66 {
60 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag eSource::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit)); 67 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag eSource::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit));
61 } 68 }
62 69
63 unsigned hashSkBitmap(const SkBitmap& bitmap) 70 unsigned hashSkBitmap(const SkBitmap& bitmap)
64 { 71 {
65 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); 72 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize());
66 } 73 }
67 74
68 void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselineHashes ) 75 void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselineHashes )
69 { 76 {
70 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 77 OwnPtr<GIFImageDecoder> decoder = createDecoder();
71 decoder->setData(data, true); 78 decoder->setData(data, true);
72 size_t frameCount = decoder->frameCount(); 79 size_t frameCount = decoder->frameCount();
73 for (size_t i = 0; i < frameCount; ++i) { 80 for (size_t i = 0; i < frameCount; ++i) {
74 ImageFrame* frame = decoder->frameBufferAtIndex(i); 81 ImageFrame* frame = decoder->frameBufferAtIndex(i);
75 baselineHashes->append(hashSkBitmap(frame->getSkBitmap())); 82 baselineHashes->append(hashSkBitmap(frame->getSkBitmap()));
76 } 83 }
77 } 84 }
78 85
79 void testRandomFrameDecode(const char* gifFile) 86 void testRandomFrameDecode(const char* dir, const char* gifFile)
80 { 87 {
81 SCOPED_TRACE(gifFile); 88 SCOPED_TRACE(gifFile);
82 89
83 RefPtr<SharedBuffer> fullData = readFile(gifFile); 90 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile);
84 ASSERT_TRUE(fullData.get()); 91 ASSERT_TRUE(fullData.get());
85 Vector<unsigned> baselineHashes; 92 Vector<unsigned> baselineHashes;
86 createDecodingBaseline(fullData.get(), &baselineHashes); 93 createDecodingBaseline(fullData.get(), &baselineHashes);
87 size_t frameCount = baselineHashes.size(); 94 size_t frameCount = baselineHashes.size();
88 95
89 // Random decoding should get the same results as sequential decoding. 96 // Random decoding should get the same results as sequential decoding.
90 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 97 OwnPtr<GIFImageDecoder> decoder = createDecoder();
91 decoder->setData(fullData.get(), true); 98 decoder->setData(fullData.get(), true);
92 const size_t skippingStep = 5; 99 const size_t skippingStep = 5;
93 for (size_t i = 0; i < skippingStep; ++i) { 100 for (size_t i = 0; i < skippingStep; ++i) {
94 for (size_t j = i; j < frameCount; j += skippingStep) { 101 for (size_t j = i; j < frameCount; j += skippingStep) {
95 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 102 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
96 ImageFrame* frame = decoder->frameBufferAtIndex(j); 103 ImageFrame* frame = decoder->frameBufferAtIndex(j);
97 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())); 104 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap()));
98 } 105 }
99 } 106 }
100 107
101 // Decoding in reverse order. 108 // Decoding in reverse order.
102 decoder = createDecoder(); 109 decoder = createDecoder();
103 decoder->setData(fullData.get(), true); 110 decoder->setData(fullData.get(), true);
104 for (size_t i = frameCount; i; --i) { 111 for (size_t i = frameCount; i; --i) {
105 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); 112 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
106 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); 113 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
107 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap())); 114 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap()));
108 } 115 }
109 } 116 }
110 117
111 void testRandomDecodeAfterClearFrameBufferCache(const char* gifFile) 118 void testRandomDecodeAfterClearFrameBufferCache(const char* dir, const char* gif File)
112 { 119 {
113 SCOPED_TRACE(gifFile); 120 SCOPED_TRACE(gifFile);
114 121
115 RefPtr<SharedBuffer> data = readFile(gifFile); 122 RefPtr<SharedBuffer> data = readFile(dir, gifFile);
116 ASSERT_TRUE(data.get()); 123 ASSERT_TRUE(data.get());
117 Vector<unsigned> baselineHashes; 124 Vector<unsigned> baselineHashes;
118 createDecodingBaseline(data.get(), &baselineHashes); 125 createDecodingBaseline(data.get(), &baselineHashes);
119 size_t frameCount = baselineHashes.size(); 126 size_t frameCount = baselineHashes.size();
120 127
121 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 128 OwnPtr<GIFImageDecoder> decoder = createDecoder();
122 decoder->setData(data.get(), true); 129 decoder->setData(data.get(), true);
123 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) { 130 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) {
124 decoder->clearCacheExceptFrame(clearExceptFrame); 131 decoder->clearCacheExceptFrame(clearExceptFrame);
125 const size_t skippingStep = 5; 132 const size_t skippingStep = 5;
126 for (size_t i = 0; i < skippingStep; ++i) { 133 for (size_t i = 0; i < skippingStep; ++i) {
127 for (size_t j = 0; j < frameCount; j += skippingStep) { 134 for (size_t j = 0; j < frameCount; j += skippingStep) {
128 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 135 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
129 ImageFrame* frame = decoder->frameBufferAtIndex(j); 136 ImageFrame* frame = decoder->frameBufferAtIndex(j);
130 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())) ; 137 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())) ;
131 } 138 }
132 } 139 }
133 } 140 }
134 } 141 }
135 142
136 } // namespace 143 } // namespace
137 144
138 TEST(GIFImageDecoderTest, decodeTwoFrames) 145 TEST(GIFImageDecoderTest, decodeTwoFrames)
139 { 146 {
140 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 147 OwnPtr<GIFImageDecoder> decoder = createDecoder();
141 148
142 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 149 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
143 ASSERT_TRUE(data.get()); 150 ASSERT_TRUE(data.get());
144 decoder->setData(data.get(), true); 151 decoder->setData(data.get(), true);
145 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 152 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
146 153
147 ImageFrame* frame = decoder->frameBufferAtIndex(0); 154 ImageFrame* frame = decoder->frameBufferAtIndex(0);
148 uint32_t generationID0 = frame->getSkBitmap().getGenerationID(); 155 uint32_t generationID0 = frame->getSkBitmap().getGenerationID();
149 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 156 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
150 EXPECT_EQ(16, frame->getSkBitmap().width()); 157 EXPECT_EQ(16, frame->getSkBitmap().width());
151 EXPECT_EQ(16, frame->getSkBitmap().height()); 158 EXPECT_EQ(16, frame->getSkBitmap().height());
152 159
153 frame = decoder->frameBufferAtIndex(1); 160 frame = decoder->frameBufferAtIndex(1);
154 uint32_t generationID1 = frame->getSkBitmap().getGenerationID(); 161 uint32_t generationID1 = frame->getSkBitmap().getGenerationID();
155 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 162 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
156 EXPECT_EQ(16, frame->getSkBitmap().width()); 163 EXPECT_EQ(16, frame->getSkBitmap().width());
157 EXPECT_EQ(16, frame->getSkBitmap().height()); 164 EXPECT_EQ(16, frame->getSkBitmap().height());
158 EXPECT_TRUE(generationID0 != generationID1); 165 EXPECT_TRUE(generationID0 != generationID1);
159 166
160 EXPECT_EQ(2u, decoder->frameCount()); 167 EXPECT_EQ(2u, decoder->frameCount());
161 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 168 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
162 } 169 }
163 170
164 TEST(GIFImageDecoderTest, parseAndDecode) 171 TEST(GIFImageDecoderTest, parseAndDecode)
165 { 172 {
166 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 173 OwnPtr<GIFImageDecoder> decoder = createDecoder();
167 174
168 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 175 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
169 ASSERT_TRUE(data.get()); 176 ASSERT_TRUE(data.get());
170 decoder->setData(data.get(), true); 177 decoder->setData(data.get(), true);
171 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 178 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
172 179
173 // This call will parse the entire file. 180 // This call will parse the entire file.
174 EXPECT_EQ(2u, decoder->frameCount()); 181 EXPECT_EQ(2u, decoder->frameCount());
175 182
176 ImageFrame* frame = decoder->frameBufferAtIndex(0); 183 ImageFrame* frame = decoder->frameBufferAtIndex(0);
177 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 184 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
178 EXPECT_EQ(16, frame->getSkBitmap().width()); 185 EXPECT_EQ(16, frame->getSkBitmap().width());
179 EXPECT_EQ(16, frame->getSkBitmap().height()); 186 EXPECT_EQ(16, frame->getSkBitmap().height());
180 187
181 frame = decoder->frameBufferAtIndex(1); 188 frame = decoder->frameBufferAtIndex(1);
182 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 189 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
183 EXPECT_EQ(16, frame->getSkBitmap().width()); 190 EXPECT_EQ(16, frame->getSkBitmap().width());
184 EXPECT_EQ(16, frame->getSkBitmap().height()); 191 EXPECT_EQ(16, frame->getSkBitmap().height());
185 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 192 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
186 } 193 }
187 194
188 TEST(GIFImageDecoderTest, parseByteByByte) 195 TEST(GIFImageDecoderTest, parseByteByByte)
189 { 196 {
190 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 197 OwnPtr<GIFImageDecoder> decoder = createDecoder();
191 198
192 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 199 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
193 ASSERT_TRUE(data.get()); 200 ASSERT_TRUE(data.get());
194 201
195 size_t frameCount = 0; 202 size_t frameCount = 0;
196 203
197 // Pass data to decoder byte by byte. 204 // Pass data to decoder byte by byte.
198 for (size_t length = 1; length <= data->size(); ++length) { 205 for (size_t length = 1; length <= data->size(); ++length) {
199 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 206 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
200 decoder->setData(tempData.get(), length == data->size()); 207 decoder->setData(tempData.get(), length == data->size());
201 208
202 EXPECT_LE(frameCount, decoder->frameCount()); 209 EXPECT_LE(frameCount, decoder->frameCount());
203 frameCount = decoder->frameCount(); 210 frameCount = decoder->frameCount();
204 } 211 }
205 212
206 EXPECT_EQ(2u, decoder->frameCount()); 213 EXPECT_EQ(2u, decoder->frameCount());
207 214
208 decoder->frameBufferAtIndex(0); 215 decoder->frameBufferAtIndex(0);
209 decoder->frameBufferAtIndex(1); 216 decoder->frameBufferAtIndex(1);
210 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 217 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
211 } 218 }
212 219
213 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) 220 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte)
214 { 221 {
215 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 222 OwnPtr<GIFImageDecoder> decoder = createDecoder();
216 223
217 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated-gif-with-offsets.gif"); 224 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated-gif-w ith-offsets.gif");
218 ASSERT_TRUE(data.get()); 225 ASSERT_TRUE(data.get());
219 226
220 size_t frameCount = 0; 227 size_t frameCount = 0;
221 size_t framesDecoded = 0; 228 size_t framesDecoded = 0;
222 229
223 // Pass data to decoder byte by byte. 230 // Pass data to decoder byte by byte.
224 for (size_t length = 1; length <= data->size(); ++length) { 231 for (size_t length = 1; length <= data->size(); ++length) {
225 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 232 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
226 decoder->setData(tempData.get(), length == data->size()); 233 decoder->setData(tempData.get(), length == data->size());
227 234
228 EXPECT_LE(frameCount, decoder->frameCount()); 235 EXPECT_LE(frameCount, decoder->frameCount());
229 frameCount = decoder->frameCount(); 236 frameCount = decoder->frameCount();
230 237
231 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); 238 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1);
232 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount) 239 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount)
233 ++framesDecoded; 240 ++framesDecoded;
234 } 241 }
235 242
236 EXPECT_EQ(5u, decoder->frameCount()); 243 EXPECT_EQ(5u, decoder->frameCount());
237 EXPECT_EQ(5u, framesDecoded); 244 EXPECT_EQ(5u, framesDecoded);
238 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 245 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
239 } 246 }
240 247
241 TEST(GIFImageDecoderTest, brokenSecondFrame) 248 TEST(GIFImageDecoderTest, brokenSecondFrame)
242 { 249 {
243 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 250 OwnPtr<GIFImageDecoder> decoder = createDecoder();
244 251
245 RefPtr<SharedBuffer> data = readFile("/Source/web/tests/data/broken.gif"); 252 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "broken.gif");
246 ASSERT_TRUE(data.get()); 253 ASSERT_TRUE(data.get());
247 decoder->setData(data.get(), true); 254 decoder->setData(data.get(), true);
248 255
249 // One frame is detected but cannot be decoded. 256 // One frame is detected but cannot be decoded.
250 EXPECT_EQ(1u, decoder->frameCount()); 257 EXPECT_EQ(1u, decoder->frameCount());
251 ImageFrame* frame = decoder->frameBufferAtIndex(1); 258 ImageFrame* frame = decoder->frameBufferAtIndex(1);
252 EXPECT_FALSE(frame); 259 EXPECT_FALSE(frame);
253 } 260 }
254 261
255 TEST(GIFImageDecoderTest, progressiveDecode) 262 TEST(GIFImageDecoderTest, progressiveDecode)
256 { 263 {
257 RefPtr<SharedBuffer> fullData = readFile("/Source/web/tests/data/radient.gif "); 264 RefPtr<SharedBuffer> fullData = readFile(webTestsDataDir, "radient.gif");
258 ASSERT_TRUE(fullData.get()); 265 ASSERT_TRUE(fullData.get());
259 const size_t fullLength = fullData->size(); 266 const size_t fullLength = fullData->size();
260 267
261 OwnPtr<GIFImageDecoder> decoder; 268 OwnPtr<GIFImageDecoder> decoder;
262 ImageFrame* frame; 269 ImageFrame* frame;
263 270
264 Vector<unsigned> truncatedHashes; 271 Vector<unsigned> truncatedHashes;
265 Vector<unsigned> progressiveHashes; 272 Vector<unsigned> progressiveHashes;
266 273
267 // Compute hashes when the file is truncated. 274 // Compute hashes when the file is truncated.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 break; 307 break;
301 } 308 }
302 } 309 }
303 EXPECT_TRUE(match); 310 EXPECT_TRUE(match);
304 } 311 }
305 312
306 TEST(GIFImageDecoderTest, allDataReceivedTruncation) 313 TEST(GIFImageDecoderTest, allDataReceivedTruncation)
307 { 314 {
308 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 315 OwnPtr<GIFImageDecoder> decoder = createDecoder();
309 316
310 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 317 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
311 ASSERT_TRUE(data.get()); 318 ASSERT_TRUE(data.get());
312 319
313 ASSERT_GE(data->size(), 10u); 320 ASSERT_GE(data->size(), 10u);
314 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 321 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
315 decoder->setData(tempData.get(), true); 322 decoder->setData(tempData.get(), true);
316 323
317 EXPECT_EQ(2u, decoder->frameCount()); 324 EXPECT_EQ(2u, decoder->frameCount());
318 EXPECT_FALSE(decoder->failed()); 325 EXPECT_FALSE(decoder->failed());
319 326
320 decoder->frameBufferAtIndex(0); 327 decoder->frameBufferAtIndex(0);
321 EXPECT_FALSE(decoder->failed()); 328 EXPECT_FALSE(decoder->failed());
322 decoder->frameBufferAtIndex(1); 329 decoder->frameBufferAtIndex(1);
323 EXPECT_TRUE(decoder->failed()); 330 EXPECT_TRUE(decoder->failed());
324 } 331 }
325 332
326 TEST(GIFImageDecoderTest, frameIsComplete) 333 TEST(GIFImageDecoderTest, frameIsComplete)
327 { 334 {
328 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 335 OwnPtr<GIFImageDecoder> decoder = createDecoder();
329 336
330 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 337 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
331 ASSERT_TRUE(data.get()); 338 ASSERT_TRUE(data.get());
332 decoder->setData(data.get(), true); 339 decoder->setData(data.get(), true);
333 340
334 EXPECT_EQ(2u, decoder->frameCount()); 341 EXPECT_EQ(2u, decoder->frameCount());
335 EXPECT_FALSE(decoder->failed()); 342 EXPECT_FALSE(decoder->failed());
336 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 343 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
337 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 344 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
338 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 345 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
339 } 346 }
340 347
341 TEST(GIFImageDecoderTest, frameIsCompleteLoading) 348 TEST(GIFImageDecoderTest, frameIsCompleteLoading)
342 { 349 {
343 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 350 OwnPtr<GIFImageDecoder> decoder = createDecoder();
344 351
345 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 352 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
346 ASSERT_TRUE(data.get()); 353 ASSERT_TRUE(data.get());
347 354
348 ASSERT_GE(data->size(), 10u); 355 ASSERT_GE(data->size(), 10u);
349 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 356 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
350 decoder->setData(tempData.get(), false); 357 decoder->setData(tempData.get(), false);
351 358
352 EXPECT_EQ(2u, decoder->frameCount()); 359 EXPECT_EQ(2u, decoder->frameCount());
353 EXPECT_FALSE(decoder->failed()); 360 EXPECT_FALSE(decoder->failed());
354 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 361 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
355 EXPECT_FALSE(decoder->frameIsCompleteAtIndex(1)); 362 EXPECT_FALSE(decoder->frameIsCompleteAtIndex(1));
356 363
357 decoder->setData(data.get(), true); 364 decoder->setData(data.get(), true);
358 EXPECT_EQ(2u, decoder->frameCount()); 365 EXPECT_EQ(2u, decoder->frameCount());
359 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 366 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
360 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 367 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
361 } 368 }
362 369
363 TEST(GIFImageDecoderTest, badTerminator) 370 TEST(GIFImageDecoderTest, badTerminator)
364 { 371 {
365 RefPtr<SharedBuffer> referenceData = readFile("/Source/web/tests/data/radien t.gif"); 372 RefPtr<SharedBuffer> referenceData = readFile(webTestsDataDir, "radient.gif" );
366 RefPtr<SharedBuffer> testData = readFile("/Source/web/tests/data/radient-bad -terminator.gif"); 373 RefPtr<SharedBuffer> testData = readFile(webTestsDataDir, "radient-bad-termi nator.gif");
367 ASSERT_TRUE(referenceData.get()); 374 ASSERT_TRUE(referenceData.get());
368 ASSERT_TRUE(testData.get()); 375 ASSERT_TRUE(testData.get());
369 376
370 OwnPtr<GIFImageDecoder> referenceDecoder(createDecoder()); 377 OwnPtr<GIFImageDecoder> referenceDecoder(createDecoder());
371 referenceDecoder->setData(referenceData.get(), true); 378 referenceDecoder->setData(referenceData.get(), true);
372 EXPECT_EQ(1u, referenceDecoder->frameCount()); 379 EXPECT_EQ(1u, referenceDecoder->frameCount());
373 ImageFrame* referenceFrame = referenceDecoder->frameBufferAtIndex(0); 380 ImageFrame* referenceFrame = referenceDecoder->frameBufferAtIndex(0);
374 ASSERT(referenceFrame); 381 ASSERT(referenceFrame);
375 382
376 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); 383 OwnPtr<GIFImageDecoder> testDecoder(createDecoder());
377 testDecoder->setData(testData.get(), true); 384 testDecoder->setData(testData.get(), true);
378 EXPECT_EQ(1u, testDecoder->frameCount()); 385 EXPECT_EQ(1u, testDecoder->frameCount());
379 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); 386 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0);
380 ASSERT(testFrame); 387 ASSERT(testFrame);
381 388
382 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram e->getSkBitmap())); 389 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram e->getSkBitmap()));
383 } 390 }
384 391
385 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) 392 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode)
386 { 393 {
387 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 394 OwnPtr<GIFImageDecoder> decoder = createDecoder();
388 395
389 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /animated-10color.gif"); 396 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif");
390 ASSERT_TRUE(fullData.get()); 397 ASSERT_TRUE(fullData.get());
391 398
392 // Give it data that is enough to parse but not decode in order to check the status 399 // Give it data that is enough to parse but not decode in order to check the status
393 // of requiredPreviousFrameIndex before decoding. 400 // of requiredPreviousFrameIndex before decoding.
394 size_t partialSize = 1; 401 size_t partialSize = 1;
395 do { 402 do {
396 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize); 403 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize);
397 decoder->setData(data.get(), false); 404 decoder->setData(data.get(), false);
398 ++partialSize; 405 ++partialSize;
399 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); 406 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty);
400 407
401 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIn dex()); 408 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIn dex());
402 unsigned frameCount = decoder->frameCount(); 409 unsigned frameCount = decoder->frameCount();
403 for (size_t i = 1; i < frameCount; ++i) 410 for (size_t i = 1; i < frameCount; ++i)
404 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex()); 411 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex());
405 412
406 decoder->setData(fullData.get(), true); 413 decoder->setData(fullData.get(), true);
407 for (size_t i = 0; i < frameCount; ++i) 414 for (size_t i = 0; i < frameCount; ++i)
408 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i)->requiredPreviousFra meIndex()); 415 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i)->requiredPreviousFra meIndex());
409 } 416 }
410 417
411 TEST(GIFImageDecoderTest, randomFrameDecode) 418 TEST(GIFImageDecoderTest, randomFrameDecode)
412 { 419 {
413 // Single frame image. 420 // Single frame image.
414 testRandomFrameDecode("/Source/web/tests/data/radient.gif"); 421 testRandomFrameDecode(webTestsDataDir, "radient.gif");
415 // Multiple frame images. 422 // Multiple frame images.
416 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-gif-with- offsets.gif"); 423 testRandomFrameDecode(layoutTestResourcesDir, "animated-gif-with-offsets.gif ");
417 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-10color.g if"); 424 testRandomFrameDecode(layoutTestResourcesDir, "animated-10color.gif");
418 } 425 }
419 426
420 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) 427 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache)
421 { 428 {
422 // Single frame image. 429 // Single frame image.
423 testRandomDecodeAfterClearFrameBufferCache("/Source/web/tests/data/radient.g if"); 430 testRandomDecodeAfterClearFrameBufferCache(webTestsDataDir, "radient.gif");
424 // Multiple frame images. 431 // Multiple frame images.
425 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc es/animated-gif-with-offsets.gif"); 432 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -gif-with-offsets.gif");
426 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc es/animated-10color.gif"); 433 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -10color.gif");
427 } 434 }
428 435
429 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) 436 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache)
430 { 437 {
431 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /animated-10color.gif"); 438 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif");
432 ASSERT_TRUE(fullData.get()); 439 ASSERT_TRUE(fullData.get());
433 Vector<unsigned> baselineHashes; 440 Vector<unsigned> baselineHashes;
434 createDecodingBaseline(fullData.get(), &baselineHashes); 441 createDecodingBaseline(fullData.get(), &baselineHashes);
435 size_t frameCount = baselineHashes.size(); 442 size_t frameCount = baselineHashes.size();
436 443
437 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 444 OwnPtr<GIFImageDecoder> decoder = createDecoder();
438 445
439 // Let frame 0 be partially decoded. 446 // Let frame 0 be partially decoded.
440 size_t partialSize = 1; 447 size_t partialSize = 1;
441 do { 448 do {
(...skipping 12 matching lines...) Expand all
454 // Resume decoding of the first frame. 461 // Resume decoding of the first frame.
455 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); 462 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
456 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); 463 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status());
457 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap())); 464 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap()));
458 } 465 }
459 466
460 // The first LZW codes in the image are invalid values that try to create a loop 467 // The first LZW codes in the image are invalid values that try to create a loop
461 // in the dictionary. Decoding should fail, but not infinitely loop or corrupt m emory. 468 // in the dictionary. Decoding should fail, but not infinitely loop or corrupt m emory.
462 TEST(GIFImageDecoderTest, badInitialCode) 469 TEST(GIFImageDecoderTest, badInitialCode)
463 { 470 {
464 RefPtr<SharedBuffer> testData = readFile("/Source/platform/image-decoders/te sting/bad-initial-code.gif"); 471 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-initial-co de.gif");
465 ASSERT_TRUE(testData.get()); 472 ASSERT_TRUE(testData.get());
466 473
467 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); 474 OwnPtr<GIFImageDecoder> testDecoder(createDecoder());
468 testDecoder->setData(testData.get(), true); 475 testDecoder->setData(testData.get(), true);
469 EXPECT_EQ(1u, testDecoder->frameCount()); 476 EXPECT_EQ(1u, testDecoder->frameCount());
470 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); 477 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0));
471 EXPECT_TRUE(testDecoder->failed()); 478 EXPECT_TRUE(testDecoder->failed());
472 } 479 }
473 480
474 // The image has an invalid LZW code that exceeds dictionary size. Decoding shou ld fail. 481 // The image has an invalid LZW code that exceeds dictionary size. Decoding shou ld fail.
475 TEST(GIFImageDecoderTest, badCode) 482 TEST(GIFImageDecoderTest, badCode)
476 { 483 {
477 RefPtr<SharedBuffer> testData = readFile("/Source/platform/image-decoders/te sting/bad-code.gif"); 484 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-code.gif") ;
478 ASSERT_TRUE(testData.get()); 485 ASSERT_TRUE(testData.get());
479 486
480 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); 487 OwnPtr<GIFImageDecoder> testDecoder(createDecoder());
481 testDecoder->setData(testData.get(), true); 488 testDecoder->setData(testData.get(), true);
482 EXPECT_EQ(1u, testDecoder->frameCount()); 489 EXPECT_EQ(1u, testDecoder->frameCount());
483 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); 490 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0));
484 EXPECT_TRUE(testDecoder->failed()); 491 EXPECT_TRUE(testDecoder->failed());
485 } 492 }
486 493
487 TEST(GIFImageDecoderTest, invalidDisposalMethod) 494 TEST(GIFImageDecoderTest, invalidDisposalMethod)
488 { 495 {
489 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 496 OwnPtr<GIFImageDecoder> decoder = createDecoder();
490 497
491 // The image has 2 frames, with disposal method 4 and 5, respectively. 498 // The image has 2 frames, with disposal method 4 and 5, respectively.
492 RefPtr<SharedBuffer> data = readFile("/Source/web/tests/data/invalid-disposa l-method.gif"); 499 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "invalid-disposal-meth od.gif");
493 ASSERT_TRUE(data.get()); 500 ASSERT_TRUE(data.get());
494 decoder->setData(data.get(), true); 501 decoder->setData(data.get(), true);
495 502
496 EXPECT_EQ(2u, decoder->frameCount()); 503 EXPECT_EQ(2u, decoder->frameCount());
497 // Disposal method 4 is converted to ImageFrame::DisposeOverwritePrevious. 504 // Disposal method 4 is converted to ImageFrame::DisposeOverwritePrevious.
498 EXPECT_EQ(ImageFrame::DisposeOverwritePrevious, decoder->frameBufferAtIndex( 0)->disposalMethod()); 505 EXPECT_EQ(ImageFrame::DisposeOverwritePrevious, decoder->frameBufferAtIndex( 0)->disposalMethod());
499 // Disposal method 5 is ignored. 506 // Disposal method 5 is ignored.
500 EXPECT_EQ(ImageFrame::DisposeNotSpecified, decoder->frameBufferAtIndex(1)->d isposalMethod()); 507 EXPECT_EQ(ImageFrame::DisposeNotSpecified, decoder->frameBufferAtIndex(1)->d isposalMethod());
501 } 508 }
509
510 TEST(GIFImageDecoderTest, firstFrameHasGreaterSizeThanScreenSize)
511 {
512 RefPtr<SharedBuffer> fullData = readFile(decodersTestingDir, "first-frame-ha s-greater-size-than-screen-size.gif");
513 ASSERT_TRUE(fullData.get());
514
515 OwnPtr<GIFImageDecoder> decoder;
516 IntSize frameSize;
517
518 // Compute hashes when the file is truncated.
519 for (size_t i = 1; i <= fullData->size(); ++i) {
520 decoder = createDecoder();
521 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
522 decoder->setData(data.get(), i == fullData->size());
523
524 if (decoder->isSizeAvailable() && !frameSize.width() && !frameSize.heigh t()) {
525 frameSize = decoder->decodedSize();
526 continue;
527 }
528
529 ASSERT_EQ(frameSize.width(), decoder->decodedSize().width());
530 ASSERT_EQ(frameSize.height(), decoder->decodedSize().height());
531 }
532 }
OLDNEW
« no previous file with comments | « no previous file | Source/platform/image-decoders/gif/GIFImageReader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698