Chromium Code Reviews| Index: tests/CodecTest.cpp |
| diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp |
| index bae8344bad631d5e6e4102ad561f2d911b455b03..7fecec1bf1d8d93acf3ab155c4d8ddb41511f64a 100644 |
| --- a/tests/CodecTest.cpp |
| +++ b/tests/CodecTest.cpp |
| @@ -289,7 +289,10 @@ static void check(skiatest::Reporter* r, |
| if (supportsNewScanlineDecoding && !isIncomplete) { |
| test_incremental_decode(r, codec, info, codecDigest); |
| - test_in_stripes(r, codec, info, codecDigest); |
| + // FIXME: This is broken for gif. |
|
scroggo_chromium
2016/10/13 20:38:16
Incremental decoding with GIF works for the case w
|
| + if (SkStrEndsWith(path, "png") || SkStrEndsWith(path, "PNG")) { |
| + test_in_stripes(r, codec, info, codecDigest); |
| + } |
| } |
| // Need to call startScanlineDecode() first. |
| @@ -469,11 +472,10 @@ DEF_TEST(Codec, r) { |
| check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, false, true); |
| // GIF |
| - // FIXME: We are not ready to test incomplete GIFs |
| - check(r, "box.gif", SkISize::Make(200, 55), true, false, false); |
| - check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false, false); |
| + check(r, "box.gif", SkISize::Make(200, 55), false, false, true, true); |
| + check(r, "color_wheel.gif", SkISize::Make(128, 128), false, false, true, true); |
| // randPixels.gif is too small to test incomplete |
| - check(r, "randPixels.gif", SkISize::Make(8, 8), true, false, false); |
| + check(r, "randPixels.gif", SkISize::Make(8, 8), false, false, false, true); |
| // JPG |
| check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, true); |
| @@ -1215,6 +1217,69 @@ DEF_TEST(Codec_F16ConversionPossible, r) { |
| test_conversion_possible(r, "yellow_rose.png", false, true); |
| } |
| +static void decode_frame(skiatest::Reporter* r, SkCodec* codec, size_t frame) { |
| + SkBitmap bm; |
| + auto info = codec->getInfo().makeColorType(kN32_SkColorType); |
| + bm.allocPixels(info); |
| + |
| + SkCodec::Options opts; |
| + SkCodec::MultiFrameOptions multiOpts; |
| + multiOpts.fIndex = frame; |
| + opts.fFrameOptions = &multiOpts; |
| + REPORTER_ASSERT(r, SkCodec::kSuccess == codec->getPixels(info, |
| + bm.getPixels(), bm.rowBytes(), &opts, nullptr, nullptr)); |
| +} |
| + |
| +// For an animated image, we should only read enough to decode the requested |
| +// frame if the client never calls getFrameInfo. |
| +DEF_TEST(Codec_skipFullParse, r) { |
| + auto path = "test640x479.gif"; |
| + SkStream* stream(GetResourceAsStream(path)); |
| + if (!stream) { |
| + return; |
| + } |
| + |
| + // Note that we cheat and hold on to the stream pointer, but SkCodec will |
| + // take ownership. We will not refer to the stream after the SkCodec |
| + // deletes it. |
| + std::unique_ptr<SkCodec> codec(SkCodec::NewFromStream(stream)); |
| + if (!codec) { |
| + ERRORF(r, "Failed to create codec for %s", path); |
| + return; |
| + } |
| + |
| + REPORTER_ASSERT(r, stream->hasPosition()); |
| + const size_t sizePosition = stream->getPosition(); |
| + REPORTER_ASSERT(r, stream->hasLength() && sizePosition < stream->getLength()); |
| + |
| + // This should read more of the stream, but not the whole stream. |
| + decode_frame(r, codec.get(), 0); |
| + const size_t positionAfterFirstFrame = stream->getPosition(); |
| + REPORTER_ASSERT(r, positionAfterFirstFrame > sizePosition |
| + && positionAfterFirstFrame < stream->getLength()); |
| + |
| + // Again, this should read more of the stream. |
| + decode_frame(r, codec.get(), 2); |
| + const size_t positionAfterThirdFrame = stream->getPosition(); |
| + REPORTER_ASSERT(r, positionAfterThirdFrame > positionAfterFirstFrame |
| + && positionAfterThirdFrame < stream->getLength()); |
| + |
| + // This does not need to read any more of the stream, since it has already |
| + // parsed the second frame. |
| + decode_frame(r, codec.get(), 1); |
| + REPORTER_ASSERT(r, stream->getPosition() == positionAfterThirdFrame); |
| + |
| + // This should read the rest of the frames. |
| + decode_frame(r, codec.get(), 3); |
| + const size_t finalPosition = stream->getPosition(); |
| + REPORTER_ASSERT(r, finalPosition > positionAfterThirdFrame); |
| + |
| + // There may be more data in the stream. |
| + auto frameInfo = codec->getFrameInfo(); |
| + REPORTER_ASSERT(r, frameInfo.size() == 4); |
| + REPORTER_ASSERT(r, stream->getPosition() >= finalPosition); |
| +} |
| + |
| // Only rewinds up to a limit. |
| class LimitedRewindingStream : public SkStream { |
| public: |
| @@ -1266,7 +1331,6 @@ DEF_TEST(Codec_fallBack, r) { |
| // Formats that currently do not support incremental decoding |
| auto files = { |
| - "box.gif", |
| "CMYK.jpg", |
| "color_wheel.ico", |
| "mandrill.wbmp", |