| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "core/platform/FileSystem.h" | 35 #include "core/platform/FileSystem.h" |
| 36 #include "core/platform/SharedBuffer.h" | 36 #include "core/platform/SharedBuffer.h" |
| 37 #include "public/platform/Platform.h" | 37 #include "public/platform/Platform.h" |
| 38 #include "public/platform/WebData.h" | 38 #include "public/platform/WebData.h" |
| 39 #include "public/platform/WebSize.h" | 39 #include "public/platform/WebSize.h" |
| 40 #include "public/platform/WebUnitTestSupport.h" | 40 #include "public/platform/WebUnitTestSupport.h" |
| 41 #include "wtf/OwnPtr.h" | 41 #include "wtf/OwnPtr.h" |
| 42 #include "wtf/PassOwnPtr.h" | 42 #include "wtf/PassOwnPtr.h" |
| 43 #include "wtf/StringHasher.h" | 43 #include "wtf/StringHasher.h" |
| 44 #include "wtf/Vector.h" | 44 #include "wtf/Vector.h" |
| 45 | |
| 46 #include <gtest/gtest.h> | 45 #include <gtest/gtest.h> |
| 47 | 46 |
| 48 using namespace WebCore; | 47 using namespace WebCore; |
| 49 using namespace WebKit; | 48 using namespace WebKit; |
| 50 | 49 |
| 51 namespace { | 50 namespace { |
| 52 | 51 |
| 53 #if !OS(ANDROID) | 52 #if !OS(ANDROID) |
| 54 | 53 |
| 55 static PassRefPtr<SharedBuffer> readFile(const char* fileName) | 54 static PassRefPtr<SharedBuffer> readFile(const char* fileName) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 72 static PassOwnPtr<GIFImageDecoder> createDecoder() | 71 static PassOwnPtr<GIFImageDecoder> createDecoder() |
| 73 { | 72 { |
| 74 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag
eSource::GammaAndColorProfileApplied)); | 73 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag
eSource::GammaAndColorProfileApplied)); |
| 75 } | 74 } |
| 76 | 75 |
| 77 static unsigned hashSkBitmap(const SkBitmap& bitmap) | 76 static unsigned hashSkBitmap(const SkBitmap& bitmap) |
| 78 { | 77 { |
| 79 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); | 78 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); |
| 80 } | 79 } |
| 81 | 80 |
| 81 static void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselin
eHashes) |
| 82 { |
| 83 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 84 decoder->setData(data, true); |
| 85 size_t frameCount = decoder->frameCount(); |
| 86 for (size_t i = 0; i < frameCount; ++i) { |
| 87 ImageFrame* frame = decoder->frameBufferAtIndex(i); |
| 88 baselineHashes->append(hashSkBitmap(frame->getSkBitmap())); |
| 89 } |
| 90 } |
| 91 |
| 82 TEST(GIFImageDecoderTest, decodeTwoFrames) | 92 TEST(GIFImageDecoderTest, decodeTwoFrames) |
| 83 { | 93 { |
| 84 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 94 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 85 | 95 |
| 86 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 96 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); |
| 87 ASSERT_TRUE(data.get()); | 97 ASSERT_TRUE(data.get()); |
| 88 decoder->setData(data.get(), true); | 98 decoder->setData(data.get(), true); |
| 89 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 99 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 90 | 100 |
| 91 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 101 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 92 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 102 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 93 EXPECT_EQ(16, frame->getSkBitmap().width()); | 103 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 94 EXPECT_EQ(16, frame->getSkBitmap().height()); | 104 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 95 | 105 |
| 96 frame = decoder->frameBufferAtIndex(1); | 106 frame = decoder->frameBufferAtIndex(1); |
| 97 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 107 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 98 EXPECT_EQ(16, frame->getSkBitmap().width()); | 108 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 99 EXPECT_EQ(16, frame->getSkBitmap().height()); | 109 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 100 | 110 |
| 101 EXPECT_EQ(2u, decoder->frameCount()); | 111 EXPECT_EQ(2u, decoder->frameCount()); |
| 102 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 112 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 103 } | 113 } |
| 104 | 114 |
| 105 TEST(GIFImageDecoderTest, parseAndDecode) | 115 TEST(GIFImageDecoderTest, parseAndDecode) |
| 106 { | 116 { |
| 107 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 117 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 108 | 118 |
| 109 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 119 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); |
| 110 ASSERT_TRUE(data.get()); | 120 ASSERT_TRUE(data.get()); |
| 111 decoder->setData(data.get(), true); | 121 decoder->setData(data.get(), true); |
| 112 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 122 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 113 | 123 |
| 114 // This call will parse the entire file. | 124 // This call will parse the entire file. |
| 115 EXPECT_EQ(2u, decoder->frameCount()); | 125 EXPECT_EQ(2u, decoder->frameCount()); |
| 116 | 126 |
| 117 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 127 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 118 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 128 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 119 EXPECT_EQ(16, frame->getSkBitmap().width()); | 129 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 120 EXPECT_EQ(16, frame->getSkBitmap().height()); | 130 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 121 | 131 |
| 122 frame = decoder->frameBufferAtIndex(1); | 132 frame = decoder->frameBufferAtIndex(1); |
| 123 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 133 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 124 EXPECT_EQ(16, frame->getSkBitmap().width()); | 134 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 125 EXPECT_EQ(16, frame->getSkBitmap().height()); | 135 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 126 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 136 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 127 } | 137 } |
| 128 | 138 |
| 129 TEST(GIFImageDecoderTest, parseByteByByte) | 139 TEST(GIFImageDecoderTest, parseByteByByte) |
| 130 { | 140 { |
| 131 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 141 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 132 | 142 |
| 133 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 143 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); |
| 134 ASSERT_TRUE(data.get()); | 144 ASSERT_TRUE(data.get()); |
| 135 | 145 |
| 136 size_t frameCount = 0; | 146 size_t frameCount = 0; |
| 137 | 147 |
| 138 // Pass data to decoder byte by byte. | 148 // Pass data to decoder byte by byte. |
| 139 for (unsigned length = 1; length <= data->size(); ++length) { | 149 for (size_t length = 1; length <= data->size(); ++length) { |
| 140 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); | 150 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); |
| 141 decoder->setData(tempData.get(), length == data->size()); | 151 decoder->setData(tempData.get(), length == data->size()); |
| 142 | 152 |
| 143 EXPECT_LE(frameCount, decoder->frameCount()); | 153 EXPECT_LE(frameCount, decoder->frameCount()); |
| 144 frameCount = decoder->frameCount(); | 154 frameCount = decoder->frameCount(); |
| 145 } | 155 } |
| 146 | 156 |
| 147 EXPECT_EQ(2u, decoder->frameCount()); | 157 EXPECT_EQ(2u, decoder->frameCount()); |
| 148 | 158 |
| 149 decoder->frameBufferAtIndex(0); | 159 decoder->frameBufferAtIndex(0); |
| 150 decoder->frameBufferAtIndex(1); | 160 decoder->frameBufferAtIndex(1); |
| 151 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 161 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 152 } | 162 } |
| 153 | 163 |
| 154 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) | 164 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) |
| 155 { | 165 { |
| 156 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 166 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 157 | 167 |
| 158 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated-gif-with-offsets.gif"); | 168 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated-gif-with-offsets.gif"); |
| 159 ASSERT_TRUE(data.get()); | 169 ASSERT_TRUE(data.get()); |
| 160 | 170 |
| 161 size_t frameCount = 0; | 171 size_t frameCount = 0; |
| 162 size_t framesDecoded = 0; | 172 size_t framesDecoded = 0; |
| 163 | 173 |
| 164 // Pass data to decoder byte by byte. | 174 // Pass data to decoder byte by byte. |
| 165 for (unsigned length = 1; length <= data->size(); ++length) { | 175 for (size_t length = 1; length <= data->size(); ++length) { |
| 166 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); | 176 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); |
| 167 decoder->setData(tempData.get(), length == data->size()); | 177 decoder->setData(tempData.get(), length == data->size()); |
| 168 | 178 |
| 169 EXPECT_LE(frameCount, decoder->frameCount()); | 179 EXPECT_LE(frameCount, decoder->frameCount()); |
| 170 frameCount = decoder->frameCount(); | 180 frameCount = decoder->frameCount(); |
| 171 | 181 |
| 172 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); | 182 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); |
| 173 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod
ed < frameCount) | 183 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod
ed < frameCount) |
| 174 ++framesDecoded; | 184 ++framesDecoded; |
| 175 } | 185 } |
| 176 | 186 |
| 177 EXPECT_EQ(5u, decoder->frameCount()); | 187 EXPECT_EQ(5u, decoder->frameCount()); |
| 178 EXPECT_EQ(5u, framesDecoded); | 188 EXPECT_EQ(5u, framesDecoded); |
| 179 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 189 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 180 } | 190 } |
| 181 | 191 |
| 182 TEST(GIFImageDecoderTest, brokenSecondFrame) | 192 TEST(GIFImageDecoderTest, brokenSecondFrame) |
| 183 { | 193 { |
| 184 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 194 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 185 | 195 |
| 186 RefPtr<SharedBuffer> data = readFile("/Source/WebKit/chromium/tests/data/bro
ken.gif"); | 196 RefPtr<SharedBuffer> data = readFile("/Source/WebKit/chromium/tests/data/bro
ken.gif"); |
| 187 ASSERT_TRUE(data.get()); | 197 ASSERT_TRUE(data.get()); |
| 188 decoder->setData(data.get(), true); | 198 decoder->setData(data.get(), true); |
| 189 | 199 |
| 190 // One frame is detected but cannot be decoded. | 200 // One frame is detected but cannot be decoded. |
| 191 EXPECT_EQ(1u, decoder->frameCount()); | 201 EXPECT_EQ(1u, decoder->frameCount()); |
| 192 ImageFrame* frame = decoder->frameBufferAtIndex(1); | 202 ImageFrame* frame = decoder->frameBufferAtIndex(1); |
| 193 EXPECT_FALSE(frame); | 203 EXPECT_FALSE(frame); |
| 194 } | 204 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 if (truncatedHashes[i] != progressiveHashes[i]) { | 247 if (truncatedHashes[i] != progressiveHashes[i]) { |
| 238 match = false; | 248 match = false; |
| 239 break; | 249 break; |
| 240 } | 250 } |
| 241 } | 251 } |
| 242 EXPECT_TRUE(match); | 252 EXPECT_TRUE(match); |
| 243 } | 253 } |
| 244 | 254 |
| 245 TEST(GIFImageDecoderTest, allDataReceivedTruncation) | 255 TEST(GIFImageDecoderTest, allDataReceivedTruncation) |
| 246 { | 256 { |
| 247 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 257 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 248 | 258 |
| 249 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 259 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); |
| 250 ASSERT_TRUE(data.get()); | 260 ASSERT_TRUE(data.get()); |
| 251 | 261 |
| 252 ASSERT_GE(data->size(), 10u); | 262 ASSERT_GE(data->size(), 10u); |
| 253 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); | 263 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); |
| 254 decoder->setData(tempData.get(), true); | 264 decoder->setData(tempData.get(), true); |
| 255 | 265 |
| 256 EXPECT_EQ(2u, decoder->frameCount()); | 266 EXPECT_EQ(2u, decoder->frameCount()); |
| 257 EXPECT_FALSE(decoder->failed()); | 267 EXPECT_FALSE(decoder->failed()); |
| 258 | 268 |
| 259 decoder->frameBufferAtIndex(0); | 269 decoder->frameBufferAtIndex(0); |
| 260 EXPECT_FALSE(decoder->failed()); | 270 EXPECT_FALSE(decoder->failed()); |
| 261 decoder->frameBufferAtIndex(1); | 271 decoder->frameBufferAtIndex(1); |
| 262 EXPECT_TRUE(decoder->failed()); | 272 EXPECT_TRUE(decoder->failed()); |
| 263 } | 273 } |
| 264 | 274 |
| 265 TEST(GIFImageDecoderTest, frameIsComplete) | 275 TEST(GIFImageDecoderTest, frameIsComplete) |
| 266 { | 276 { |
| 267 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 277 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 268 | 278 |
| 269 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 279 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); |
| 270 ASSERT_TRUE(data.get()); | 280 ASSERT_TRUE(data.get()); |
| 271 decoder->setData(data.get(), true); | 281 decoder->setData(data.get(), true); |
| 272 | 282 |
| 273 EXPECT_EQ(2u, decoder->frameCount()); | 283 EXPECT_EQ(2u, decoder->frameCount()); |
| 274 EXPECT_FALSE(decoder->failed()); | 284 EXPECT_FALSE(decoder->failed()); |
| 275 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); | 285 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); |
| 276 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); | 286 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); |
| 277 } | 287 } |
| 278 | 288 |
| 279 TEST(GIFImageDecoderTest, frameIsCompleteLoading) | 289 TEST(GIFImageDecoderTest, frameIsCompleteLoading) |
| 280 { | 290 { |
| 281 OwnPtr<GIFImageDecoder> decoder(createDecoder()); | 291 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 282 | 292 |
| 283 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 293 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); |
| 284 ASSERT_TRUE(data.get()); | 294 ASSERT_TRUE(data.get()); |
| 285 | 295 |
| 286 ASSERT_GE(data->size(), 10u); | 296 ASSERT_GE(data->size(), 10u); |
| 287 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); | 297 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); |
| 288 decoder->setData(tempData.get(), false); | 298 decoder->setData(tempData.get(), false); |
| 289 | 299 |
| 290 EXPECT_EQ(2u, decoder->frameCount()); | 300 EXPECT_EQ(2u, decoder->frameCount()); |
| 291 EXPECT_FALSE(decoder->failed()); | 301 EXPECT_FALSE(decoder->failed()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 313 | 323 |
| 314 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); | 324 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); |
| 315 testDecoder->setData(testData.get(), true); | 325 testDecoder->setData(testData.get(), true); |
| 316 EXPECT_EQ(1u, testDecoder->frameCount()); | 326 EXPECT_EQ(1u, testDecoder->frameCount()); |
| 317 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); | 327 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); |
| 318 ASSERT(testFrame); | 328 ASSERT(testFrame); |
| 319 | 329 |
| 320 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram
e->getSkBitmap())); | 330 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram
e->getSkBitmap())); |
| 321 } | 331 } |
| 322 | 332 |
| 333 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) |
| 334 { |
| 335 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 336 |
| 337 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/animated-10color.gif"); |
| 338 ASSERT_TRUE(fullData.get()); |
| 339 |
| 340 // Give it data that is enough to parse but not decode in order to check the
status |
| 341 // of requiredPreviousFrameIndex before decoding. |
| 342 size_t partialSize = 1; |
| 343 do { |
| 344 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); |
| 345 decoder->setData(data.get(), false); |
| 346 ++partialSize; |
| 347 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status()
== ImageFrame::FrameEmpty); |
| 348 |
| 349 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameInd
ex()); |
| 350 unsigned frameCount = decoder->frameCount(); |
| 351 for (size_t i = 1; i < frameCount; ++i) |
| 352 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn
dex()); |
| 353 |
| 354 decoder->setData(fullData.get(), true); |
| 355 for (size_t i = 0; i < frameCount; ++i) |
| 356 EXPECT_EQ(notFound, decoder->frameBufferAtIndex(i)->requiredPreviousFram
eIndex()); |
| 357 } |
| 358 |
| 359 void testRandomFrameDecode(const char* gifFile) |
| 360 { |
| 361 SCOPED_TRACE(gifFile); |
| 362 |
| 363 RefPtr<SharedBuffer> fullData = readFile(gifFile); |
| 364 ASSERT_TRUE(fullData.get()); |
| 365 Vector<unsigned> baselineHashes; |
| 366 createDecodingBaseline(fullData.get(), &baselineHashes); |
| 367 size_t frameCount = baselineHashes.size(); |
| 368 |
| 369 // Random decoding should get the same results as sequential decoding. |
| 370 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 371 decoder->setData(fullData.get(), true); |
| 372 const size_t skippingStep = 5; |
| 373 for (size_t i = 0; i < skippingStep; ++i) { |
| 374 for (size_t j = i; j < frameCount; j += skippingStep) { |
| 375 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); |
| 376 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 377 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())); |
| 378 } |
| 379 } |
| 380 |
| 381 // Decoding in reverse order. |
| 382 decoder = createDecoder(); |
| 383 decoder->setData(fullData.get(), true); |
| 384 for (size_t i = frameCount; i; --i) { |
| 385 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); |
| 386 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); |
| 387 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap())); |
| 388 } |
| 389 } |
| 390 |
| 391 TEST(GIFImageDecoderTest, randomFrameDecode) |
| 392 { |
| 393 // Single frame image. |
| 394 testRandomFrameDecode("/Source/WebKit/chromium/tests/data/radient.gif"); |
| 395 // Multiple frame image. |
| 396 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-gif-with-
offsets.gif"); |
| 397 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-10color.g
if"); |
| 398 } |
| 399 |
| 400 void testRandomDecodeAfterClearFrameBufferCache(const char* gifFile) |
| 401 { |
| 402 SCOPED_TRACE(gifFile); |
| 403 |
| 404 RefPtr<SharedBuffer> data = readFile(gifFile); |
| 405 ASSERT_TRUE(data.get()); |
| 406 Vector<unsigned> baselineHashes; |
| 407 createDecodingBaseline(data.get(), &baselineHashes); |
| 408 size_t frameCount = baselineHashes.size(); |
| 409 |
| 410 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 411 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce
ptFrame) { |
| 412 decoder->clearCacheExceptFrame(clearExceptFrame); |
| 413 const size_t skippingStep = 5; |
| 414 for (size_t i = 0; i < skippingStep; ++i) { |
| 415 for (size_t j = 0; j < frameCount; j += skippingStep) { |
| 416 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" <<
j); |
| 417 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 418 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap()))
; |
| 419 } |
| 420 } |
| 421 } |
| 422 } |
| 423 |
| 424 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) |
| 425 { |
| 426 // Single frame image. |
| 427 testRandomFrameDecode("/Source/WebKit/chromium/tests/data/radient.gif"); |
| 428 // Multiple frame image. |
| 429 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-gif-with-
offsets.gif"); |
| 430 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-10color.g
if"); |
| 431 } |
| 432 |
| 433 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) |
| 434 { |
| 435 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/animated-10color.gif"); |
| 436 ASSERT_TRUE(fullData.get()); |
| 437 Vector<unsigned> baselineHashes; |
| 438 createDecodingBaseline(fullData.get(), &baselineHashes); |
| 439 size_t frameCount = baselineHashes.size(); |
| 440 |
| 441 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 442 |
| 443 // Let frame 0 be partially decoded. |
| 444 size_t partialSize = 1; |
| 445 do { |
| 446 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); |
| 447 decoder->setData(data.get(), false); |
| 448 ++partialSize; |
| 449 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status()
== ImageFrame::FrameEmpty); |
| 450 |
| 451 // Skip to the last frame and clear. |
| 452 decoder->setData(fullData.get(), true); |
| 453 EXPECT_EQ(frameCount, decoder->frameCount()); |
| 454 ImageFrame* lastFrame = decoder->frameBufferAtIndex(frameCount - 1); |
| 455 EXPECT_EQ(baselineHashes[frameCount - 1], hashSkBitmap(lastFrame->getSkBitma
p())); |
| 456 decoder->clearCacheExceptFrame(notFound); |
| 457 |
| 458 // Resume decoding of the first frame. |
| 459 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); |
| 460 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); |
| 461 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap())); |
| 462 } |
| 463 |
| 323 #endif | 464 #endif |
| 324 | 465 |
| 325 } // namespace | 466 } // namespace |
| OLD | NEW |