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

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

Powered by Google App Engine
This is Rietveld 408576698