xref: /third_party/skia/tools/skp_parser.cpp (revision cb93a386)
1/*
2 * Copyright 2016 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 "include/core/SkPicture.h"
9#include "include/core/SkStream.h"
10#include "include/utils/SkNullCanvas.h"
11#include "tools/debugger/DebugCanvas.h"
12
13#include <iostream>
14
15#ifdef SK_BUILD_FOR_WIN
16#include <fcntl.h>
17#include <io.h>
18#endif
19
20/*
21If you execute skp_parser with one argument, it spits out a json representation
22of the skp, but that's incomplete since it's missing many binary blobs (these
23could represent images or typefaces or just anything that doesn't currently
24have a json representation).  Each unique blob is labeled with a string in the
25form "data/%d".  So for example:
26
27    tools/git-sync-deps
28    bin/gn gen out/debug
29    ninja -C out/debug dm skp_parser
30    out/debug/dm -m grayscale -w /tmp/dm --config skp
31    out/debug/skp_parser /tmp/dm/skp/gm/grayscalejpg.skp | less
32    out/debug/skp_parser /tmp/dm/skp/gm/grayscalejpg.skp | grep data
33    out/debug/skp_parser /tmp/dm/skp/gm/grayscalejpg.skp data/0 | file -
34    out/debug/skp_parser /tmp/dm/skp/gm/grayscalejpg.skp data/0 > /tmp/data0.png
35
36"data/0" is an image that the SKP serializer has encoded as PNG.
37*/
38int main(int argc, char** argv) {
39    if (argc < 2) {
40        SkDebugf("Usage:\n  %s SKP_FILE [DATA_URL]\n", argv[0]);
41        return 1;
42    }
43    SkFILEStream input(argv[1]);
44    if (!input.isValid()) {
45        SkDebugf("Bad file: '%s'\n", argv[1]);
46        return 2;
47    }
48    sk_sp<SkPicture> pic = SkPicture::MakeFromStream(&input);
49    if (!pic) {
50        SkDebugf("Bad skp: '%s'\n", argv[1]);
51        return 3;
52    }
53    SkISize size = pic->cullRect().roundOut().size();
54    DebugCanvas debugCanvas(size.width(), size.height());
55    pic->playback(&debugCanvas);
56    std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
57    UrlDataManager dataManager(SkString("data"));
58    SkDynamicMemoryWStream stream;
59    SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
60    writer.beginObject(); // root
61    debugCanvas.toJSON(writer, dataManager, nullCanvas.get());
62    writer.endObject(); // root
63    writer.flush();
64    if (argc > 2) {
65        if (UrlDataManager::UrlData* data =
66            dataManager.getDataFromUrl(SkString(argv[2]))) {
67            SkData* skdata = data->fData.get();
68            SkASSERT(skdata);
69            #ifdef SK_BUILD_FOR_WIN
70            fflush(stdout);
71            (void)_setmode(_fileno(stdout), _O_BINARY);
72            #endif
73            fwrite(skdata->data(), skdata->size(), 1, stdout);
74        } else {
75            SkDebugf("Bad data url.\n");
76            return 4;
77        }
78    } else {
79        sk_sp<SkData> data = stream.detachAsData();
80        fwrite(data->data(), data->size(), 1, stdout);
81    }
82    return 0;
83}
84