| 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 18 matching lines...) Expand all Loading... |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "platform/image-decoders/webp/WEBPImageDecoder.h" | 31 #include "platform/image-decoders/webp/WEBPImageDecoder.h" |
| 32 | 32 |
| 33 #include "platform/RuntimeEnabledFeatures.h" | 33 #include "platform/RuntimeEnabledFeatures.h" |
| 34 #include "platform/SharedBuffer.h" | 34 #include "platform/SharedBuffer.h" |
| 35 #include "platform/image-decoders/ImageDecoderTestHelpers.h" | 35 #include "platform/image-decoders/ImageDecoderTestHelpers.h" |
| 36 #include "public/platform/WebData.h" | 36 #include "public/platform/WebData.h" |
| 37 #include "public/platform/WebSize.h" | 37 #include "public/platform/WebSize.h" |
| 38 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
| 39 #include "wtf/PtrUtil.h" | 39 #include "wtf/OwnPtr.h" |
| 40 #include "wtf/PassOwnPtr.h" |
| 40 #include "wtf/Vector.h" | 41 #include "wtf/Vector.h" |
| 41 #include "wtf/dtoa/utils.h" | 42 #include "wtf/dtoa/utils.h" |
| 42 #include <memory> | |
| 43 | 43 |
| 44 namespace blink { | 44 namespace blink { |
| 45 | 45 |
| 46 namespace { | 46 namespace { |
| 47 | 47 |
| 48 std::unique_ptr<ImageDecoder> createDecoder(ImageDecoder::AlphaOption alphaOptio
n) | 48 PassOwnPtr<ImageDecoder> createDecoder(ImageDecoder::AlphaOption alphaOption) |
| 49 { | 49 { |
| 50 return wrapUnique(new WEBPImageDecoder(alphaOption, ImageDecoder::GammaAndCo
lorProfileApplied, ImageDecoder::noDecodedImageByteLimit)); | 50 return adoptPtr(new WEBPImageDecoder(alphaOption, ImageDecoder::GammaAndColo
rProfileApplied, ImageDecoder::noDecodedImageByteLimit)); |
| 51 } | 51 } |
| 52 | 52 |
| 53 std::unique_ptr<ImageDecoder> createDecoder() | 53 PassOwnPtr<ImageDecoder> createDecoder() |
| 54 { | 54 { |
| 55 return createDecoder(ImageDecoder::AlphaNotPremultiplied); | 55 return createDecoder(ImageDecoder::AlphaNotPremultiplied); |
| 56 } | 56 } |
| 57 | 57 |
| 58 void testRandomFrameDecode(const char* webpFile) | 58 void testRandomFrameDecode(const char* webpFile) |
| 59 { | 59 { |
| 60 SCOPED_TRACE(webpFile); | 60 SCOPED_TRACE(webpFile); |
| 61 | 61 |
| 62 RefPtr<SharedBuffer> fullData = readFile(webpFile); | 62 RefPtr<SharedBuffer> fullData = readFile(webpFile); |
| 63 ASSERT_TRUE(fullData.get()); | 63 ASSERT_TRUE(fullData.get()); |
| 64 Vector<unsigned> baselineHashes; | 64 Vector<unsigned> baselineHashes; |
| 65 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); | 65 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); |
| 66 size_t frameCount = baselineHashes.size(); | 66 size_t frameCount = baselineHashes.size(); |
| 67 | 67 |
| 68 // Random decoding should get the same results as sequential decoding. | 68 // Random decoding should get the same results as sequential decoding. |
| 69 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 69 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 70 decoder->setData(fullData.get(), true); | 70 decoder->setData(fullData.get(), true); |
| 71 const size_t skippingStep = 5; | 71 const size_t skippingStep = 5; |
| 72 for (size_t i = 0; i < skippingStep; ++i) { | 72 for (size_t i = 0; i < skippingStep; ++i) { |
| 73 for (size_t j = i; j < frameCount; j += skippingStep) { | 73 for (size_t j = i; j < frameCount; j += skippingStep) { |
| 74 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); | 74 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" << j); |
| 75 ImageFrame* frame = decoder->frameBufferAtIndex(j); | 75 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 76 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); | 76 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); |
| 77 } | 77 } |
| 78 } | 78 } |
| 79 | 79 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 90 void testRandomDecodeAfterClearFrameBufferCache(const char* webpFile) | 90 void testRandomDecodeAfterClearFrameBufferCache(const char* webpFile) |
| 91 { | 91 { |
| 92 SCOPED_TRACE(webpFile); | 92 SCOPED_TRACE(webpFile); |
| 93 | 93 |
| 94 RefPtr<SharedBuffer> data = readFile(webpFile); | 94 RefPtr<SharedBuffer> data = readFile(webpFile); |
| 95 ASSERT_TRUE(data.get()); | 95 ASSERT_TRUE(data.get()); |
| 96 Vector<unsigned> baselineHashes; | 96 Vector<unsigned> baselineHashes; |
| 97 createDecodingBaseline(&createDecoder, data.get(), &baselineHashes); | 97 createDecodingBaseline(&createDecoder, data.get(), &baselineHashes); |
| 98 size_t frameCount = baselineHashes.size(); | 98 size_t frameCount = baselineHashes.size(); |
| 99 | 99 |
| 100 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 100 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 101 decoder->setData(data.get(), true); | 101 decoder->setData(data.get(), true); |
| 102 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce
ptFrame) { | 102 for (size_t clearExceptFrame = 0; clearExceptFrame < frameCount; ++clearExce
ptFrame) { |
| 103 decoder->clearCacheExceptFrame(clearExceptFrame); | 103 decoder->clearCacheExceptFrame(clearExceptFrame); |
| 104 const size_t skippingStep = 5; | 104 const size_t skippingStep = 5; |
| 105 for (size_t i = 0; i < skippingStep; ++i) { | 105 for (size_t i = 0; i < skippingStep; ++i) { |
| 106 for (size_t j = 0; j < frameCount; j += skippingStep) { | 106 for (size_t j = 0; j < frameCount; j += skippingStep) { |
| 107 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" <<
j); | 107 SCOPED_TRACE(testing::Message() << "Random i:" << i << " j:" <<
j); |
| 108 ImageFrame* frame = decoder->frameBufferAtIndex(j); | 108 ImageFrame* frame = decoder->frameBufferAtIndex(j); |
| 109 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); | 109 EXPECT_EQ(baselineHashes[j], hashBitmap(frame->bitmap())); |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 | 114 |
| 115 void testDecodeAfterReallocatingData(const char* webpFile) | 115 void testDecodeAfterReallocatingData(const char* webpFile) |
| 116 { | 116 { |
| 117 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 117 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 118 RefPtr<SharedBuffer> data = readFile(webpFile); | 118 RefPtr<SharedBuffer> data = readFile(webpFile); |
| 119 ASSERT_TRUE(data.get()); | 119 ASSERT_TRUE(data.get()); |
| 120 | 120 |
| 121 // Parse from 'data'. | 121 // Parse from 'data'. |
| 122 decoder->setData(data.get(), true); | 122 decoder->setData(data.get(), true); |
| 123 size_t frameCount = decoder->frameCount(); | 123 size_t frameCount = decoder->frameCount(); |
| 124 | 124 |
| 125 // ... and then decode frames from 'reallocatedData'. | 125 // ... and then decode frames from 'reallocatedData'. |
| 126 RefPtr<SharedBuffer> reallocatedData = data.get()->copy(); | 126 RefPtr<SharedBuffer> reallocatedData = data.get()->copy(); |
| 127 ASSERT_TRUE(reallocatedData.get()); | 127 ASSERT_TRUE(reallocatedData.get()); |
| 128 data.clear(); | 128 data.clear(); |
| 129 decoder->setData(reallocatedData.get(), true); | 129 decoder->setData(reallocatedData.get(), true); |
| 130 | 130 |
| 131 for (size_t i = 0; i < frameCount; ++i) { | 131 for (size_t i = 0; i < frameCount; ++i) { |
| 132 const ImageFrame* const frame = decoder->frameBufferAtIndex(i); | 132 const ImageFrame* const frame = decoder->frameBufferAtIndex(i); |
| 133 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); | 133 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); |
| 134 } | 134 } |
| 135 } | 135 } |
| 136 | 136 |
| 137 void testByteByByteSizeAvailable(const char* webpFile, size_t frameOffset, bool
hasColorProfile, int expectedRepetitionCount) | 137 void testByteByByteSizeAvailable(const char* webpFile, size_t frameOffset, bool
hasColorProfile, int expectedRepetitionCount) |
| 138 { | 138 { |
| 139 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 139 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 140 RefPtr<SharedBuffer> data = readFile(webpFile); | 140 RefPtr<SharedBuffer> data = readFile(webpFile); |
| 141 ASSERT_TRUE(data.get()); | 141 ASSERT_TRUE(data.get()); |
| 142 EXPECT_LT(frameOffset, data->size()); | 142 EXPECT_LT(frameOffset, data->size()); |
| 143 | 143 |
| 144 // Send data to the decoder byte-by-byte and use the provided frame offset i
n the data to check | 144 // Send data to the decoder byte-by-byte and use the provided frame offset i
n the data to check |
| 145 // isSizeAvailable() changes state only when that offset is reached, and the
associated decoder | 145 // isSizeAvailable() changes state only when that offset is reached, and the
associated decoder |
| 146 // state also: size, colorProfile, frameCount, repetitionCount ... | 146 // state also: size, colorProfile, frameCount, repetitionCount ... |
| 147 | 147 |
| 148 for (size_t length = 1; length <= frameOffset; ++length) { | 148 for (size_t length = 1; length <= frameOffset; ++length) { |
| 149 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); | 149 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), lengt
h); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 174 EXPECT_FALSE(decoder->failed()); | 174 EXPECT_FALSE(decoder->failed()); |
| 175 if (decoder->failed()) | 175 if (decoder->failed()) |
| 176 return; | 176 return; |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 | 179 |
| 180 // If 'parseErrorExpected' is true, error is expected during parse (frameCount() | 180 // If 'parseErrorExpected' is true, error is expected during parse (frameCount() |
| 181 // call); else error is expected during decode (frameBufferAtIndex() call). | 181 // call); else error is expected during decode (frameBufferAtIndex() call). |
| 182 void testInvalidImage(const char* webpFile, bool parseErrorExpected) | 182 void testInvalidImage(const char* webpFile, bool parseErrorExpected) |
| 183 { | 183 { |
| 184 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 184 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 185 | 185 |
| 186 RefPtr<SharedBuffer> data = readFile(webpFile); | 186 RefPtr<SharedBuffer> data = readFile(webpFile); |
| 187 ASSERT_TRUE(data.get()); | 187 ASSERT_TRUE(data.get()); |
| 188 decoder->setData(data.get(), true); | 188 decoder->setData(data.get(), true); |
| 189 | 189 |
| 190 if (parseErrorExpected) { | 190 if (parseErrorExpected) { |
| 191 EXPECT_EQ(0u, decoder->frameCount()); | 191 EXPECT_EQ(0u, decoder->frameCount()); |
| 192 EXPECT_FALSE(decoder->frameBufferAtIndex(0)); | 192 EXPECT_FALSE(decoder->frameBufferAtIndex(0)); |
| 193 } else { | 193 } else { |
| 194 EXPECT_GT(decoder->frameCount(), 0u); | 194 EXPECT_GT(decoder->frameCount(), 0u); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 // that the frames match if the RGBA channel values differ by at most 2. | 235 // that the frames match if the RGBA channel values differ by at most 2. |
| 236 EXPECT_GE(2, maxDifference) << webpFile; | 236 EXPECT_GE(2, maxDifference) << webpFile; |
| 237 } | 237 } |
| 238 | 238 |
| 239 // Verify that result of alpha blending is similar for AlphaPremultiplied and Al
phaNotPremultiplied cases. | 239 // Verify that result of alpha blending is similar for AlphaPremultiplied and Al
phaNotPremultiplied cases. |
| 240 void testAlphaBlending(const char* webpFile) | 240 void testAlphaBlending(const char* webpFile) |
| 241 { | 241 { |
| 242 RefPtr<SharedBuffer> data = readFile(webpFile); | 242 RefPtr<SharedBuffer> data = readFile(webpFile); |
| 243 ASSERT_TRUE(data.get()); | 243 ASSERT_TRUE(data.get()); |
| 244 | 244 |
| 245 std::unique_ptr<ImageDecoder> decoderA = createDecoder(ImageDecoder::AlphaPr
emultiplied); | 245 OwnPtr<ImageDecoder> decoderA = createDecoder(ImageDecoder::AlphaPremultipli
ed); |
| 246 decoderA->setData(data.get(), true); | 246 decoderA->setData(data.get(), true); |
| 247 | 247 |
| 248 std::unique_ptr<ImageDecoder> decoderB = createDecoder(ImageDecoder::AlphaNo
tPremultiplied); | 248 OwnPtr<ImageDecoder> decoderB = createDecoder(ImageDecoder::AlphaNotPremulti
plied); |
| 249 decoderB->setData(data.get(), true); | 249 decoderB->setData(data.get(), true); |
| 250 | 250 |
| 251 size_t frameCount = decoderA->frameCount(); | 251 size_t frameCount = decoderA->frameCount(); |
| 252 ASSERT_EQ(frameCount, decoderB->frameCount()); | 252 ASSERT_EQ(frameCount, decoderB->frameCount()); |
| 253 | 253 |
| 254 for (size_t i = 0; i < frameCount; ++i) | 254 for (size_t i = 0; i < frameCount; ++i) |
| 255 verifyFramesMatch(webpFile, decoderA->frameBufferAtIndex(i), decoderB->f
rameBufferAtIndex(i)); | 255 verifyFramesMatch(webpFile, decoderA->frameBufferAtIndex(i), decoderB->f
rameBufferAtIndex(i)); |
| 256 } | 256 } |
| 257 | 257 |
| 258 } // anonymous namespace | 258 } // anonymous namespace |
| 259 | 259 |
| 260 TEST(AnimatedWebPTests, uniqueGenerationIDs) | 260 TEST(AnimatedWebPTests, uniqueGenerationIDs) |
| 261 { | 261 { |
| 262 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 262 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 263 | 263 |
| 264 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated.webp"); | 264 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated.webp"); |
| 265 ASSERT_TRUE(data.get()); | 265 ASSERT_TRUE(data.get()); |
| 266 decoder->setData(data.get(), true); | 266 decoder->setData(data.get(), true); |
| 267 | 267 |
| 268 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 268 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 269 uint32_t generationID0 = frame->bitmap().getGenerationID(); | 269 uint32_t generationID0 = frame->bitmap().getGenerationID(); |
| 270 frame = decoder->frameBufferAtIndex(1); | 270 frame = decoder->frameBufferAtIndex(1); |
| 271 uint32_t generationID1 = frame->bitmap().getGenerationID(); | 271 uint32_t generationID1 = frame->bitmap().getGenerationID(); |
| 272 | 272 |
| 273 EXPECT_TRUE(generationID0 != generationID1); | 273 EXPECT_TRUE(generationID0 != generationID1); |
| 274 } | 274 } |
| 275 | 275 |
| 276 TEST(AnimatedWebPTests, verifyAnimationParametersTransparentImage) | 276 TEST(AnimatedWebPTests, verifyAnimationParametersTransparentImage) |
| 277 { | 277 { |
| 278 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 278 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 279 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 279 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 280 | 280 |
| 281 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated.webp"); | 281 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated.webp"); |
| 282 ASSERT_TRUE(data.get()); | 282 ASSERT_TRUE(data.get()); |
| 283 decoder->setData(data.get(), true); | 283 decoder->setData(data.get(), true); |
| 284 | 284 |
| 285 const int canvasWidth = 11; | 285 const int canvasWidth = 11; |
| 286 const int canvasHeight = 29; | 286 const int canvasHeight = 29; |
| 287 const struct AnimParam { | 287 const struct AnimParam { |
| 288 int xOffset, yOffset, width, height; | 288 int xOffset, yOffset, width, height; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 310 EXPECT_EQ(frameParameters[i].duration, frame->duration()); | 310 EXPECT_EQ(frameParameters[i].duration, frame->duration()); |
| 311 EXPECT_EQ(frameParameters[i].hasAlpha, frame->hasAlpha()); | 311 EXPECT_EQ(frameParameters[i].hasAlpha, frame->hasAlpha()); |
| 312 } | 312 } |
| 313 | 313 |
| 314 EXPECT_EQ(WTF_ARRAY_LENGTH(frameParameters), decoder->frameCount()); | 314 EXPECT_EQ(WTF_ARRAY_LENGTH(frameParameters), decoder->frameCount()); |
| 315 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 315 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 316 } | 316 } |
| 317 | 317 |
| 318 TEST(AnimatedWebPTests, verifyAnimationParametersOpaqueFramesTransparentBackgrou
nd) | 318 TEST(AnimatedWebPTests, verifyAnimationParametersOpaqueFramesTransparentBackgrou
nd) |
| 319 { | 319 { |
| 320 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 320 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 321 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 321 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 322 | 322 |
| 323 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated-opaque.webp"); | 323 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated-opaque.webp"); |
| 324 ASSERT_TRUE(data.get()); | 324 ASSERT_TRUE(data.get()); |
| 325 decoder->setData(data.get(), true); | 325 decoder->setData(data.get(), true); |
| 326 | 326 |
| 327 const int canvasWidth = 94; | 327 const int canvasWidth = 94; |
| 328 const int canvasHeight = 87; | 328 const int canvasHeight = 87; |
| 329 const struct AnimParam { | 329 const struct AnimParam { |
| 330 int xOffset, yOffset, width, height; | 330 int xOffset, yOffset, width, height; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 353 EXPECT_EQ(frameParameters[i].duration, frame->duration()); | 353 EXPECT_EQ(frameParameters[i].duration, frame->duration()); |
| 354 EXPECT_EQ(frameParameters[i].hasAlpha, frame->hasAlpha()); | 354 EXPECT_EQ(frameParameters[i].hasAlpha, frame->hasAlpha()); |
| 355 } | 355 } |
| 356 | 356 |
| 357 EXPECT_EQ(WTF_ARRAY_LENGTH(frameParameters), decoder->frameCount()); | 357 EXPECT_EQ(WTF_ARRAY_LENGTH(frameParameters), decoder->frameCount()); |
| 358 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); | 358 EXPECT_EQ(cAnimationLoopInfinite, decoder->repetitionCount()); |
| 359 } | 359 } |
| 360 | 360 |
| 361 TEST(AnimatedWebPTests, verifyAnimationParametersBlendOverwrite) | 361 TEST(AnimatedWebPTests, verifyAnimationParametersBlendOverwrite) |
| 362 { | 362 { |
| 363 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 363 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 364 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 364 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 365 | 365 |
| 366 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated-no-blend.webp"); | 366 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated-no-blend.webp"); |
| 367 ASSERT_TRUE(data.get()); | 367 ASSERT_TRUE(data.get()); |
| 368 decoder->setData(data.get(), true); | 368 decoder->setData(data.get(), true); |
| 369 | 369 |
| 370 const int canvasWidth = 94; | 370 const int canvasWidth = 94; |
| 371 const int canvasHeight = 87; | 371 const int canvasHeight = 87; |
| 372 const struct AnimParam { | 372 const struct AnimParam { |
| 373 int xOffset, yOffset, width, height; | 373 int xOffset, yOffset, width, height; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 TEST(AnimatedWebPTests, invalidImages) | 410 TEST(AnimatedWebPTests, invalidImages) |
| 411 { | 411 { |
| 412 // ANMF chunk size is smaller than ANMF header size. | 412 // ANMF chunk size is smaller than ANMF header size. |
| 413 testInvalidImage("/LayoutTests/fast/images/resources/invalid-animated-webp.w
ebp", true); | 413 testInvalidImage("/LayoutTests/fast/images/resources/invalid-animated-webp.w
ebp", true); |
| 414 // One of the frame rectangles extends outside the image boundary. | 414 // One of the frame rectangles extends outside the image boundary. |
| 415 testInvalidImage("/LayoutTests/fast/images/resources/invalid-animated-webp3.
webp", true); | 415 testInvalidImage("/LayoutTests/fast/images/resources/invalid-animated-webp3.
webp", true); |
| 416 } | 416 } |
| 417 | 417 |
| 418 TEST(AnimatedWebPTests, truncatedLastFrame) | 418 TEST(AnimatedWebPTests, truncatedLastFrame) |
| 419 { | 419 { |
| 420 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 420 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 421 | 421 |
| 422 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/inv
alid-animated-webp2.webp"); | 422 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/inv
alid-animated-webp2.webp"); |
| 423 ASSERT_TRUE(data.get()); | 423 ASSERT_TRUE(data.get()); |
| 424 decoder->setData(data.get(), true); | 424 decoder->setData(data.get(), true); |
| 425 | 425 |
| 426 size_t frameCount = 8; | 426 size_t frameCount = 8; |
| 427 EXPECT_EQ(frameCount, decoder->frameCount()); | 427 EXPECT_EQ(frameCount, decoder->frameCount()); |
| 428 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 428 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
| 429 ASSERT_TRUE(frame); | 429 ASSERT_TRUE(frame); |
| 430 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); | 430 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); |
| 431 EXPECT_FALSE(decoder->failed()); | 431 EXPECT_FALSE(decoder->failed()); |
| 432 frame = decoder->frameBufferAtIndex(frameCount - 1); | 432 frame = decoder->frameBufferAtIndex(frameCount - 1); |
| 433 ASSERT_TRUE(frame); | 433 ASSERT_TRUE(frame); |
| 434 EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus()); | 434 EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus()); |
| 435 EXPECT_TRUE(decoder->failed()); | 435 EXPECT_TRUE(decoder->failed()); |
| 436 frame = decoder->frameBufferAtIndex(0); | 436 frame = decoder->frameBufferAtIndex(0); |
| 437 ASSERT_TRUE(frame); | 437 ASSERT_TRUE(frame); |
| 438 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); | 438 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); |
| 439 } | 439 } |
| 440 | 440 |
| 441 TEST(AnimatedWebPTests, truncatedInBetweenFrame) | 441 TEST(AnimatedWebPTests, truncatedInBetweenFrame) |
| 442 { | 442 { |
| 443 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 443 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 444 | 444 |
| 445 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/invalid-animated-webp4.webp"); | 445 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/invalid-animated-webp4.webp"); |
| 446 ASSERT_TRUE(fullData.get()); | 446 ASSERT_TRUE(fullData.get()); |
| 447 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), fullData-
>size() - 1); | 447 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), fullData-
>size() - 1); |
| 448 decoder->setData(data.get(), false); | 448 decoder->setData(data.get(), false); |
| 449 | 449 |
| 450 ImageFrame* frame = decoder->frameBufferAtIndex(1); | 450 ImageFrame* frame = decoder->frameBufferAtIndex(1); |
| 451 ASSERT_TRUE(frame); | 451 ASSERT_TRUE(frame); |
| 452 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); | 452 EXPECT_EQ(ImageFrame::FrameComplete, frame->getStatus()); |
| 453 frame = decoder->frameBufferAtIndex(2); | 453 frame = decoder->frameBufferAtIndex(2); |
| 454 ASSERT_TRUE(frame); | 454 ASSERT_TRUE(frame); |
| 455 EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus()); | 455 EXPECT_EQ(ImageFrame::FramePartial, frame->getStatus()); |
| 456 EXPECT_TRUE(decoder->failed()); | 456 EXPECT_TRUE(decoder->failed()); |
| 457 } | 457 } |
| 458 | 458 |
| 459 // Reproduce a crash that used to happen for a specific file with specific seque
nce of method calls. | 459 // Reproduce a crash that used to happen for a specific file with specific seque
nce of method calls. |
| 460 TEST(AnimatedWebPTests, reproCrash) | 460 TEST(AnimatedWebPTests, reproCrash) |
| 461 { | 461 { |
| 462 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 462 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 463 | 463 |
| 464 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/invalid_vp8_vp8x.webp"); | 464 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/invalid_vp8_vp8x.webp"); |
| 465 ASSERT_TRUE(fullData.get()); | 465 ASSERT_TRUE(fullData.get()); |
| 466 | 466 |
| 467 // Parse partial data up to which error in bitstream is not detected. | 467 // Parse partial data up to which error in bitstream is not detected. |
| 468 const size_t partialSize = 32768; | 468 const size_t partialSize = 32768; |
| 469 ASSERT_GT(fullData->size(), partialSize); | 469 ASSERT_GT(fullData->size(), partialSize); |
| 470 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), partialSi
ze); | 470 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), partialSi
ze); |
| 471 decoder->setData(data.get(), false); | 471 decoder->setData(data.get(), false); |
| 472 EXPECT_EQ(1u, decoder->frameCount()); | 472 EXPECT_EQ(1u, decoder->frameCount()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 484 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); | 484 EXPECT_EQ(cAnimationLoopOnce, decoder->repetitionCount()); |
| 485 EXPECT_TRUE(decoder->failed()); | 485 EXPECT_TRUE(decoder->failed()); |
| 486 } | 486 } |
| 487 | 487 |
| 488 TEST(AnimatedWebPTests, progressiveDecode) | 488 TEST(AnimatedWebPTests, progressiveDecode) |
| 489 { | 489 { |
| 490 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/webp-animated.webp"); | 490 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/webp-animated.webp"); |
| 491 ASSERT_TRUE(fullData.get()); | 491 ASSERT_TRUE(fullData.get()); |
| 492 const size_t fullLength = fullData->size(); | 492 const size_t fullLength = fullData->size(); |
| 493 | 493 |
| 494 std::unique_ptr<ImageDecoder> decoder; | 494 OwnPtr<ImageDecoder> decoder; |
| 495 ImageFrame* frame; | 495 ImageFrame* frame; |
| 496 | 496 |
| 497 Vector<unsigned> truncatedHashes; | 497 Vector<unsigned> truncatedHashes; |
| 498 Vector<unsigned> progressiveHashes; | 498 Vector<unsigned> progressiveHashes; |
| 499 | 499 |
| 500 // Compute hashes when the file is truncated. | 500 // Compute hashes when the file is truncated. |
| 501 const size_t increment = 1; | 501 const size_t increment = 1; |
| 502 for (size_t i = 1; i <= fullLength; i += increment) { | 502 for (size_t i = 1; i <= fullLength; i += increment) { |
| 503 decoder = createDecoder(); | 503 decoder = createDecoder(); |
| 504 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); | 504 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), i); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 529 if (truncatedHashes[i] != progressiveHashes[i]) { | 529 if (truncatedHashes[i] != progressiveHashes[i]) { |
| 530 match = false; | 530 match = false; |
| 531 break; | 531 break; |
| 532 } | 532 } |
| 533 } | 533 } |
| 534 EXPECT_TRUE(match); | 534 EXPECT_TRUE(match); |
| 535 } | 535 } |
| 536 | 536 |
| 537 TEST(AnimatedWebPTests, frameIsCompleteAndDuration) | 537 TEST(AnimatedWebPTests, frameIsCompleteAndDuration) |
| 538 { | 538 { |
| 539 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 539 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 540 | 540 |
| 541 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated.webp"); | 541 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-animated.webp"); |
| 542 ASSERT_TRUE(data.get()); | 542 ASSERT_TRUE(data.get()); |
| 543 | 543 |
| 544 ASSERT_GE(data->size(), 10u); | 544 ASSERT_GE(data->size(), 10u); |
| 545 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); | 545 RefPtr<SharedBuffer> tempData = SharedBuffer::create(data->data(), data->siz
e() - 10); |
| 546 decoder->setData(tempData.get(), false); | 546 decoder->setData(tempData.get(), false); |
| 547 | 547 |
| 548 EXPECT_EQ(2u, decoder->frameCount()); | 548 EXPECT_EQ(2u, decoder->frameCount()); |
| 549 EXPECT_FALSE(decoder->failed()); | 549 EXPECT_FALSE(decoder->failed()); |
| 550 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); | 550 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); |
| 551 EXPECT_EQ(1000, decoder->frameDurationAtIndex(0)); | 551 EXPECT_EQ(1000, decoder->frameDurationAtIndex(0)); |
| 552 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); | 552 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); |
| 553 EXPECT_EQ(500, decoder->frameDurationAtIndex(1)); | 553 EXPECT_EQ(500, decoder->frameDurationAtIndex(1)); |
| 554 | 554 |
| 555 decoder->setData(data.get(), true); | 555 decoder->setData(data.get(), true); |
| 556 EXPECT_EQ(3u, decoder->frameCount()); | 556 EXPECT_EQ(3u, decoder->frameCount()); |
| 557 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); | 557 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(0)); |
| 558 EXPECT_EQ(1000, decoder->frameDurationAtIndex(0)); | 558 EXPECT_EQ(1000, decoder->frameDurationAtIndex(0)); |
| 559 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); | 559 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(1)); |
| 560 EXPECT_EQ(500, decoder->frameDurationAtIndex(1)); | 560 EXPECT_EQ(500, decoder->frameDurationAtIndex(1)); |
| 561 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(2)); | 561 EXPECT_TRUE(decoder->frameIsCompleteAtIndex(2)); |
| 562 EXPECT_EQ(1000.0, decoder->frameDurationAtIndex(2)); | 562 EXPECT_EQ(1000.0, decoder->frameDurationAtIndex(2)); |
| 563 } | 563 } |
| 564 | 564 |
| 565 TEST(AnimatedWebPTests, updateRequiredPreviousFrameAfterFirstDecode) | 565 TEST(AnimatedWebPTests, updateRequiredPreviousFrameAfterFirstDecode) |
| 566 { | 566 { |
| 567 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 567 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 568 | 568 |
| 569 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/webp-animated.webp"); | 569 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/webp-animated.webp"); |
| 570 ASSERT_TRUE(fullData.get()); | 570 ASSERT_TRUE(fullData.get()); |
| 571 | 571 |
| 572 // Give it data that is enough to parse but not decode in order to check the
status | 572 // Give it data that is enough to parse but not decode in order to check the
status |
| 573 // of requiredPreviousFrameIndex before decoding. | 573 // of requiredPreviousFrameIndex before decoding. |
| 574 size_t partialSize = 1; | 574 size_t partialSize = 1; |
| 575 do { | 575 do { |
| 576 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); | 576 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); |
| 577 decoder->setData(data.get(), false); | 577 decoder->setData(data.get(), false); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 605 } | 605 } |
| 606 | 606 |
| 607 TEST(AnimatedWebPTests, DISABLED_resumePartialDecodeAfterClearFrameBufferCache) | 607 TEST(AnimatedWebPTests, DISABLED_resumePartialDecodeAfterClearFrameBufferCache) |
| 608 { | 608 { |
| 609 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/webp-animated-large.webp"); | 609 RefPtr<SharedBuffer> fullData = readFile("/LayoutTests/fast/images/resources
/webp-animated-large.webp"); |
| 610 ASSERT_TRUE(fullData.get()); | 610 ASSERT_TRUE(fullData.get()); |
| 611 Vector<unsigned> baselineHashes; | 611 Vector<unsigned> baselineHashes; |
| 612 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); | 612 createDecodingBaseline(&createDecoder, fullData.get(), &baselineHashes); |
| 613 size_t frameCount = baselineHashes.size(); | 613 size_t frameCount = baselineHashes.size(); |
| 614 | 614 |
| 615 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 615 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 616 | 616 |
| 617 // Let frame 0 be partially decoded. | 617 // Let frame 0 be partially decoded. |
| 618 size_t partialSize = 1; | 618 size_t partialSize = 1; |
| 619 do { | 619 do { |
| 620 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); | 620 RefPtr<SharedBuffer> data = SharedBuffer::create(fullData->data(), parti
alSize); |
| 621 decoder->setData(data.get(), false); | 621 decoder->setData(data.get(), false); |
| 622 ++partialSize; | 622 ++partialSize; |
| 623 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->getStatus
() == ImageFrame::FrameEmpty); | 623 } while (!decoder->frameCount() || decoder->frameBufferAtIndex(0)->getStatus
() == ImageFrame::FrameEmpty); |
| 624 | 624 |
| 625 // Skip to the last frame and clear. | 625 // Skip to the last frame and clear. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 } | 672 } |
| 673 | 673 |
| 674 TEST(StaticWebPTests, isSizeAvailable) | 674 TEST(StaticWebPTests, isSizeAvailable) |
| 675 { | 675 { |
| 676 testByteByByteSizeAvailable("/LayoutTests/fast/images/resources/webp-color-p
rofile-lossy.webp", 520u, true, cAnimationNone); | 676 testByteByByteSizeAvailable("/LayoutTests/fast/images/resources/webp-color-p
rofile-lossy.webp", 520u, true, cAnimationNone); |
| 677 testByteByByteSizeAvailable("/LayoutTests/fast/images/resources/test.webp",
30u, false, cAnimationNone); | 677 testByteByByteSizeAvailable("/LayoutTests/fast/images/resources/test.webp",
30u, false, cAnimationNone); |
| 678 } | 678 } |
| 679 | 679 |
| 680 TEST(StaticWebPTests, notAnimated) | 680 TEST(StaticWebPTests, notAnimated) |
| 681 { | 681 { |
| 682 std::unique_ptr<ImageDecoder> decoder = createDecoder(); | 682 OwnPtr<ImageDecoder> decoder = createDecoder(); |
| 683 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-color-profile-lossy.webp"); | 683 RefPtr<SharedBuffer> data = readFile("/LayoutTests/fast/images/resources/web
p-color-profile-lossy.webp"); |
| 684 ASSERT_TRUE(data.get()); | 684 ASSERT_TRUE(data.get()); |
| 685 decoder->setData(data.get(), true); | 685 decoder->setData(data.get(), true); |
| 686 EXPECT_EQ(1u, decoder->frameCount()); | 686 EXPECT_EQ(1u, decoder->frameCount()); |
| 687 EXPECT_EQ(cAnimationNone, decoder->repetitionCount()); | 687 EXPECT_EQ(cAnimationNone, decoder->repetitionCount()); |
| 688 } | 688 } |
| 689 | 689 |
| 690 } // namespace blink | 690 } // namespace blink |
| OLD | NEW |