render_pictures_main.cpp revision 9299eded3838a7997235ff033aa3b9a8d4c6d4d4
1/* 2 * Copyright 2012 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 "SkBitmap.h" 9#include "SkCanvas.h" 10#include "SkDevice.h" 11#include "SkOSFile.h" 12#include "SkPicture.h" 13#include "SkStream.h" 14#include "SkString.h" 15#include "SkTArray.h" 16#include "PictureRenderer.h" 17#include "picture_utils.h" 18 19static void usage(const char* argv0) { 20 SkDebugf("SkPicture rendering tool\n"); 21 SkDebugf("\n" 22"Usage: \n" 23" %s <input>... <outputDir> \n" 24" [--mode pipe | simple | tile width[%] height[%]]\n" 25" [--device bitmap" 26#if SK_SUPPORT_GPU 27" | gpu" 28#endif 29"]" 30, argv0); 31 SkDebugf("\n\n"); 32 SkDebugf( 33" input: A list of directories and files to use as input. Files are\n" 34" expected to have the .skp extension.\n\n"); 35 SkDebugf( 36" outputDir: directory to write the rendered images.\n\n"); 37 SkDebugf( 38" --mode pipe | simple | tile width[%] height[%]: Run in the\n" 39" corresponding mode. Default is simple.\n"); 40 SkDebugf( 41" pipe, Render using a SkGPipe.\n"); 42 SkDebugf( 43" simple, Render using the default rendering method.\n"); 44 SkDebugf( 45" tile width[%] height[%], Do a simple render using tiles\n" 46" with the given dimensions.\n"); 47 SkDebugf("\n"); 48 SkDebugf( 49" --device bitmap" 50#if SK_SUPPORT_GPU 51" | gpu" 52#endif 53": Use the corresponding device. Default is bitmap.\n"); 54 SkDebugf( 55" bitmap, Render to a bitmap.\n"); 56#if SK_SUPPORT_GPU 57 SkDebugf( 58" gpu, Render to the GPU.\n"); 59#endif 60} 61 62static void make_output_filepath(SkString* path, const SkString& dir, 63 const SkString& name) { 64 sk_tools::make_filepath(path, dir, name); 65 path->remove(path->size() - 3, 3); 66 path->append("png"); 67} 68 69static void write_output(const SkString& outputDir, const SkString& inputFilename, 70 const sk_tools::PictureRenderer& renderer) { 71 SkString outputPath; 72 make_output_filepath(&outputPath, outputDir, inputFilename); 73 bool isWritten = renderer.write(outputPath); 74 if (!isWritten) { 75 SkDebugf("Could not write to file %s\n", outputPath.c_str()); 76 } 77} 78 79static void render_picture(const SkString& inputPath, const SkString& outputDir, 80 sk_tools::PictureRenderer& renderer) { 81 SkString inputFilename; 82 sk_tools::get_basename(&inputFilename, inputPath); 83 84 SkFILEStream inputStream; 85 inputStream.setPath(inputPath.c_str()); 86 if (!inputStream.isValid()) { 87 SkDebugf("Could not open file %s\n", inputPath.c_str()); 88 return; 89 } 90 91 SkPicture picture(&inputStream); 92 93 renderer.init(&picture); 94 95 renderer.render(); 96 97 write_output(outputDir, inputFilename, renderer); 98 99 renderer.end(); 100} 101 102static void process_input(const SkString& input, const SkString& outputDir, 103 sk_tools::PictureRenderer& renderer) { 104 SkOSFile::Iter iter(input.c_str(), "skp"); 105 SkString inputFilename; 106 107 if (iter.next(&inputFilename)) { 108 do { 109 SkString inputPath; 110 sk_tools::make_filepath(&inputPath, input, inputFilename); 111 render_picture(inputPath, outputDir, renderer); 112 } while(iter.next(&inputFilename)); 113 } else { 114 SkString inputPath(input); 115 render_picture(inputPath, outputDir, renderer); 116 } 117} 118 119static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs, 120 sk_tools::PictureRenderer*& renderer){ 121 const char* argv0 = argv[0]; 122 char* const* stop = argv + argc; 123 124 sk_tools::PictureRenderer::SkDeviceTypes deviceType = 125 sk_tools::PictureRenderer::kBitmap_DeviceType; 126 127 for (++argv; argv < stop; ++argv) { 128 if (0 == strcmp(*argv, "--mode")) { 129 SkDELETE(renderer); 130 131 ++argv; 132 if (argv >= stop) { 133 SkDebugf("Missing mode for --mode\n"); 134 usage(argv0); 135 exit(-1); 136 } 137 138 if (0 == strcmp(*argv, "pipe")) { 139 renderer = SkNEW(sk_tools::PipePictureRenderer); 140 } else if (0 == strcmp(*argv, "simple")) { 141 renderer = SkNEW(sk_tools::SimplePictureRenderer); 142 } else if (0 == strcmp(*argv, "tile")) { 143 sk_tools::TiledPictureRenderer* tileRenderer = 144 SkNEW(sk_tools::TiledPictureRenderer); 145 ++argv; 146 if (argv >= stop) { 147 SkDELETE(tileRenderer); 148 SkDebugf("Missing width for --mode tile\n"); 149 usage(argv0); 150 exit(-1); 151 } 152 153 if (sk_tools::is_percentage(*argv)) { 154 tileRenderer->setTileWidthPercentage(atof(*argv)); 155 if (!(tileRenderer->getTileWidthPercentage() > 0)) { 156 SkDELETE(tileRenderer); 157 SkDebugf("--mode tile must be given a width percentage > 0\n"); 158 exit(-1); 159 } 160 } else { 161 tileRenderer->setTileWidth(atoi(*argv)); 162 if (!(tileRenderer->getTileWidth() > 0)) { 163 SkDELETE(tileRenderer); 164 SkDebugf("--mode tile must be given a width > 0\n"); 165 exit(-1); 166 } 167 } 168 169 ++argv; 170 if (argv >= stop) { 171 SkDELETE(tileRenderer); 172 SkDebugf("Missing height for --mode tile\n"); 173 usage(argv0); 174 exit(-1); 175 } 176 177 if (sk_tools::is_percentage(*argv)) { 178 tileRenderer->setTileHeightPercentage(atof(*argv)); 179 if (!(tileRenderer->getTileHeightPercentage() > 0)) { 180 SkDELETE(tileRenderer); 181 SkDebugf( 182 "--mode tile must be given a height percentage > 0\n"); 183 exit(-1); 184 } 185 } else { 186 tileRenderer->setTileHeight(atoi(*argv)); 187 if (!(tileRenderer->getTileHeight() > 0)) { 188 SkDELETE(tileRenderer); 189 SkDebugf("--mode tile must be given a height > 0\n"); 190 exit(-1); 191 } 192 } 193 194 renderer = tileRenderer; 195 } else { 196 SkDebugf("%s is not a valid mode for --mode\n", *argv); 197 usage(argv0); 198 exit(-1); 199 } 200 } else if (0 == strcmp(*argv, "--device")) { 201 ++argv; 202 if (argv >= stop) { 203 SkDebugf("Missing mode for --deivce\n"); 204 usage(argv0); 205 exit(-1); 206 } 207 208 if (0 == strcmp(*argv, "bitmap")) { 209 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; 210 } 211#if SK_SUPPORT_GPU 212 else if (0 == strcmp(*argv, "gpu")) { 213 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; 214 } 215#endif 216 else { 217 SkDebugf("%s is not a valid mode for --device\n", *argv); 218 usage(argv0); 219 exit(-1); 220 } 221 222 } else if ((0 == strcmp(*argv, "-h")) || (0 == strcmp(*argv, "--help"))) { 223 SkDELETE(renderer); 224 usage(argv0); 225 exit(-1); 226 } else { 227 inputs->push_back(SkString(*argv)); 228 } 229 } 230 231 if (inputs->count() < 2) { 232 SkDELETE(renderer); 233 usage(argv0); 234 exit(-1); 235 } 236 237 if (NULL == renderer) { 238 renderer = SkNEW(sk_tools::SimplePictureRenderer); 239 } 240 241 renderer->setDeviceType(deviceType); 242} 243 244int main(int argc, char* const argv[]) { 245 SkTArray<SkString> inputs; 246 sk_tools::PictureRenderer* renderer = NULL; 247 248 parse_commandline(argc, argv, &inputs, renderer); 249 SkString outputDir = inputs[inputs.count() - 1]; 250 SkASSERT(renderer); 251 252 for (int i = 0; i < inputs.count() - 1; i ++) { 253 process_input(inputs[i], outputDir, *renderer); 254 } 255 256 SkDELETE(renderer); 257} 258