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
This commit is contained in:
rmistry 2016-04-25 10:35:03 -07:00 committed by Commit bot
parent 484b3d0b83
commit 8d965a612e
2 changed files with 78 additions and 11 deletions

View File

@ -278,6 +278,7 @@
], ],
'dependencies': [ 'dependencies': [
'flags.gyp:flags', 'flags.gyp:flags',
'jsoncpp.gyp:jsoncpp',
'skia_lib.gyp:skia_lib', 'skia_lib.gyp:skia_lib',
], ],
}, },

View File

@ -5,9 +5,11 @@
* found in the LICENSE file. * found in the LICENSE file.
*/ */
#include "SkBitmap.h"
#include "SkCodec.h" #include "SkCodec.h"
#include "SkCommandLineFlags.h" #include "SkCommandLineFlags.h"
#include "SkData.h" #include "SkData.h"
#include "SkJSONCPP.h"
#include "SkMD5.h" #include "SkMD5.h"
#include "SkOSFile.h" #include "SkOSFile.h"
#include "SkPicture.h" #include "SkPicture.h"
@ -15,17 +17,31 @@
#include "SkStream.h" #include "SkStream.h"
#include "SkTHash.h" #include "SkTHash.h"
#include <map>
DEFINE_string2(skps, s, "skps", "A path to a directory of skps."); 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_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 gKnown;
static int gUnknown;
static const char* gOutputDir; static const char* gOutputDir;
static std::map<std::string, unsigned int> gSkpToUnknownCount = {};
static SkTHashSet<SkMD5::Digest> gSeen; static SkTHashSet<SkMD5::Digest> gSeen;
struct Sniffer : public SkPixelSerializer { struct Sniffer : public SkPixelSerializer {
std::string skpName;
Sniffer(std::string name) {
skpName = name;
}
void sniff(const void* ptr, size_t len) { void sniff(const void* ptr, size_t len) {
SkMD5 md5; SkMD5 md5;
md5.write(ptr, len); md5.write(ptr, len);
@ -40,7 +56,10 @@ struct Sniffer : public SkPixelSerializer {
SkAutoTUnref<SkData> data(SkData::NewWithoutCopy(ptr, len)); SkAutoTUnref<SkData> data(SkData::NewWithoutCopy(ptr, len));
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data)); SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data));
if (!codec) { 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; return;
} }
SkString ext; SkString ext;
@ -53,17 +72,35 @@ struct Sniffer : public SkPixelSerializer {
case SkEncodedFormat::kDNG_SkEncodedFormat: ext = "dng"; break; case SkEncodedFormat::kDNG_SkEncodedFormat: ext = "dng"; break;
case SkEncodedFormat::kWBMP_SkEncodedFormat: ext = "wbmp"; break; case SkEncodedFormat::kWBMP_SkEncodedFormat: ext = "wbmp"; break;
case SkEncodedFormat::kWEBP_SkEncodedFormat: ext = "webp"; 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);
} }
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; SkString path;
path.appendf("%s/%d.%s", gOutputDir, gKnown++, ext.c_str()); path.appendf("%s/%d.%s", gOutputDir, gKnown, ext.c_str());
SkFILEWStream file(path.c_str()); SkFILEWStream file(path.c_str());
file.write(ptr, len); 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 { bool onUseEncodedData(const void* ptr, size_t len) override {
this->sniff(ptr, len); this->sniff(ptr, len);
@ -75,7 +112,8 @@ struct Sniffer : public SkPixelSerializer {
int main(int argc, char** argv) { int main(int argc, char** argv) {
SkCommandLineFlags::SetUsage( SkCommandLineFlags::SetUsage(
"Usage: get_images_from_skps -s <dir of skps> -o <dir for output images>\n"); "Usage: get_images_from_skps -s <dir of skps> -o <dir for output images> --testDecode "
"-j <output JSON path>\n");
SkCommandLineFlags::Parse(argc, argv); SkCommandLineFlags::Parse(argc, argv);
const char* inputs = FLAGS_skps[0]; const char* inputs = FLAGS_skps[0];
@ -93,10 +131,38 @@ int main(int argc, char** argv) {
sk_sp<SkPicture> picture(SkPicture::MakeFromStream(stream)); sk_sp<SkPicture> picture(SkPicture::MakeFromStream(stream));
SkDynamicMemoryWStream scratch; SkDynamicMemoryWStream scratch;
Sniffer sniff; Sniffer sniff(file.c_str());
picture->serialize(&scratch, &sniff); 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; return 0;
} }