84836b799a
Like any normal variable, flags can be made file-scoped static, and like any normal variable, mostly they should be if they can. This CL converts most flags to be static, if only so that the ones that do cross files stand out more clearly, and so that there's more examples of static flags through the codebase for people to ape. Change-Id: Ibb5ddd7aa09fce073d0996ac3ef0487b078b7d79 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/202800 Commit-Queue: Mike Klein <mtklein@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Auto-Submit: Mike Klein <mtklein@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
162 lines
5.0 KiB
C++
162 lines
5.0 KiB
C++
/*
|
|
* Copyright 2014 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "CommandLineFlags.h"
|
|
#include "SkFontDescriptor.h"
|
|
#include "SkPicture.h"
|
|
#include "SkPictureCommon.h"
|
|
#include "SkPictureData.h"
|
|
#include "SkStream.h"
|
|
#include "SkTo.h"
|
|
|
|
static DEFINE_string2(input, i, "", "skp on which to report");
|
|
static DEFINE_bool2(version, v, true, "version");
|
|
static DEFINE_bool2(cullRect, c, true, "cullRect");
|
|
static DEFINE_bool2(flags, f, true, "flags");
|
|
static DEFINE_bool2(tags, t, true, "tags");
|
|
static DEFINE_bool2(quiet, q, false, "quiet");
|
|
|
|
// This tool can print simple information about an SKP but its main use
|
|
// is just to check if an SKP has been truncated during the recording
|
|
// process.
|
|
// return codes:
|
|
static const int kSuccess = 0;
|
|
static const int kTruncatedFile = 1;
|
|
static const int kNotAnSKP = 2;
|
|
static const int kInvalidTag = 3;
|
|
static const int kMissingInput = 4;
|
|
static const int kIOError = 5;
|
|
|
|
int main(int argc, char** argv) {
|
|
CommandLineFlags::SetUsage("Prints information about an skp file");
|
|
CommandLineFlags::Parse(argc, argv);
|
|
|
|
if (FLAGS_input.count() != 1) {
|
|
if (!FLAGS_quiet) {
|
|
SkDebugf("Missing input file\n");
|
|
}
|
|
return kMissingInput;
|
|
}
|
|
|
|
SkFILEStream stream(FLAGS_input[0]);
|
|
if (!stream.isValid()) {
|
|
if (!FLAGS_quiet) {
|
|
SkDebugf("Couldn't open file\n");
|
|
}
|
|
return kIOError;
|
|
}
|
|
|
|
size_t totStreamSize = stream.getLength();
|
|
|
|
SkPictInfo info;
|
|
if (!SkPicture_StreamIsSKP(&stream, &info)) {
|
|
return kNotAnSKP;
|
|
}
|
|
|
|
if (FLAGS_version && !FLAGS_quiet) {
|
|
SkDebugf("Version: %d\n", info.getVersion());
|
|
}
|
|
if (FLAGS_cullRect && !FLAGS_quiet) {
|
|
SkDebugf("Cull Rect: %f,%f,%f,%f\n",
|
|
info.fCullRect.fLeft, info.fCullRect.fTop,
|
|
info.fCullRect.fRight, info.fCullRect.fBottom);
|
|
}
|
|
|
|
bool hasData;
|
|
if (!stream.readBool(&hasData)) { return kTruncatedFile; }
|
|
if (!hasData) {
|
|
// If we read true there's a picture playback object flattened
|
|
// in the file; if false, there isn't a playback, so we're done
|
|
// reading the file.
|
|
return kSuccess;
|
|
}
|
|
|
|
for (;;) {
|
|
uint32_t tag;
|
|
if (!stream.readU32(&tag)) { return kTruncatedFile; }
|
|
if (SK_PICT_EOF_TAG == tag) {
|
|
break;
|
|
}
|
|
|
|
uint32_t chunkSize;
|
|
if (!stream.readU32(&chunkSize)) { return kTruncatedFile; }
|
|
size_t curPos = stream.getPosition();
|
|
|
|
// "move" doesn't error out when seeking beyond the end of file
|
|
// so we need a preemptive check here.
|
|
if (curPos+chunkSize > totStreamSize) {
|
|
if (!FLAGS_quiet) {
|
|
SkDebugf("truncated file\n");
|
|
}
|
|
return kTruncatedFile;
|
|
}
|
|
|
|
// Not all the tags store the chunk size (in bytes). Three
|
|
// of them store tag-specific size information (e.g., number of
|
|
// fonts) instead. This forces us to early exit when those
|
|
// chunks are encountered.
|
|
switch (tag) {
|
|
case SK_PICT_READER_TAG:
|
|
if (FLAGS_tags && !FLAGS_quiet) {
|
|
SkDebugf("SK_PICT_READER_TAG %d\n", chunkSize);
|
|
}
|
|
break;
|
|
case SK_PICT_FACTORY_TAG:
|
|
if (FLAGS_tags && !FLAGS_quiet) {
|
|
SkDebugf("SK_PICT_FACTORY_TAG %d\n", chunkSize);
|
|
}
|
|
break;
|
|
case SK_PICT_TYPEFACE_TAG: {
|
|
if (FLAGS_tags && !FLAGS_quiet) {
|
|
SkDebugf("SK_PICT_TYPEFACE_TAG %d\n", chunkSize);
|
|
}
|
|
|
|
const int count = SkToInt(chunkSize);
|
|
for (int i = 0; i < count; i++) {
|
|
SkFontDescriptor desc;
|
|
if (!SkFontDescriptor::Deserialize(&stream, &desc)) {
|
|
if (!FLAGS_quiet) {
|
|
SkDebugf("File corruption in SkFontDescriptor\n");
|
|
}
|
|
return kInvalidTag;
|
|
}
|
|
}
|
|
|
|
// clear this since we've consumed all the typefaces
|
|
chunkSize = 0;
|
|
break;
|
|
}
|
|
case SK_PICT_PICTURE_TAG:
|
|
if (FLAGS_tags && !FLAGS_quiet) {
|
|
SkDebugf("SK_PICT_PICTURE_TAG %d\n", chunkSize);
|
|
SkDebugf("Exiting early due to format limitations\n");
|
|
}
|
|
return kSuccess; // TODO: need to store size in bytes
|
|
break;
|
|
case SK_PICT_BUFFER_SIZE_TAG:
|
|
if (FLAGS_tags && !FLAGS_quiet) {
|
|
SkDebugf("SK_PICT_BUFFER_SIZE_TAG %d\n", chunkSize);
|
|
}
|
|
break;
|
|
default:
|
|
if (!FLAGS_quiet) {
|
|
SkDebugf("Unknown tag %d\n", chunkSize);
|
|
}
|
|
return kInvalidTag;
|
|
}
|
|
|
|
if (!stream.move(chunkSize)) {
|
|
if (!FLAGS_quiet) {
|
|
SkDebugf("seek error\n");
|
|
}
|
|
return kTruncatedFile;
|
|
}
|
|
}
|
|
|
|
return kSuccess;
|
|
}
|