/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkCodec.h" #include "SkCommandLineFlags.h" #include "SkData.h" #include "SkMD5.h" #include "SkOSFile.h" #include "SkPicture.h" #include "SkPixelSerializer.h" #include "SkStream.h" #include "SkTHash.h" DEFINE_string2(skps, s, "skps", "A path to a directory of skps."); DEFINE_string2(out, o, "img-out", "A path to an output directory."); static int gKnown; static int gUnknown; static const char* gOutputDir; static SkTHashSet gSeen; struct Sniffer : public SkPixelSerializer { void sniff(const void* ptr, size_t len) { SkMD5 md5; md5.write(ptr, len); SkMD5::Digest digest; md5.finish(digest); if (gSeen.contains(digest)) { return; } gSeen.add(digest); SkAutoTUnref data(SkData::NewWithoutCopy(ptr, len)); SkAutoTDelete codec(SkCodec::NewFromData(data)); if (!codec) { gUnknown++; return; } SkString ext; switch (codec->getEncodedFormat()) { case SkEncodedFormat::kBMP_SkEncodedFormat: ext = "bmp"; break; case SkEncodedFormat::kGIF_SkEncodedFormat: ext = "gif"; break; case SkEncodedFormat::kICO_SkEncodedFormat: ext = "ico"; break; case SkEncodedFormat::kJPEG_SkEncodedFormat: ext = "jpg"; break; case SkEncodedFormat::kPNG_SkEncodedFormat: ext = "png"; break; case SkEncodedFormat::kDNG_SkEncodedFormat: ext = "dng"; break; case SkEncodedFormat::kWBMP_SkEncodedFormat: ext = "wbmp"; break; case SkEncodedFormat::kWEBP_SkEncodedFormat: ext = "webp"; break; default: gUnknown++; return; } SkString path; path.appendf("%s/%d.%s", gOutputDir, gKnown++, ext.c_str()); SkFILEWStream file(path.c_str()); file.write(ptr, len); SkDebugf("%s\n", path.c_str()); } bool onUseEncodedData(const void* ptr, size_t len) override { this->sniff(ptr, len); return true; } SkData* onEncode(const SkPixmap&) override { return nullptr; } }; int main(int argc, char** argv) { SkCommandLineFlags::SetUsage( "Usage: get_images_from_skps -s -o \n"); SkCommandLineFlags::Parse(argc, argv); const char* inputs = FLAGS_skps[0]; gOutputDir = FLAGS_out[0]; if (!sk_isdir(inputs) || !sk_isdir(gOutputDir)) { SkCommandLineFlags::PrintUsage(); return 1; } SkOSFile::Iter iter(inputs, "skp"); for (SkString file; iter.next(&file); ) { SkAutoTDelete stream = SkStream::NewFromFile(SkOSPath::Join(inputs, file.c_str()).c_str()); sk_sp picture(SkPicture::MakeFromStream(stream)); SkDynamicMemoryWStream scratch; Sniffer sniff; picture->serialize(&scratch, &sniff); } SkDebugf("%d known, %d unknown\n", gKnown, gUnknown); return 0; }