render_pictures_main.cpp revision a2333d970329e8fffb7347f758f8c421452fe858
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 9#include "SkBitmap.h" 10#include "SamplePipeControllers.h" 11#include "SkCanvas.h" 12#include "SkColorPriv.h" 13#include "SkGPipe.h" 14#include "SkImageEncoder.h" 15#include "SkOSFile.h" 16#include "SkPicture.h" 17#include "SkStream.h" 18#include "SkString.h" 19#include "SkTArray.h" 20#include "picture_utils.h" 21 22typedef void (*RenderFunc) (SkPicture*, SkBitmap*); 23 24static void usage(const char* argv0) { 25 SkDebugf("SkPicture rendering tool\n"); 26 SkDebugf("\n" 27"Usage: \n" 28" %s <input>... <outputDir> \n\n" 29, argv0); 30 SkDebugf( 31" input: A list of directories and files to use as input.\n" 32" Files are expected to have the .skp extension.\n"); 33 SkDebugf( 34" outputDir: directory to write the rendered images.\n"); 35} 36 37static void make_output_filepath(SkString* path, const SkString& dir, 38 const SkString& name) { 39 sk_tools::make_filepath(path, dir, name); 40 path->remove(path->size() - 3, 3); 41 path->append("png"); 42} 43 44static void simple_render(SkPicture* pict, SkBitmap* bitmap) { 45 sk_tools::setup_bitmap(bitmap, pict->width(), pict->height()); 46 SkCanvas canvas(*bitmap); 47 canvas.drawPicture(*pict); 48} 49 50/* since PNG insists on unpremultiplying our alpha, we take no precision chances 51 and force all pixels to be 100% opaque, otherwise on compare we may not get 52 a perfect match. 53 */ 54static void force_all_opaque(const SkBitmap& bitmap) { 55 SkAutoLockPixels lock(bitmap); 56 for (int y = 0; y < bitmap.height(); y++) { 57 for (int x = 0; x < bitmap.width(); x++) { 58 *bitmap.getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT); 59 } 60 } 61} 62 63static bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { 64 SkBitmap copy; 65 bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); 66 force_all_opaque(copy); 67 return SkImageEncoder::EncodeFile(path.c_str(), copy, 68 SkImageEncoder::kPNG_Type, 100); 69} 70 71static void write_output(const SkString& outputDir, const SkString& inputFilename, 72 const SkBitmap& bitmap) { 73 SkString outputPath; 74 make_output_filepath(&outputPath, outputDir, inputFilename); 75 bool isWritten = write_bitmap(outputPath, bitmap); 76 if (!isWritten) { 77 SkDebugf("Could not write to file %s\n", outputPath.c_str()); 78 } 79} 80 81static void pipe_run(SkPicture* picture, SkCanvas* canvas) { 82 PipeController pipeController(canvas); 83 SkGPipeWriter writer; 84 SkCanvas* pipeCanvas = writer.startRecording(&pipeController); 85 pipeCanvas->drawPicture(*picture); 86 writer.endRecording(); 87} 88 89static void pipe_render(SkPicture* picture, SkBitmap* bitmap) { 90 sk_tools::setup_bitmap(bitmap, picture->width(), picture->height()); 91 92 SkCanvas canvas(*bitmap); 93 94 pipe_run(picture, &canvas); 95} 96 97static void render_picture(const SkString& inputPath, const SkString& outputDir, 98 RenderFunc renderFunc) { 99 SkString inputFilename; 100 sk_tools::get_basename(&inputFilename, inputPath); 101 102 SkFILEStream inputStream; 103 inputStream.setPath(inputPath.c_str()); 104 if (!inputStream.isValid()) { 105 SkDebugf("Could not open file %s\n", inputPath.c_str()); 106 return; 107 } 108 109 SkPicture picture(&inputStream); 110 SkBitmap bitmap; 111 renderFunc(&picture, &bitmap); 112 write_output(outputDir, inputFilename, bitmap); 113} 114 115static void process_input(const SkString& input, const SkString& outputDir, 116 RenderFunc renderFunc) { 117 SkOSFile::Iter iter(input.c_str(), "skp"); 118 SkString inputFilename; 119 120 if (iter.next(&inputFilename)) { 121 do { 122 SkString inputPath; 123 sk_tools::make_filepath(&inputPath, input, inputFilename); 124 render_picture(inputPath, outputDir, renderFunc); 125 } while(iter.next(&inputFilename)); 126 } else { 127 SkString inputPath(input); 128 render_picture(inputPath, outputDir, renderFunc); 129 } 130} 131 132static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs, 133 RenderFunc* renderFunc){ 134 const char* argv0 = argv[0]; 135 char* const* stop = argv + argc; 136 137 for (++argv; argv < stop; ++argv) { 138 if (0 == strcmp(*argv, "--pipe")) { 139 *renderFunc = pipe_render; 140 } else { 141 inputs->push_back(SkString(*argv)); 142 } 143 } 144} 145 146int main(int argc, char* const argv[]) { 147 SkTArray<SkString> inputs; 148 RenderFunc renderFunc = simple_render; 149 parse_commandline(argc, argv, &inputs, &renderFunc); 150 SkString outputDir = inputs[inputs.count() - 1]; 151 152 for (int i = 0; i < inputs.count() - 1; i ++) { 153 process_input(inputs[i], outputDir, renderFunc); 154 } 155} 156