msarett | 3478f75 | 2016-02-12 14:47:09 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "SkCanvas.h" |
| 9 | #include "SkCodec.h" |
| 10 | #include "SkCommandLineFlags.h" |
| 11 | #include "SkData.h" |
| 12 | #include "SkOSFile.h" |
| 13 | #include "SkPicture.h" |
| 14 | #include "SkStream.h" |
| 15 | |
| 16 | DEFINE_string2(skps, s, "", "A path to a directory of skps."); |
| 17 | DEFINE_string2(out, o, "", "A path to an output directory."); |
| 18 | |
| 19 | static int gCtr = 0; |
| 20 | static int gSuccessCtr = 0; |
| 21 | static int gUnknownCtr = 0; |
| 22 | static int gFailureCtr = 0; |
| 23 | static const char* gOutputDir; |
| 24 | |
| 25 | void setup_output_dirs() { |
| 26 | const char* exts[] = { "jpg", "png", "gif", "webp", "bmp", "wbmp", "ico", "dng", "unknown" }; |
| 27 | for (const char* ext : exts) { |
| 28 | sk_mkdir(SkOSPath::Join(gOutputDir, ext).c_str()); |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | bool store_encoded_to_file(const void* encoded, size_t length, SkBitmap* bitmap) { |
| 33 | // Silence warnings about empty bitmaps. |
| 34 | bitmap->allocN32Pixels(1, 1, true); |
| 35 | |
| 36 | SkString path; |
| 37 | SkAutoTUnref<SkData> data(SkData::NewWithoutCopy(encoded, length)); |
| 38 | SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data)); |
| 39 | if (codec) { |
| 40 | switch (codec->getEncodedFormat()) { |
| 41 | case SkEncodedFormat::kJPEG_SkEncodedFormat: |
| 42 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "jpg").c_str(), ""); |
| 43 | path.appendS32(gCtr++); |
| 44 | path.append(".jpg"); |
| 45 | break; |
| 46 | case SkEncodedFormat::kPNG_SkEncodedFormat: |
| 47 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "png").c_str(), ""); |
| 48 | path.appendS32(gCtr++); |
| 49 | path.append(".png"); |
| 50 | break; |
| 51 | case SkEncodedFormat::kGIF_SkEncodedFormat: |
| 52 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "gif").c_str(), ""); |
| 53 | path.appendS32(gCtr++); |
| 54 | path.append(".gif"); |
| 55 | break; |
| 56 | case SkEncodedFormat::kWEBP_SkEncodedFormat: |
| 57 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "webp").c_str(), ""); |
| 58 | path.appendS32(gCtr++); |
| 59 | path.append(".webp"); |
| 60 | break; |
| 61 | case SkEncodedFormat::kBMP_SkEncodedFormat: |
| 62 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "bmp").c_str(), ""); |
| 63 | path.appendS32(gCtr++); |
| 64 | path.append(".bmp"); |
| 65 | break; |
| 66 | case SkEncodedFormat::kWBMP_SkEncodedFormat: |
| 67 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "wbmp").c_str(), ""); |
| 68 | path.appendS32(gCtr++); |
| 69 | path.append(".wbmp"); |
| 70 | break; |
| 71 | case SkEncodedFormat::kICO_SkEncodedFormat: |
| 72 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "ico").c_str(), ""); |
| 73 | path.appendS32(gCtr++); |
| 74 | path.append(".ico"); |
| 75 | break; |
| 76 | case SkEncodedFormat::kRAW_SkEncodedFormat: |
| 77 | path = SkOSPath::Join(SkOSPath::Join(gOutputDir, "dng").c_str(), ""); |
| 78 | path.appendS32(gCtr++); |
| 79 | path.append(".dng"); |
| 80 | break; |
| 81 | default: |
| 82 | path = SkOSPath::Join(gOutputDir, "unknown"); |
| 83 | path.appendS32(gUnknownCtr++); |
| 84 | break; |
| 85 | } |
| 86 | } else { |
| 87 | path = SkOSPath::Join(gOutputDir, "unknown"); |
| 88 | path.appendS32(gUnknownCtr++); |
| 89 | } |
| 90 | |
| 91 | FILE* file = sk_fopen(path.c_str(), kWrite_SkFILE_Flag); |
| 92 | if (file) { |
| 93 | sk_fwrite(encoded, length, file); |
| 94 | sk_fclose(file); |
| 95 | gSuccessCtr++; |
| 96 | return true; |
| 97 | } |
| 98 | |
| 99 | gFailureCtr++; |
| 100 | SkDebugf("Could not open %s\n", path.c_str()); |
| 101 | return false; |
| 102 | } |
| 103 | |
| 104 | int main(int argc, char** argv) { |
| 105 | SkCommandLineFlags::SetUsage( |
| 106 | "Usage: get_images_from_skps -s <dir of skps> -o <dir for output images>\n"); |
| 107 | |
| 108 | SkCommandLineFlags::Parse(argc, argv); |
| 109 | if (FLAGS_skps.isEmpty() || FLAGS_out.isEmpty()) { |
| 110 | SkCommandLineFlags::PrintUsage(); |
| 111 | return 1; |
| 112 | } |
| 113 | |
| 114 | const char* inputs = FLAGS_skps[0]; |
| 115 | gOutputDir = FLAGS_out[0]; |
| 116 | if (!sk_isdir(inputs) || !sk_isdir(gOutputDir)) { |
| 117 | SkCommandLineFlags::PrintUsage(); |
| 118 | return 1; |
| 119 | } |
| 120 | |
| 121 | setup_output_dirs(); |
| 122 | SkOSFile::Iter iter(inputs, "skp"); |
| 123 | for (SkString file; iter.next(&file); ) { |
| 124 | SkAutoTDelete<SkStream> stream = |
| 125 | SkStream::NewFromFile(SkOSPath::Join(inputs, file.c_str()).c_str()); |
| 126 | |
| 127 | // Rather than passing in a function that actually decodes the encoded data, |
| 128 | // we pass in a function that saves the encoded data to a file. |
| 129 | SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(stream, store_encoded_to_file)); |
| 130 | |
| 131 | SkCanvas canvas; |
| 132 | canvas.drawPicture(picture); |
| 133 | } |
| 134 | |
| 135 | SkDebugf("Successfully saved %d recognized images and %d unrecognized images\n", gSuccessCtr, |
| 136 | gUnknownCtr); |
| 137 | SkDebugf("Failed to write %d images\n", gFailureCtr); |
| 138 | return 0; |
| 139 | } |