16f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org/*
26f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org * Copyright 2014 Google Inc.
36f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org *
46f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
56f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org * found in the LICENSE file.
66f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org */
76f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
86f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#include "SkCommandLineFlags.h"
96f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#include "SkPicture.h"
106f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#include "SkPicturePlayback.h"
116f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#include "SkStream.h"
126f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
136f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_string2(input, i, "", "skp on which to report");
146f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_bool2(version, v, true, "version");
156f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_bool2(width, w, true, "width");
166f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_bool2(height, h, true, "height");
17e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.orgDEFINE_bool2(flags, f, true, "flags");
186f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_bool2(tags, t, true, "tags");
196f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_bool2(quiet, q, false, "quiet");
206f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
216f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// This tool can print simple information about an SKP but its main use
226f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// is just to check if an SKP has been truncated during the recording
236f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// process.
246f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// return codes:
256f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kSuccess = 0;
266f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kTruncatedFile = 1;
276f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kNotAnSKP = 2;
286f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kInvalidTag = 3;
296f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kMissingInput = 4;
306f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kIOError = 5;
316f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
326f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgint tool_main(int argc, char** argv);
336f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgint tool_main(int argc, char** argv) {
346f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkCommandLineFlags::SetUsage("Prints information about an skp file");
356f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkCommandLineFlags::Parse(argc, argv);
366f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
376f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (FLAGS_input.count() != 1) {
386f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (!FLAGS_quiet) {
396f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            SkDebugf("Missing input file\n");
406f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
416f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kMissingInput;
426f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
436f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
446f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkFILEStream stream(FLAGS_input[0]);
456f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (!stream.isValid()) {
466f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (!FLAGS_quiet) {
476f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            SkDebugf("Couldn't open file\n");
486f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
496f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kIOError;
506f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
516f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
526f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    size_t totStreamSize = stream.getLength();
536f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
546f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkPictInfo info;
556f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (!SkPicture::InternalOnly_StreamIsSKP(&stream, &info)) {
566f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kNotAnSKP;
576f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
586f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
596f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (FLAGS_version && !FLAGS_quiet) {
606f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        SkDebugf("Version: %d\n", info.fVersion);
616f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
626f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (FLAGS_width && !FLAGS_quiet) {
636f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        SkDebugf("Width: %d\n", info.fWidth);
646f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
656f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (FLAGS_height && !FLAGS_quiet) {
666f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        SkDebugf("Height: %d\n", info.fHeight);
676f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
68e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org    if (FLAGS_flags && !FLAGS_quiet) {
69e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org        SkDebugf("Flags: 0x%x\n", info.fFlags);
70e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org    }
716f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
726f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (!stream.readBool()) {
73ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.com        // If we read true there's a picture playback object flattened
74ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.com        // in the file; if false, there isn't a playback, so we're done
756f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // reading the file.
766f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kSuccess;
776f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
786f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
796f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    for (;;) {
806f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        uint32_t tag = stream.readU32();
816f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
826f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
836f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
846f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
856f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        uint32_t chunkSize = stream.readU32();
866f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        size_t curPos = stream.getPosition();
876f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
886f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // "move" doesn't error out when seeking beyond the end of file
896f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // so we need a preemptive check here.
906f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (curPos+chunkSize > totStreamSize) {
916f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (!FLAGS_quiet) {
926f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("truncated file\n");
936f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
946f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kTruncatedFile;
956f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
966f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
976f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // Not all the tags store the chunk size (in bytes). Three
986f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // of them store tag-specific size information (e.g., number of
996f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // fonts) instead. This forces us to early exit when those
1006f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // chunks are encountered.
1016f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        switch (tag) {
102ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.com        case SK_PICT_READER_TAG:
1036f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1046f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_READER_TAG %d\n", chunkSize);
1056f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1066f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1076f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_FACTORY_TAG:
1086f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1096f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_FACTORY_TAG %d\n", chunkSize);
1106f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
111dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            // Remove this code when v21 and below are no longer supported
112dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#ifndef DISABLE_V21_COMPATIBILITY_CODE
113dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            if (info.fVersion < 22) {
114dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                if (!FLAGS_quiet) {
115dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                    SkDebugf("Exiting early due to format limitations\n");
116dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                }
117dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                return kSuccess;       // TODO: need to store size in bytes
118dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            }
119dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#endif
1206f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1216f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_TYPEFACE_TAG:
1226f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1236f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_TYPEFACE_TAG %d\n", chunkSize);
1246f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("Exiting early due to format limitations\n");
1256f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1266f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kSuccess;       // TODO: need to store size in bytes
1276f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1286f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PICTURE_TAG:
1296f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1306f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_PICTURE_TAG %d\n", chunkSize);
1316f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("Exiting early due to format limitations\n");
1326f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1336f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kSuccess;       // TODO: need to store size in bytes
1346f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1356f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_BUFFER_SIZE_TAG:
1366f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1376f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_BUFFER_SIZE_TAG %d\n", chunkSize);
1386f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1396f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1406f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        default:
1416f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (!FLAGS_quiet) {
1426f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("Unknown tag %d\n", chunkSize);
1436f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1446f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kInvalidTag;
1456f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
1466f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
1476f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (!stream.move(chunkSize)) {
1486f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (!FLAGS_quiet) {
1496f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("seek error\n");
1506f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1516f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kTruncatedFile;
1526f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
1536f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
1546f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
1556f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    return kSuccess;
1566f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org}
1576f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
1586f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#if !defined SK_BUILD_FOR_IOS
1596f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgint main(int argc, char * const argv[]) {
1606f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    return tool_main(argc, (char**) argv);
1616f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org}
1626f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#endif
163