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:
parent
cb54e8ed45
commit
cc7f305c69
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user