SkScaledCodec should implement onRewind()

This is a bug fix.  I'm also adding a test.

BUG=skia:

Review URL: https://codereview.chromium.org/1385703002
This commit is contained in:
msarett 2015-10-05 14:20:27 -07:00 committed by Commit bot
parent cb54e8ed45
commit cc7f305c69
3 changed files with 62 additions and 33 deletions

View File

@ -26,6 +26,8 @@ public:
int* sampleSizeX, int* sampleSizeY); int* sampleSizeX, int* sampleSizeY);
protected: protected:
bool onRewind() override;
/** /**
* Recommend a set of destination dimensions given a requested scale * Recommend a set of destination dimensions given a requested scale
*/ */

View File

@ -44,6 +44,10 @@ SkScaledCodec::SkScaledCodec(SkCodec* codec)
SkScaledCodec::~SkScaledCodec() {} SkScaledCodec::~SkScaledCodec() {}
bool SkScaledCodec::onRewind() {
return fCodec->onRewind();
}
static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& nativeDims, static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& nativeDims,
const SkISize& scaledCodecDims, float desiredScale) { const SkISize& scaledCodecDims, float desiredScale) {
if (nativeDims == scaledCodecDims) { if (nativeDims == scaledCodecDims) {

View File

@ -74,39 +74,20 @@ SkIRect generate_random_subset(SkRandom* rand, int w, int h) {
return rect; return rect;
} }
static void check(skiatest::Reporter* r, static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, const SkImageInfo& info,
const char path[], const SkISize& size, bool supports565, SkMD5::Digest* digest,
SkISize size, const SkMD5::Digest* goodDigest) {
bool supportsScanlineDecoding,
bool supportsSubsetDecoding,
bool supports565 = true) {
SkAutoTDelete<SkStream> stream(resource(path));
if (!stream) {
SkDebugf("Missing resource '%s'\n", path);
return;
}
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
if (!codec) {
ERRORF(r, "Unable to decode '%s'", path);
return;
}
// This test is used primarily to verify rewinding works properly. Using kN32 allows
// us to test this without the added overhead of creating different bitmaps depending
// on the color type (ex: building a color table for kIndex8). DM is where we test
// decodes to all possible destination color types.
SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
REPORTER_ASSERT(r, info.dimensions() == size); REPORTER_ASSERT(r, info.dimensions() == size);
SkBitmap bm;
bm.allocPixels(info); bm.allocPixels(info);
SkAutoLockPixels autoLockPixels(bm); SkAutoLockPixels autoLockPixels(bm);
SkCodec::Result result =
codec->getPixels(info, bm.getPixels(), bm.rowBytes(), nullptr, nullptr, nullptr); SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes());
REPORTER_ASSERT(r, result == SkCodec::kSuccess); REPORTER_ASSERT(r, result == SkCodec::kSuccess);
SkMD5::Digest digest; md5(bm, digest);
md5(bm, &digest); if (goodDigest) {
REPORTER_ASSERT(r, *digest == *goodDigest);
}
{ {
// Test decoding to 565 // Test decoding to 565
@ -120,7 +101,7 @@ static void check(skiatest::Reporter* r,
// a decode to 565, since choosing to decode to 565 may result in some of the decode // a decode to 565, since choosing to decode to 565 may result in some of the decode
// options being modified. These options should return to their defaults on another // options being modified. These options should return to their defaults on another
// decode to kN32, so the new digest should match the old digest. // decode to kN32, so the new digest should match the old digest.
test_info(r, codec, info, SkCodec::kSuccess, &digest); test_info(r, codec, info, SkCodec::kSuccess, digest);
{ {
// Check alpha type conversions // Check alpha type conversions
@ -143,10 +124,34 @@ static void check(skiatest::Reporter* r,
test_info(r, codec, info.makeAlphaType(otherAt), SkCodec::kSuccess, nullptr); test_info(r, codec, info.makeAlphaType(otherAt), SkCodec::kSuccess, nullptr);
} }
} }
}
static void check(skiatest::Reporter* r,
const char path[],
SkISize size,
bool supportsScanlineDecoding,
bool supportsSubsetDecoding,
bool supports565 = true) {
SkAutoTDelete<SkStream> stream(resource(path));
if (!stream) {
SkDebugf("Missing resource '%s'\n", path);
return;
}
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
if (!codec) {
ERRORF(r, "Unable to decode '%s'", path);
return;
}
// Test full image decodes with SkCodec
SkMD5::Digest codecDigest;
SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
SkBitmap bm;
test_codec(r, codec, bm, info, size, supports565, &codecDigest, nullptr);
// Scanline decoding follows. // Scanline decoding follows.
// Need to call startScanlineDecode() first.
// Need to call start() first.
REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
== SkCodec::kScanlineDecodingNotStarted); == SkCodec::kScanlineDecodingNotStarted);
REPORTER_ASSERT(r, codec->skipScanlines(1) REPORTER_ASSERT(r, codec->skipScanlines(1)
@ -159,12 +164,12 @@ static void check(skiatest::Reporter* r,
REPORTER_ASSERT(r, startResult == SkCodec::kSuccess); REPORTER_ASSERT(r, startResult == SkCodec::kSuccess);
for (int y = 0; y < info.height(); y++) { for (int y = 0; y < info.height(); y++) {
result = codec->getScanlines(bm.getAddr(0, y), 1, 0); SkCodec::Result result = codec->getScanlines(bm.getAddr(0, y), 1, 0);
REPORTER_ASSERT(r, result == SkCodec::kSuccess); REPORTER_ASSERT(r, result == SkCodec::kSuccess);
} }
// verify that scanline decoding gives the same result. // verify that scanline decoding gives the same result.
if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) { if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) {
compare_to_good_digest(r, digest, bm); compare_to_good_digest(r, codecDigest, bm);
} }
// Cannot continue to decode scanlines beyond the end // Cannot continue to decode scanlines beyond the end
@ -220,6 +225,24 @@ static void check(skiatest::Reporter* r,
REPORTER_ASSERT(r, result == SkCodec::kUnimplemented); REPORTER_ASSERT(r, result == SkCodec::kUnimplemented);
} }
} }
// SkScaledCodec tests
if (supportsScanlineDecoding || supportsSubsetDecoding){
SkAutoTDelete<SkStream> stream(resource(path));
if (!stream) {
SkDebugf("Missing resource '%s'\n", path);
return;
}
SkAutoTDelete<SkCodec> codec(SkScaledCodec::NewFromStream(stream.detach()));
if (!codec) {
ERRORF(r, "Unable to decode '%s'", path);
return;
}
SkBitmap bm;
SkMD5::Digest scaledCodecDigest;
test_codec(r, codec, bm, info, size, supports565, &scaledCodecDigest, &codecDigest);
}
} }
DEF_TEST(Codec, r) { DEF_TEST(Codec, r) {