OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |