| Index: tests/CodecTest.cpp
|
| diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp
|
| index 45455b440577228e3a259de6401481f79c9af683..441fc1436f6a21e332d825dddd4983a7dd6ac380 100644
|
| --- a/tests/CodecTest.cpp
|
| +++ b/tests/CodecTest.cpp
|
| @@ -290,7 +290,12 @@ static void check(skiatest::Reporter* r,
|
|
|
| if (supportsNewScanlineDecoding && !isIncomplete) {
|
| test_incremental_decode(r, codec, info, codecDigest);
|
| - test_in_stripes(r, codec, info, codecDigest);
|
| + // This is only supported by codecs that use incremental decoding to
|
| + // support subset decodes - png and jpeg (once SkJpegCodec is
|
| + // converted).
|
| + if (SkStrEndsWith(path, "png") || SkStrEndsWith(path, "PNG")) {
|
| + test_in_stripes(r, codec, info, codecDigest);
|
| + }
|
| }
|
|
|
| // Need to call startScanlineDecode() first.
|
| @@ -470,11 +475,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);
|
| @@ -1218,6 +1222,67 @@ 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;
|
| + opts.fFrameIndex = frame;
|
| + 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:
|
| @@ -1269,7 +1334,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",
|
|
|