Index: tools/get_images_from_skps.cpp |
diff --git a/tools/get_images_from_skps.cpp b/tools/get_images_from_skps.cpp |
index e6bb6e2012190698ebda8359826f7d36be275861..46f6ef484503069413e7b39a7f65985d2922e165 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 <map> |
+ |
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. Wll not be " |
msarett
2016/04/25 15:29:53
nit: *Will
rmistry
2016/04/25 17:11:45
Oops. Done.
|
+ "written anywhere if empty."); |
static int gKnown; |
-static int gUnknown; |
static const char* gOutputDir; |
+static std::map<std::string, unsigned int> gSkpToUnknownCount = {}; |
static SkTHashSet<SkMD5::Digest> 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,8 @@ struct Sniffer : public SkPixelSerializer { |
SkAutoTUnref<SkData> data(SkData::NewWithoutCopy(ptr, len)); |
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data)); |
if (!codec) { |
- gUnknown++; |
+ SkDebugf("Codec could not be created for %s\n", skpName.c_str()); |
msarett
2016/04/25 15:29:53
I believe this is unreachable... Looks like we cr
rmistry
2016/04/25 17:11:45
Done.
|
+ gSkpToUnknownCount[skpName]++; |
return; |
} |
SkString ext; |
@@ -53,16 +70,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: |
+ SkDebugf("Unrecognized encoded format for %s\n", skpName.c_str()); |
msarett
2016/04/25 15:29:53
I think this is also unreachable - just because we
rmistry
2016/04/25 17:11:45
Done.
|
+ gSkpToUnknownCount[skpName]++; |
+ return; |
} |
- 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())) |
msarett
2016/04/25 15:29:53
Our dm tests treat kSuccess and kIncompleteInput a
rmistry
2016/04/25 17:11:45
k, lets leave this in for now. I am guessing we wi
|
+ { |
+ 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 +110,8 @@ struct Sniffer : public SkPixelSerializer { |
int main(int argc, char** argv) { |
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); |
const char* inputs = FLAGS_skps[0]; |
@@ -93,10 +129,38 @@ int main(int argc, char** argv) { |
sk_sp<SkPicture> 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; |
} |