skpdiff_main.cpp revision 58190644c30e1c4aa8e527f3503c58f841e0fcf3
158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/* 258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Copyright 2013 Google Inc. 358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * 458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * found in the LICENSE file. 658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */ 758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#define __NO_STD_VECTOR // Uses cl::vectpr instead of std::vectpr 1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#define __NO_STD_STRING // Uses cl::STRING_CLASS instead of std::string 1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_BUILD_FOR_MAC 1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// Note that some macs don't have this header and it can be downloaded from the Khronos registry 1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger# include <OpenCL/cl.hpp> 1558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#else 1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger# include <CL/cl.hpp> 1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 1858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 1958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkCommandLineFlags.h" 2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkGraphics.h" 2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkStream.h" 2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTDArray.h" 2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkDifferentPixelsMetric.h" 2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkDiffContext.h" 2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkImageDiffer.h" 2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkPMetric.h" 3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "skpdiff_util.h" 3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkForceLinking.h" 3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger__SK_FORCE_IMAGE_DECODER_LINKING; 3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// Command line argument definitions go here 3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_bool2(list, l, false, "List out available differs"); 3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(differs, d, "", "The names of the differs to use or all of them by default"); 3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(folders, f, "", "Compare two folders with identical subfile names: <baseline folder> <test folder>"); 3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(patterns, p, "", "Use two patterns to compare images: <baseline> <test>"); 4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(output, o, "", "Writes the output of these diffs to output: <output>"); 4158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_bool(jsonp, true, "Output JSON with padding"); 4258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string(csv, "", "Writes the output of these diffs to a csv file"); 4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 4458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 4558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/// A callback for any OpenCL errors 4658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void CL_CALLBACK error_notify(const char* errorInfo, const void* privateInfoSize, ::size_t cb, void* userData) { 4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("OpenCL error notify: %s\n", errorInfo); 4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger exit(1); 4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/// Creates a device and context with OpenCL 5258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic bool init_device_and_context(cl::Device* device, cl::Context* context) { 5358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Query for a platform 5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::vector<cl::Platform> platformList; 5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Platform::get(&platformList); 5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("The number of platforms is %u\n", platformList.size()); 5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Print some information about the platform for debugging 5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Platform& platform = platformList[0]; 6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::STRING_CLASS platformName; 6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger platform.getInfo(CL_PLATFORM_NAME, &platformName); 6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Platform index 0 is named %s\n", platformName.c_str()); 6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Query for a device 6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::vector<cl::Device> deviceList; 6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger platform.getDevices(CL_DEVICE_TYPE_ALL, &deviceList); 6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("The number of devices is %u\n", deviceList.size()); 6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Print some information about the device for debugging 7058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *device = deviceList[0]; 7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::STRING_CLASS deviceName; 7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger device->getInfo(CL_DEVICE_NAME, &deviceName); 7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Device index 0 is named %s\n", deviceName.c_str()); 7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Create a CL context and check for all errors 7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl_int contextErr = CL_SUCCESS; 7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *context = cl::Context(deviceList, NULL, error_notify, NULL, &contextErr); 7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (contextErr != CL_SUCCESS) { 7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Context creation failed: %s\n", cl_error_to_string(contextErr)); 8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return false; 8158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return true; 8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic bool init_cl_diff(SkImageDiffer* differ) { 8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Setup OpenCL 8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Device device; 8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Context context; 9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!init_device_and_context(&device, &context)) { 9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return false; 9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Setup our differ of choice 9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkCLImageDiffer* clDiffer = (SkCLImageDiffer*)differ; 9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return clDiffer->init(device(), context()); 9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// TODO Find a better home for the diff registry. One possibility is to have the differs self 10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// register. 10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// List here every differ 10458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkDifferentPixelsMetric gDiffPixel; 10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkPMetric gPDiff; 10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// A null terminated array of pointer to every differ declared above 10858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkImageDiffer* gDiffers[] = { &gDiffPixel, &gPDiff, NULL }; 10958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerint tool_main(int argc, char * argv[]); 11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerint tool_main(int argc, char * argv[]) { 11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Setup command line parsing 11358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkCommandLineFlags::SetUsage("Compare images using various metrics."); 11458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkCommandLineFlags::Parse(argc, argv); 11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Needed by various Skia components 11758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoGraphics ag; 11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_list) { 12058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Available Metrics:\n"); 12158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 12258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 12358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Figure which differs the user chose, and optionally print them if the user requests it 12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkTDArray<SkImageDiffer*> chosenDiffers; 12558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger for (int differIndex = 0; NULL != gDiffers[differIndex]; differIndex++) { 12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkImageDiffer* differ = gDiffers[differIndex]; 12758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_list) { 12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf(" %s", differ->getName()); 12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("\n"); 13058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 13158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 13258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Check if this differ was chosen by any of the flags. Initialize them if they were chosen. 13358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_differs.isEmpty()) { 13458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // If no differs were chosen, they all get added 13558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (differ->requiresOpenCL()) { 13658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 13758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger init_cl_diff(differ); 13858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 13958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 14058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 14158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 14258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 14358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 14458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger for (int flagIndex = 0; flagIndex < FLAGS_differs.count(); flagIndex++) { 14558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (SkString(FLAGS_differs[flagIndex]).equals(differ->getName())) { 14658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Initialize OpenCL for the differ if it needs it and support was compiled in. 14758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (differ->requiresOpenCL()) { 14858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 14958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger init_cl_diff(differ); 15058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 15158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 15258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 15358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 15458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 15558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger break; 15658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 15758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 15858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 15958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 16058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 16158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Don't attempt to initialize the differ if we aren't going to use it 16258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_folders.isEmpty() && FLAGS_patterns.isEmpty()) { 16358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 0; 16458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 16558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 16658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Validate command line flags 16758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_folders.isEmpty()) { 16858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (2 != FLAGS_folders.count()) { 16958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Folders flag expects two arguments: <baseline folder> <test folder>\n"); 17058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 1; 17158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 17258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 17358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 17458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_patterns.isEmpty()) { 17558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (2 != FLAGS_patterns.count()) { 17658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Patterns flag expects two arguments: <baseline pattern> <test pattern>\n"); 17758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 1; 17858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 17958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 18058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 18158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_csv.isEmpty()) { 18258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (1 != FLAGS_csv.count()) { 18358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("csv flag expects one argument: <csv file>\n"); 18458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 1; 18558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 18658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 18758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 18858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDiffContext ctx; 18958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.setDiffers(chosenDiffers); 19058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 19158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Perform a folder diff if one is requested 19258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_folders.isEmpty()) { 19358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.diffDirectories(FLAGS_folders[0], FLAGS_folders[1]); 19458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 19558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 19658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Perform a pattern diff if one is requested 19758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_patterns.isEmpty()) { 19858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.diffPatterns(FLAGS_patterns[0], FLAGS_patterns[1]); 19958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 20058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 20158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Output to the file specified 20258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_output.isEmpty()) { 20358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkFILEWStream outputStream(FLAGS_output[0]); 20458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.outputRecords(outputStream, FLAGS_jsonp); 20558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 20658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 20758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_csv.isEmpty()) { 20858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkFILEWStream outputStream(FLAGS_csv[0]); 20958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.outputCsv(outputStream); 21058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 21158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 21258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 0; 21358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 21458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 21558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 21658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerint main(int argc, char * argv[]) { 21758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return tool_main(argc, (char**) argv); 21858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 21958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 220