Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3617)

Unified Diff: tests/CodecTest.cpp

Issue 1997703003: Make SkPngCodec decode progressively. (Closed) Base URL: https://skia.googlesource.com/skia.git@foil
Patch Set: Switch statement for setjmp Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/codec/SkSampler.h ('K') | « tests/CodecPartial.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/CodecTest.cpp
diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp
index bdb5e7792e983c686a3de82a4d4064da76846d73..e1f194a803029d8decd767d5cfff2fc384e14c54 100644
--- a/tests/CodecTest.cpp
+++ b/tests/CodecTest.cpp
@@ -83,6 +83,62 @@ SkIRect generate_random_subset(SkRandom* rand, int w, int h) {
return rect;
}
+static void test_incremental_decode(skiatest::Reporter* r, SkCodec* codec, const SkImageInfo& info,
+ const SkMD5::Digest& goodDigest) {
+ SkBitmap bm;
+ bm.allocPixels(info);
+ SkAutoLockPixels autoLockPixels(bm);
+
+ REPORTER_ASSERT(r, SkCodec::kSuccess == codec->startIncrementalDecode(info, bm.getPixels(),
+ bm.rowBytes()));
+
+ REPORTER_ASSERT(r, SkCodec::kSuccess == codec->incrementalDecode());
+
+ compare_to_good_digest(r, goodDigest, bm);
+}
+
+// Test in stripes, similar to DM's kStripe_Mode
+static void test_in_stripes(skiatest::Reporter* r, SkCodec* codec, const SkImageInfo& info,
+ const SkMD5::Digest& goodDigest) {
+ SkBitmap bm;
+ bm.allocPixels(info);
+ bm.eraseColor(SK_ColorYELLOW);
+
+ const int height = info.height();
+ // Note that if numStripes does not evenly divide height there will be an extra
+ // stripe.
+ const int numStripes = 4;
+
+ if (numStripes > height) {
+ // Image is too small.
+ return;
+ }
+
+ const int stripeHeight = height / numStripes;
+
+ // Iterate through the image twice. Once to decode odd stripes, and once for even.
+ for (int oddEven = 1; oddEven >= 0; oddEven--) {
+ for (int y = oddEven * stripeHeight; y < height; y += 2 * stripeHeight) {
+ SkIRect subset = SkIRect::MakeLTRB(0, y, info.width(),
+ SkTMin(y + stripeHeight, height));
+ SkCodec::Options options;
+ options.fSubset = &subset;
+ if (SkCodec::kSuccess != codec->startIncrementalDecode(info, bm.getAddr(0, y),
+ bm.rowBytes(), &options)) {
+ ERRORF(r, "failed to start incremental decode!\ttop: %i\tbottom%i\n",
+ subset.top(), subset.bottom());
+ return;
+ }
+ if (SkCodec::kSuccess != codec->incrementalDecode()) {
+ ERRORF(r, "failed incremental decode starting from line %i\n", y);
+ return;
+ }
+ }
+ }
+
+ compare_to_good_digest(r, goodDigest, bm);
+}
+
template<typename Codec>
static void test_codec(skiatest::Reporter* r, Codec* codec, SkBitmap& bm, const SkImageInfo& info,
const SkISize& size, SkCodec::Result expectedResult, SkMD5::Digest* digest,
@@ -151,12 +207,14 @@ static bool supports_partial_scanlines(const char path[]) {
return false;
}
+// FIXME: Break up this giant function
static void check(skiatest::Reporter* r,
const char path[],
SkISize size,
bool supportsScanlineDecoding,
bool supportsSubsetDecoding,
- bool supportsIncomplete = true) {
+ bool supportsIncomplete,
+ bool supportsNewScanlineDecoding = false) {
SkAutoTDelete<SkStream> stream(resource(path));
if (!stream) {
@@ -186,12 +244,15 @@ static void check(skiatest::Reporter* r,
test_codec(r, codec.get(), bm, info, size, expectedResult, &codecDigest, nullptr);
// Scanline decoding follows.
- // Need to call startScanlineDecode() first.
- REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
- == 0);
- REPORTER_ASSERT(r, codec->skipScanlines(1)
- == 0);
+ if (supportsNewScanlineDecoding && !isIncomplete) {
+ test_incremental_decode(r, codec, info, codecDigest);
+ test_in_stripes(r, codec, info, codecDigest);
+ }
+
+ // Need to call startScanlineDecode() first.
+ REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) == 0);
+ REPORTER_ASSERT(r, !codec->skipScanlines(1));
const SkCodec::Result startResult = codec->startScanlineDecode(info);
if (supportsScanlineDecoding) {
bm.eraseColor(SK_ColorYELLOW);
@@ -286,7 +347,7 @@ static void check(skiatest::Reporter* r,
}
// SkAndroidCodec tests
- if (supportsScanlineDecoding || supportsSubsetDecoding) {
+ if (supportsScanlineDecoding || supportsSubsetDecoding || supportsNewScanlineDecoding) {
SkAutoTDelete<SkStream> stream(resource(path));
if (!stream) {
@@ -343,16 +404,16 @@ static void check(skiatest::Reporter* r,
DEF_TEST(Codec, r) {
// WBMP
- check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false);
+ check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false, true);
// WEBP
- check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true);
- check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true);
- check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true);
+ check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true, true);
+ check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true, true);
+ check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true, true);
// BMP
- check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false);
- check(r, "rle.bmp", SkISize::Make(320, 240), true, false);
+ check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false, true);
+ check(r, "rle.bmp", SkISize::Make(320, 240), true, false, true);
// ICO
// FIXME: We are not ready to test incomplete ICOs
@@ -360,7 +421,7 @@ DEF_TEST(Codec, r) {
// Decodes an embedded BMP image
check(r, "color_wheel.ico", SkISize::Make(128, 128), true, false, false);
// Decodes an embedded PNG image
- check(r, "google_chrome.ico", SkISize::Make(256, 256), true, false, false);
+ check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, false, true);
// GIF
// FIXME: We are not ready to test incomplete GIFs
@@ -370,30 +431,30 @@ DEF_TEST(Codec, r) {
check(r, "randPixels.gif", SkISize::Make(8, 8), true, false, false);
// JPG
- check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false);
- check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false);
+ check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, true);
+ check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false, true);
// grayscale.jpg is too small to test incomplete
check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false, false);
- check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false);
+ check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false, true);
// randPixels.jpg is too small to test incomplete
check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false, false);
// PNG
- check(r, "arrow.png", SkISize::Make(187, 312), true, false, false);
- check(r, "baby_tux.png", SkISize::Make(240, 246), true, false, false);
- check(r, "color_wheel.png", SkISize::Make(128, 128), true, false, false);
- check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, false, false);
- check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false, false);
- check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false, false);
- check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false, false);
- check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false, false);
- check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false, false);
- check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false, false);
- check(r, "plane.png", SkISize::Make(250, 126), true, false, false);
- // FIXME: We are not ready to test incomplete interlaced pngs
- check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false, false);
- check(r, "randPixels.png", SkISize::Make(8, 8), true, false, false);
- check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false, false);
+ check(r, "arrow.png", SkISize::Make(187, 312), false, false, true, true);
+ check(r, "baby_tux.png", SkISize::Make(240, 246), false, false, true, true);
+ check(r, "color_wheel.png", SkISize::Make(128, 128), false, false, true, true);
+ // half-transparent-white-pixel.png is too small to test incomplete
+ check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), false, false, false, true);
+ check(r, "mandrill_128.png", SkISize::Make(128, 128), false, false, true, true);
+ check(r, "mandrill_16.png", SkISize::Make(16, 16), false, false, true, true);
+ check(r, "mandrill_256.png", SkISize::Make(256, 256), false, false, true, true);
+ check(r, "mandrill_32.png", SkISize::Make(32, 32), false, false, true, true);
+ check(r, "mandrill_512.png", SkISize::Make(512, 512), false, false, true, true);
+ check(r, "mandrill_64.png", SkISize::Make(64, 64), false, false, true, true);
+ check(r, "plane.png", SkISize::Make(250, 126), false, false, true, true);
+ check(r, "plane_interlaced.png", SkISize::Make(250, 126), false, false, true, true);
+ check(r, "randPixels.png", SkISize::Make(8, 8), false, false, true, true);
+ check(r, "yellow_rose.png", SkISize::Make(400, 301), false, false, true, true);
// RAW
// Disable RAW tests for Win32.
@@ -404,97 +465,6 @@ DEF_TEST(Codec, r) {
#endif
}
-// 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.release()));
- 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
- bool skipResult = codec->skipScanlines(stripeHeight);
- REPORTER_ASSERT(r, skipResult);
-
- int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeight,
- bm.rowBytes());
- REPORTER_ASSERT(r, linesDecoded == stripeHeight);
- }
-
- // Even stripes
- result = codec->startScanlineDecode(info);
- REPORTER_ASSERT(r, result == SkCodec::kSuccess);
-
- for (int i = 0; i < numStripes; i += 2) {
- int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeight,
- bm.rowBytes());
- REPORTER_ASSERT(r, linesDecoded == stripeHeight);
-
- // Skip the odd stripes
- if (i + 1 < numStripes) {
- bool skipResult = codec->skipScanlines(stripeHeight);
- REPORTER_ASSERT(r, skipResult);
- }
- }
-
- // Remainder at the end
- if (remainingLines > 0) {
- result = codec->startScanlineDecode(info);
- REPORTER_ASSERT(r, result == SkCodec::kSuccess);
-
- bool skipResult = codec->skipScanlines(height - remainingLines);
- REPORTER_ASSERT(r, skipResult);
-
- int linesDecoded = codec->getScanlines(bm.getAddr(0, height - remainingLines),
- remainingLines, bm.rowBytes());
- REPORTER_ASSERT(r, linesDecoded == remainingLines);
- }
-
- compare_to_good_digest(r, digest, bm);
-}
-
static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_t len) {
// Neither of these calls should return a codec. Bots should catch us if we leaked anything.
SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, false));
@@ -638,25 +608,36 @@ static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) {
}
SkAutoTDelete<SkCodec> decoder(SkCodec::NewFromStream(stream.release()));
+ const SkImageInfo info = decoder->getInfo().makeColorType(kIndex_8_SkColorType);
+
// This should return kSuccess because kIndex8 is supported.
SkPMColor colorStorage[256];
int colorCount;
- 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
- if (SkCodec::kSuccess != result) {
+ SkCodec::Result result = decoder->startScanlineDecode(info, nullptr, colorStorage,
+ &colorCount);
+ if (SkCodec::kSuccess == result) {
+ // This should return kInvalidParameters because, in kIndex_8 mode, we must pass in a valid
+ // colorPtr and a valid colorCountPtr.
+ result = decoder->startScanlineDecode(info, nullptr, nullptr, nullptr);
+ REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
+ result = decoder->startScanlineDecode(info);
+ REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
+ } else if (SkCodec::kUnimplemented == result) {
+ // New method should be supported:
+ SkBitmap bm;
+ sk_sp<SkColorTable> colorTable(new SkColorTable(colorStorage, 256));
+ bm.allocPixels(info, nullptr, colorTable.get());
+ result = decoder->startIncrementalDecode(info, bm.getPixels(), bm.rowBytes(), nullptr,
+ colorStorage, &colorCount);
+ REPORTER_ASSERT(r, SkCodec::kSuccess == result);
+ result = decoder->startIncrementalDecode(info, bm.getPixels(), bm.rowBytes());
+ REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
+ } else {
+ // The test is uninteresting if kIndex8 is not supported
+ ERRORF(r, "Should not call test_invalid_parameters for non-Index8 file: %s\n", path);
return;
}
- // This should return kInvalidParameters because, in kIndex_8 mode, we must pass in a valid
- // colorPtr and a valid colorCountPtr.
- result = decoder->startScanlineDecode(
- decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, nullptr, nullptr);
- REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
- result = decoder->startScanlineDecode(
- decoder->getInfo().makeColorType(kIndex_8_SkColorType));
- REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
}
DEF_TEST(Codec_Params, r) {
« src/codec/SkSampler.h ('K') | « tests/CodecPartial.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698