| Index: tests/CodexTest.cpp
|
| diff --git a/tests/CodexTest.cpp b/tests/CodexTest.cpp
|
| index 2ea6eda57ec86a899a83f5778b31ddea2b0fada6..f1c5bbaa128e1c989bf06af39f27f7a22e211864 100644
|
| --- a/tests/CodexTest.cpp
|
| +++ b/tests/CodexTest.cpp
|
| @@ -11,7 +11,6 @@
|
| #include "SkMD5.h"
|
| #include "SkRandom.h"
|
| #include "SkScaledCodec.h"
|
| -#include "SkScanlineDecoder.h"
|
| #include "Test.h"
|
|
|
| static SkStreamAsset* resource(const char path[]) {
|
| @@ -147,25 +146,44 @@ static void check(skiatest::Reporter* r,
|
|
|
| // Scanline decoding follows.
|
|
|
| - stream.reset(resource(path));
|
| - SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(
|
| - SkScanlineDecoder::NewFromStream(stream.detach()));
|
| + // Need to call start() first.
|
| + REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
|
| + == SkCodec::kScanlineDecodingNotStarted);
|
| + REPORTER_ASSERT(r, codec->skipScanlines(1)
|
| + == SkCodec::kScanlineDecodingNotStarted);
|
| +
|
| + const SkCodec::Result startResult = codec->startScanlineDecode(info);
|
| if (supportsScanlineDecoding) {
|
| bm.eraseColor(SK_ColorYELLOW);
|
| - REPORTER_ASSERT(r, scanlineDecoder);
|
|
|
| - REPORTER_ASSERT(r, scanlineDecoder->start(info) == SkCodec::kSuccess);
|
| + REPORTER_ASSERT(r, startResult == SkCodec::kSuccess);
|
|
|
| for (int y = 0; y < info.height(); y++) {
|
| - result = scanlineDecoder->getScanlines(bm.getAddr(0, y), 1, 0);
|
| + result = codec->getScanlines(bm.getAddr(0, y), 1, 0);
|
| REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| }
|
| // verify that scanline decoding gives the same result.
|
| - if (SkScanlineDecoder::kTopDown_SkScanlineOrder == scanlineDecoder->getScanlineOrder()) {
|
| + if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) {
|
| compare_to_good_digest(r, digest, bm);
|
| }
|
| +
|
| + // Cannot continue to decode scanlines beyond the end
|
| + REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
|
| + == SkCodec::kInvalidParameters);
|
| +
|
| + // Interrupting a scanline decode with a full decode starts from
|
| + // scratch
|
| + REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess);
|
| + REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
|
| + == SkCodec::kSuccess);
|
| + REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes())
|
| + == SkCodec::kSuccess);
|
| + REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
|
| + == SkCodec::kScanlineDecodingNotStarted);
|
| + REPORTER_ASSERT(r, codec->skipScanlines(1)
|
| + == SkCodec::kScanlineDecodingNotStarted);
|
| } else {
|
| - REPORTER_ASSERT(r, !scanlineDecoder);
|
| + REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented);
|
| }
|
|
|
| // The rest of this function tests decoding subsets, and will decode an arbitrary number of
|
| @@ -247,10 +265,102 @@ DEF_TEST(Codec, r) {
|
| check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false);
|
| check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false);
|
| check(r, "plane.png", SkISize::Make(250, 126), true, false);
|
| + check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false);
|
| check(r, "randPixels.png", SkISize::Make(8, 8), true, false);
|
| check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false);
|
| }
|
|
|
| +// Test interlaced PNG in stripes, similar to DM's kStripe_Mode
|
| +DEF_TEST(Codec_stripes, r) {
|
| + const char * path = "plane_interlaced.png";
|
| + SkAutoTDelete<SkStream> stream(resource(path));
|
| + if (!stream) {
|
| + SkDebugf("Missing resource '%s'\n", path);
|
| + }
|
| +
|
| + SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
|
| + REPORTER_ASSERT(r, codec);
|
| +
|
| + if (!codec) {
|
| + return;
|
| + }
|
| +
|
| + switch (codec->getScanlineOrder()) {
|
| + case SkCodec::kBottomUp_SkScanlineOrder:
|
| + case SkCodec::kOutOfOrder_SkScanlineOrder:
|
| + ERRORF(r, "This scanline order will not match the original.");
|
| + return;
|
| + default:
|
| + break;
|
| + }
|
| +
|
| + // Baseline for what the image should look like, using N32.
|
| + const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
|
| +
|
| + SkBitmap bm;
|
| + bm.allocPixels(info);
|
| + SkAutoLockPixels autoLockPixels(bm);
|
| + SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes());
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| +
|
| + SkMD5::Digest digest;
|
| + md5(bm, &digest);
|
| +
|
| + // Now decode in stripes
|
| + const int height = info.height();
|
| + const int numStripes = 4;
|
| + int stripeHeight;
|
| + int remainingLines;
|
| + SkTDivMod(height, numStripes, &stripeHeight, &remainingLines);
|
| +
|
| + bm.eraseColor(SK_ColorYELLOW);
|
| +
|
| + result = codec->startScanlineDecode(info);
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| +
|
| + // Odd stripes
|
| + for (int i = 1; i < numStripes; i += 2) {
|
| + // Skip the even stripes
|
| + result = codec->skipScanlines(stripeHeight);
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| +
|
| + result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeight,
|
| + bm.rowBytes());
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| + }
|
| +
|
| + // Even stripes
|
| + result = codec->startScanlineDecode(info);
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| +
|
| + for (int i = 0; i < numStripes; i += 2) {
|
| + result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeight,
|
| + bm.rowBytes());
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| +
|
| + // Skip the odd stripes
|
| + if (i + 1 < numStripes) {
|
| + result = codec->skipScanlines(stripeHeight);
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| + }
|
| + }
|
| +
|
| + // Remainder at the end
|
| + if (remainingLines > 0) {
|
| + result = codec->startScanlineDecode(info);
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| +
|
| + result = codec->skipScanlines(height - remainingLines);
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| +
|
| + result = codec->getScanlines(bm.getAddr(0, height - remainingLines),
|
| + remainingLines, bm.rowBytes());
|
| + REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
| + }
|
| +
|
| + compare_to_good_digest(r, digest, bm);
|
| +}
|
| +
|
| static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_t len) {
|
| SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, false));
|
| // We should not have gotten a codec. Bots should catch us if we leaked anything.
|
| @@ -369,13 +479,12 @@ static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) {
|
| SkDebugf("Missing resource '%s'\n", path);
|
| return;
|
| }
|
| - SkAutoTDelete<SkScanlineDecoder> decoder(SkScanlineDecoder::NewFromStream(
|
| - stream.detach()));
|
| + SkAutoTDelete<SkCodec> decoder(SkCodec::NewFromStream(stream.detach()));
|
|
|
| // This should return kSuccess because kIndex8 is supported.
|
| SkPMColor colorStorage[256];
|
| int colorCount;
|
| - SkCodec::Result result = decoder->start(
|
| + SkCodec::Result result = decoder->startScanlineDecode(
|
| decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, colorStorage, &colorCount);
|
| REPORTER_ASSERT(r, SkCodec::kSuccess == result);
|
| // The rest of the test is uninteresting if kIndex8 is not supported
|
| @@ -385,10 +494,10 @@ static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) {
|
|
|
| // This should return kInvalidParameters because, in kIndex_8 mode, we must pass in a valid
|
| // colorPtr and a valid colorCountPtr.
|
| - result = decoder->start(
|
| + result = decoder->startScanlineDecode(
|
| decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, nullptr, nullptr);
|
| REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
|
| - result = decoder->start(
|
| + result = decoder->startScanlineDecode(
|
| decoder->getInfo().makeColorType(kIndex_8_SkColorType));
|
| REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
|
| }
|
|
|