| 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 29 matching lines...) Expand all Loading... |
| 40 #include "wtf/OwnPtr.h" | 40 #include "wtf/OwnPtr.h" |
| 41 #include "wtf/PassOwnPtr.h" | 41 #include "wtf/PassOwnPtr.h" |
| 42 #include "wtf/StringHasher.h" | 42 #include "wtf/StringHasher.h" |
| 43 #include "wtf/Vector.h" | 43 #include "wtf/Vector.h" |
| 44 #include <gtest/gtest.h> | 44 #include <gtest/gtest.h> |
| 45 | 45 |
| 46 using namespace blink; | 46 using namespace blink; |
| 47 | 47 |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 PassRefPtr<SharedBuffer> readFile(const char* fileName) | 50 const char decodersTestingDir[] = "Source/platform/image-decoders/testing"; |
| 51 const char layoutTestResourcesDir[] = "LayoutTests/fast/images/resources"; |
| 52 const char webTestsDataDir[] = "Source/web/tests/data"; |
| 53 |
| 54 PassRefPtr<SharedBuffer> readFile(const char* dir, const char* fileName) |
| 51 { | 55 { |
| 52 String filePath = Platform::current()->unitTestSupport()->webKitRootDir(); | 56 String filePath = Platform::current()->unitTestSupport()->webKitRootDir(); |
| 57 filePath.append("/"); |
| 58 filePath.append(dir); |
| 59 filePath.append("/"); |
| 53 filePath.append(fileName); | 60 filePath.append(fileName); |
| 54 | 61 |
| 55 return Platform::current()->unitTestSupport()->readFromFile(filePath); | 62 return Platform::current()->unitTestSupport()->readFromFile(filePath); |
| 56 } | 63 } |
| 57 | 64 |
| 58 PassOwnPtr<GIFImageDecoder> createDecoder() | 65 PassOwnPtr<GIFImageDecoder> createDecoder() |
| 59 { | 66 { |
| 60 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag
eSource::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit)); | 67 return adoptPtr(new GIFImageDecoder(ImageSource::AlphaNotPremultiplied, Imag
eSource::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit)); |
| 61 } | 68 } |
| 62 | 69 |
| 63 unsigned hashSkBitmap(const SkBitmap& bitmap) | 70 unsigned hashSkBitmap(const SkBitmap& bitmap) |
| 64 { | 71 { |
| 65 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); | 72 return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize()); |
| 66 } | 73 } |
| 67 | 74 |
| 68 void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselineHashes
) | 75 void createDecodingBaseline(SharedBuffer* data, Vector<unsigned>* baselineHashes
) |
| 69 { | 76 { |
| 70 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 77 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 71 decoder->setData(data, true); | 78 decoder->setData(data, true); |
| 72 size_t frameCount = decoder->frameCount(); | 79 size_t frameCount = decoder->frameCount(); |
| 73 for (size_t i = 0; i < frameCount; ++i) { | 80 for (size_t i = 0; i < frameCount; ++i) { |
| 74 ImageFrame* frame = decoder->frameBufferAtIndex(i); | 81 ImageFrame* frame = decoder->frameBufferAtIndex(i); |
| 75 baselineHashes->append(hashSkBitmap(frame->getSkBitmap())); | 82 baselineHashes->append(hashSkBitmap(frame->getSkBitmap())); |
| 76 } | 83 } |
| 77 } | 84 } |
| 78 | 85 |
| 79 void testRandomFrameDecode(const char* gifFile) | 86 void testRandomFrameDecode(const char* dir, const char* gifFile) |
| 80 { | 87 { |
| 81 SCOPED_TRACE(gifFile); | 88 SCOPED_TRACE(gifFile); |
| 82 | 89 |
| 83 RefPtr<SharedBuffer> fullData = readFile(gifFile); | 90 RefPtr<SharedBuffer> fullData = readFile(dir, gifFile); |
| 84 ASSERT_TRUE(fullData.get()); | 91 ASSERT_TRUE(fullData.get()); |
| 85 Vector<unsigned> baselineHashes; | 92 Vector<unsigned> baselineHashes; |
| 86 createDecodingBaseline(fullData.get(), &baselineHashes); | 93 createDecodingBaseline(fullData.get(), &baselineHashes); |
| 87 size_t frameCount = baselineHashes.size(); | 94 size_t frameCount = baselineHashes.size(); |
| 88 | 95 |
| 89 // Random decoding should get the same results as sequential decoding. | 96 // Random decoding should get the same results as sequential decoding. |
| 90 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 97 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 91 decoder->setData(fullData.get(), true); | 98 decoder->setData(fullData.get(), true); |
| 92 const size_t skippingStep = 5; | 99 const size_t skippingStep = 5; |
| 93 for (size_t i = 0; i < skippingStep; ++i) { | 100 for (size_t i = 0; i < skippingStep; ++i) { |
| 94 for (size_t j = i; j < frameCount; j += skippingStep) { | 101 for (size_t j = i; j < frameCount; j += skippingStep) { |
| 95 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); | 102 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); |
| 96 ImageFrame* frame = decoder->frameBufferAtIndex(j); | 103 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 97 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())); | 104 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap())); |
| 98 } | 105 } |
| 99 } | 106 } |
| 100 | 107 |
| 101 // Decoding in reverse order. | 108 // Decoding in reverse order. |
| 102 decoder = createDecoder(); | 109 decoder = createDecoder(); |
| 103 decoder->setData(fullData.get(), true); | 110 decoder->setData(fullData.get(), true); |
| 104 for (size_t i = frameCount; i; --i) { | 111 for (size_t i = frameCount; i; --i) { |
| 105 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); | 112 SCOPED_TRACE(testing::Message() << "Reverse i:" << i); |
| 106 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); | 113 ImageFrame* frame = decoder->frameBufferAtIndex(i - 1); |
| 107 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap())); | 114 EXPECT_EQ(baselineHashes[i - 1], hashSkBitmap(frame->getSkBitmap())); |
| 108 } | 115 } |
| 109 } | 116 } |
| 110 | 117 |
| 111 void testRandomDecodeAfterClearFrameBufferCache(const char* gifFile) | 118 void testRandomDecodeAfterClearFrameBufferCache(const char* dir, const char* gif
File) |
| 112 { | 119 { |
| 113 SCOPED_TRACE(gifFile); | 120 SCOPED_TRACE(gifFile); |
| 114 | 121 |
| 115 RefPtr<SharedBuffer> data = readFile(gifFile); | 122 RefPtr<SharedBuffer> data = readFile(dir, gifFile); |
| 116 ASSERT_TRUE(data.get()); | 123 ASSERT_TRUE(data.get()); |
| 117 Vector<unsigned> baselineHashes; | 124 Vector<unsigned> baselineHashes; |
| 118 createDecodingBaseline(data.get(), &baselineHashes); | 125 createDecodingBaseline(data.get(), &baselineHashes); |
| 119 size_t frameCount = baselineHashes.size(); | 126 size_t frameCount = baselineHashes.size(); |
| 120 | 127 |
| 121 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 128 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 122 decoder->setData(data.get(), true); | 129 decoder->setData(data.get(), true); |
| 123 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce
ptFrame) { | 130 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce
ptFrame) { |
| 124 decoder->clearCacheExceptFrame(clearExceptFrame); | 131 decoder->clearCacheExceptFrame(clearExceptFrame); |
| 125 const size_t skippingStep = 5; | 132 const size_t skippingStep = 5; |
| 126 for (size_t i = 0; i < skippingStep; ++i) { | 133 for (size_t i = 0; i < skippingStep; ++i) { |
| 127 for (size_t j = 0; j < frameCount; j += skippingStep) { | 134 for (size_t j = 0; j < frameCount; j += skippingStep) { |
| 128 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" <<
j); | 135 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" <<
j); |
| 129 ImageFrame* frame = decoder->frameBufferAtIndex(j); | 136 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 130 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap()))
; | 137 EXPECT_EQ(baselineHashes[j], hashSkBitmap(frame->getSkBitmap()))
; |
| 131 } | 138 } |
| 132 } | 139 } |
| 133 } | 140 } |
| 134 } | 141 } |
| 135 | 142 |
| 136 } // namespace | 143 } // namespace |
| 137 | 144 |
| 138 TEST(GIFImageDecoderTest, decodeTwoFrames) | 145 TEST(GIFImageDecoderTest, decodeTwoFrames) |
| 139 { | 146 { |
| 140 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 147 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 141 | 148 |
| 142 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 149 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif")
; |
| 143 ASSERT_TRUE(data.get()); | 150 ASSERT_TRUE(data.get()); |
| 144 decoder->setData(data.get(), true); | 151 decoder->setData(data.get(), true); |
| 145 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 152 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 146 | 153 |
| 147 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 154 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 148 uint32_t generationID0 = frame->getSkBitmap().getGenerationID(); | 155 uint32_t generationID0 = frame->getSkBitmap().getGenerationID(); |
| 149 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 156 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 150 EXPECT_EQ(16, frame->getSkBitmap().width()); | 157 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 151 EXPECT_EQ(16, frame->getSkBitmap().height()); | 158 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 152 | 159 |
| 153 frame = decoder->frameBufferAtIndex(1); | 160 frame = decoder->frameBufferAtIndex(1); |
| 154 uint32_t generationID1 = frame->getSkBitmap().getGenerationID(); | 161 uint32_t generationID1 = frame->getSkBitmap().getGenerationID(); |
| 155 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 162 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 156 EXPECT_EQ(16, frame->getSkBitmap().width()); | 163 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 157 EXPECT_EQ(16, frame->getSkBitmap().height()); | 164 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 158 EXPECT_TRUE(generationID0 != generationID1); | 165 EXPECT_TRUE(generationID0 != generationID1); |
| 159 | 166 |
| 160 EXPECT_EQ(2u, decoder->frameCount()); | 167 EXPECT_EQ(2u, decoder->frameCount()); |
| 161 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 168 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 162 } | 169 } |
| 163 | 170 |
| 164 TEST(GIFImageDecoderTest, parseAndDecode) | 171 TEST(GIFImageDecoderTest, parseAndDecode) |
| 165 { | 172 { |
| 166 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 173 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 167 | 174 |
| 168 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 175 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif")
; |
| 169 ASSERT_TRUE(data.get()); | 176 ASSERT_TRUE(data.get()); |
| 170 decoder->setData(data.get(), true); | 177 decoder->setData(data.get(), true); |
| 171 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 178 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 172 | 179 |
| 173 // This call will parse the entire file. | 180 // This call will parse the entire file. |
| 174 EXPECT_EQ(2u, decoder->frameCount()); | 181 EXPECT_EQ(2u, decoder->frameCount()); |
| 175 | 182 |
| 176 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 183 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 177 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 184 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 178 EXPECT_EQ(16, frame->getSkBitmap().width()); | 185 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 179 EXPECT_EQ(16, frame->getSkBitmap().height()); | 186 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 180 | 187 |
| 181 frame = decoder->frameBufferAtIndex(1); | 188 frame = decoder->frameBufferAtIndex(1); |
| 182 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); | 189 EXPECT_EQ(ImageFrame::FrameComplete, frame->status()); |
| 183 EXPECT_EQ(16, frame->getSkBitmap().width()); | 190 EXPECT_EQ(16, frame->getSkBitmap().width()); |
| 184 EXPECT_EQ(16, frame->getSkBitmap().height()); | 191 EXPECT_EQ(16, frame->getSkBitmap().height()); |
| 185 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 192 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 186 } | 193 } |
| 187 | 194 |
| 188 TEST(GIFImageDecoderTest, parseByteByByte) | 195 TEST(GIFImageDecoderTest, parseByteByByte) |
| 189 { | 196 { |
| 190 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 197 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 191 | 198 |
| 192 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 199 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif")
; |
| 193 ASSERT_TRUE(data.get()); | 200 ASSERT_TRUE(data.get()); |
| 194 | 201 |
| 195 size_t frameCount = 0; | 202 size_t frameCount = 0; |
| 196 | 203 |
| 197 // Pass data to decoder byte by byte. | 204 // Pass data to decoder byte by byte. |
| 198 for (size_t length = 1; length <= data->size(); ++length) { | 205 for (size_t length = 1; length <= data->size(); ++length) { |
| 199 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); | 206 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); |
| 200 decoder->setData(tempData.get(), length == data->size()); | 207 decoder->setData(tempData.get(), length == data->size()); |
| 201 | 208 |
| 202 EXPECT_LE(frameCount, decoder->frameCount()); | 209 EXPECT_LE(frameCount, decoder->frameCount()); |
| 203 frameCount = decoder->frameCount(); | 210 frameCount = decoder->frameCount(); |
| 204 } | 211 } |
| 205 | 212 |
| 206 EXPECT_EQ(2u, decoder->frameCount()); | 213 EXPECT_EQ(2u, decoder->frameCount()); |
| 207 | 214 |
| 208 decoder->frameBufferAtIndex(0); | 215 decoder->frameBufferAtIndex(0); |
| 209 decoder->frameBufferAtIndex(1); | 216 decoder->frameBufferAtIndex(1); |
| 210 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 217 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 211 } | 218 } |
| 212 | 219 |
| 213 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) | 220 TEST(GIFImageDecoderTest, parseAndDecodeByteByByte) |
| 214 { | 221 { |
| 215 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 222 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 216 | 223 |
| 217 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated-gif-with-offsets.gif"); | 224 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated-gif-w
ith-offsets.gif"); |
| 218 ASSERT_TRUE(data.get()); | 225 ASSERT_TRUE(data.get()); |
| 219 | 226 |
| 220 size_t frameCount = 0; | 227 size_t frameCount = 0; |
| 221 size_t framesDecoded = 0; | 228 size_t framesDecoded = 0; |
| 222 | 229 |
| 223 // Pass data to decoder byte by byte. | 230 // Pass data to decoder byte by byte. |
| 224 for (size_t length = 1; length <= data->size(); ++length) { | 231 for (size_t length = 1; length <= data->size(); ++length) { |
| 225 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); | 232 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); |
| 226 decoder->setData(tempData.get(), length == data->size()); | 233 decoder->setData(tempData.get(), length == data->size()); |
| 227 | 234 |
| 228 EXPECT_LE(frameCount, decoder->frameCount()); | 235 EXPECT_LE(frameCount, decoder->frameCount()); |
| 229 frameCount = decoder->frameCount(); | 236 frameCount = decoder->frameCount(); |
| 230 | 237 |
| 231 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); | 238 ImageFrame* frame = decoder->frameBufferAtIndex(frameCount - 1); |
| 232 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod
ed < frameCount) | 239 if (frame && frame->status() == ImageFrame::FrameComplete && framesDecod
ed < frameCount) |
| 233 ++framesDecoded; | 240 ++framesDecoded; |
| 234 } | 241 } |
| 235 | 242 |
| 236 EXPECT_EQ(5u, decoder->frameCount()); | 243 EXPECT_EQ(5u, decoder->frameCount()); |
| 237 EXPECT_EQ(5u, framesDecoded); | 244 EXPECT_EQ(5u, framesDecoded); |
| 238 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 245 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 239 } | 246 } |
| 240 | 247 |
| 241 TEST(GIFImageDecoderTest, brokenSecondFrame) | 248 TEST(GIFImageDecoderTest, brokenSecondFrame) |
| 242 { | 249 { |
| 243 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 250 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 244 | 251 |
| 245 RefPtr<SharedBuffer> data = readFile("/Source/web/tests/data/broken.gif"); | 252 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "broken.gif"); |
| 246 ASSERT_TRUE(data.get()); | 253 ASSERT_TRUE(data.get()); |
| 247 decoder->setData(data.get(), true); | 254 decoder->setData(data.get(), true); |
| 248 | 255 |
| 249 // One frame is detected but cannot be decoded. | 256 // One frame is detected but cannot be decoded. |
| 250 EXPECT_EQ(1u, decoder->frameCount()); | 257 EXPECT_EQ(1u, decoder->frameCount()); |
| 251 ImageFrame* frame = decoder->frameBufferAtIndex(1); | 258 ImageFrame* frame = decoder->frameBufferAtIndex(1); |
| 252 EXPECT_FALSE(frame); | 259 EXPECT_FALSE(frame); |
| 253 } | 260 } |
| 254 | 261 |
| 255 TEST(GIFImageDecoderTest, progressiveDecode) | 262 TEST(GIFImageDecoderTest, progressiveDecode) |
| 256 { | 263 { |
| 257 RefPtr<SharedBuffer> fullData = readFile("/Source/web/tests/data/radient.gif
"); | 264 RefPtr<SharedBuffer> fullData = readFile(webTestsDataDir, "radient.gif"); |
| 258 ASSERT_TRUE(fullData.get()); | 265 ASSERT_TRUE(fullData.get()); |
| 259 const size_t fullLength = fullData->size(); | 266 const size_t fullLength = fullData->size(); |
| 260 | 267 |
| 261 OwnPtr<GIFImageDecoder> decoder; | 268 OwnPtr<GIFImageDecoder> decoder; |
| 262 ImageFrame* frame; | 269 ImageFrame* frame; |
| 263 | 270 |
| 264 Vector<unsigned> truncatedHashes; | 271 Vector<unsigned> truncatedHashes; |
| 265 Vector<unsigned> progressiveHashes; | 272 Vector<unsigned> progressiveHashes; |
| 266 | 273 |
| 267 // Compute hashes when the file is truncated. | 274 // Compute hashes when the file is truncated. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 break; | 307 break; |
| 301 } | 308 } |
| 302 } | 309 } |
| 303 EXPECT_TRUE(match); | 310 EXPECT_TRUE(match); |
| 304 } | 311 } |
| 305 | 312 |
| 306 TEST(GIFImageDecoderTest, allDataReceivedTruncation) | 313 TEST(GIFImageDecoderTest, allDataReceivedTruncation) |
| 307 { | 314 { |
| 308 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 315 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 309 | 316 |
| 310 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 317 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif")
; |
| 311 ASSERT_TRUE(data.get()); | 318 ASSERT_TRUE(data.get()); |
| 312 | 319 |
| 313 ASSERT_GE(data->size(), 10u); | 320 ASSERT_GE(data->size(), 10u); |
| 314 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); | 321 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); |
| 315 decoder->setData(tempData.get(), true); | 322 decoder->setData(tempData.get(), true); |
| 316 | 323 |
| 317 EXPECT_EQ(2u, decoder->frameCount()); | 324 EXPECT_EQ(2u, decoder->frameCount()); |
| 318 EXPECT_FALSE(decoder->failed()); | 325 EXPECT_FALSE(decoder->failed()); |
| 319 | 326 |
| 320 decoder->frameBufferAtIndex(0); | 327 decoder->frameBufferAtIndex(0); |
| 321 EXPECT_FALSE(decoder->failed()); | 328 EXPECT_FALSE(decoder->failed()); |
| 322 decoder->frameBufferAtIndex(1); | 329 decoder->frameBufferAtIndex(1); |
| 323 EXPECT_TRUE(decoder->failed()); | 330 EXPECT_TRUE(decoder->failed()); |
| 324 } | 331 } |
| 325 | 332 |
| 326 TEST(GIFImageDecoderTest, frameIsComplete) | 333 TEST(GIFImageDecoderTest, frameIsComplete) |
| 327 { | 334 { |
| 328 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 335 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 329 | 336 |
| 330 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 337 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif")
; |
| 331 ASSERT_TRUE(data.get()); | 338 ASSERT_TRUE(data.get()); |
| 332 decoder->setData(data.get(), true); | 339 decoder->setData(data.get(), true); |
| 333 | 340 |
| 334 EXPECT_EQ(2u, decoder->frameCount()); | 341 EXPECT_EQ(2u, decoder->frameCount()); |
| 335 EXPECT_FALSE(decoder->failed()); | 342 EXPECT_FALSE(decoder->failed()); |
| 336 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); | 343 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); |
| 337 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); | 344 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); |
| 338 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 345 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 339 } | 346 } |
| 340 | 347 |
| 341 TEST(GIFImageDecoderTest, frameIsCompleteLoading) | 348 TEST(GIFImageDecoderTest, frameIsCompleteLoading) |
| 342 { | 349 { |
| 343 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 350 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 344 | 351 |
| 345 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/ani
mated.gif"); | 352 RefPtr<SharedBuffer> data = readFile(layoutTestResourcesDir, "animated.gif")
; |
| 346 ASSERT_TRUE(data.get()); | 353 ASSERT_TRUE(data.get()); |
| 347 | 354 |
| 348 ASSERT_GE(data->size(), 10u); | 355 ASSERT_GE(data->size(), 10u); |
| 349 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); | 356 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); |
| 350 decoder->setData(tempData.get(), false); | 357 decoder->setData(tempData.get(), false); |
| 351 | 358 |
| 352 EXPECT_EQ(2u, decoder->frameCount()); | 359 EXPECT_EQ(2u, decoder->frameCount()); |
| 353 EXPECT_FALSE(decoder->failed()); | 360 EXPECT_FALSE(decoder->failed()); |
| 354 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); | 361 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); |
| 355 EXPECT_FALSE(decoder->frameIsCompleteAtIndex(1)); | 362 EXPECT_FALSE(decoder->frameIsCompleteAtIndex(1)); |
| 356 | 363 |
| 357 decoder->setData(data.get(), true); | 364 decoder->setData(data.get(), true); |
| 358 EXPECT_EQ(2u, decoder->frameCount()); | 365 EXPECT_EQ(2u, decoder->frameCount()); |
| 359 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); | 366 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); |
| 360 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); | 367 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); |
| 361 } | 368 } |
| 362 | 369 |
| 363 TEST(GIFImageDecoderTest, badTerminator) | 370 TEST(GIFImageDecoderTest, badTerminator) |
| 364 { | 371 { |
| 365 RefPtr<SharedBuffer> referenceData = readFile("/Source/web/tests/data/radien
t.gif"); | 372 RefPtr<SharedBuffer> referenceData = readFile(webTestsDataDir, "radient.gif"
); |
| 366 RefPtr<SharedBuffer> testData = readFile("/Source/web/tests/data/radient-bad
-terminator.gif"); | 373 RefPtr<SharedBuffer> testData = readFile(webTestsDataDir, "radient-bad-termi
nator.gif"); |
| 367 ASSERT_TRUE(referenceData.get()); | 374 ASSERT_TRUE(referenceData.get()); |
| 368 ASSERT_TRUE(testData.get()); | 375 ASSERT_TRUE(testData.get()); |
| 369 | 376 |
| 370 OwnPtr<GIFImageDecoder> referenceDecoder(createDecoder()); | 377 OwnPtr<GIFImageDecoder> referenceDecoder(createDecoder()); |
| 371 referenceDecoder->setData(referenceData.get(), true); | 378 referenceDecoder->setData(referenceData.get(), true); |
| 372 EXPECT_EQ(1u, referenceDecoder->frameCount()); | 379 EXPECT_EQ(1u, referenceDecoder->frameCount()); |
| 373 ImageFrame* referenceFrame = referenceDecoder->frameBufferAtIndex(0); | 380 ImageFrame* referenceFrame = referenceDecoder->frameBufferAtIndex(0); |
| 374 ASSERT(referenceFrame); | 381 ASSERT(referenceFrame); |
| 375 | 382 |
| 376 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); | 383 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); |
| 377 testDecoder->setData(testData.get(), true); | 384 testDecoder->setData(testData.get(), true); |
| 378 EXPECT_EQ(1u, testDecoder->frameCount()); | 385 EXPECT_EQ(1u, testDecoder->frameCount()); |
| 379 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); | 386 ImageFrame* testFrame = testDecoder->frameBufferAtIndex(0); |
| 380 ASSERT(testFrame); | 387 ASSERT(testFrame); |
| 381 | 388 |
| 382 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram
e->getSkBitmap())); | 389 EXPECT_EQ(hashSkBitmap(referenceFrame->getSkBitmap()), hashSkBitmap(testFram
e->getSkBitmap())); |
| 383 } | 390 } |
| 384 | 391 |
| 385 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) | 392 TEST(GIFImageDecoderTest, updateRequiredPreviousFrameAfterFirstDecode) |
| 386 { | 393 { |
| 387 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 394 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 388 | 395 |
| 389 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/animated-10color.gif"); | 396 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1
0color.gif"); |
| 390 ASSERT_TRUE(fullData.get()); | 397 ASSERT_TRUE(fullData.get()); |
| 391 | 398 |
| 392 // Give it data that is enough to parse but not decode in order to check the
status | 399 // Give it data that is enough to parse but not decode in order to check the
status |
| 393 // of requiredPreviousFrameIndex before decoding. | 400 // of requiredPreviousFrameIndex before decoding. |
| 394 size_t partialSize = 1; | 401 size_t partialSize = 1; |
| 395 do { | 402 do { |
| 396 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); | 403 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); |
| 397 decoder->setData(data.get(), false); | 404 decoder->setData(data.get(), false); |
| 398 ++partialSize; | 405 ++partialSize; |
| 399 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status()
== ImageFrame::FrameEmpty); | 406 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->status()
== ImageFrame::FrameEmpty); |
| 400 | 407 |
| 401 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIn
dex()); | 408 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(0)->requiredPreviousFrameIn
dex()); |
| 402 unsigned frameCount = decoder->frameCount(); | 409 unsigned frameCount = decoder->frameCount(); |
| 403 for (size_t i = 1; i < frameCount; ++i) | 410 for (size_t i = 1; i < frameCount; ++i) |
| 404 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn
dex()); | 411 EXPECT_EQ(i - 1, decoder->frameBufferAtIndex(i)->requiredPreviousFrameIn
dex()); |
| 405 | 412 |
| 406 decoder->setData(fullData.get(), true); | 413 decoder->setData(fullData.get(), true); |
| 407 for (size_t i = 0; i < frameCount; ++i) | 414 for (size_t i = 0; i < frameCount; ++i) |
| 408 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i)->requiredPreviousFra
meIndex()); | 415 EXPECT_EQ(kNotFound, decoder->frameBufferAtIndex(i)->requiredPreviousFra
meIndex()); |
| 409 } | 416 } |
| 410 | 417 |
| 411 TEST(GIFImageDecoderTest, randomFrameDecode) | 418 TEST(GIFImageDecoderTest, randomFrameDecode) |
| 412 { | 419 { |
| 413 // Single frame image. | 420 // Single frame image. |
| 414 testRandomFrameDecode("/Source/web/tests/data/radient.gif"); | 421 testRandomFrameDecode(webTestsDataDir, "radient.gif"); |
| 415 // Multiple frame images. | 422 // Multiple frame images. |
| 416 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-gif-with-
offsets.gif"); | 423 testRandomFrameDecode(layoutTestResourcesDir, "animated-gif-with-offsets.gif
"); |
| 417 testRandomFrameDecode("/LayoutTests/fast/images/resources/animated-10color.g
if"); | 424 testRandomFrameDecode(layoutTestResourcesDir, "animated-10color.gif"); |
| 418 } | 425 } |
| 419 | 426 |
| 420 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) | 427 TEST(GIFImageDecoderTest, randomDecodeAfterClearFrameBufferCache) |
| 421 { | 428 { |
| 422 // Single frame image. | 429 // Single frame image. |
| 423 testRandomDecodeAfterClearFrameBufferCache("/Source/web/tests/data/radient.g
if"); | 430 testRandomDecodeAfterClearFrameBufferCache(webTestsDataDir, "radient.gif"); |
| 424 // Multiple frame images. | 431 // Multiple frame images. |
| 425 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc
es/animated-gif-with-offsets.gif"); | 432 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated
-gif-with-offsets.gif"); |
| 426 testRandomDecodeAfterClearFrameBufferCache("/LayoutTests/fast/images/resourc
es/animated-10color.gif"); | 433 testRandomDecodeAfterClearFrameBufferCache(layoutTestResourcesDir, "animated
-10color.gif"); |
| 427 } | 434 } |
| 428 | 435 |
| 429 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) | 436 TEST(GIFImageDecoderTest, resumePartialDecodeAfterClearFrameBufferCache) |
| 430 { | 437 { |
| 431 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/animated-10color.gif"); | 438 RefPtr<SharedBuffer> fullData = readFile(layoutTestResourcesDir, "animated-1
0color.gif"); |
| 432 ASSERT_TRUE(fullData.get()); | 439 ASSERT_TRUE(fullData.get()); |
| 433 Vector<unsigned> baselineHashes; | 440 Vector<unsigned> baselineHashes; |
| 434 createDecodingBaseline(fullData.get(), &baselineHashes); | 441 createDecodingBaseline(fullData.get(), &baselineHashes); |
| 435 size_t frameCount = baselineHashes.size(); | 442 size_t frameCount = baselineHashes.size(); |
| 436 | 443 |
| 437 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 444 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 438 | 445 |
| 439 // Let frame 0 be partially decoded. | 446 // Let frame 0 be partially decoded. |
| 440 size_t partialSize = 1; | 447 size_t partialSize = 1; |
| 441 do { | 448 do { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 454 // Resume decoding of the first frame. | 461 // Resume decoding of the first frame. |
| 455 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); | 462 ImageFrame* firstFrame = decoder->frameBufferAtIndex(0); |
| 456 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); | 463 EXPECT_EQ(ImageFrame::FrameComplete, firstFrame->status()); |
| 457 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap())); | 464 EXPECT_EQ(baselineHashes[0], hashSkBitmap(firstFrame->getSkBitmap())); |
| 458 } | 465 } |
| 459 | 466 |
| 460 // The first LZW codes in the image are invalid values that try to create a loop | 467 // The first LZW codes in the image are invalid values that try to create a loop |
| 461 // in the dictionary. Decoding should fail, but not infinitely loop or corrupt m
emory. | 468 // in the dictionary. Decoding should fail, but not infinitely loop or corrupt m
emory. |
| 462 TEST(GIFImageDecoderTest, badInitialCode) | 469 TEST(GIFImageDecoderTest, badInitialCode) |
| 463 { | 470 { |
| 464 RefPtr<SharedBuffer> testData = readFile("/Source/platform/image-decoders/te
sting/bad-initial-code.gif"); | 471 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-initial-co
de.gif"); |
| 465 ASSERT_TRUE(testData.get()); | 472 ASSERT_TRUE(testData.get()); |
| 466 | 473 |
| 467 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); | 474 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); |
| 468 testDecoder->setData(testData.get(), true); | 475 testDecoder->setData(testData.get(), true); |
| 469 EXPECT_EQ(1u, testDecoder->frameCount()); | 476 EXPECT_EQ(1u, testDecoder->frameCount()); |
| 470 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); | 477 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); |
| 471 EXPECT_TRUE(testDecoder->failed()); | 478 EXPECT_TRUE(testDecoder->failed()); |
| 472 } | 479 } |
| 473 | 480 |
| 474 // The image has an invalid LZW code that exceeds dictionary size. Decoding shou
ld fail. | 481 // The image has an invalid LZW code that exceeds dictionary size. Decoding shou
ld fail. |
| 475 TEST(GIFImageDecoderTest, badCode) | 482 TEST(GIFImageDecoderTest, badCode) |
| 476 { | 483 { |
| 477 RefPtr<SharedBuffer> testData = readFile("/Source/platform/image-decoders/te
sting/bad-code.gif"); | 484 RefPtr<SharedBuffer> testData = readFile(decodersTestingDir, "bad-code.gif")
; |
| 478 ASSERT_TRUE(testData.get()); | 485 ASSERT_TRUE(testData.get()); |
| 479 | 486 |
| 480 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); | 487 OwnPtr<GIFImageDecoder> testDecoder(createDecoder()); |
| 481 testDecoder->setData(testData.get(), true); | 488 testDecoder->setData(testData.get(), true); |
| 482 EXPECT_EQ(1u, testDecoder->frameCount()); | 489 EXPECT_EQ(1u, testDecoder->frameCount()); |
| 483 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); | 490 ASSERT_TRUE(testDecoder->frameBufferAtIndex(0)); |
| 484 EXPECT_TRUE(testDecoder->failed()); | 491 EXPECT_TRUE(testDecoder->failed()); |
| 485 } | 492 } |
| 486 | 493 |
| 487 TEST(GIFImageDecoderTest, invalidDisposalMethod) | 494 TEST(GIFImageDecoderTest, invalidDisposalMethod) |
| 488 { | 495 { |
| 489 OwnPtr<GIFImageDecoder> decoder = createDecoder(); | 496 OwnPtr<GIFImageDecoder> decoder = createDecoder(); |
| 490 | 497 |
| 491 // The image has 2 frames, with disposal method 4 and 5, respectively. | 498 // The image has 2 frames, with disposal method 4 and 5, respectively. |
| 492 RefPtr<SharedBuffer> data = readFile("/Source/web/tests/data/invalid-disposa
l-method.gif"); | 499 RefPtr<SharedBuffer> data = readFile(webTestsDataDir, "invalid-disposal-meth
od.gif"); |
| 493 ASSERT_TRUE(data.get()); | 500 ASSERT_TRUE(data.get()); |
| 494 decoder->setData(data.get(), true); | 501 decoder->setData(data.get(), true); |
| 495 | 502 |
| 496 EXPECT_EQ(2u, decoder->frameCount()); | 503 EXPECT_EQ(2u, decoder->frameCount()); |
| 497 // Disposal method 4 is converted to ImageFrame::DisposeOverwritePrevious. | 504 // Disposal method 4 is converted to ImageFrame::DisposeOverwritePrevious. |
| 498 EXPECT_EQ(ImageFrame::DisposeOverwritePrevious, decoder->frameBufferAtIndex(
0)->disposalMethod()); | 505 EXPECT_EQ(ImageFrame::DisposeOverwritePrevious, decoder->frameBufferAtIndex(
0)->disposalMethod()); |
| 499 // Disposal method 5 is ignored. | 506 // Disposal method 5 is ignored. |
| 500 EXPECT_EQ(ImageFrame::DisposeNotSpecified, decoder->frameBufferAtIndex(1)->d
isposalMethod()); | 507 EXPECT_EQ(ImageFrame::DisposeNotSpecified, decoder->frameBufferAtIndex(1)->d
isposalMethod()); |
| 501 } | 508 } |
| 509 |
| 510 TEST(GIFImageDecoderTest, firstFrameHasGreaterSizeThanScreenSize) |
| 511 { |
| 512 RefPtr<SharedBuffer> fullData = readFile(decodersTestingDir, "first-frame-ha
s-greater-size-than-screen-size.gif"); |
| 513 ASSERT_TRUE(fullData.get()); |
| 514 |
| 515 OwnPtr<GIFImageDecoder> decoder; |
| 516 IntSize frameSize; |
| 517 |
| 518 // Compute hashes when the file is truncated. |
| 519 for (size_t i = 1; i <= fullData->size(); ++i) { |
| 520 decoder = createDecoder(); |
| 521 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); |
| 522 decoder->setData(data.get(), i == fullData->size()); |
| 523 |
| 524 if (decoder->isSizeAvailable() && !frameSize.width() && !frameSize.heigh
t()) { |
| 525 frameSize = decoder->decodedSize(); |
| 526 continue; |
| 527 } |
| 528 |
| 529 ASSERT_EQ(frameSize.width(), decoder->decodedSize().width()); |
| 530 ASSERT_EQ(frameSize.height(), decoder->decodedSize().height()); |
| 531 } |
| 532 } |
| OLD | NEW |