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

Side by Side Diff: Source/WebKit/chromium/tests/GIFImageDecoderTest.cpp

Issue 15350006: Decode GIF image frames on demand. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Don't preserve the last frame and frames at intervals Created 7 years, 7 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 32
33 #include "core/platform/image-decoders/gif/GIFImageDecoder.h" 33 #include "core/platform/image-decoders/gif/GIFImageDecoder.h"
34 34
35 #include <gtest/gtest.h>
36 #include "core/platform/FileSystem.h" 35 #include "core/platform/FileSystem.h"
37 #include "core/platform/SharedBuffer.h" 36 #include "core/platform/SharedBuffer.h"
37 #include "wtf/OwnPtr.h"
Alpha Left Google 2013/05/22 20:18:09 nit: I'm not sure whether we are moving to use "wt
Xianzhu 2013/05/22 23:43:29 Yes, this is the new style. The presubmit script r
38 #include "wtf/PassOwnPtr.h"
39 #include "wtf/StringHasher.h"
40 #include "wtf/Vector.h"
41 #include <gtest/gtest.h>
38 #include <public/Platform.h> 42 #include <public/Platform.h>
39 #include <public/WebData.h> 43 #include <public/WebData.h>
40 #include <public/WebSize.h> 44 #include <public/WebSize.h>
41 #include <public/WebUnitTestSupport.h> 45 #include <public/WebUnitTestSupport.h>
42 #include <wtf/OwnPtr.h>
43 #include <wtf/PassOwnPtr.h>
44 #include <wtf/StringHasher.h>
45 #include <wtf/Vector.h>
46 46
47 using namespace WebCore; 47 using namespace WebCore;
48 using namespace WebKit; 48 using namespace WebKit;
49 49
50 namespace { 50 namespace {
51 51
52 #if !OS(ANDROID) 52 #if !OS(ANDROID)
53 53
54 static PassRefPtr<SharedBuffer> readFile(const char* fileName) 54 static PassRefPtr<SharedBuffer> readFile(const char* fileName)
55 { 55 {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 TEST(GIFImageDecoderTest, parseByteByByte) 128 TEST(GIFImageDecoderTest, parseByteByByte)
129 { 129 {
130 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 130 OwnPtr<GIFImageDecoder> decoder(createDecoder());
131 131
132 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 132 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
133 ASSERT_TRUE(data.get()); 133 ASSERT_TRUE(data.get());
134 134
135 size_t frameCount = 0; 135 size_t frameCount = 0;
136 136
137 // Pass data to decoder byte by byte. 137 // Pass data to decoder byte by byte.
138 for (unsigned length = 1; length <= data->size(); ++length) { 138 for (size_t length = 1; length <= data->size(); ++length) {
139 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 139 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
140 decoder->setData(tempData.get(), length == data->size()); 140 decoder->setData(tempData.get(), length == data->size());
141 141
142 EXPECT_LE(frameCount, decoder->frameCount()); 142 EXPECT_LE(frameCount, decoder->frameCount());
143 frameCount = decoder->frameCount(); 143 frameCount = decoder->frameCount();
144 } 144 }
145 145
146 EXPECT_EQ(2u, decoder->frameCount()); 146 EXPECT_EQ(2u, decoder->frameCount());
147 147
148 decoder->frameBufferAtIndex(0); 148 decoder->frameBufferAtIndex(0);
149 decoder->frameBufferAtIndex(1); 149 decoder->frameBufferAtIndex(1);
150 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 150 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
151 } 151 }
152 152
153 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) 153 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte)
154 { 154 {
155 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 155 OwnPtr<GIFImageDecoder> decoder(createDecoder());
156 156
157 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated-gif-with-offsets.gif"); 157 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated-gif-with-offsets.gif");
158 ASSERT_TRUE(data.get()); 158 ASSERT_TRUE(data.get());
159 159
160 size_t frameCount = 0; 160 size_t frameCount = 0;
161 size_t framesDecoded = 0; 161 size_t framesDecoded = 0;
162 162
163 // Pass data to decoder byte by byte. 163 // Pass data to decoder byte by byte.
164 for (unsigned length = 1; length <= data->size(); ++length) { 164 for (size_t length = 1; length <= data->size(); ++length) {
165 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h); 165 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
166 decoder->setData(tempData.get(), length == data->size()); 166 decoder->setData(tempData.get(), length == data->size());
167 167
168 EXPECT_LE(frameCount, decoder->frameCount()); 168 EXPECT_LE(frameCount, decoder->frameCount());
169 frameCount = decoder->frameCount(); 169 frameCount = decoder->frameCount();
170 170
171 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); 171 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1);
172 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount) 172 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount)
173 ++framesDecoded; 173 ++framesDecoded;
174 } 174 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 bool match = true; 234 bool match = true;
235 for (size_t i = 0; i < truncatedHashes.size(); ++i) { 235 for (size_t i = 0; i < truncatedHashes.size(); ++i) {
236 if (truncatedHashes[i] != progressiveHashes[i]) { 236 if (truncatedHashes[i] != progressiveHashes[i]) {
237 match = false; 237 match = false;
238 break; 238 break;
239 } 239 }
240 } 240 }
241 EXPECT_TRUE(match); 241 EXPECT_TRUE(match);
242 } 242 }
243 243
244 TEST(GIFImageDecoderTest, randomFrameDecode)
245 {
246 RefPtr<SharedBuffer> fullData = readFile("/Source/WebKit/chromium/tests/data /radient.gif");
247 ASSERT_TRUE(fullData.get());
248
249 OwnPtr<GIFImageDecoder> decoder;
250
251 // Compute hashes when the frames are requested sequentially.
Alpha Left Google 2013/05/22 20:18:09 This is not really random isn't it?
Xianzhu 2013/05/22 23:43:29 This is to get a baseline for testing the random d
252 decoder = createDecoder();
253 decoder->setData(fullData.get(), true);
254 decoder->frameBufferAtIndex(0); // To trigger parsing.
Alpha Left Google 2013/05/22 20:18:09 frameCount() will trigger parsing already.
Xianzhu 2013/05/22 23:43:29 Done.
255 size_t frameCount = decoder->frameCount();
256 Vector<unsigned> sequentialHashes(frameCount);
257 for (size_t i = 0; i < frameCount; ++i) {
258 ImageFrame* frame = decoder->frameBufferAtIndex(i);
259 sequentialHashes[i] = hashSkBitmap(frame->getSkBitmap());
260 }
261
262 // Compute hashes when frames are requested randomly.
263 decoder = createDecoder();
264 decoder->setData(fullData.get(), true);
265 const size_t skippingStep = 5;
266 for (size_t i = 0; i < skippingStep; ++i) {
267 for (size_t j = i; j < frameCount; j += skippingStep) {
268 ImageFrame* frame = decoder->frameBufferAtIndex(j);
269 EXPECT_EQ(sequentialHashes[j], hashSkBitmap(frame->getSkBitmap()));
270 }
271 }
272
273 // Compute hashes when frames are requested in reverse order.
274 decoder = createDecoder();
275 decoder->setData(fullData.get(), true);
276 for (size_t i = frameCount; i; --i) {
277 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
278 EXPECT_EQ(sequentialHashes[i - 1], hashSkBitmap(frame->getSkBitmap()));
279 }
280 }
281
282 TEST(GIFImageDecoderTest, decodeAfterClearFrameBufferCache)
283 {
284 RefPtr<SharedBuffer> fullData = readFile("/Source/WebKit/chromium/tests/data /radient.gif");
285 ASSERT_TRUE(fullData.get());
286
287 OwnPtr<GIFImageDecoder> decoder;
288
289 // Compute hashes when the frames are requested sequentially.
290 decoder = createDecoder();
291 decoder->setData(fullData.get(), true);
292 decoder->frameBufferAtIndex(0); // To trigger parsing.
Alpha Left Google 2013/05/22 20:18:09 frameCount() will trigger parsing so this is not n
Xianzhu 2013/05/22 23:43:29 Done.
293 size_t frameCount = decoder->frameCount();
294 Vector<unsigned> sequentialHashes(frameCount);
295 for (size_t i = 0; i < frameCount; ++i) {
296 ImageFrame* frame = decoder->frameBufferAtIndex(i);
297 sequentialHashes[i] = hashSkBitmap(frame->getSkBitmap());
298 }
299
300 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) {
301 decoder->clearFrameBufferCache(clearExceptFrame);
302 const size_t skippingStep = 5;
303 for (size_t i = 0; i < skippingStep; ++i) {
304 for (size_t j = 0; j < frameCount; j += skippingStep) {
305 ImageFrame* frame = decoder->frameBufferAtIndex(j);
306 EXPECT_EQ(sequentialHashes[j], hashSkBitmap(frame->getSkBitmap() ));
307 }
308 }
309 }
310 }
311
Alpha Left Google 2013/05/22 20:18:09 You also need to test this corner case: 1. Frame 1
Xianzhu 2013/05/22 23:43:29 Done.
244 TEST(GIFImageDecoderTest, allDataReceivedTruncation) 312 TEST(GIFImageDecoderTest, allDataReceivedTruncation)
245 { 313 {
246 OwnPtr<GIFImageDecoder> decoder(createDecoder()); 314 OwnPtr<GIFImageDecoder> decoder(createDecoder());
247 315
248 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 316 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
249 ASSERT_TRUE(data.get()); 317 ASSERT_TRUE(data.get());
250 318
251 ASSERT_GE(data->size(), 10u); 319 ASSERT_GE(data->size(), 10u);
252 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 320 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
253 decoder->setData(tempData.get(), true); 321 decoder->setData(tempData.get(), true);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 361
294 decoder->setData(data.get(), true); 362 decoder->setData(data.get(), true);
295 EXPECT_EQ(2u, decoder->frameCount()); 363 EXPECT_EQ(2u, decoder->frameCount());
296 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 364 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
297 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 365 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
298 } 366 }
299 367
300 #endif 368 #endif
301 369
302 } // namespace 370 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698