From 8d965a612e3963e039fa19e74c09d942398c611a Mon Sep 17 00:00:00 2001 From: rmistry Date: Mon, 25 Apr 2016 10:35:03 -0700 Subject: Test decoding and output failures to JSON in get_images_from_skps. Testing for decoding was copy pasted from msarett's CL https://codereview.chromium.org/1828323002/ BUG=skia:4981 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1844713003 Review URL: https://codereview.chromium.org/1844713003 --- tools/get_images_from_skps.cpp | 88 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 11 deletions(-) (limited to 'tools/get_images_from_skps.cpp') diff --git a/tools/get_images_from_skps.cpp b/tools/get_images_from_skps.cpp index e6bb6e2012..f963b9a86b 100644 --- a/tools/get_images_from_skps.cpp +++ b/tools/get_images_from_skps.cpp @@ -5,9 +5,11 @@ * found in the LICENSE file. */ +#include "SkBitmap.h" #include "SkCodec.h" #include "SkCommandLineFlags.h" #include "SkData.h" +#include "SkJSONCPP.h" #include "SkMD5.h" #include "SkOSFile.h" #include "SkPicture.h" @@ -15,17 +17,31 @@ #include "SkStream.h" #include "SkTHash.h" + +#include + DEFINE_string2(skps, s, "skps", "A path to a directory of skps."); DEFINE_string2(out, o, "img-out", "A path to an output directory."); +DEFINE_bool(testDecode, false, "Indicates if we want to test that the images decode successfully."); +DEFINE_bool(writeImages, true, "Indicates if we want to write out images."); +DEFINE_string2(failuresJsonPath, j, "", + "Dump SKP and count of unknown images to the specified JSON file. Will not be " + "written anywhere if empty."); static int gKnown; -static int gUnknown; static const char* gOutputDir; +static std::map gSkpToUnknownCount = {}; static SkTHashSet gSeen; struct Sniffer : public SkPixelSerializer { + std::string skpName; + + Sniffer(std::string name) { + skpName = name; + } + void sniff(const void* ptr, size_t len) { SkMD5 md5; md5.write(ptr, len); @@ -40,7 +56,10 @@ struct Sniffer : public SkPixelSerializer { SkAutoTUnref data(SkData::NewWithoutCopy(ptr, len)); SkAutoTDelete codec(SkCodec::NewFromData(data)); if (!codec) { - gUnknown++; + // FIXME: This code is currently unreachable because we create an empty generator when + // we fail to create a codec. + SkDebugf("Codec could not be created for %s\n", skpName.c_str()); + gSkpToUnknownCount[skpName]++; return; } SkString ext; @@ -53,16 +72,34 @@ struct Sniffer : public SkPixelSerializer { case SkEncodedFormat::kDNG_SkEncodedFormat: ext = "dng"; break; case SkEncodedFormat::kWBMP_SkEncodedFormat: ext = "wbmp"; break; case SkEncodedFormat::kWEBP_SkEncodedFormat: ext = "webp"; break; - default: gUnknown++; return; + default: + // This should be unreachable because we cannot create a codec if we do not know + // the image type. + SkASSERT(false); } - SkString path; - path.appendf("%s/%d.%s", gOutputDir, gKnown++, ext.c_str()); + if (FLAGS_testDecode) { + SkBitmap bitmap; + SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); + bitmap.allocPixels(info); + if (SkCodec::kSuccess != codec->getPixels(info, bitmap.getPixels(), bitmap.rowBytes())) + { + SkDebugf("Decoding failed for %s\n", skpName.c_str()); + gSkpToUnknownCount[skpName]++; + return; + } + } + + if (FLAGS_writeImages) { + SkString path; + path.appendf("%s/%d.%s", gOutputDir, gKnown, ext.c_str()); - SkFILEWStream file(path.c_str()); - file.write(ptr, len); + SkFILEWStream file(path.c_str()); + file.write(ptr, len); - SkDebugf("%s\n", path.c_str()); + SkDebugf("%s\n", path.c_str()); + } + gKnown++; } bool onUseEncodedData(const void* ptr, size_t len) override { @@ -75,7 +112,8 @@ struct Sniffer : public SkPixelSerializer { int main(int argc, char** argv) { SkCommandLineFlags::SetUsage( - "Usage: get_images_from_skps -s -o \n"); + "Usage: get_images_from_skps -s -o --testDecode " + "-j \n"); SkCommandLineFlags::Parse(argc, argv); const char* inputs = FLAGS_skps[0]; @@ -93,10 +131,38 @@ int main(int argc, char** argv) { sk_sp picture(SkPicture::MakeFromStream(stream)); SkDynamicMemoryWStream scratch; - Sniffer sniff; + Sniffer sniff(file.c_str()); picture->serialize(&scratch, &sniff); } - SkDebugf("%d known, %d unknown\n", gKnown, gUnknown); + int totalUnknowns = 0; + /** + JSON results are written out in the following format: + { + "failures": { + "skp1": 12, + "skp4": 2, + ... + }, + "totalFailures": 32, + "totalSuccesses": 21, + } + */ + Json::Value fRoot; + for(auto it = gSkpToUnknownCount.cbegin(); it != gSkpToUnknownCount.cend(); ++it) + { + SkDebugf("%s %d\n", it->first.c_str(), it->second); + totalUnknowns += it->second; + fRoot["failures"][it->first.c_str()] = it->second; + } + SkDebugf("%d known, %d unknown\n", gKnown, totalUnknowns); + fRoot["totalFailures"] = totalUnknowns; + fRoot["totalSuccesses"] = gKnown; + if (totalUnknowns > 0 && !FLAGS_failuresJsonPath.isEmpty()) { + SkDebugf("Writing failures to %s\n", FLAGS_failuresJsonPath[0]); + SkFILEWStream stream(FLAGS_failuresJsonPath[0]); + stream.writeText(Json::StyledWriter().write(fRoot).c_str()); + stream.flush(); + } return 0; } -- cgit v1.2.3