skpinfo.cpp revision 6f4fb0f1296422a44d5d0dac155d82595dc5ebec
1/* 2 * Copyright 2014 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 "SkCommandLineFlags.h" 9#include "SkPicture.h" 10#include "SkPicturePlayback.h" 11#include "SkStream.h" 12 13DEFINE_string2(input, i, "", "skp on which to report"); 14DEFINE_bool2(version, v, true, "version"); 15DEFINE_bool2(width, w, true, "width"); 16DEFINE_bool2(height, h, true, "height"); 17DEFINE_bool2(tags, t, true, "tags"); 18DEFINE_bool2(quiet, q, false, "quiet"); 19 20// This tool can print simple information about an SKP but its main use 21// is just to check if an SKP has been truncated during the recording 22// process. 23// return codes: 24static const int kSuccess = 0; 25static const int kTruncatedFile = 1; 26static const int kNotAnSKP = 2; 27static const int kInvalidTag = 3; 28static const int kMissingInput = 4; 29static const int kIOError = 5; 30 31int tool_main(int argc, char** argv); 32int tool_main(int argc, char** argv) { 33 SkCommandLineFlags::SetUsage("Prints information about an skp file"); 34 SkCommandLineFlags::Parse(argc, argv); 35 36 if (FLAGS_input.count() != 1) { 37 if (!FLAGS_quiet) { 38 SkDebugf("Missing input file\n"); 39 } 40 return kMissingInput; 41 } 42 43 SkFILEStream stream(FLAGS_input[0]); 44 if (!stream.isValid()) { 45 if (!FLAGS_quiet) { 46 SkDebugf("Couldn't open file\n"); 47 } 48 return kIOError; 49 } 50 51 size_t totStreamSize = stream.getLength(); 52 53 SkPictInfo info; 54 if (!SkPicture::InternalOnly_StreamIsSKP(&stream, &info)) { 55 return kNotAnSKP; 56 } 57 58 if (FLAGS_version && !FLAGS_quiet) { 59 SkDebugf("Version: %d\n", info.fVersion); 60 } 61 if (FLAGS_width && !FLAGS_quiet) { 62 SkDebugf("Width: %d\n", info.fWidth); 63 } 64 if (FLAGS_height && !FLAGS_quiet) { 65 SkDebugf("Height: %d\n", info.fHeight); 66 } 67 68 if (!stream.readBool()) { 69 // If we read true there's a picture playback object flattened 70 // in the file; if false, there isn't a playback, so we're done 71 // reading the file. 72 return kSuccess; 73 } 74 75 for (;;) { 76 uint32_t tag = stream.readU32(); 77 if (SK_PICT_EOF_TAG == tag) { 78 break; 79 } 80 81 uint32_t chunkSize = stream.readU32(); 82 size_t curPos = stream.getPosition(); 83 84 // "move" doesn't error out when seeking beyond the end of file 85 // so we need a preemptive check here. 86 if (curPos+chunkSize > totStreamSize) { 87 if (!FLAGS_quiet) { 88 SkDebugf("truncated file\n"); 89 } 90 return kTruncatedFile; 91 } 92 93 // Not all the tags store the chunk size (in bytes). Three 94 // of them store tag-specific size information (e.g., number of 95 // fonts) instead. This forces us to early exit when those 96 // chunks are encountered. 97 switch (tag) { 98 case SK_PICT_READER_TAG: 99 if (FLAGS_tags && !FLAGS_quiet) { 100 SkDebugf("SK_PICT_READER_TAG %d\n", chunkSize); 101 } 102 break; 103 case SK_PICT_FACTORY_TAG: 104 if (FLAGS_tags && !FLAGS_quiet) { 105 SkDebugf("SK_PICT_FACTORY_TAG %d\n", chunkSize); 106 SkDebugf("Exiting early due to format limitations\n"); 107 } 108 return kSuccess; // TODO: need to store size in bytes 109 break; 110 case SK_PICT_TYPEFACE_TAG: 111 if (FLAGS_tags && !FLAGS_quiet) { 112 SkDebugf("SK_PICT_TYPEFACE_TAG %d\n", chunkSize); 113 SkDebugf("Exiting early due to format limitations\n"); 114 } 115 return kSuccess; // TODO: need to store size in bytes 116 break; 117 case SK_PICT_PICTURE_TAG: 118 if (FLAGS_tags && !FLAGS_quiet) { 119 SkDebugf("SK_PICT_PICTURE_TAG %d\n", chunkSize); 120 SkDebugf("Exiting early due to format limitations\n"); 121 } 122 return kSuccess; // TODO: need to store size in bytes 123 break; 124 case SK_PICT_BUFFER_SIZE_TAG: 125 if (FLAGS_tags && !FLAGS_quiet) { 126 SkDebugf("SK_PICT_BUFFER_SIZE_TAG %d\n", chunkSize); 127 } 128 break; 129 default: 130 if (!FLAGS_quiet) { 131 SkDebugf("Unknown tag %d\n", chunkSize); 132 } 133 return kInvalidTag; 134 } 135 136 if (!stream.move(chunkSize)) { 137 if (!FLAGS_quiet) { 138 SkDebugf("seek error\n"); 139 } 140 return kTruncatedFile; 141 } 142 } 143 144 return kSuccess; 145} 146 147#if !defined SK_BUILD_FOR_IOS 148int main(int argc, char * const argv[]) { 149 return tool_main(argc, (char**) argv); 150} 151#endif 152