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

Side by Side Diff: Source/core/platform/image-decoders/webp/WEBPImageDecoderTest.cpp

Issue 13980003: Add animation support for WebP images (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase + Handle transparent frame background Created 7 years, 6 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 12 matching lines...) Expand all
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
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 "config.h" 31 #include "config.h"
32 32
33 #include "core/platform/image-decoders/gif/GIFImageDecoder.h" 33 #include "core/platform/image-decoders/webp/WEBPImageDecoder.h"
34 34
35 #include "RuntimeEnabledFeatures.h"
35 #include "core/platform/FileSystem.h" 36 #include "core/platform/FileSystem.h"
36 #include "core/platform/SharedBuffer.h" 37 #include "core/platform/SharedBuffer.h"
37 #include "public/platform/Platform.h" 38 #include "public/platform/Platform.h"
38 #include "public/platform/WebData.h" 39 #include "public/platform/WebData.h"
39 #include "public/platform/WebSize.h" 40 #include "public/platform/WebSize.h"
40 #include "public/platform/WebUnitTestSupport.h" 41 #include "public/platform/WebUnitTestSupport.h"
41 #include "wtf/OwnPtr.h" 42 #include "wtf/OwnPtr.h"
42 #include "wtf/PassOwnPtr.h" 43 #include "wtf/PassOwnPtr.h"
43 #include "wtf/StringHasher.h" 44 #include "wtf/StringHasher.h"
44 #include "wtf/Vector.h" 45 #include "wtf/Vector.h"
46 #include <base/basictypes.h>
jamesr 2013/06/21 04:45:30 you shouldn't use chromium's base library in blink
urvang (Google) 2013/06/24 11:02:03 Thanks for pointing that out James! Using "wtf/dto
45 #include <gtest/gtest.h> 47 #include <gtest/gtest.h>
46 48
47 using namespace WebCore; 49 using namespace WebCore;
48 using namespace WebKit; 50 using namespace WebKit;
49 51
52 namespace {
53
50 #if !OS(ANDROID) 54 #if !OS(ANDROID)
51 55
52 namespace { 56 static PassRefPtr<SharedBuffer> readFile(const char* fileName)
53
54 PassRefPtr<SharedBuffer> readFile(const char* fileName)
55 { 57 {
56 String filePath = Platform::current()->unitTestSupport()->webKitRootDir(); 58 String filePath = Platform::current()->unitTestSupport()->webKitRootDir();
57 filePath.append(fileName); 59 filePath.append(fileName);
58 60
59 long long fileSize; 61 long long fileSize;
60 if (!getFileSize(filePath, fileSize)) 62 if (!getFileSize(filePath, fileSize))
61 return 0; 63 return 0;
62 64
63 PlatformFileHandle handle = openFile(filePath, OpenForRead); 65 PlatformFileHandle handle = openFile(filePath, OpenForRead);
64 int fileLength = static_cast<int>(fileSize); 66 int fileLength = static_cast<int>(fileSize);
65 Vector<char> buffer(fileLength); 67 Vector<char> buffer(fileLength);
66 readFromFile(handle, buffer.data(), fileLength); 68 readFromFile(handle, buffer.data(), fileLength);
67 closeFile(handle); 69 closeFile(handle);
68 return SharedBuffer::adoptVector(buffer); 70 return SharedBuffer::adoptVector(buffer);
69 } 71 }
70 72
71 PassOwnPtr<GIFImageDecoder> createDecoder() 73 static PassOwnPtr<WEBPImageDecoder> createDecoder()
72 { 74 {
73 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag eSource::GammaAndColorProfileApplied)); 75 return adoptPtr(new WEBPImageDecoder(ImageSource::AlphaNotPremultiplied, Ima geSource::GammaAndColorProfileApplied));
74 } 76 }
75 77
76 unsigned hashSkBitmap(const SkBitmap& bitmap) 78 static unsigned hashSkBitmap(const SkBitmap& bitmap)
77 { 79 {
78 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); 80 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize());
79 } 81 }
80 82
81 void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselineHashes ) 83 static void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselin eHashes)
82 { 84 {
83 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 85 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
84 decoder->setData(data, true); 86 decoder->setData(data, true);
85 size_t frameCount = decoder->frameCount(); 87 size_t frameCount = decoder->frameCount();
86 for (size_t i = 0; i < frameCount; ++i) { 88 for (size_t i = 0; i < frameCount; ++i) {
87 ImageFrame* frame = decoder->frameBufferAtIndex(i); 89 ImageFrame* frame = decoder->frameBufferAtIndex(i);
88 baselineHashes->append(hashSkBitmap(frame->getSkBitmap())); 90 baselineHashes->append(hashSkBitmap(frame->getSkBitmap()));
89 } 91 }
90 } 92 }
91 93
92 void testRandomFrameDecode(const char* gifFile) 94 void testRandomFrameDecode(const char* webpFile)
93 { 95 {
94 SCOPED_TRACE(gifFile); 96 SCOPED_TRACE(webpFile);
95 97
96 RefPtr<SharedBuffer> fullData = readFile(gifFile); 98 RefPtr<SharedBuffer> fullData = readFile(webpFile);
97 ASSERT_TRUE(fullData.get()); 99 ASSERT_TRUE(fullData.get());
98 Vector<unsigned> baselineHashes; 100 Vector<unsigned> baselineHashes;
99 createDecodingBaseline(fullData.get(), &baselineHashes); 101 createDecodingBaseline(fullData.get(), &baselineHashes);
100 size_t frameCount = baselineHashes.size(); 102 size_t frameCount = baselineHashes.size();
101 103
102 // Random decoding should get the same results as sequential decoding. 104 // Random decoding should get the same results as sequential decoding.
103 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 105 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
104 decoder->setData(fullData.get(), true); 106 decoder->setData(fullData.get(), true);
105 const size_t skippingStep = 5; 107 const size_t skippingStep = 5;
106 for (size_t i = 0; i < skippingStep; ++i) { 108 for (size_t i = 0; i < skippingStep; ++i) {
107 for (size_t j = i; j < frameCount; j += skippingStep) { 109 for (size_t j = i; j < frameCount; j += skippingStep) {
108 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 110 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
109 ImageFrame* frame = decoder->frameBufferAtIndex(j); 111 ImageFrame* frame = decoder->frameBufferAtIndex(j);
110 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())); 112 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap()));
111 } 113 }
112 } 114 }
113 115
114 // Decoding in reverse order. 116 // Decoding in reverse order.
115 decoder = createDecoder(); 117 decoder = createDecoder();
116 decoder->setData(fullData.get(), true); 118 decoder->setData(fullData.get(), true);
117 for (size_t i = frameCount; i; --i) { 119 for (size_t i = frameCount; i; --i) {
118 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); 120 SCOPED_TRACE(testing::Message() << "Reverse i:" << i);
119 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); 121 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1);
120 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap())); 122 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap()));
121 } 123 }
122 } 124 }
123 125
124 void testRandomDecodeAfterClearFrameBufferCache(const char* gifFile) 126 void testRandomDecodeAfterClearFrameBufferCache(const char* webpFile)
125 { 127 {
126 SCOPED_TRACE(gifFile); 128 SCOPED_TRACE(webpFile);
127 129
128 RefPtr<SharedBuffer> data = readFile(gifFile); 130 RefPtr<SharedBuffer> data = readFile(webpFile);
129 ASSERT_TRUE(data.get()); 131 ASSERT_TRUE(data.get());
130 Vector<unsigned> baselineHashes; 132 Vector<unsigned> baselineHashes;
131 createDecodingBaseline(data.get(), &baselineHashes); 133 createDecodingBaseline(data.get(), &baselineHashes);
132 size_t frameCount = baselineHashes.size(); 134 size_t frameCount = baselineHashes.size();
133 135
134 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 136 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
135 decoder->setData(data.get(), true); 137 decoder->setData(data.get(), true);
136 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) { 138 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce ptFrame) {
137 decoder->clearCacheExceptFrame(clearExceptFrame); 139 decoder->clearCacheExceptFrame(clearExceptFrame);
138 const size_t skippingStep = 5; 140 const size_t skippingStep = 5;
139 for (size_t i = 0; i < skippingStep; ++i) { 141 for (size_t i = 0; i < skippingStep; ++i) {
140 for (size_t j = 0; j < frameCount; j += skippingStep) { 142 for (size_t j = 0; j < frameCount; j += skippingStep) {
141 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); 143 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j);
142 ImageFrame* frame = decoder->frameBufferAtIndex(j); 144 ImageFrame* frame = decoder->frameBufferAtIndex(j);
143 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())) ; 145 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())) ;
144 } 146 }
145 } 147 }
146 } 148 }
147 } 149 }
148 150
149 } // namespace 151 class AnimatedWebPTests : public ::testing::Test {
152 protected:
153 virtual void SetUp()
154 {
155 // Enable animated WebP for all the tests.
156 WebCore::RuntimeEnabledFeatures::setAnimatedWebPEnabled(true);
157 }
158 };
150 159
151 TEST(GIFImageDecoderTest, decodeTwoFrames) 160 TEST_F(AnimatedWebPTests, verifyAnimationParameters)
152 { 161 {
153 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 162 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
163 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
154 164
155 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 165 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web p-animated.webp");
156 ASSERT_TRUE(data.get()); 166 ASSERT_TRUE(data.get());
157 decoder->setData(data.get(), true); 167 decoder->setData(data.get(), true);
158 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
159 168
160 ImageFrame* frame = decoder->frameBufferAtIndex(0); 169 const int canvasWidth = 11;
161 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 170 const int canvasHeight = 29;
162 EXPECT_EQ(16, frame->getSkBitmap().width()); 171 const int hasAlpha = true;
163 EXPECT_EQ(16, frame->getSkBitmap().height()); 172 const struct AnimParam {
173 int xOffset, yOffset, width, height;
174 ImageFrame::FrameDisposalMethod dispose;
175 unsigned duration;
176 } animParams[] = {
177 { 0, 0, 11, 29, ImageFrame::DisposeKeep, 1000u },
178 { 2, 10, 7, 17, ImageFrame::DisposeKeep, 500u },
179 { 2, 2, 7, 16, ImageFrame::DisposeKeep, 1000u },
180 };
164 181
165 frame = decoder->frameBufferAtIndex(1); 182 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(animParams); ++i) {
166 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 183 const ImageFrame* const frame = decoder->frameBufferAtIndex(i);
167 EXPECT_EQ(16, frame->getSkBitmap().width()); 184 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
168 EXPECT_EQ(16, frame->getSkBitmap().height()); 185 EXPECT_EQ(canvasWidth, frame->getSkBitmap().width());
186 EXPECT_EQ(canvasHeight, frame->getSkBitmap().height());
187 EXPECT_EQ(hasAlpha, frame->hasAlpha());
188 EXPECT_EQ(animParams[i].xOffset, frame->originalFrameRect().x());
189 EXPECT_EQ(animParams[i].yOffset, frame->originalFrameRect().y());
190 EXPECT_EQ(animParams[i].width, frame->originalFrameRect().width());
191 EXPECT_EQ(animParams[i].height, frame->originalFrameRect().height());
192 EXPECT_EQ(animParams[i].dispose, frame->disposalMethod());
193 EXPECT_EQ(animParams[i].duration, frame->duration());
194 }
169 195
170 EXPECT_EQ(2u, decoder->frameCount()); 196 EXPECT_EQ(ARRAYSIZE_UNSAFE(animParams), decoder->frameCount());
171 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 197 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
172 } 198 }
173 199
174 TEST(GIFImageDecoderTest, parseAndDecode) 200 TEST_F(AnimatedWebPTests, parseAndDecodeByteByByte)
175 { 201 {
176 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 202 const struct TestImage {
203 const char* filename;
204 unsigned frameCount;
205 int repetitionCount;
206 } testImages[] = {
207 { "/LayoutTests/fast/images/resources/webp-animated.webp", 3u, cAnimatio nLoopInfinite },
208 { "/LayoutTests/fast/images/resources/webp-animated-icc-xmp.webp", 13u, 32000 },
209 };
177 210
178 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 211 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(testImages); ++i) {
179 ASSERT_TRUE(data.get()); 212 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
180 decoder->setData(data.get(), true); 213 RefPtr<SharedBuffer> data = readFile(testImages[i].filename);
181 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); 214 ASSERT_TRUE(data.get());
182 215
183 // This call will parse the entire file. 216 size_t frameCount = 0;
184 EXPECT_EQ(2u, decoder->frameCount()); 217 size_t framesDecoded = 0;
185 218
186 ImageFrame* frame = decoder->frameBufferAtIndex(0); 219 // Pass data to decoder byte by byte.
187 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 220 for (size_t length = 1; length <= data->size(); ++length) {
188 EXPECT_EQ(16, frame->getSkBitmap().width()); 221 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), l ength);
189 EXPECT_EQ(16, frame->getSkBitmap().height()); 222 decoder->setData(tempData.get(), length == data->size());
190 223
191 frame = decoder->frameBufferAtIndex(1); 224 EXPECT_LE(frameCount, decoder->frameCount());
192 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); 225 frameCount = decoder->frameCount();
193 EXPECT_EQ(16, frame->getSkBitmap().width()); 226
194 EXPECT_EQ(16, frame->getSkBitmap().height()); 227 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1);
195 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); 228 if (frame && frame->status() == ImageFrame::FrameComplete && framesD ecoded < frameCount)
229 ++framesDecoded;
230 }
231
232 EXPECT_EQ(testImages[i].frameCount, decoder->frameCount());
233 EXPECT_EQ(testImages[i].frameCount, framesDecoded);
234 EXPECT_EQ(testImages[i].repetitionCount, decoder->repetitionCount());
235 }
196 } 236 }
197 237
198 TEST(GIFImageDecoderTest, parseByteByByte) 238 TEST_F(AnimatedWebPTests, invalidImage)
199 { 239 {
200 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 240 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
201 241
202 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 242 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/inv alid-animated-webp.webp");
203 ASSERT_TRUE(data.get());
204
205 size_t frameCount = 0;
206
207 // Pass data to decoder byte by byte.
208 for (size_t length = 1; length <= data->size(); ++length) {
209 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
210 decoder->setData(tempData.get(), length == data->size());
211
212 EXPECT_LE(frameCount, decoder->frameCount());
213 frameCount = decoder->frameCount();
214 }
215
216 EXPECT_EQ(2u, decoder->frameCount());
217
218 decoder->frameBufferAtIndex(0);
219 decoder->frameBufferAtIndex(1);
220 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
221 }
222
223 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte)
224 {
225 OwnPtr<GIFImageDecoder> decoder = createDecoder();
226
227 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated-gif-with-offsets.gif");
228 ASSERT_TRUE(data.get());
229
230 size_t frameCount = 0;
231 size_t framesDecoded = 0;
232
233 // Pass data to decoder byte by byte.
234 for (size_t length = 1; length <= data->size(); ++length) {
235 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt h);
236 decoder->setData(tempData.get(), length == data->size());
237
238 EXPECT_LE(frameCount, decoder->frameCount());
239 frameCount = decoder->frameCount();
240
241 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1);
242 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod ed < frameCount)
243 ++framesDecoded;
244 }
245
246 EXPECT_EQ(5u, decoder->frameCount());
247 EXPECT_EQ(5u, framesDecoded);
248 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount());
249 }
250
251 TEST(GIFImageDecoderTest, brokenSecondFrame)
252 {
253 OwnPtr<GIFImageDecoder> decoder = createDecoder();
254
255 RefPtr<SharedBuffer> data = readFile("/Source/WebKit/chromium/tests/data/bro ken.gif");
256 ASSERT_TRUE(data.get()); 243 ASSERT_TRUE(data.get());
257 decoder->setData(data.get(), true); 244 decoder->setData(data.get(), true);
258 245
259 // One frame is detected but cannot be decoded. 246 EXPECT_EQ(0u, decoder->frameCount());
260 EXPECT_EQ(1u, decoder->frameCount()); 247 ImageFrame* frame = decoder->frameBufferAtIndex(0);
261 ImageFrame* frame = decoder->frameBufferAtIndex(1);
262 EXPECT_FALSE(frame); 248 EXPECT_FALSE(frame);
249 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount());
263 } 250 }
264 251
265 TEST(GIFImageDecoderTest, progressiveDecode) 252 TEST_F(AnimatedWebPTests, progressiveDecode)
266 { 253 {
267 RefPtr<SharedBuffer> fullData = readFile("/Source/WebKit/chromium/tests/data /radient.gif"); 254 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /webp-animated.webp");
268 ASSERT_TRUE(fullData.get()); 255 ASSERT_TRUE(fullData.get());
269 const size_t fullLength = fullData->size(); 256 const size_t fullLength = fullData->size();
270 257
271 OwnPtr<GIFImageDecoder> decoder; 258 OwnPtr<WEBPImageDecoder> decoder;
272 ImageFrame* frame; 259 ImageFrame* frame;
273 260
274 Vector<unsigned> truncatedHashes; 261 Vector<unsigned> truncatedHashes;
275 Vector<unsigned> progressiveHashes; 262 Vector<unsigned> progressiveHashes;
276 263
277 // Compute hashes when the file is truncated. 264 // Compute hashes when the file is truncated.
278 const size_t increment = 1; 265 const size_t increment = 1;
279 for (size_t i = 1; i <= fullLength; i += increment) { 266 for (size_t i = 1; i <= fullLength; i += increment) {
280 decoder = createDecoder(); 267 decoder = createDecoder();
281 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); 268 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i);
(...skipping 22 matching lines...) Expand all
304 bool match = true; 291 bool match = true;
305 for (size_t i = 0; i < truncatedHashes.size(); ++i) { 292 for (size_t i = 0; i < truncatedHashes.size(); ++i) {
306 if (truncatedHashes[i] != progressiveHashes[i]) { 293 if (truncatedHashes[i] != progressiveHashes[i]) {
307 match = false; 294 match = false;
308 break; 295 break;
309 } 296 }
310 } 297 }
311 EXPECT_TRUE(match); 298 EXPECT_TRUE(match);
312 } 299 }
313 300
314 TEST(GIFImageDecoderTest, allDataReceivedTruncation) 301 TEST_F(AnimatedWebPTests, frameIsCompleteAndDuration)
315 { 302 {
316 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 303 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
317 304
318 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif"); 305 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web p-animated.webp");
319 ASSERT_TRUE(data.get()); 306 ASSERT_TRUE(data.get());
320 307
321 ASSERT_GE(data->size(), 10u); 308 ASSERT_GE(data->size(), 10u);
322 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
323 decoder->setData(tempData.get(), true);
324
325 EXPECT_EQ(2u, decoder->frameCount());
326 EXPECT_FALSE(decoder->failed());
327
328 decoder->frameBufferAtIndex(0);
329 EXPECT_FALSE(decoder->failed());
330 decoder->frameBufferAtIndex(1);
331 EXPECT_TRUE(decoder->failed());
332 }
333
334 TEST(GIFImageDecoderTest, frameIsComplete)
335 {
336 OwnPtr<GIFImageDecoder> decoder = createDecoder();
337
338 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
339 ASSERT_TRUE(data.get());
340 decoder->setData(data.get(), true);
341
342 EXPECT_EQ(2u, decoder->frameCount());
343 EXPECT_FALSE(decoder->failed());
344 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
345 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
346 }
347
348 TEST(GIFImageDecoderTest, frameIsCompleteLoading)
349 {
350 OwnPtr<GIFImageDecoder> decoder = createDecoder();
351
352 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani mated.gif");
353 ASSERT_TRUE(data.get());
354
355 ASSERT_GE(data->size(), 10u);
356 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10); 309 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz e() - 10);
357 decoder->setData(tempData.get(), false); 310 decoder->setData(tempData.get(), false);
358 311
359 EXPECT_EQ(2u, decoder->frameCount()); 312 EXPECT_EQ(2u, decoder->frameCount());
360 EXPECT_FALSE(decoder->failed()); 313 EXPECT_FALSE(decoder->failed());
361 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 314 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
362 EXPECT_FALSE(decoder->frameIsCompleteAtIndex(1)); 315 EXPECT_EQ(1000, decoder->frameDurationAtIndex(0));
316 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
317 EXPECT_EQ(500, decoder->frameDurationAtIndex(1));
363 318
364 decoder->setData(data.get(), true); 319 decoder->setData(data.get(), true);
365 EXPECT_EQ(2u, decoder->frameCount()); 320 EXPECT_EQ(3u, decoder->frameCount());
366 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); 321 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0));
322 EXPECT_EQ(1000, decoder->frameDurationAtIndex(0));
367 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); 323 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1));
324 EXPECT_EQ(500, decoder->frameDurationAtIndex(1));
325 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(2));
326 EXPECT_EQ(1000.0, decoder->frameDurationAtIndex(2));
368 } 327 }
369 328
370 TEST(GIFImageDecoderTest, badTerminator) 329 TEST_F(AnimatedWebPTests, updateRequiredPreviousFrameAfterFirstDecode)
371 { 330 {
372 RefPtr<SharedBuffer> referenceData = readFile("/Source/WebKit/chromium/tests /data/radient.gif"); 331 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
373 RefPtr<SharedBuffer> testData = readFile("/Source/WebKit/chromium/tests/data /radient-bad-terminator.gif");
374 ASSERT_TRUE(referenceData.get());
375 ASSERT_TRUE(testData.get());
376 332
377 OwnPtr<GIFImageDecoder> referenceDecoder(createDecoder()); 333 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /webp-animated.webp");
378 referenceDecoder->setData(referenceData.get(), true);
379 EXPECT_EQ(1u, referenceDecoder->frameCount());
380 ImageFrame* referenceFrame = referenceDecoder->frameBufferAtIndex(0);
381 ASSERT(referenceFrame);
382
383 OwnPtr<GIFImageDecoder> testDecoder(createDecoder());
384 testDecoder->setData(testData.get(), true);
385 EXPECT_EQ(1u, testDecoder->frameCount());
386 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0);
387 ASSERT(testFrame);
388
389 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram e->getSkBitmap()));
390 }
391
392 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode)
393 {
394 OwnPtr<GIFImageDecoder> decoder = createDecoder();
395
396 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /animated-10color.gif");
397 ASSERT_TRUE(fullData.get()); 334 ASSERT_TRUE(fullData.get());
398 335
399 // Give it data that is enough to parse but not decode in order to check the status 336 // Give it data that is enough to parse but not decode in order to check the status
400 // of requiredPreviousFrameIndex before decoding. 337 // of requiredPreviousFrameIndex before decoding.
401 size_t partialSize = 1; 338 size_t partialSize = 1;
402 do { 339 do {
403 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize); 340 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize);
404 decoder->setData(data.get(), false); 341 decoder->setData(data.get(), false);
405 ++partialSize; 342 ++partialSize;
406 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); 343 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty);
407 344
408 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameInd ex()); 345 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameInd ex());
409 unsigned frameCount = decoder->frameCount(); 346 unsigned frameCount = decoder->frameCount();
410 for (size_t i = 1; i < frameCount; ++i) 347 for (size_t i = 1; i < frameCount; ++i)
411 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex()); 348 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn dex());
412 349
413 decoder->setData(fullData.get(), true); 350 decoder->setData(fullData.get(), true);
414 for (size_t i = 0; i < frameCount; ++i) 351 for (size_t i = 0; i < frameCount; ++i)
415 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(i)->requiredPreviousFram eIndex()); 352 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(i)->requiredPreviousFram eIndex());
416 } 353 }
417 354
418 TEST(GIFImageDecoderTest, randomFrameDecode) 355 TEST_F(AnimatedWebPTests, randomFrameDecode)
419 { 356 {
420 // Single frame image. 357 testRandomFrameDecode("/LayoutTests/fast/images/resources/webp-animated.webp ");
421 testRandomFrameDecode("/Source/WebKit/chromium/tests/data/radient.gif"); 358 testRandomFrameDecode("/LayoutTests/fast/images/resources/webp-animated-larg e.webp");
422 // Multiple frame images. 359 testRandomFrameDecode("/LayoutTests/fast/images/resources/webp-animated-icc- xmp.webp");
423 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-gif-with- offsets.gif");
424 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-10color.g if");
425 } 360 }
426 361
427 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) 362 TEST_F(AnimatedWebPTests, randomDecodeAfterClearFrameBufferCache)
428 { 363 {
429 // Single frame image. 364 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc es/webp-animated.webp");
430 testRandomDecodeAfterClearFrameBufferCache("/Source/WebKit/chromium/tests/da ta/radient.gif"); 365 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc es/webp-animated-large.webp");
431 // Multiple frame images. 366 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc es/webp-animated-icc-xmp.webp");
432 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc es/animated-gif-with-offsets.gif");
433 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc es/animated-10color.gif");
434 } 367 }
435 368
436 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) 369 TEST_F(AnimatedWebPTests, resumePartialDecodeAfterClearFrameBufferCache)
437 { 370 {
438 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /animated-10color.gif"); 371 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources /webp-animated-large.webp");
439 ASSERT_TRUE(fullData.get()); 372 ASSERT_TRUE(fullData.get());
440 Vector<unsigned> baselineHashes; 373 Vector<unsigned> baselineHashes;
441 createDecodingBaseline(fullData.get(), &baselineHashes); 374 createDecodingBaseline(fullData.get(), &baselineHashes);
442 size_t frameCount = baselineHashes.size(); 375 size_t frameCount = baselineHashes.size();
443 376
444 OwnPtr<GIFImageDecoder> decoder = createDecoder(); 377 OwnPtr<WEBPImageDecoder> decoder = createDecoder();
445 378
446 // Let frame 0 be partially decoded. 379 // Let frame 0 be partially decoded.
447 size_t partialSize = 1; 380 size_t partialSize = 1;
448 do { 381 do {
449 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize); 382 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti alSize);
450 decoder->setData(data.get(), false); 383 decoder->setData(data.get(), false);
451 ++partialSize; 384 ++partialSize;
452 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty); 385 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status() == ImageFrame::FrameEmpty);
453 386
454 // Skip to the last frame and clear. 387 // Skip to the last frame and clear.
455 decoder->setData(fullData.get(), true); 388 decoder->setData(fullData.get(), true);
456 EXPECT_EQ(frameCount, decoder->frameCount()); 389 EXPECT_EQ(frameCount, decoder->frameCount());
457 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1); 390 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1);
458 EXPECT_EQ(baselineHashes[frameCount - 1], hashSkBitmap(lastFrame->getSkBitma p())); 391 EXPECT_EQ(baselineHashes[frameCount - 1], hashSkBitmap(lastFrame->getSkBitma p()));
459 decoder->clearCacheExceptFrame(notFound); 392 decoder->clearCacheExceptFrame(notFound);
460 393
461 // Resume decoding of the first frame. 394 // Resume decoding of the first frame.
462 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); 395 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0);
463 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); 396 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status());
464 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap())); 397 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap()));
465 } 398 }
466 399
467 #endif 400 #endif
401
402 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698