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"
10db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#include "SkPictureData.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");
15a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillipsDEFINE_bool2(cullRect, c, true, "cullRect");
16e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.orgDEFINE_bool2(flags, f, true, "flags");
176f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_bool2(tags, t, true, "tags");
186f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgDEFINE_bool2(quiet, q, false, "quiet");
196f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
206f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// This tool can print simple information about an SKP but its main use
216f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// is just to check if an SKP has been truncated during the recording
226f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// process.
236f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// return codes:
246f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kSuccess = 0;
256f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kTruncatedFile = 1;
266f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kNotAnSKP = 2;
276f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kInvalidTag = 3;
286f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kMissingInput = 4;
296f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgstatic const int kIOError = 5;
306f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
316f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgint tool_main(int argc, char** argv);
326f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgint tool_main(int argc, char** argv) {
336f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkCommandLineFlags::SetUsage("Prints information about an skp file");
346f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkCommandLineFlags::Parse(argc, argv);
356f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
366f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (FLAGS_input.count() != 1) {
376f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (!FLAGS_quiet) {
386f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            SkDebugf("Missing input file\n");
396f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
406f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kMissingInput;
416f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
426f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
436f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkFILEStream stream(FLAGS_input[0]);
446f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (!stream.isValid()) {
456f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (!FLAGS_quiet) {
466f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            SkDebugf("Couldn't open file\n");
476f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
486f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kIOError;
496f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
506f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
516f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    size_t totStreamSize = stream.getLength();
526f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
536f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    SkPictInfo info;
546f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (!SkPicture::InternalOnly_StreamIsSKP(&stream, &info)) {
556f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kNotAnSKP;
566f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
576f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
586f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (FLAGS_version && !FLAGS_quiet) {
596f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        SkDebugf("Version: %d\n", info.fVersion);
606f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
61a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    if (FLAGS_cullRect && !FLAGS_quiet) {
62a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips        SkDebugf("Cull Rect: %f,%f,%f,%f\n",
63a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips                 info.fCullRect.fLeft, info.fCullRect.fTop,
64a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips                 info.fCullRect.fRight, info.fCullRect.fBottom);
656f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
66e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org    if (FLAGS_flags && !FLAGS_quiet) {
67e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org        SkDebugf("Flags: 0x%x\n", info.fFlags);
68e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org    }
696f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
706f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    if (!stream.readBool()) {
71ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.com        // If we read true there's a picture playback object flattened
72ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.com        // in the file; if false, there isn't a playback, so we're done
736f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // reading the file.
746f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        return kSuccess;
756f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
766f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
776f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    for (;;) {
786f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        uint32_t tag = stream.readU32();
796f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
806f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
816f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
826f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
836f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        uint32_t chunkSize = stream.readU32();
846f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        size_t curPos = stream.getPosition();
856f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
866f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // "move" doesn't error out when seeking beyond the end of file
876f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // so we need a preemptive check here.
886f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (curPos+chunkSize > totStreamSize) {
896f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (!FLAGS_quiet) {
906f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("truncated file\n");
916f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
926f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kTruncatedFile;
936f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
946f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
956f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // Not all the tags store the chunk size (in bytes). Three
966f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // of them store tag-specific size information (e.g., number of
976f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // fonts) instead. This forces us to early exit when those
986f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        // chunks are encountered.
996f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        switch (tag) {
100ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.com        case SK_PICT_READER_TAG:
1016f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1026f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_READER_TAG %d\n", chunkSize);
1036f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1046f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1056f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_FACTORY_TAG:
1066f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1076f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_FACTORY_TAG %d\n", chunkSize);
1086f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
109dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            // Remove this code when v21 and below are no longer supported
110dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#ifndef DISABLE_V21_COMPATIBILITY_CODE
111dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            if (info.fVersion < 22) {
112dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                if (!FLAGS_quiet) {
113dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                    SkDebugf("Exiting early due to format limitations\n");
114dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                }
115dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                return kSuccess;       // TODO: need to store size in bytes
116dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            }
117dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#endif
1186f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1196f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_TYPEFACE_TAG:
1206f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1216f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_TYPEFACE_TAG %d\n", chunkSize);
1226f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("Exiting early due to format limitations\n");
1236f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1246f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kSuccess;       // TODO: need to store size in bytes
1256f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1266f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PICTURE_TAG:
1276f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1286f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_PICTURE_TAG %d\n", chunkSize);
1296f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("Exiting early due to format limitations\n");
1306f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1316f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kSuccess;       // TODO: need to store size in bytes
1326f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1336f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_BUFFER_SIZE_TAG:
1346f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (FLAGS_tags && !FLAGS_quiet) {
1356f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("SK_PICT_BUFFER_SIZE_TAG %d\n", chunkSize);
1366f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1376f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            break;
1386f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        default:
1396f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (!FLAGS_quiet) {
1406f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("Unknown tag %d\n", chunkSize);
1416f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1426f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kInvalidTag;
1436f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
1446f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
1456f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (!stream.move(chunkSize)) {
1466f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            if (!FLAGS_quiet) {
1476f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org                SkDebugf("seek error\n");
1486f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            }
1496f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org            return kTruncatedFile;
1506f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        }
1516f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    }
1526f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
1536f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    return kSuccess;
1546f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org}
1556f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
1566f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#if !defined SK_BUILD_FOR_IOS
1576f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.orgint main(int argc, char * const argv[]) {
1586f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    return tool_main(argc, (char**) argv);
1596f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org}
1606f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#endif
161