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 29 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |