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

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

Issue 1460523002: GIF decoding to Index8, unit tests and misusing unit test as benchmark (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 14 matching lines...) Expand all
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "platform/image-decoders/gif/GIFImageDecoder.h" 32 #include "platform/image-decoders/gif/GIFImageDecoder.h"
33 33
34 #include "platform/SharedBuffer.h" 34 #include "platform/SharedBuffer.h"
35 #include "platform/graphics/ImageDecodingStore.h"
36 #include "platform/graphics/ImageFrameGenerator.h"
35 #include "platform/image-decoders/ImageDecoderTestHelpers.h" 37 #include "platform/image-decoders/ImageDecoderTestHelpers.h"
36 #include "public/platform/WebData.h" 38 #include "public/platform/WebData.h"
37 #include "public/platform/WebSize.h" 39 #include "public/platform/WebSize.h"
38 #include "testing/gtest/include/gtest/gtest.h" 40 #include "testing/gtest/include/gtest/gtest.h"
39 #include "wtf/OwnPtr.h" 41 #include "wtf/OwnPtr.h"
40 #include "wtf/PassOwnPtr.h" 42 #include "wtf/PassOwnPtr.h"
41 #include "wtf/Vector.h" 43 #include "wtf/Vector.h"
42 44
43 namespace blink { 45 namespace blink {
44 46
45 namespace { 47 namespace {
46 48
47 const char decodersTestingDir[] = "Source/platform/image-decoders/testing"; 49 const char decodersTestingDir[] = "Source/platform/image-decoders/testing";
48 const char layoutTestResourcesDir[] = "LayoutTests/fast/images/resources"; 50 const char layoutTestResourcesDir[] = "LayoutTests/fast/images/resources";
49 const char webTestsDataDir[] = "Source/web/tests/data"; 51 const char webTestsDataDir[] = "Source/web/tests/data";
50 52
51 PassOwnPtr<ImageDecoder> createDecoder() 53 #define LOOP_DECODERS_BEGIN \
54 DecoderCreator decoderCreators[2] = { &createDecoderN32, &createDecoderIndex 8 }; \
55 for (DecoderCreator createDecoder : decoderCreators) {
56
57 #define LOOP_DECODERS_END \
58 }
59
60 PassOwnPtr<ImageDecoder> createDecoderN32()
52 { 61 {
53 return adoptPtr(new GIFImageDecoder(ImageDecoder::AlphaNotPremultiplied, Ima geDecoder::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit)); 62 return adoptPtr(new GIFImageDecoder(ImageDecoder::AlphaNotPremultiplied, Ima geDecoder::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit, I mageFrame::N32));
63 }
64
65 PassOwnPtr<ImageDecoder> createDecoderIndex8()
66 {
67 return adoptPtr(new GIFImageDecoder(ImageDecoder::AlphaNotPremultiplied, Ima geDecoder::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit, I mageFrame::Index8));
68 }
69
70 static bool areBitmapsColorsEqual(const SkBitmap& bitmap1, const SkBitmap& bitma p2)
71 {
72 int width = bitmap1.width();
73 int height = bitmap1.height();
74 int width2 = bitmap2.width();
75 int height2 = bitmap2.height();
76 if (bitmap1.alphaType() != bitmap2.alphaType())
77 return false;
78 if (bitmap1.profileType() != bitmap2.profileType())
79 return false;
80 if (width != width2 || height != height2)
81 return false;
82
83 for (int j = 0; j < height; ++j) {
84 for (int i = 0; i < width; ++i) {
85 uint32_t c1 = bitmap1.getColor(i, j);
86 uint32_t c2 = bitmap2.getColor(i, j);
87 if (c1 != c2) {
88 return false;
89 }
90 }
91 }
92
93 return true;
94 }
95
96 static bool areFramesColorsEqual(const ImageFrame& b1, const ImageFrame& b2)
97 {
98 // The same premultiply alpha should be set.
99 if (b1.premultiplyAlpha() != b2.premultiplyAlpha())
100 return false;
101 return areBitmapsColorsEqual(b1.getSkBitmap(), b2.getSkBitmap());
54 } 102 }
55 103
56 void testRandomFrameDecode(const char* dir, const char* gifFile) 104 void testRandomFrameDecode(const char* dir, const char* gifFile)
57 { 105 {
106 LOOP_DECODERS_BEGIN
58 SCOPED_TRACE(gifFile); 107 SCOPED_TRACE(gifFile);
59 108
60 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile); 109 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile);
61 ASSERT_TRUE(fullData.get()); 110 ASSERT_TRUE(fullData.get());
62 Vector<unsigned> baselineHashes; 111 Vector<unsigned> baselineHashes;
63 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); 112 createDecodingBaseline(createDecoder, fullData.get(), &baselineHashes);
64 size_t frameCount = baselineHashes.size(); 113 size_t frameCount = baselineHashes.size();
65 114
66 // Random decoding should get the same results as sequential decoding. 115 // Random decoding should get the same results as sequential decoding.
67 OwnPtr<ImageDecoder> decoder = createDecoder(); 116 OwnPtr<ImageDecoder> decoder = createDecoder();
68 decoder->setData(fullData.get(), true); 117 decoder->setData(fullData.get(), true);
69 const size_t skippingStep = 5; 118 const size_t skippingStep = 5;
70 for (size_t i = 0; i < skippingStep; ++i) { 119 for (size_t i = 0; i < skippingStep; ++i) {
71 for (size_t j = i; j < frameCount; j += skippingStep) { 120 for (size_t j = i; j < frameCount; j += skippingStep) {
72 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 121 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
73 ImageFrame* frame = decoder->frameBufferAtIndex(j); 122 ImageFrame* frame = decoder->frameBufferAtIndex(j);
74 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); 123 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap()));
75 } 124 }
76 } 125 }
77 126
78 // Decoding in reverse order. 127 // Decoding in reverse order.
79 decoder = createDecoder(); 128 decoder = createDecoder();
80 decoder->setData(fullData.get(), true); 129 decoder->setData(fullData.get(), true);
81 for (size_t i = frameCount; i; --i) { 130 for (size_t i = frameCount; i; --i) {
82 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); 131 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
83 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); 132 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
84 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->getSkBitmap())); 133 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->getSkBitmap()));
85 } 134 }
135 LOOP_DECODERS_END
86 } 136 }
87 137
88 void testRandomDecodeAfterClearFrameBufferCache(const char* dir, const char* gif File) 138 void testRandomDecodeAfterClearFrameBufferCache(const char* dir, const char* gif File, ImageFrame::ColorType targetType = ImageFrame::N32)
89 { 139 {
90 SCOPED_TRACE(gifFile); 140 SCOPED_TRACE(gifFile);
91 141
92 RefPtr<SharedBuffer> data = readFile(dir, gifFile); 142 RefPtr<SharedBuffer> data = readFile(dir, gifFile);
93 ASSERT_TRUE(data.get()); 143 ASSERT_TRUE(data.get());
94 Vector<unsigned> baselineHashes; 144 Vector<unsigned> baselineHashes;
95 createDecodingBaseline(&createDecoder, data.get(), &baselineHashes); 145 DecoderCreator decoderCreator = &createDecoderIndex8;
146 if (targetType == ImageFrame::N32) {
147 decoderCreator = &createDecoderN32;
148 }
149 createDecodingBaseline(decoderCreator, data.get(), &baselineHashes);
150
96 size_t frameCount = baselineHashes.size(); 151 size_t frameCount = baselineHashes.size();
97 152
98 OwnPtr<ImageDecoder> decoder = createDecoder(); 153 OwnPtr<ImageDecoder> decoder = decoderCreator();
99 decoder->setData(data.get(), true); 154 decoder->setData(data.get(), true);
100 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) { 155 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) {
101 decoder->clearCacheExceptFrame(clearExceptFrame); 156 decoder->clearCacheExceptFrame(clearExceptFrame);
102 const size_t skippingStep = 5; 157 const size_t skippingStep = 5;
103 for (size_t i = 0; i < skippingStep; ++i) { 158 for (size_t i = 0; i < skippingStep; ++i) {
104 for (size_t j = 0; j < frameCount; j += skippingStep) { 159 for (size_t j = 0; j < frameCount; j += skippingStep) {
105 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 160 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
161 bool canDecodeToIndex8 = decoder->canDecodeTo(j, ImageFrame::Ind ex8);
106 ImageFrame* frame = decoder->frameBufferAtIndex(j); 162 ImageFrame* frame = decoder->frameBufferAtIndex(j);
107 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap())); 163 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap()));
164 EXPECT_EQ(canDecodeToIndex8, frame->getSkBitmap().colorType() == kIndex_8_SkColorType);
108 } 165 }
109 } 166 }
110 } 167 }
168 }
169
170 void testRandomFrameDecodeCompare(const char* dir, const char* gifFile)
171 {
172 SCOPED_TRACE(gifFile);
173
174 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile);
175 ASSERT_TRUE(fullData.get());
176 Vector<unsigned> baselineHashes;
177 createDecodingBaseline(&createDecoderN32, fullData.get(), &baselineHashes);
178 size_t frameCount = baselineHashes.size();
179
180 // Random decoding should get the same results as sequential decoding.
181 OwnPtr<ImageDecoder> decoder = createDecoderN32();
182 // Test Index8 and RGBA through the same scenario.
183 OwnPtr<ImageDecoder> decoderI8 = createDecoderIndex8();
184
185 decoder->setData(fullData.get(), true);
186 decoderI8->setData(fullData.get(), true);
187 const size_t skippingStep = 5;
188 for (size_t i = 0; i < skippingStep; ++i) {
189 for (size_t j = i; j < frameCount; j += skippingStep) {
190 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
191 ImageFrame* frame = decoder->frameBufferAtIndex(j);
192 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap()));
193 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(j);
194 ASSERT_TRUE(areFramesColorsEqual(*frame, *frameI8));
195 }
196 }
197
198 // Decoding in reverse order.
199 decoder = createDecoderN32();
200 decoderI8 = createDecoderIndex8();
201 decoder->setData(fullData.get(), true);
202 decoderI8->setData(fullData.get(), true);
203 for (size_t i = frameCount; i; --i) {
204 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
205 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
206 EXPECT_EQ(baselineHashes[i - 1], hashBitmap(frame->getSkBitmap()));
207 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(i - 1);
208 ASSERT_TRUE(areFramesColorsEqual(*frame, *frameI8));
209 }
210 }
211
212 void testRandomDecodeAfterClearFrameBufferCacheCompare(const char* dir, const ch ar* gifFile)
213 {
214 SCOPED_TRACE(gifFile);
215
216 RefPtr<SharedBuffer> data = readFile(dir, gifFile);
217 ASSERT_TRUE(data.get());
218 Vector<unsigned> baselineHashes;
219 createDecodingBaseline(&createDecoderN32, data.get(), &baselineHashes);
220 size_t frameCount = baselineHashes.size();
221
222 OwnPtr<ImageDecoder> decoder = createDecoderN32();
223 // Test Index8 and RGBA through the same scenario and compare pixels.
224 OwnPtr<ImageDecoder> decoderI8 = createDecoderIndex8();
225
226 decoder->setData(data.get(), true);
227 decoderI8->setData(data.get(), true);
228 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) {
229 decoder->clearCacheExceptFrame(clearExceptFrame);
230 decoderI8->clearCacheExceptFrame(clearExceptFrame);
231 const size_t skippingStep = 5;
232 for (size_t i = 0; i < skippingStep; ++i) {
233 for (size_t j = 0; j < frameCount; j += (i + 2)) {
234 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
235 ImageFrame* frame = decoder->frameBufferAtIndex(j);
236 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->getSkBitmap()));
237 bool canDecodeToIndex8 = decoderI8->canDecodeTo(j, ImageFrame::I ndex8);
238 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(j);
239 EXPECT_EQ(canDecodeToIndex8, frameI8->getSkBitmap().colorType() == kIndex_8_SkColorType);
240 ASSERT_TRUE(areFramesColorsEqual(*frame, *frameI8));
241 }
242 }
243 }
111 } 244 }
112 245
113 } // anonymous namespace 246 } // anonymous namespace
114 247
115 TEST(GIFImageDecoderTest, decodeTwoFrames) 248 TEST(GIFImageDecoderTest, decodeTwoFrames)
116 { 249 {
117 OwnPtr<ImageDecoder> decoder = createDecoder(); 250 OwnPtr<ImageDecoder> decoder = createDecoderN32();
251 OwnPtr<ImageDecoder> decoderI8 = createDecoderIndex8();
118 252
119 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; 253 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
120 ASSERT_TRUE(data.get()); 254 ASSERT_TRUE(data.get());
121 decoder->setData(data.get(), true); 255 decoder->setData(data.get(), true);
256 decoderI8->setData(data.get(), true);
122 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 257 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
123 258
124 ImageFrame* frame = decoder->frameBufferAtIndex(0); 259 ImageFrame* frame = decoder->frameBufferAtIndex(0);
125 uint32_t generationID0 = frame->getSkBitmap().getGenerationID(); 260 uint32_t generationID0 = frame->getSkBitmap().getGenerationID();
126 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 261 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
127 EXPECT_EQ(16, frame->getSkBitmap().width()); 262 EXPECT_EQ(16, frame->getSkBitmap().width());
128 EXPECT_EQ(16, frame->getSkBitmap().height()); 263 EXPECT_EQ(16, frame->getSkBitmap().height());
129 264
265 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(0);
266 generationID0 = frameI8->getSkBitmap().getGenerationID();
267 EXPECT_EQ(ImageFrame::FrameComplete, frameI8->status());
268 EXPECT_EQ(16, frameI8->getSkBitmap().width());
269 EXPECT_EQ(16, frameI8->getSkBitmap().height());
270
271 ASSERT_TRUE(areFramesColorsEqual(*frame, *frameI8));
272
130 frame = decoder->frameBufferAtIndex(1); 273 frame = decoder->frameBufferAtIndex(1);
131 uint32_t generationID1 = frame->getSkBitmap().getGenerationID(); 274 uint32_t generationID1 = frame->getSkBitmap().getGenerationID();
132 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 275 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
133 EXPECT_EQ(16, frame->getSkBitmap().width()); 276 EXPECT_EQ(16, frame->getSkBitmap().width());
134 EXPECT_EQ(16, frame->getSkBitmap().height()); 277 EXPECT_EQ(16, frame->getSkBitmap().height());
135 EXPECT_TRUE(generationID0 != generationID1); 278 EXPECT_TRUE(generationID0 != generationID1);
136 279
137 EXPECT_EQ(2u, decoder->frameCount()); 280 EXPECT_EQ(2u, decoder->frameCount());
138 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 281 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
282
283 frameI8 = decoderI8->frameBufferAtIndex(1);
284 ASSERT_TRUE(areFramesColorsEqual(*frame, *frameI8));
285 EXPECT_EQ(2u, decoderI8->frameCount());
286 EXPECT_EQ(cAnimationLoopInfinite, decoderI8->repetitionCount());
139 } 287 }
140 288
141 TEST(GIFImageDecoderTest, parseAndDecode) 289 TEST(GIFImageDecoderTest, parseAndDecode)
142 { 290 {
291 LOOP_DECODERS_BEGIN
143 OwnPtr<ImageDecoder> decoder = createDecoder(); 292 OwnPtr<ImageDecoder> decoder = createDecoder();
144 293
145 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; 294 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
146 ASSERT_TRUE(data.get()); 295 ASSERT_TRUE(data.get());
147 decoder->setData(data.get(), true); 296 decoder->setData(data.get(), true);
148 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 297 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
149 298
150 // This call will parse the entire file. 299 // This call will parse the entire file.
151 EXPECT_EQ(2u, decoder->frameCount()); 300 EXPECT_EQ(2u, decoder->frameCount());
152 301
153 ImageFrame* frame = decoder->frameBufferAtIndex(0); 302 ImageFrame* frame = decoder->frameBufferAtIndex(0);
154 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 303 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
155 EXPECT_EQ(16, frame->getSkBitmap().width()); 304 EXPECT_EQ(16, frame->getSkBitmap().width());
156 EXPECT_EQ(16, frame->getSkBitmap().height()); 305 EXPECT_EQ(16, frame->getSkBitmap().height());
157 306
158 frame = decoder->frameBufferAtIndex(1); 307 frame = decoder->frameBufferAtIndex(1);
159 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 308 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
160 EXPECT_EQ(16, frame->getSkBitmap().width()); 309 EXPECT_EQ(16, frame->getSkBitmap().width());
161 EXPECT_EQ(16, frame->getSkBitmap().height()); 310 EXPECT_EQ(16, frame->getSkBitmap().height());
162 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 311 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
312 LOOP_DECODERS_END
163 } 313 }
164 314
165 TEST(GIFImageDecoderTest, parseByteByByte) 315 TEST(GIFImageDecoderTest, parseByteByByte)
166 { 316 {
167 OwnPtr<ImageDecoder> decoder = createDecoder(); 317 OwnPtr<ImageDecoder> decoder = createDecoderN32();
318 OwnPtr<ImageDecoder> decoderI8 = createDecoderIndex8();
168 319
169 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; 320 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
170 ASSERT_TRUE(data.get()); 321 ASSERT_TRUE(data.get());
171 322
172 size_t frameCount = 0; 323 size_t frameCount = 0;
173 324
174 // Pass data to decoder byte by byte. 325 // Pass data to decoder byte by byte.
175 for (size_t length = 1; length <= data->size(); ++length) { 326 for (size_t length = 1; length <= data->size(); ++length) {
176 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 327 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
177 decoder->setData(tempData.get(), length == data->size()); 328 decoder->setData(tempData.get(), length == data->size());
329 decoderI8->setData(tempData.get(), length == data->size());
178 330
179 EXPECT_LE(frameCount, decoder->frameCount()); 331 EXPECT_LE(frameCount, decoder->frameCount());
332 EXPECT_LE(frameCount, decoderI8->frameCount());
333 EXPECT_EQ(decoder->frameCount(), decoderI8->frameCount());
180 frameCount = decoder->frameCount(); 334 frameCount = decoder->frameCount();
181 } 335 }
182 336
183 EXPECT_EQ(2u, decoder->frameCount()); 337 EXPECT_EQ(2u, decoder->frameCount());
184 338
185 decoder->frameBufferAtIndex(0); 339 decoder->frameBufferAtIndex(0);
186 decoder->frameBufferAtIndex(1); 340 decoder->frameBufferAtIndex(1);
187 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 341 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
188 } 342 }
189 343
190 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) 344 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte)
191 { 345 {
192 OwnPtr<ImageDecoder> decoder = createDecoder(); 346 OwnPtr<ImageDecoder> decoder = createDecoderN32();
347 OwnPtr<ImageDecoder> decoderI8 = createDecoderIndex8();
193 348
194 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated-gif-w ith-offsets.gif"); 349 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated-gif-w ith-offsets.gif");
195 ASSERT_TRUE(data.get()); 350 ASSERT_TRUE(data.get());
196 351
197 size_t frameCount = 0; 352 size_t frameCount = 0;
198 size_t framesDecoded = 0; 353 size_t framesDecoded = 0;
199 354
200 // Pass data to decoder byte by byte. 355 // Pass data to decoder byte by byte.
201 for (size_t length = 1; length <= data->size(); ++length) { 356 for (size_t length = 1; length <= data->size(); ++length) {
202 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 357 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
203 decoder->setData(tempData.get(), length == data->size()); 358 decoder->setData(tempData.get(), length == data->size());
359 decoderI8->setData(tempData.get(), length == data->size());
204 360
205 EXPECT_LE(frameCount, decoder->frameCount()); 361 EXPECT_LE(frameCount, decoder->frameCount());
206 frameCount = decoder->frameCount(); 362 frameCount = decoder->frameCount();
363 EXPECT_EQ(frameCount, decoderI8->frameCount());
207 364
208 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); 365 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1);
209 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount) 366 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount)
210 ++framesDecoded; 367 ++framesDecoded;
368
369 ImageFrame* frameI8 = decoderI8->frameBufferAtIndex(frameCount - 1);
370 ASSERT_TRUE(!(frame || frameI8) || areFramesColorsEqual(*frame, *frameI8 ));
211 } 371 }
212 372
213 EXPECT_EQ(5u, decoder->frameCount()); 373 EXPECT_EQ(5u, decoder->frameCount());
214 EXPECT_EQ(5u, framesDecoded); 374 EXPECT_EQ(5u, framesDecoded);
215 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 375 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
216 } 376 }
217 377
218 TEST(GIFImageDecoderTest, brokenSecondFrame) 378 TEST(GIFImageDecoderTest, brokenSecondFrame)
219 { 379 {
380 LOOP_DECODERS_BEGIN
220 OwnPtr<ImageDecoder> decoder = createDecoder(); 381 OwnPtr<ImageDecoder> decoder = createDecoder();
221 382
222 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "broken.gif"); 383 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "broken.gif");
223 ASSERT_TRUE(data.get()); 384 ASSERT_TRUE(data.get());
224 decoder->setData(data.get(), true); 385 decoder->setData(data.get(), true);
225 386
226 // One frame is detected but cannot be decoded. 387 // One frame is detected but cannot be decoded.
227 EXPECT_EQ(1u, decoder->frameCount()); 388 EXPECT_EQ(1u, decoder->frameCount());
228 ImageFrame* frame = decoder->frameBufferAtIndex(1); 389 ImageFrame* frame = decoder->frameBufferAtIndex(1);
229 EXPECT_FALSE(frame); 390 EXPECT_FALSE(frame);
391 LOOP_DECODERS_END
230 } 392 }
231 393
232 TEST(GIFImageDecoderTest, progressiveDecode) 394 TEST(GIFImageDecoderTest, progressiveDecode)
233 { 395 {
396 LOOP_DECODERS_BEGIN
234 RefPtr<SharedBuffer> fullData = readFile(webTestsDataDir, "radient.gif"); 397 RefPtr<SharedBuffer> fullData = readFile(webTestsDataDir, "radient.gif");
235 ASSERT_TRUE(fullData.get()); 398 ASSERT_TRUE(fullData.get());
236 const size_t fullLength = fullData->size(); 399 const size_t fullLength = fullData->size();
237 400
238 OwnPtr<ImageDecoder> decoder; 401 OwnPtr<ImageDecoder> decoder;
239 ImageFrame* frame; 402 ImageFrame* frame;
240 403
241 Vector<unsigned> truncatedHashes; 404 Vector<unsigned> truncatedHashes;
242 Vector<unsigned> progressiveHashes; 405 Vector<unsigned> progressiveHashes;
243 406
(...skipping 27 matching lines...) Expand all
271 EXPECT_EQ(cAnimationNone, decoder->repetitionCount()); 434 EXPECT_EQ(cAnimationNone, decoder->repetitionCount());
272 435
273 bool match = true; 436 bool match = true;
274 for (size_t i = 0; i < truncatedHashes.size(); ++i) { 437 for (size_t i = 0; i < truncatedHashes.size(); ++i) {
275 if (truncatedHashes[i] != progressiveHashes[i]) { 438 if (truncatedHashes[i] != progressiveHashes[i]) {
276 match = false; 439 match = false;
277 break; 440 break;
278 } 441 }
279 } 442 }
280 EXPECT_TRUE(match); 443 EXPECT_TRUE(match);
444 LOOP_DECODERS_END
281 } 445 }
282 446
283 TEST(GIFImageDecoderTest, allDataReceivedTruncation) 447 TEST(GIFImageDecoderTest, allDataReceivedTruncation)
284 { 448 {
449 LOOP_DECODERS_BEGIN
285 OwnPtr<ImageDecoder> decoder = createDecoder(); 450 OwnPtr<ImageDecoder> decoder = createDecoder();
286 451
287 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; 452 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
288 ASSERT_TRUE(data.get()); 453 ASSERT_TRUE(data.get());
289 454
290 ASSERT_GE(data->size(), 10u); 455 ASSERT_GE(data->size(), 10u);
291 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 456 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
292 decoder->setData(tempData.get(), true); 457 decoder->setData(tempData.get(), true);
293 458
294 EXPECT_EQ(2u, decoder->frameCount()); 459 EXPECT_EQ(2u, decoder->frameCount());
295 EXPECT_FALSE(decoder->failed()); 460 EXPECT_FALSE(decoder->failed());
296 461
297 decoder->frameBufferAtIndex(0); 462 decoder->frameBufferAtIndex(0);
298 EXPECT_FALSE(decoder->failed()); 463 EXPECT_FALSE(decoder->failed());
299 decoder->frameBufferAtIndex(1); 464 decoder->frameBufferAtIndex(1);
300 EXPECT_TRUE(decoder->failed()); 465 EXPECT_TRUE(decoder->failed());
466 LOOP_DECODERS_END
301 } 467 }
302 468
303 TEST(GIFImageDecoderTest, frameIsComplete) 469 TEST(GIFImageDecoderTest, frameIsComplete)
304 { 470 {
471 LOOP_DECODERS_BEGIN
305 OwnPtr<ImageDecoder> decoder = createDecoder(); 472 OwnPtr<ImageDecoder> decoder = createDecoder();
306 473
307 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; 474 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
308 ASSERT_TRUE(data.get()); 475 ASSERT_TRUE(data.get());
309 decoder->setData(data.get(), true); 476 decoder->setData(data.get(), true);
310 477
311 EXPECT_EQ(2u, decoder->frameCount()); 478 EXPECT_EQ(2u, decoder->frameCount());
312 EXPECT_FALSE(decoder->failed()); 479 EXPECT_FALSE(decoder->failed());
313 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 480 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
314 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 481 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
315 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 482 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
483 LOOP_DECODERS_END
316 } 484 }
317 485
318 TEST(GIFImageDecoderTest, frameIsCompleteLoading) 486 TEST(GIFImageDecoderTest, frameIsCompleteLoading)
319 { 487 {
488 LOOP_DECODERS_BEGIN
320 OwnPtr<ImageDecoder> decoder = createDecoder(); 489 OwnPtr<ImageDecoder> decoder = createDecoder();
321 490
322 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ; 491 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif") ;
323 ASSERT_TRUE(data.get()); 492 ASSERT_TRUE(data.get());
324 493
325 ASSERT_GE(data->size(), 10u); 494 ASSERT_GE(data->size(), 10u);
326 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 495 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
327 decoder->setData(tempData.get(), false); 496 decoder->setData(tempData.get(), false);
328 497
329 EXPECT_EQ(2u, decoder->frameCount()); 498 EXPECT_EQ(2u, decoder->frameCount());
330 EXPECT_FALSE(decoder->failed()); 499 EXPECT_FALSE(decoder->failed());
331 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 500 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
332 EXPECT_FALSE(decoder->frameIsCompleteAtIndex(1)); 501 EXPECT_FALSE(decoder->frameIsCompleteAtIndex(1));
333 502
334 decoder->setData(data.get(), true); 503 decoder->setData(data.get(), true);
335 EXPECT_EQ(2u, decoder->frameCount()); 504 EXPECT_EQ(2u, decoder->frameCount());
336 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 505 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
337 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 506 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
507 LOOP_DECODERS_END
338 } 508 }
339 509
340 TEST(GIFImageDecoderTest, badTerminator) 510 TEST(GIFImageDecoderTest, badTerminator)
341 { 511 {
512 LOOP_DECODERS_BEGIN
342 RefPtr<SharedBuffer> referenceData = readFile(webTestsDataDir, "radient.gif" ); 513 RefPtr<SharedBuffer> referenceData = readFile(webTestsDataDir, "radient.gif" );
343 RefPtr<SharedBuffer> testData = readFile(webTestsDataDir, "radient-bad-termi nator.gif"); 514 RefPtr<SharedBuffer> testData = readFile(webTestsDataDir, "radient-bad-termi nator.gif");
344 ASSERT_TRUE(referenceData.get()); 515 ASSERT_TRUE(referenceData.get());
345 ASSERT_TRUE(testData.get()); 516 ASSERT_TRUE(testData.get());
346 517
347 OwnPtr<ImageDecoder> referenceDecoder = createDecoder(); 518 OwnPtr<ImageDecoder> referenceDecoder = createDecoder();
348 referenceDecoder->setData(referenceData.get(), true); 519 referenceDecoder->setData(referenceData.get(), true);
349 EXPECT_EQ(1u, referenceDecoder->frameCount()); 520 EXPECT_EQ(1u, referenceDecoder->frameCount());
350 ImageFrame* referenceFrame = referenceDecoder->frameBufferAtIndex(0); 521 ImageFrame* referenceFrame = referenceDecoder->frameBufferAtIndex(0);
351 ASSERT(referenceFrame); 522 ASSERT(referenceFrame);
352 523
353 OwnPtr<ImageDecoder> testDecoder = createDecoder(); 524 OwnPtr<ImageDecoder> testDecoder = createDecoder();
354 testDecoder->setData(testData.get(), true); 525 testDecoder->setData(testData.get(), true);
355 EXPECT_EQ(1u, testDecoder->frameCount()); 526 EXPECT_EQ(1u, testDecoder->frameCount());
356 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); 527 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0);
357 ASSERT(testFrame); 528 ASSERT(testFrame);
358 529
359 EXPECT_EQ(hashBitmap(referenceFrame->getSkBitmap()), hashBitmap(testFrame->g etSkBitmap())); 530 EXPECT_EQ(hashBitmap(referenceFrame->getSkBitmap()), hashBitmap(testFrame->g etSkBitmap()));
531 LOOP_DECODERS_END
360 } 532 }
361 533
362 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) 534 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode)
363 { 535 {
536 LOOP_DECODERS_BEGIN
364 OwnPtr<ImageDecoder> decoder = createDecoder(); 537 OwnPtr<ImageDecoder> decoder = createDecoder();
365 538
366 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif"); 539 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif");
367 ASSERT_TRUE(fullData.get()); 540 ASSERT_TRUE(fullData.get());
368 541
369 // Give it data that is enough to parse but not decode in order to check the status 542 // Give it data that is enough to parse but not decode in order to check the status
370 // of requiredPreviousFrameIndex before decoding. 543 // of requiredPreviousFrameIndex before decoding.
371 size_t partialSize = 1; 544 size_t partialSize = 1;
372 do { 545 do {
373 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize); 546 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize);
374 decoder->setData(data.get(), false); 547 decoder->setData(data.get(), false);
375 ++partialSize; 548 ++partialSize;
376 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); 549 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty);
377 550
378 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIn dex()); 551 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIn dex());
379 unsigned frameCount = decoder->frameCount(); 552 unsigned frameCount = decoder->frameCount();
380 for (size_t i = 1; i < frameCount; ++i) 553 for (size_t i = 1; i < frameCount; ++i)
381 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex()); 554 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex());
382 555
383 decoder->setData(fullData.get(), true); 556 decoder->setData(fullData.get(), true);
384 for (size_t i = 0; i < frameCount; ++i) 557 for (size_t i = 0; i < frameCount; ++i)
385 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i)->requiredPreviousFra meIndex()); 558 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i)->requiredPreviousFra meIndex());
559 LOOP_DECODERS_END
386 } 560 }
387 561
388 TEST(GIFImageDecoderTest, randomFrameDecode) 562 TEST(GIFImageDecoderTest, randomFrameDecode)
389 { 563 {
390 // Single frame image. 564 // Single frame image.
391 testRandomFrameDecode(webTestsDataDir, "radient.gif"); 565 testRandomFrameDecode(webTestsDataDir, "radient.gif");
392 // Multiple frame images. 566 // Multiple frame images.
393 testRandomFrameDecode(layoutTestResourcesDir, "animated-gif-with-offsets.gif "); 567 testRandomFrameDecode(layoutTestResourcesDir, "animated-gif-with-offsets.gif ");
394 testRandomFrameDecode(layoutTestResourcesDir, "animated-10color.gif"); 568 testRandomFrameDecode(layoutTestResourcesDir, "animated-10color.gif");
395 } 569 }
396 570
571 TEST(GIFImageDecoderTest, randomFrameDecodeCompare)
572 {
573 // Single frame image.
574 testRandomFrameDecodeCompare(webTestsDataDir, "radient.gif");
575 // Multiple frame images.
576 testRandomFrameDecodeCompare(layoutTestResourcesDir, "animated-gif-with-offs ets.gif");
577 testRandomFrameDecodeCompare(layoutTestResourcesDir, "animated-10color.gif") ;
578 }
579
397 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) 580 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache)
398 { 581 {
399 // Single frame image. 582 // Single frame image.
400 testRandomDecodeAfterClearFrameBufferCache(webTestsDataDir, "radient.gif"); 583 testRandomDecodeAfterClearFrameBufferCache(webTestsDataDir, "radient.gif");
401 // Multiple frame images. 584 // Multiple frame images.
402 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -gif-with-offsets.gif"); 585 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -gif-with-offsets.gif");
403 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -10color.gif"); 586 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated -10color.gif");
404 } 587 }
405 588
589 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCacheCompare)
590 {
591 // Single frame image.
592 testRandomDecodeAfterClearFrameBufferCacheCompare(webTestsDataDir, "radient. gif");
593 // Multiple frame images with offset. All frames depend to frame 0.
594 testRandomDecodeAfterClearFrameBufferCacheCompare(layoutTestResourcesDir, "a nimated-gif-with-offsets.gif");
595 testRandomDecodeAfterClearFrameBufferCacheCompare(layoutTestResourcesDir, "a nimated-10color.gif");
596 }
597
406 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) 598 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache)
407 { 599 {
408 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif"); 600 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif");
409 ASSERT_TRUE(fullData.get()); 601 ASSERT_TRUE(fullData.get());
602
603 LOOP_DECODERS_BEGIN
410 Vector<unsigned> baselineHashes; 604 Vector<unsigned> baselineHashes;
411 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); 605 createDecodingBaseline(createDecoder, fullData.get(), &baselineHashes);
412 size_t frameCount = baselineHashes.size(); 606 size_t frameCount = baselineHashes.size();
413 607
414 OwnPtr<ImageDecoder> decoder = createDecoder(); 608 OwnPtr<ImageDecoder> decoder = createDecoder();
415 609
416 // Let frame 0 be partially decoded. 610 // Let frame 0 be partially decoded.
417 size_t partialSize = 1; 611 size_t partialSize = 1;
418 do { 612 do {
419 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize); 613 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize);
420 decoder->setData(data.get(), false); 614 decoder->setData(data.get(), false);
421 ++partialSize; 615 ++partialSize;
422 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); 616 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty);
423 617
424 // Skip to the last frame and clear. 618 // Skip to the last frame and clear.
425 decoder->setData(fullData.get(), true); 619 decoder->setData(fullData.get(), true);
426 EXPECT_EQ(frameCount, decoder->frameCount()); 620 EXPECT_EQ(frameCount, decoder->frameCount());
427 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1); 621 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1);
428 EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->getSkBitmap( ))); 622 EXPECT_EQ(baselineHashes[frameCount - 1], hashBitmap(lastFrame->getSkBitmap( )));
429 decoder->clearCacheExceptFrame(kNotFound); 623 decoder->clearCacheExceptFrame(kNotFound);
430 624
431 // Resume decoding of the first frame. 625 // Resume decoding of the first frame.
432 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); 626 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
433 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); 627 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status());
434 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->getSkBitmap())); 628 EXPECT_EQ(baselineHashes[0], hashBitmap(firstFrame->getSkBitmap()));
629 LOOP_DECODERS_END
435 } 630 }
436 631
437 // The first LZW codes in the image are invalid values that try to create a loop 632 // 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. 633 // in the dictionary. Decoding should fail, but not infinitely loop or corrupt m emory.
439 TEST(GIFImageDecoderTest, badInitialCode) 634 TEST(GIFImageDecoderTest, badInitialCode)
440 { 635 {
441 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-initial-co de.gif"); 636 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-initial-co de.gif");
442 ASSERT_TRUE(testData.get()); 637 ASSERT_TRUE(testData.get());
443 638
639 LOOP_DECODERS_BEGIN
444 OwnPtr<ImageDecoder> testDecoder = createDecoder(); 640 OwnPtr<ImageDecoder> testDecoder = createDecoder();
445 testDecoder->setData(testData.get(), true); 641 testDecoder->setData(testData.get(), true);
446 EXPECT_EQ(1u, testDecoder->frameCount()); 642 EXPECT_EQ(1u, testDecoder->frameCount());
447 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); 643 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0));
448 EXPECT_TRUE(testDecoder->failed()); 644 EXPECT_TRUE(testDecoder->failed());
645 LOOP_DECODERS_END
449 } 646 }
450 647
451 // The image has an invalid LZW code that exceeds dictionary size. Decoding shou ld fail. 648 // The image has an invalid LZW code that exceeds dictionary size. Decoding shou ld fail.
452 TEST(GIFImageDecoderTest, badCode) 649 TEST(GIFImageDecoderTest, badCode)
453 { 650 {
454 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-code.gif") ; 651 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-code.gif") ;
455 ASSERT_TRUE(testData.get()); 652 ASSERT_TRUE(testData.get());
456 653
654 LOOP_DECODERS_BEGIN
457 OwnPtr<ImageDecoder> testDecoder = createDecoder(); 655 OwnPtr<ImageDecoder> testDecoder = createDecoder();
458 testDecoder->setData(testData.get(), true); 656 testDecoder->setData(testData.get(), true);
459 EXPECT_EQ(1u, testDecoder->frameCount()); 657 EXPECT_EQ(1u, testDecoder->frameCount());
460 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); 658 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0));
461 EXPECT_TRUE(testDecoder->failed()); 659 EXPECT_TRUE(testDecoder->failed());
660 LOOP_DECODERS_END
462 } 661 }
463 662
464 TEST(GIFImageDecoderTest, invalidDisposalMethod) 663 TEST(GIFImageDecoderTest, invalidDisposalMethod)
465 { 664 {
665 LOOP_DECODERS_BEGIN
466 OwnPtr<ImageDecoder> decoder = createDecoder(); 666 OwnPtr<ImageDecoder> decoder = createDecoder();
467 667
468 // The image has 2 frames, with disposal method 4 and 5, respectively. 668 // The image has 2 frames, with disposal method 4 and 5, respectively.
469 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "invalid-disposal-meth od.gif"); 669 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "invalid-disposal-meth od.gif");
470 ASSERT_TRUE(data.get()); 670 ASSERT_TRUE(data.get());
471 decoder->setData(data.get(), true); 671 decoder->setData(data.get(), true);
472 672
473 EXPECT_EQ(2u, decoder->frameCount()); 673 EXPECT_EQ(2u, decoder->frameCount());
474 // Disposal method 4 is converted to ImageFrame::DisposeOverwritePrevious. 674 // Disposal method 4 is converted to ImageFrame::DisposeOverwritePrevious.
475 EXPECT_EQ(ImageFrame::DisposeOverwritePrevious, decoder->frameBufferAtIndex( 0)->disposalMethod()); 675 EXPECT_EQ(ImageFrame::DisposeOverwritePrevious, decoder->frameBufferAtIndex( 0)->disposalMethod());
476 // Disposal method 5 is ignored. 676 // Disposal method 5 is ignored.
477 EXPECT_EQ(ImageFrame::DisposeNotSpecified, decoder->frameBufferAtIndex(1)->d isposalMethod()); 677 EXPECT_EQ(ImageFrame::DisposeNotSpecified, decoder->frameBufferAtIndex(1)->d isposalMethod());
678 LOOP_DECODERS_END
478 } 679 }
479 680
480 TEST(GIFImageDecoderTest, firstFrameHasGreaterSizeThanScreenSize) 681 TEST(GIFImageDecoderTest, firstFrameHasGreaterSizeThanScreenSize)
481 { 682 {
482 RefPtr<SharedBuffer> fullData = readFile(decodersTestingDir, "first-frame-ha s-greater-size-than-screen-size.gif"); 683 RefPtr<SharedBuffer> fullData = readFile(decodersTestingDir, "first-frame-ha s-greater-size-than-screen-size.gif");
483 ASSERT_TRUE(fullData.get()); 684 ASSERT_TRUE(fullData.get());
484 685 LOOP_DECODERS_BEGIN
485 OwnPtr<ImageDecoder> decoder; 686 OwnPtr<ImageDecoder> decoder;
486 IntSize frameSize; 687 IntSize frameSize;
487 688
488 // Compute hashes when the file is truncated. 689 // Compute hashes when the file is truncated.
489 for (size_t i = 1; i <= fullData->size(); ++i) { 690 for (size_t i = 1; i <= fullData->size(); ++i) {
490 decoder = createDecoder(); 691 decoder = createDecoder();
491 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); 692 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
492 decoder->setData(data.get(), i == fullData->size()); 693 decoder->setData(data.get(), i == fullData->size());
493 694
494 if (decoder->isSizeAvailable() && !frameSize.width() && !frameSize.heigh t()) { 695 if (decoder->isSizeAvailable() && !frameSize.width() && !frameSize.heigh t()) {
495 frameSize = decoder->decodedSize(); 696 frameSize = decoder->decodedSize();
496 continue; 697 continue;
497 } 698 }
498 699
499 ASSERT_EQ(frameSize.width(), decoder->decodedSize().width()); 700 ASSERT_EQ(frameSize.width(), decoder->decodedSize().width());
500 ASSERT_EQ(frameSize.height(), decoder->decodedSize().height()); 701 ASSERT_EQ(frameSize.height(), decoder->decodedSize().height());
501 } 702 }
703 LOOP_DECODERS_END
502 } 704 }
503 705
706 TEST(GIFImageDecoderTest, convertInFrameGenerator)
707 {
708 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1 0color.gif");
709 ASSERT_TRUE(fullData.get());
710 OwnPtr<ImageDecoder> decoder = createDecoderIndex8();
711 decoder->setData(fullData.get(), true);
712 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
713 ASSERT_TRUE(firstFrame->bitmap().colorType() == kIndex_8_SkColorType);
714 const SkBitmap index8Bitmap = firstFrame->bitmap();
715 SkBitmap target;
716 target.setInfo(SkImageInfo::MakeN32(firstFrame->bitmap().width(), firstFrame ->bitmap().height(), index8Bitmap.alphaType()));
717 target.allocPixels();
718
719 RefPtr<ImageFrameGenerator> m_generator = ImageFrameGenerator::create(firstF rame->bitmap().info().dimensions(), fullData, true);
720 ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024);
721 ImageDecodingStore::instance().insertDecoder(m_generator.get(), decoder.rele ase());
722 SkAutoLockPixels lock(target);
723 m_generator->decodeAndScale(target.info(), 0, target.getPixels(), target.row Bytes());
724 ImageDecodingStore::instance().clear();
725 SkAutoLockPixels lockI8(index8Bitmap);
726 ASSERT_TRUE(areBitmapsColorsEqual(target, index8Bitmap));
727 }
728
729 // FIXME following benchmarks need to be removed before submitting.
730 #define BENCHMARK_DECODE(dir, file, title, count)\
731 TEST(GIFImageDecoderTest, tempBench_decodeIndex8##title##warmuprun)\
732 {\
733 testRandomDecodeAfterClearFrameBufferCache(dir, file);\
734 }\
735 TEST(GIFImageDecoderTest, tempBench_decodeN32##title##_x##count) \
736 {\
737 for (int i = 0; i < count; ++i)\
738 testRandomDecodeAfterClearFrameBufferCache(dir, file);\
739 }\
740 \
741 TEST(GIFImageDecoderTest, tempBench_decodeIndex8##title##_x##count)\
742 {\
743 for (int i = 0; i < count; ++i)\
744 testRandomDecodeAfterClearFrameBufferCache(dir, file, ImageFrame::Index8 );\
745 }\
746
747 BENCHMARK_DECODE(layoutTestResourcesDir, "animated-10color.gif", animated_10colo r_gif, 5)
748 BENCHMARK_DECODE(webTestsDataDir, "radient.gif", radient_gif, 10)
749 BENCHMARK_DECODE(layoutTestResourcesDir, "animated-gif-with-offsets.gif", animat ed_gif_with_offsets_gif, 5)
750 BENCHMARK_DECODE(layoutTestResourcesDir, "animated.gif", animated_gif, 10)
751 BENCHMARK_DECODE(layoutTestResourcesDir, "quicksort.gif", quicksort_gif, 5)
752 BENCHMARK_DECODE(layoutTestResourcesDir, "large-gif-checkerboard.gif", large_gif _checkerboard_gif, 5)
753 BENCHMARK_DECODE(layoutTestResourcesDir, "3dolph.gif", 3dolph_gif, 5)
504 } // namespace blink 754 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698