diff options
author | 2015-03-19 06:03:39 -0700 | |
---|---|---|
committer | 2015-03-19 06:03:39 -0700 | |
commit | 9b77ddde08efe702256355a333cf31ade8f15bb0 (patch) | |
tree | b3bc069a191e747bf5107740d5b3b9b3fc84d1e2 /dm | |
parent | effcba4a4d1a6fdfdd5ec440e10e1424b768182d (diff) |
Run CodecSrc DM.
Rather than making SkCodec an option instead of SkImageDecoder,
create a separate CodecSrc. This allows us to compare the two.
For both CodecSrc and ImageSrc, do not decode to a gpu backend.
BUG=skia:3475
Review URL: https://codereview.chromium.org/978823002
Diffstat (limited to 'dm')
-rw-r--r-- | dm/DM.cpp | 12 | ||||
-rw-r--r-- | dm/DMSrcSink.cpp | 156 | ||||
-rw-r--r-- | dm/DMSrcSink.h | 12 |
3 files changed, 114 insertions, 66 deletions
@@ -18,7 +18,7 @@ #include "Test.h" #include "Timer.h" -DEFINE_string(src, "tests gm skp image subset", "Source types to test."); +DEFINE_string(src, "tests gm skp image subset codec", "Source types to test."); DEFINE_bool(nameByHash, false, "If true, write to FLAGS_writePath[0]/<hash>.png instead of " "to FLAGS_writePath[0]/<config>/<sourceType>/<name>.png"); @@ -148,6 +148,12 @@ static void push_src(const char* tag, Src* s) { } } +static bool codec_supported(const char* ext) { + // FIXME: Once other versions of SkCodec are available, we can add them to this + // list (and eventually we can remove this check once they are all supported). + return strcmp(ext, "png") == 0 || strcmp(ext, "PNG") == 0; +} + static void gather_srcs() { for (const skiagm::GMRegistry* r = skiagm::GMRegistry::Head(); r; r = r->next()) { push_src("gm", new GMSrc(r->factory())); @@ -176,12 +182,16 @@ static void gather_srcs() { SkString path = SkOSPath::Join(flag, file.c_str()); push_src("image", new ImageSrc(path)); // Decode entire image. push_src("subset", new ImageSrc(path, 2)); // Decode into 2 x 2 subsets + if (codec_supported(exts[j])) { + push_src("codec", new CodecSrc(path)); // Decode with SkCodec. + } } } } else if (sk_exists(flag)) { // assume that FLAGS_images[i] is a valid image if it is a file. push_src("image", new ImageSrc(flag)); // Decode entire image. push_src("subset", new ImageSrc(flag, 2)); // Decode into 2 x 2 subsets + push_src("codec", new CodecSrc(flag)); // Decode with SkCodec. } } } diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 6f6664f27c..7bbdff73bc 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -14,8 +14,6 @@ #include "SkStream.h" #include "SkXMLWriter.h" -DEFINE_bool(codec, false, "Use SkCodec instead of SkImageDecoder"); - namespace DM { GMSrc::GMSrc(skiagm::GMRegistry::Factory factory) : fFactory(factory) {} @@ -39,59 +37,99 @@ Name GMSrc::name() const { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +CodecSrc::CodecSrc(Path path) : fPath(path) {} + +Error CodecSrc::draw(SkCanvas* canvas) const { + SkImageInfo canvasInfo; + if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { + // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a deferred decode to + // let the GPU handle it. + return Error::Nonfatal("No need to test decoding to non-raster backend."); + } + + SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); + if (!encoded) { + return SkStringPrintf("Couldn't read %s.", fPath.c_str()); + } + + SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); + if (!codec) { + return SkStringPrintf("Couldn't decode %s.", fPath.c_str()); + } + + SkImageInfo decodeInfo; + if (!codec->getInfo(&decodeInfo)) { + return SkStringPrintf("Couldn't getInfo %s.", fPath.c_str()); + } + + decodeInfo = decodeInfo.makeColorType(canvasInfo.colorType()); + if (decodeInfo.alphaType() == kUnpremul_SkAlphaType) { + // FIXME: Currently we cannot draw unpremultiplied sources. + decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType); + } + + SkBitmap bitmap; + if (!bitmap.tryAllocPixels(decodeInfo)) { + return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str(), + decodeInfo.width(), decodeInfo.height()); + } + + SkAutoLockPixels alp(bitmap); + switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes())) { + case SkImageGenerator::kSuccess: + // We consider incomplete to be valid, since we should still decode what is + // available. + case SkImageGenerator::kIncompleteInput: + canvas->drawBitmap(bitmap, 0, 0); + return ""; + case SkImageGenerator::kInvalidConversion: + return Error::Nonfatal("Incompatible colortype conversion"); + default: + // Everything else is considered a failure. + return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str()); + } +} + +SkISize CodecSrc::size() const { + SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); + SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); + SkImageInfo info; + if (codec && codec->getInfo(&info)) { + return info.dimensions(); + } + return SkISize::Make(0,0); +} + +Name CodecSrc::name() const { + return SkOSPath::Basename(fPath.c_str()); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {} Error ImageSrc::draw(SkCanvas* canvas) const { + SkImageInfo canvasInfo; + if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { + // TODO: Instead, use lazy decoding to allow the GPU to handle cases like YUV. + return Error::Nonfatal("No need to test decoding to non-raster backend."); + } + SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); if (!encoded) { return SkStringPrintf("Couldn't read %s.", fPath.c_str()); } - const SkColorType dstColorType = canvas->imageInfo().colorType(); + const SkColorType dstColorType = canvasInfo.colorType(); if (fDivisor == 0) { // Decode the full image. SkBitmap bitmap; - if (FLAGS_codec) { - SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); - if (!codec) { - return SkStringPrintf("Couldn't decode %s.", fPath.c_str()); - } - SkImageInfo info; - if (!codec->getInfo(&info)) { - return SkStringPrintf("Couldn't getInfo %s.", fPath.c_str()); - } - info = info.makeColorType(dstColorType); - if (info.alphaType() == kUnpremul_SkAlphaType) { - // FIXME: Currently we cannot draw unpremultiplied sources. - info = info.makeAlphaType(kPremul_SkAlphaType); - } - if (!bitmap.tryAllocPixels(info)) { - return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str(), - info.width(), info.height()); - } - SkAutoLockPixels alp(bitmap); - const SkImageGenerator::Result result = codec->getPixels(info, bitmap.getPixels(), - bitmap.rowBytes()); - switch (result) { - case SkImageGenerator::kSuccess: - // We consider incomplete to be valid, since we should still decode what is - // available. - case SkImageGenerator::kIncompleteInput: - break; - case SkImageGenerator::kInvalidConversion: - return Error::Nonfatal("Incompatible colortype conversion"); - default: - // Everything else is considered a failure. - return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str()); - } - } else { - if (!SkImageDecoder::DecodeMemory(encoded->data(), encoded->size(), &bitmap, - dstColorType, SkImageDecoder::kDecodePixels_Mode)) { - return SkStringPrintf("Couldn't decode %s.", fPath.c_str()); - } - if (kRGB_565_SkColorType == dstColorType && !bitmap.isOpaque()) { - // Do not draw a bitmap with alpha to a destination without alpha. - return Error::Nonfatal("Uninteresting to decode image with alpha into 565."); - } + if (!SkImageDecoder::DecodeMemory(encoded->data(), encoded->size(), &bitmap, + dstColorType, SkImageDecoder::kDecodePixels_Mode)) { + return SkStringPrintf("Couldn't decode %s.", fPath.c_str()); + } + if (kRGB_565_SkColorType == dstColorType && !bitmap.isOpaque()) { + // Do not draw a bitmap with alpha to a destination without alpha. + return Error::Nonfatal("Uninteresting to decode image with alpha into 565."); } encoded.reset((SkData*)NULL); // Might as well drop this when we're done with it. canvas->drawBitmap(bitmap, 0,0); @@ -141,27 +179,15 @@ Error ImageSrc::draw(SkCanvas* canvas) const { SkISize ImageSrc::size() const { SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); - if (FLAGS_codec) { - SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); - if (!codec) { - return SkISize::Make(0,0); - } - SkImageInfo info; - if (!codec->getInfo(&info)) { - return SkISize::Make(0,0); - } - return info.dimensions(); - } else { - SkBitmap bitmap; - if (!encoded || !SkImageDecoder::DecodeMemory(encoded->data(), - encoded->size(), - &bitmap, - kUnknown_SkColorType, - SkImageDecoder::kDecodeBounds_Mode)) { - return SkISize::Make(0,0); - } - return bitmap.dimensions(); + SkBitmap bitmap; + if (!encoded || !SkImageDecoder::DecodeMemory(encoded->data(), + encoded->size(), + &bitmap, + kUnknown_SkColorType, + SkImageDecoder::kDecodeBounds_Mode)) { + return SkISize::Make(0,0); } + return bitmap.dimensions(); } Name ImageSrc::name() const { diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index dcd169e322..364afe0e11 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -81,6 +81,18 @@ private: skiagm::GMRegistry::Factory fFactory; }; +class CodecSrc : public Src { +public: + explicit CodecSrc(Path path); + + Error draw(SkCanvas*) const SK_OVERRIDE; + SkISize size() const SK_OVERRIDE; + Name name() const SK_OVERRIDE; +private: + Path fPath; +}; + + class ImageSrc : public Src { public: // divisor == 0 means decode the whole image |