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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 | 46 |
47 const char decodersTestingDir[] = "Source/platform/image-decoders/testing"; | 47 const char decodersTestingDir[] = "Source/platform/image-decoders/testing"; |
48 const char layoutTestResourcesDir[] = "LayoutTests/fast/images/resources"; | 48 const char layoutTestResourcesDir[] = "LayoutTests/fast/images/resources"; |
49 const char webTestsDataDir[] = "Source/web/tests/data"; | 49 const char webTestsDataDir[] = "Source/web/tests/data"; |
50 | 50 |
51 PassOwnPtr<ImageDecoder> createDecoder() | 51 PassOwnPtr<ImageDecoder> createDecoder() |
52 { | 52 { |
53 return adoptPtr(new GIFImageDecoder(ImageDecoder::AlphaNotPremultiplied, Ima geDecoder::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit)); | 53 return adoptPtr(new GIFImageDecoder(ImageDecoder::AlphaNotPremultiplied, Ima geDecoder::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit)); |
54 } | 54 } |
55 | 55 |
56 void testRandomFrameDecode(const char* dir, const char* gifFile) | 56 static bool areFramesColorsEqual(ImageFrame* b1, ImageFrame* b2) |
scroggo_chromium
2015/12/03 21:47:22
can these be const references?
aleksandar.stojiljkovic
2015/12/22 15:19:55
Done.
| |
57 { | |
58 // The same premultiply alpha should be set. | |
59 if (b1->premultiplyAlpha() != b2->premultiplyAlpha()) | |
60 return false; | |
61 if (b1->getSkBitmap().width() != b2->getSkBitmap().width() | |
62 || b1->getSkBitmap().height() != b2->getSkBitmap().height()) | |
63 return false; | |
64 | |
65 int width = b1->getSkBitmap().width(); | |
scroggo_chromium
2015/12/03 21:47:22
Why not set these variables before the last if sta
aleksandar.stojiljkovic
2015/12/22 15:19:55
Done.
| |
66 int height = b1->getSkBitmap().height(); | |
67 for (int j = 0; j < height; ++j) { | |
68 for (int i = 0; i < width; ++i) { | |
69 uint32_t c1 = b1->getSkBitmap().getColor(i, j); | |
70 uint32_t c2 = b2->getSkBitmap().getColor(i, j); | |
71 if (c1 != c2) { | |
72 return false; | |
73 } | |
74 } | |
75 } | |
76 return true; | |
77 } | |
78 | |
79 void testRandomFrameDecode(const char* dir, const char* gifFile, ImageFrame::Col orType targetType = ImageFrame::N32) | |
57 { | 80 { |
58 SCOPED_TRACE(gifFile); | 81 SCOPED_TRACE(gifFile); |
59 | 82 |
83 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile); | |
84 ASSERT_TRUE(fullData.get()); | |
85 Vector<unsigned> baselineHashes; | |
86 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes, targ etType); | |
87 size_t frameCount = baselineHashes.size(); | |
88 | |
89 // Random decoding should get the same results as sequential decoding. | |
90 OwnPtr<ImageDecoder> decoder = createDecoder(); | |
91 decoder->setData(fullData.get(), true); | |
92 const size_t skippingStep = 5; | |
93 for (size_t i = 0; i < skippingStep; ++i) { | |
94 for (size_t j = i; j < frameCount; j += skippingStep) { | |
95 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); | |
96 ImageFrame* frame = decoder->frameBufferAtIndex(j, targetType); | |
97 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); | |
98 } | |
99 } | |
100 | |
101 // Decoding in reverse order. | |
102 decoder = createDecoder(); | |
103 decoder->setData(fullData.get(), true); | |
104 for (size_t i = frameCount; i; --i) { | |
105 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); | |
106 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1, targetType); | |
107 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->getSkBitmap())); | |
108 } | |
109 } | |
110 | |
111 void testRandomDecodeAfterClearFrameBufferCache(const char* dir, const char* gif File, ImageFrame::ColorType targetType = ImageFrame::N32) | |
112 { | |
113 SCOPED_TRACE(gifFile); | |
114 | |
115 RefPtr<SharedBuffer> data = readFile(dir, gifFile); | |
116 ASSERT_TRUE(data.get()); | |
117 Vector<unsigned> baselineHashes; | |
118 createDecodingBaseline(&createDecoder, data.get(), &baselineHashes, targetTy pe); | |
119 size_t frameCount = baselineHashes.size(); | |
120 | |
121 OwnPtr<ImageDecoder> decoder = createDecoder(); | |
122 decoder->setData(data.get(), true); | |
123 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) { | |
124 decoder->clearCacheExceptFrame(clearExceptFrame); | |
125 const size_t skippingStep = 5; | |
126 for (size_t i = 0; i < skippingStep; ++i) { | |
127 for (size_t j = 0; j < frameCount; j += skippingStep) { | |
128 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); | |
129 ImageFrame* frame = decoder->frameBufferAtIndex(j, targetType); | |
130 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); | |
131 } | |
132 } | |
133 } | |
134 } | |
135 | |
136 void testRandomFrameDecodeCompare(const char* dir, const char* gifFile) | |
137 { | |
138 SCOPED_TRACE(gifFile); | |
139 | |
60 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile); | 140 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile); |
61 ASSERT_TRUE(fullData.get()); | 141 ASSERT_TRUE(fullData.get()); |
62 Vector<unsigned> baselineHashes; | 142 Vector<unsigned> baselineHashes; |
63 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); | 143 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); |
64 size_t frameCount = baselineHashes.size(); | 144 size_t frameCount = baselineHashes.size(); |
65 | 145 |
66 // Random decoding should get the same results as sequential decoding. | 146 // Random decoding should get the same results as sequential decoding. |
67 OwnPtr<ImageDecoder> decoder = createDecoder(); | 147 OwnPtr<ImageDecoder> decoder = createDecoder(); |
148 // Test Index8 and RGBA through the same scenario. | |
149 OwnPtr<ImageDecoder> decoderI8 = createDecoder(); | |
150 | |
68 decoder->setData(fullData.get(), true); | 151 decoder->setData(fullData.get(), true); |
152 decoderI8->setData(fullData.get(), true); | |
69 const size_t skippingStep = 5; | 153 const size_t skippingStep = 5; |
70 for (size_t i = 0; i < skippingStep; ++i) { | 154 for (size_t i = 0; i < skippingStep; ++i) { |
71 for (size_t j = i; j < frameCount; j += skippingStep) { | 155 for (size_t j = i; j < frameCount; j += skippingStep) { |
72 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); | 156 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); |
73 ImageFrame* frame = decoder->frameBufferAtIndex(j); | 157 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
74 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); | 158 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); |
159 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(j, ImageFrame::I ndex8); | |
160 ASSERT_TRUE(areFramesColorsEqual(frame, frameI8)); | |
75 } | 161 } |
76 } | 162 } |
77 | 163 |
78 // Decoding in reverse order. | 164 // Decoding in reverse order. |
79 decoder = createDecoder(); | 165 decoder = createDecoder(); |
166 decoderI8 = createDecoder(); | |
80 decoder->setData(fullData.get(), true); | 167 decoder->setData(fullData.get(), true); |
168 decoderI8->setData(fullData.get(), true); | |
81 for (size_t i = frameCount; i; --i) { | 169 for (size_t i = frameCount; i; --i) { |
82 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); | 170 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); |
83 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); | 171 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); |
84 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->getSkBitmap())); | 172 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->getSkBitmap())); |
173 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(i - 1, ImageFrame::I ndex8); | |
174 ASSERT_TRUE(areFramesColorsEqual(frame, frameI8)); | |
85 } | 175 } |
86 } | 176 } |
87 | 177 |
88 void testRandomDecodeAfterClearFrameBufferCache(const char* dir, const char* gif File) | 178 void testRandomDecodeAfterClearFrameBufferCacheCompare(const char* dir, const ch ar* gifFile) |
89 { | 179 { |
90 SCOPED_TRACE(gifFile); | 180 SCOPED_TRACE(gifFile); |
91 | 181 |
92 RefPtr<SharedBuffer> data = readFile(dir, gifFile); | 182 RefPtr<SharedBuffer> data = readFile(dir, gifFile); |
93 ASSERT_TRUE(data.get()); | 183 ASSERT_TRUE(data.get()); |
94 Vector<unsigned> baselineHashes; | 184 Vector<unsigned> baselineHashes; |
95 createDecodingBaseline(&createDecoder, data.get(), &baselineHashes); | 185 createDecodingBaseline(&createDecoder, data.get(), &baselineHashes); |
96 size_t frameCount = baselineHashes.size(); | 186 size_t frameCount = baselineHashes.size(); |
97 | 187 |
98 OwnPtr<ImageDecoder> decoder = createDecoder(); | 188 OwnPtr<ImageDecoder> decoder = createDecoder(); |
189 // Test Index8 and RGBA through the same scenario. | |
190 OwnPtr<ImageDecoder> decoderI8 = createDecoder(); | |
99 decoder->setData(data.get(), true); | 191 decoder->setData(data.get(), true); |
192 decoderI8->setData(data.get(), true); | |
100 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) { | 193 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) { |
101 decoder->clearCacheExceptFrame(clearExceptFrame); | 194 decoder->clearCacheExceptFrame(clearExceptFrame); |
195 decoderI8->clearCacheExceptFrame(clearExceptFrame); | |
102 const size_t skippingStep = 5; | 196 const size_t skippingStep = 5; |
103 for (size_t i = 0; i < skippingStep; ++i) { | 197 for (size_t i = 0; i < skippingStep; ++i) { |
104 for (size_t j = 0; j < frameCount; j += skippingStep) { | 198 for (size_t j = 0; j < frameCount; j += (i + 2)) { |
105 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); | 199 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); |
106 ImageFrame* frame = decoder->frameBufferAtIndex(j); | 200 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
107 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); | 201 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); |
202 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(j, ImageFram e::Index8); | |
203 ASSERT_TRUE(areFramesColorsEqual(frame, frameI8)); | |
108 } | 204 } |
109 } | 205 } |
110 } | 206 } |
111 } | 207 } |
112 | 208 |
113 } // anonymous namespace | 209 } // anonymous namespace |
114 | 210 |
115 TEST(GIFImageDecoderTest, decodeTwoFrames) | 211 TEST(GIFImageDecoderTest, decodeTwoFrames) |
116 { | 212 { |
117 OwnPtr<ImageDecoder> decoder = createDecoder(); | 213 OwnPtr<ImageDecoder> decoder = createDecoder(); |
214 OwnPtr<ImageDecoder> decoderI8 = createDecoder(); | |
118 | 215 |
119 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; | 216 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; |
120 ASSERT_TRUE(data.get()); | 217 ASSERT_TRUE(data.get()); |
121 decoder->setData(data.get(), true); | 218 decoder->setData(data.get(), true); |
219 decoderI8->setData(data.get(), true); | |
122 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 220 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
123 | 221 |
124 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 222 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
125 uint32_t generationID0 = frame->getSkBitmap().getGenerationID(); | 223 uint32_t generationID0 = frame->getSkBitmap().getGenerationID(); |
126 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 224 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
127 EXPECT_EQ(16, frame->getSkBitmap().width()); | 225 EXPECT_EQ(16, frame->getSkBitmap().width()); |
128 EXPECT_EQ(16, frame->getSkBitmap().height()); | 226 EXPECT_EQ(16, frame->getSkBitmap().height()); |
129 | 227 |
228 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(0, ImageFrame::Index8); | |
229 generationID0 = frameI8->getSkBitmap().getGenerationID(); | |
230 EXPECT_EQ(ImageFrame::FrameComplete, frameI8->status()); | |
231 EXPECT_EQ(16, frameI8->getSkBitmap().width()); | |
232 EXPECT_EQ(16, frameI8->getSkBitmap().height()); | |
233 | |
234 ASSERT_TRUE(areFramesColorsEqual(frame, frameI8)); | |
235 | |
130 frame = decoder->frameBufferAtIndex(1); | 236 frame = decoder->frameBufferAtIndex(1); |
131 uint32_t generationID1 = frame->getSkBitmap().getGenerationID(); | 237 uint32_t generationID1 = frame->getSkBitmap().getGenerationID(); |
132 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 238 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
133 EXPECT_EQ(16, frame->getSkBitmap().width()); | 239 EXPECT_EQ(16, frame->getSkBitmap().width()); |
134 EXPECT_EQ(16, frame->getSkBitmap().height()); | 240 EXPECT_EQ(16, frame->getSkBitmap().height()); |
135 EXPECT_TRUE(generationID0 != generationID1); | 241 EXPECT_TRUE(generationID0 != generationID1); |
136 | 242 |
137 EXPECT_EQ(2u, decoder->frameCount()); | 243 EXPECT_EQ(2u, decoder->frameCount()); |
138 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 244 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
245 | |
246 frameI8 = decoderI8->frameBufferAtIndex(1, ImageFrame::Index8); | |
247 ASSERT_TRUE(areFramesColorsEqual(frame, frameI8)); | |
248 EXPECT_EQ(2u, decoderI8->frameCount()); | |
249 EXPECT_EQ(cAnimationLoopInfinite, decoderI8->repetitionCount()); | |
139 } | 250 } |
140 | 251 |
141 TEST(GIFImageDecoderTest, parseAndDecode) | 252 TEST(GIFImageDecoderTest, parseAndDecode) |
142 { | 253 { |
143 OwnPtr<ImageDecoder> decoder = createDecoder(); | 254 OwnPtr<ImageDecoder> decoder = createDecoder(); |
144 | 255 |
145 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; | 256 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; |
146 ASSERT_TRUE(data.get()); | 257 ASSERT_TRUE(data.get()); |
147 decoder->setData(data.get(), true); | 258 decoder->setData(data.get(), true); |
148 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 259 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
149 | 260 |
150 // This call will parse the entire file. | 261 // This call will parse the entire file. |
151 EXPECT_EQ(2u, decoder->frameCount()); | 262 EXPECT_EQ(2u, decoder->frameCount()); |
152 | 263 |
153 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 264 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
154 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 265 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
155 EXPECT_EQ(16, frame->getSkBitmap().width()); | 266 EXPECT_EQ(16, frame->getSkBitmap().width()); |
156 EXPECT_EQ(16, frame->getSkBitmap().height()); | 267 EXPECT_EQ(16, frame->getSkBitmap().height()); |
157 | 268 |
158 frame = decoder->frameBufferAtIndex(1); | 269 frame = decoder->frameBufferAtIndex(1); |
159 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 270 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
160 EXPECT_EQ(16, frame->getSkBitmap().width()); | 271 EXPECT_EQ(16, frame->getSkBitmap().width()); |
161 EXPECT_EQ(16, frame->getSkBitmap().height()); | 272 EXPECT_EQ(16, frame->getSkBitmap().height()); |
162 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 273 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
163 } | 274 } |
164 | 275 |
165 TEST(GIFImageDecoderTest, parseByteByByte) | 276 TEST(GIFImageDecoderTest, parseByteByByte) |
166 { | 277 { |
167 OwnPtr<ImageDecoder> decoder = createDecoder(); | 278 OwnPtr<ImageDecoder> decoder = createDecoder(); |
279 OwnPtr<ImageDecoder> decoderI8 = createDecoder(); | |
168 | 280 |
169 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; | 281 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; |
170 ASSERT_TRUE(data.get()); | 282 ASSERT_TRUE(data.get()); |
171 | 283 |
172 size_t frameCount = 0; | 284 size_t frameCount = 0; |
173 | 285 |
174 // Pass data to decoder byte by byte. | 286 // Pass data to decoder byte by byte. |
175 for (size_t length = 1; length <= data->size(); ++length) { | 287 for (size_t length = 1; length <= data->size(); ++length) { |
176 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); | 288 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); |
177 decoder->setData(tempData.get(), length == data->size()); | 289 decoder->setData(tempData.get(), length == data->size()); |
290 decoderI8->setData(tempData.get(), length == data->size()); | |
178 | 291 |
179 EXPECT_LE(frameCount, decoder->frameCount()); | 292 EXPECT_LE(frameCount, decoder->frameCount()); |
293 EXPECT_LE(frameCount, decoderI8->frameCount()); | |
294 EXPECT_EQ(decoder->frameCount(), decoderI8->frameCount()); | |
180 frameCount = decoder->frameCount(); | 295 frameCount = decoder->frameCount(); |
181 } | 296 } |
182 | 297 |
183 EXPECT_EQ(2u, decoder->frameCount()); | 298 EXPECT_EQ(2u, decoder->frameCount()); |
184 | 299 |
185 decoder->frameBufferAtIndex(0); | 300 decoder->frameBufferAtIndex(0); |
186 decoder->frameBufferAtIndex(1); | 301 decoder->frameBufferAtIndex(1); |
187 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 302 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
188 } | 303 } |
189 | 304 |
190 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) | 305 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) |
191 { | 306 { |
192 OwnPtr<ImageDecoder> decoder = createDecoder(); | 307 OwnPtr<ImageDecoder> decoder = createDecoder(); |
308 OwnPtr<ImageDecoder> decoderI8 = createDecoder(); | |
193 | 309 |
194 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated-gif-w ith-offsets.gif"); | 310 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated-gif-w ith-offsets.gif"); |
195 ASSERT_TRUE(data.get()); | 311 ASSERT_TRUE(data.get()); |
196 | 312 |
197 size_t frameCount = 0; | 313 size_t frameCount = 0; |
198 size_t framesDecoded = 0; | 314 size_t framesDecoded = 0; |
199 | 315 |
200 // Pass data to decoder byte by byte. | 316 // Pass data to decoder byte by byte. |
201 for (size_t length = 1; length <= data->size(); ++length) { | 317 for (size_t length = 1; length <= data->size(); ++length) { |
202 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); | 318 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); |
203 decoder->setData(tempData.get(), length == data->size()); | 319 decoder->setData(tempData.get(), length == data->size()); |
320 decoderI8->setData(tempData.get(), length == data->size()); | |
204 | 321 |
205 EXPECT_LE(frameCount, decoder->frameCount()); | 322 EXPECT_LE(frameCount, decoder->frameCount()); |
206 frameCount = decoder->frameCount(); | 323 frameCount = decoder->frameCount(); |
324 EXPECT_EQ(frameCount, decoderI8->frameCount()); | |
207 | 325 |
208 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); | 326 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); |
209 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount) | 327 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount) |
210 ++framesDecoded; | 328 ++framesDecoded; |
329 | |
330 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(frameCount - 1, Imag eFrame::Index8); | |
331 ASSERT_TRUE(!(frame || frameI8) || areFramesColorsEqual(frame, frameI8)) ; | |
211 } | 332 } |
212 | 333 |
213 EXPECT_EQ(5u, decoder->frameCount()); | 334 EXPECT_EQ(5u, decoder->frameCount()); |
214 EXPECT_EQ(5u, framesDecoded); | 335 EXPECT_EQ(5u, framesDecoded); |
215 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 336 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
216 } | 337 } |
217 | 338 |
218 TEST(GIFImageDecoderTest, brokenSecondFrame) | 339 TEST(GIFImageDecoderTest, brokenSecondFrame) |
219 { | 340 { |
220 OwnPtr<ImageDecoder> decoder = createDecoder(); | 341 OwnPtr<ImageDecoder> decoder = createDecoder(); |
221 | 342 |
222 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "broken.gif"); | 343 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "broken.gif"); |
223 ASSERT_TRUE(data.get()); | 344 ASSERT_TRUE(data.get()); |
224 decoder->setData(data.get(), true); | 345 decoder->setData(data.get(), true); |
225 | 346 |
226 // One frame is detected but cannot be decoded. | 347 // One frame is detected but cannot be decoded. |
227 EXPECT_EQ(1u, decoder->frameCount()); | 348 EXPECT_EQ(1u, decoder->frameCount()); |
228 ImageFrame* frame = decoder->frameBufferAtIndex(1); | 349 ImageFrame* frame = decoder->frameBufferAtIndex(1); |
229 EXPECT_FALSE(frame); | 350 EXPECT_FALSE(frame); |
351 frame = decoder->frameBufferAtIndex(1, ImageFrame::Index8); | |
352 EXPECT_FALSE(frame); | |
230 } | 353 } |
231 | 354 |
232 TEST(GIFImageDecoderTest, progressiveDecode) | 355 TEST(GIFImageDecoderTest, progressiveDecode) |
233 { | 356 { |
234 RefPtr<SharedBuffer> fullData = readFile(webTestsDataDir, "radient.gif"); | 357 RefPtr<SharedBuffer> fullData = readFile(webTestsDataDir, "radient.gif"); |
235 ASSERT_TRUE(fullData.get()); | 358 ASSERT_TRUE(fullData.get()); |
236 const size_t fullLength = fullData->size(); | 359 const size_t fullLength = fullData->size(); |
237 | 360 |
238 OwnPtr<ImageDecoder> decoder; | 361 OwnPtr<ImageDecoder> decoder; |
239 ImageFrame* frame; | 362 ImageFrame* frame; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
354 testDecoder->setData(testData.get(), true); | 477 testDecoder->setData(testData.get(), true); |
355 EXPECT_EQ(1u, testDecoder->frameCount()); | 478 EXPECT_EQ(1u, testDecoder->frameCount()); |
356 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); | 479 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); |
357 ASSERT(testFrame); | 480 ASSERT(testFrame); |
358 | 481 |
359 EXPECT_EQ(hashBitmap(referenceFrame->getSkBitmap()), hashBitmap(testFrame->g etSkBitmap())); | 482 EXPECT_EQ(hashBitmap(referenceFrame->getSkBitmap()), hashBitmap(testFrame->g etSkBitmap())); |
360 } | 483 } |
361 | 484 |
362 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) | 485 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) |
363 { | 486 { |
364 OwnPtr<ImageDecoder> decoder = createDecoder(); | 487 const ImageFrame::ColorType targetTypes[] = { ImageFrame::N32, ImageFrame::I ndex8 }; |
488 for (ImageFrame::ColorType targetType : targetTypes) { | |
489 OwnPtr<ImageDecoder> decoder = createDecoder(); | |
365 | 490 |
366 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif"); | 491 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animat ed-10color.gif"); |
367 ASSERT_TRUE(fullData.get()); | 492 ASSERT_TRUE(fullData.get()); |
368 | 493 |
369 // Give it data that is enough to parse but not decode in order to check the status | 494 // Give it data that is enough to parse but not decode in order to check the status |
370 // of requiredPreviousFrameIndex before decoding. | 495 // of requiredPreviousFrameIndex before decoding. |
371 size_t partialSize = 1; | 496 size_t partialSize = 1; |
372 do { | 497 do { |
373 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize); | 498 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), p artialSize); |
374 decoder->setData(data.get(), false); | 499 decoder->setData(data.get(), false); |
375 ++partialSize; | 500 ++partialSize; |
376 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); | 501 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0, target Type)->status() == ImageFrame::FrameEmpty); |
377 | 502 |
378 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIn dex()); | 503 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0, targetType)->require dPreviousFrameIndex()); |
379 unsigned frameCount = decoder->frameCount(); | 504 unsigned frameCount = decoder->frameCount(); |
380 for (size_t i = 1; i < frameCount; ++i) | 505 for (size_t i = 1; i < frameCount; ++i) |
381 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex()); | 506 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i, targetType)->require dPreviousFrameIndex()); |
382 | 507 |
383 decoder->setData(fullData.get(), true); | 508 decoder->setData(fullData.get(), true); |
384 for (size_t i = 0; i < frameCount; ++i) | 509 for (size_t i = 0; i < frameCount; ++i) |
385 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i)->requiredPreviousFra meIndex()); | 510 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i, targetType)->req uiredPreviousFrameIndex()); |
511 } | |
386 } | 512 } |
387 | 513 |
388 TEST(GIFImageDecoderTest, randomFrameDecode) | 514 TEST(GIFImageDecoderTest, randomFrameDecode) |
389 { | 515 { |
390 // Single frame image. | 516 // Single frame image. |
391 testRandomFrameDecode(webTestsDataDir, "radient.gif"); | 517 testRandomFrameDecode(webTestsDataDir, "radient.gif"); |
392 // Multiple frame images. | 518 // Multiple frame images. |
393 testRandomFrameDecode(layoutTestResourcesDir, "animated-gif-with-offsets.gif "); | 519 testRandomFrameDecode(layoutTestResourcesDir, "animated-gif-with-offsets.gif "); |
394 testRandomFrameDecode(layoutTestResourcesDir, "animated-10color.gif"); | 520 testRandomFrameDecode(layoutTestResourcesDir, "animated-10color.gif"); |
395 } | 521 } |
396 | 522 |
523 TEST(GIFImageDecoderTest, randomFrameDecodeCompare) | |
524 { | |
525 // Single frame image. | |
526 testRandomFrameDecodeCompare(webTestsDataDir, "radient.gif"); | |
527 // Multiple frame images. | |
528 testRandomFrameDecodeCompare(layoutTestResourcesDir, "animated-gif-with-offs ets.gif"); | |
529 testRandomFrameDecodeCompare(layoutTestResourcesDir, "animated-10color.gif") ; | |
530 } | |
531 | |
397 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) | 532 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) |
398 { | 533 { |
399 // Single frame image. | 534 // Single frame image. |
400 testRandomDecodeAfterClearFrameBufferCache(webTestsDataDir, "radient.gif"); | 535 testRandomDecodeAfterClearFrameBufferCache(webTestsDataDir, "radient.gif"); |
401 // Multiple frame images. | 536 // Multiple frame images. |
402 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -gif-with-offsets.gif"); | 537 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -gif-with-offsets.gif"); |
403 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -10color.gif"); | 538 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -10color.gif"); |
404 } | 539 } |
405 | 540 |
541 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCacheCompare) | |
542 { | |
543 // Single frame image. | |
544 testRandomDecodeAfterClearFrameBufferCacheCompare(webTestsDataDir, "radient. gif"); | |
545 // Multiple frame images with offset. All frames depend to frame 0. | |
546 testRandomDecodeAfterClearFrameBufferCacheCompare(layoutTestResourcesDir, "a nimated-gif-with-offsets.gif"); | |
547 testRandomDecodeAfterClearFrameBufferCacheCompare(layoutTestResourcesDir, "a nimated-10color.gif"); | |
548 } | |
549 | |
406 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) | 550 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) |
407 { | 551 { |
408 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif"); | 552 const ImageFrame::ColorType targetTypes[] = { ImageFrame::N32, ImageFrame::I ndex8 }; |
409 ASSERT_TRUE(fullData.get()); | 553 for (ImageFrame::ColorType targetType : targetTypes) { |
410 Vector<unsigned> baselineHashes; | 554 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animat ed-10color.gif"); |
411 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); | 555 ASSERT_TRUE(fullData.get()); |
412 size_t frameCount = baselineHashes.size(); | 556 Vector<unsigned> baselineHashes; |
557 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes, targetType); | |
558 size_t frameCount = baselineHashes.size(); | |
413 | 559 |
414 OwnPtr<ImageDecoder> decoder = createDecoder(); | 560 OwnPtr<ImageDecoder> decoder = createDecoder(); |
415 | 561 |
416 // Let frame 0 be partially decoded. | 562 // Let frame 0 be partially decoded. |
417 size_t partialSize = 1; | 563 size_t partialSize = 1; |
418 do { | 564 do { |
419 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize); | 565 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), p artialSize); |
420 decoder->setData(data.get(), false); | 566 decoder->setData(data.get(), false); |
421 ++partialSize; | 567 ++partialSize; |
422 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); | 568 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0, target Type)->status() == ImageFrame::FrameEmpty); |
423 | 569 |
424 // Skip to the last frame and clear. | 570 // Skip to the last frame and clear. |
425 decoder->setData(fullData.get(), true); | 571 decoder->setData(fullData.get(), true); |
426 EXPECT_EQ(frameCount, decoder->frameCount()); | 572 EXPECT_EQ(frameCount, decoder->frameCount()); |
427 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1); | 573 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1, targ etType); |
428 EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->getSkBitmap( ))); | 574 EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->getSkBit map())); |
429 decoder->clearCacheExceptFrame(kNotFound); | 575 decoder->clearCacheExceptFrame(kNotFound); |
430 | 576 |
431 // Resume decoding of the first frame. | 577 // Resume decoding of the first frame. |
432 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); | 578 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0, targetType); |
433 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); | 579 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); |
434 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->getSkBitmap())); | 580 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->getSkBitmap())); |
581 } | |
435 } | 582 } |
436 | 583 |
437 // The first LZW codes in the image are invalid values that try to create a loop | 584 // The first LZW codes in the image are invalid values that try to create a loop |
438 // in the dictionary. Decoding should fail, but not infinitely loop or corrupt m emory. | 585 // in the dictionary. Decoding should fail, but not infinitely loop or corrupt m emory. |
439 TEST(GIFImageDecoderTest, badInitialCode) | 586 TEST(GIFImageDecoderTest, badInitialCode) |
440 { | 587 { |
441 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-initial-co de.gif"); | 588 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-initial-co de.gif"); |
442 ASSERT_TRUE(testData.get()); | 589 ASSERT_TRUE(testData.get()); |
443 | 590 |
444 OwnPtr<ImageDecoder> testDecoder = createDecoder(); | 591 OwnPtr<ImageDecoder> testDecoder = createDecoder(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
494 if (decoder->isSizeAvailable() && !frameSize.width() && !frameSize.heigh t()) { | 641 if (decoder->isSizeAvailable() && !frameSize.width() && !frameSize.heigh t()) { |
495 frameSize = decoder->decodedSize(); | 642 frameSize = decoder->decodedSize(); |
496 continue; | 643 continue; |
497 } | 644 } |
498 | 645 |
499 ASSERT_EQ(frameSize.width(), decoder->decodedSize().width()); | 646 ASSERT_EQ(frameSize.width(), decoder->decodedSize().width()); |
500 ASSERT_EQ(frameSize.height(), decoder->decodedSize().height()); | 647 ASSERT_EQ(frameSize.height(), decoder->decodedSize().height()); |
501 } | 648 } |
502 } | 649 } |
503 | 650 |
651 #define BENCHMARK_DECODE(dir, file, title, count)\ | |
652 TEST(GIFImageDecoderTest, tempBench_decodeIndex8##title##warmuprun)\ | |
653 {\ | |
654 testRandomDecodeAfterClearFrameBufferCache(dir, file);\ | |
655 }\ | |
656 TEST(GIFImageDecoderTest, tempBench_decodeN32##title##_x##count) \ | |
657 {\ | |
658 for (int i = 0; i < count; ++i)\ | |
659 testRandomDecodeAfterClearFrameBufferCache(dir, file);\ | |
660 }\ | |
661 \ | |
662 TEST(GIFImageDecoderTest, tempBench_decodeIndex8##title##_x##count)\ | |
663 {\ | |
664 for (int i = 0; i < count; ++i)\ | |
665 testRandomDecodeAfterClearFrameBufferCache(dir, file, ImageFrame::Index8 );\ | |
666 }\ | |
667 | |
668 BENCHMARK_DECODE(layoutTestResourcesDir, "animated-10color.gif", animated_10colo r_gif, 5) | |
669 BENCHMARK_DECODE(webTestsDataDir, "radient.gif", radient_gif, 10) | |
670 BENCHMARK_DECODE(layoutTestResourcesDir, "animated-gif-with-offsets.gif", animat ed_gif_with_offsets_gif, 5) | |
671 BENCHMARK_DECODE(layoutTestResourcesDir, "animated.gif", animated_gif, 10) | |
672 BENCHMARK_DECODE(layoutTestResourcesDir, "quicksort.gif", quicksort_gif, 5) | |
673 BENCHMARK_DECODE(layoutTestResourcesDir, "large-gif-checkerboard.gif", large_gif _checkerboard_gif, 5) | |
674 BENCHMARK_DECODE(layoutTestResourcesDir, "3dolph.gif", 3dolph_gif, 5) | |
675 // BENCHMARK_DECODE(layoutTestResourcesDir, "disneypixar-disney-pixar-jTXvL4Ljak YI8.gif", disneypixar_disney_pixar_jTXvL4LjakYI8_gif, 1) | |
676 // BENCHMARK_DECODE(webTestsDataDir, "issue_476531_AqLvXJh.gif", issue_476531_Aq LvXJh_gif, 1) | |
677 | |
504 } // namespace blink | 678 } // namespace blink |
OLD | NEW |