2
1
mirror of https://github.com/qpdf/qpdf.git synced 2025-01-03 07:12:28 +00:00

Change the output of --json to use "qpdf" instead of "objects"

This commit is contained in:
Jay Berkenbilt 2022-07-30 20:53:30 -04:00
parent d01c4f8819
commit 69820847af
33 changed files with 13693 additions and 13157 deletions

16
TODO
View File

@ -97,21 +97,19 @@ JSON v2 fixes
This implies a few things:
* Still need to test pushedinheritedpageresources and
calledgetallpages and check/use their values when reading
* Fix --json-help
* --json-key=objects is only valid for v1. --json-key=qpdf is only
valid for v2.
* This changes the policy about additional extra keys. Have a
guarantee that qpdf will never add a key whose name is or starts
with "xdata". We still have to ignore unknown keys for future
compatibility, but at least this gives people a namespace they can
know will never conflict with future keys.
* When reading back in, we'll have to call
pushInheritedAttributesToPage or getAllPages based on the values
of the metadata.
* Test --json with --json-stream-data and --json-output with
--json-stream-data=none. Recheck writeJSON's handling of the
pipeline argument.
* Support json v2 in the C API. At a minimum, write_json,
create_from_json, and update_from_json need to be there and should
take the same kinds of functions as the C API for logger.

View File

@ -142,7 +142,8 @@ class QPDF
// "complete" is false, the "qpdf" key and its value are written
// to the pipeline assuming that a dictionary is already open, and
// finish() is not called. The parameter first_key indicates
// whether this is the first key if in-progress dictionary.
// whether this is the first key in an in-progress dictionary. It
// will be set to false by writeJSON.
//
// The decode_level parameter controls which streams are
// uncompressed in the JSON. Use qpdf_dl_none to preserve all
@ -168,7 +169,7 @@ class QPDF
int version,
Pipeline* p,
bool complete,
bool first_key,
bool& first_key,
qpdf_stream_decode_level_e decode_level,
qpdf_json_stream_data_e json_stream_data,
std::string const& file_prefix,

View File

@ -543,7 +543,7 @@ class QPDFJob
void setEncryptionOptions(QPDF&, QPDFWriter&);
void maybeFixWritePassword(int R, std::string& password);
void writeOutfile(QPDF& pdf);
void writeJSON(QPDF& pdf);
void writeJSON(Pipeline* p, QPDF& pdf, bool complete, bool& first_key);
// JSON
void doJSON(QPDF& pdf, Pipeline*);
@ -700,7 +700,7 @@ class QPDFJob
std::shared_ptr<char> infilename;
std::shared_ptr<char> outfilename;
bool json_input;
int json_output;
bool json_output;
std::string update_from_json;
};
std::shared_ptr<Members> m;

View File

@ -6,12 +6,12 @@ include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a3
include/qpdf/auto_job_c_main.hh cdba1ae6ea5525a585d10a3dd95b7996d62b17de4211fe658b78d9d463b0f313
include/qpdf/auto_job_c_pages.hh b3cc0f21029f6d89efa043dcdbfa183cb59325b6506001c18911614fe8e568ec
include/qpdf/auto_job_c_uo.hh ae21b69a1efa9333050f4833d465f6daff87e5b38e5106e49bbef5d4132e4ed1
job.yml 3b2b3c6f92b48f6c76109711cbfdd74669fa31a80cd17379548b09f8e76be05d
job.yml ad7c086267fe6f309bf0838840f22cbd95326259cad148b4d5e6699b49f5f379
libqpdf/qpdf/auto_job_decl.hh 74df4d7fdbdf51ecd0d58ce1e9844bb5525b9adac5a45f7c9a787ecdda2868df
libqpdf/qpdf/auto_job_help.hh db2e4350c700e064b204e3e20d4fee4eddfe312b28092afcf608b4b6863d30e5
libqpdf/qpdf/auto_job_init.hh 7ea8e0641dc26fdfba6e283e14dbbff0c016654e174cdace8054f8bef53750fd
libqpdf/qpdf/auto_job_init.hh 3c3576b6d1d79fda64ae53f08fd9fd2b42c86f3c1d52dd4db0d7f2d4d64b9b4a
libqpdf/qpdf/auto_job_json_decl.hh 06caa46eaf71db8a50c046f91866baa8087745a9474319fb7c86d92634cc8297
libqpdf/qpdf/auto_job_json_init.hh 5f6b53e3c81d4b54ce5c4cf9c3f52d0c02f987c53bf8841c0280367bad23e335
libqpdf/qpdf/auto_job_json_init.hh 59545578a2e47c660ff98516ed53f06638be75eb4658e2a09d32cc08e0cb7268
libqpdf/qpdf/auto_job_schema.hh 9d543cd4a43eafffc2c4b8a6fee29e399c271c52cb6f7d417ae5497b3c1127dc
manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580
manual/cli.rst 8e1f443c6fa000e023e516c318df4d04d58233d4d8648907c4a71f0ea5722bca

View File

@ -44,10 +44,11 @@ choices:
- attachments
- encrypt
- objectinfo # only v1
- objects
- objects # only v1
- outlines
- pagelabels
- pages
- qpdf # only v2
json_output:
- 2
- latest

View File

@ -417,7 +417,7 @@ QPDFJob::Members::Members() :
check_is_encrypted(false),
check_requires_password(false),
json_input(false),
json_output(0)
json_output(false)
{
}
@ -728,8 +728,15 @@ QPDFJob::checkConfiguration()
" overwrite the input file");
}
if (m->json_keys.count("objectinfo")) {
usage("json key \"objectinfo\" is only valid for json version 1");
if (m->json_version == 1) {
if (m->json_keys.count("qpdf")) {
usage("json key \"qpdf\" is only valid for json version > 1");
}
} else {
if (m->json_keys.count("objectinfo") || m->json_keys.count("objects")) {
usage("json keys \"objects\" and \"objectinfo\" are only valid for"
" json version 1");
}
}
}
@ -1568,12 +1575,12 @@ QPDFJob::json_schema(int json_version, std::set<std::string>* keys)
// The list of selectable top-level keys id duplicated in the
// following places: job.yml, QPDFJob::json_schema, and
// QPDFJob::doJSON.
if (json_version == 1) {
if (all_keys || keys->count("objects")) {
schema.addDictionaryMember("objects", JSON::parse(R"({
"<n n R|trailer>": "json representation of object"
})"));
}
if (json_version == 1) {
if (all_keys || keys->count("objectinfo")) {
JSON objectinfo =
schema.addDictionaryMember("objectinfo", JSON::parse(R"({
@ -1586,6 +1593,19 @@ QPDFJob::json_schema(int json_version, std::set<std::string>* keys)
}
})"));
}
} else {
if (all_keys || keys->count("qpdf")) {
schema.addDictionaryMember("qpdf", JSON::parse(R"([{
"jsonversion": "numeric JSON version",
"pdfversion": "PDF version as x.y",
"pushedinheritedpageresources": "whether inherited attributes were pushed to the page level",
"calledgetallpages": "whether getAllPages was called",
"maxobjectid": "highest object ID in output, ignored on input"
},
{
"<obj:n n R|trailer>": "json representation of object"
}])"));
}
}
if (all_keys || keys->count("pages")) {
JSON page = schema.addDictionaryMember("pages", JSON::parse(R"([
@ -1812,9 +1832,14 @@ QPDFJob::doJSON(QPDF& pdf, Pipeline* p)
// We do objects last so their information is consistent with
// repairing the page tree. To see the original file with any page
// tree problems and the page tree not flattened, select
// objects/objectinfo without other keys.
if (all_keys || m->json_keys.count("objects")) {
// qpdf/objects/objectinfo without other keys.
if (all_keys || m->json_keys.count("objects") ||
m->json_keys.count("qpdf")) {
if (this->m->json_version == 1) {
doJSONObjects(p, first, pdf);
} else {
writeJSON(p, pdf, false, first);
}
}
if (this->m->json_version == 1) {
// "objectinfo" is not needed for version >1 since you can
@ -2274,7 +2299,8 @@ QPDFJob::addAttachments(QPDF& pdf)
}
message = pdf.getFilename() +
" already has attachments with the following keys: " + message +
"; use --replace to replace or --key to specify a different key";
"; use --replace to replace or --key to specify a different "
"key";
throw std::runtime_error(message);
}
}
@ -2925,10 +2951,12 @@ QPDFJob::maybeFixWritePassword(int R, std::string& password)
<< this->m->message_prefix << ": WARNING: "
<< "supplied password looks like a Unicode"
<< " password with characters not allowed in"
<< " passwords for 40-bit and 128-bit encryption;"
<< " passwords for 40-bit and 128-bit "
"encryption;"
<< " most readers will not be able to open this"
<< " file with the supplied password."
<< " (Use --password-mode=bytes to suppress this"
<< " (Use --password-mode=bytes to suppress "
"this"
<< " warning and use the password anyway.)\n";
}
} else if ((R >= 5) && (!is_valid_utf8)) {
@ -2978,13 +3006,15 @@ QPDFJob::setEncryptionOptions(QPDF& pdf, QPDFWriter& w)
QTC::TC("qpdf", "QPDFJob weak crypto error");
*this->m->log->getError()
<< this->m->message_prefix
<< ": refusing to write a file with RC4, a weak cryptographic "
<< ": refusing to write a file with RC4, a weak "
"cryptographic "
"algorithm\n"
<< "Please use 256-bit keys for better security.\n"
<< "Pass --allow-weak-crypto to enable writing insecure "
"files.\n"
<< "See also "
"https://qpdf.readthedocs.io/en/stable/weak-crypto.html\n";
"https://qpdf.readthedocs.io/en/stable/"
"weak-crypto.html\n";
throw std::runtime_error(
"refusing to write a file with weak crypto");
}
@ -3293,7 +3323,8 @@ QPDFJob::writeOutfile(QPDF& pdf)
m->outfilename = nullptr;
}
if (this->m->json_output) {
writeJSON(pdf);
bool unused = true;
writeJSON(nullptr, pdf, true, unused);
} else {
// QPDFWriter must have block scope so the output file will be
// closed after write() finishes.
@ -3347,7 +3378,7 @@ QPDFJob::writeOutfile(QPDF& pdf)
}
void
QPDFJob::writeJSON(QPDF& pdf)
QPDFJob::writeJSON(Pipeline* p, QPDF& pdf, bool complete, bool& first_key)
{
// File pipeline must have block scope so it will be closed
// after write.
@ -3369,8 +3400,13 @@ QPDFJob::writeJSON(QPDF& pdf)
"name is unknown");
} else {
QTC::TC("qpdf", "QPDFJob write json to stdout");
if (p == nullptr) {
fp = this->m->log->getInfo();
}
}
if (p == nullptr) {
p = fp.get();
}
std::set<std::string> json_objects;
if (this->m->json_objects.count("trailer")) {
json_objects.insert("trailer");
@ -3382,10 +3418,10 @@ QPDFJob::writeJSON(QPDF& pdf)
json_objects.insert(s.str());
}
pdf.writeJSON(
this->m->json_output,
fp.get(),
true,
true,
this->m->json_version,
p,
complete,
first_key,
this->m->decode_level,
this->m->json_stream_data,
file_prefix,

View File

@ -296,12 +296,13 @@ QPDFJob::Config::jsonInput()
QPDFJob::Config*
QPDFJob::Config::jsonOutput(std::string const& parameter)
{
o.m->json_output = true;
if (parameter.empty() || (parameter == "latest")) {
o.m->json_output = JSON::LATEST;
o.m->json_version = JSON::LATEST;
} else {
o.m->json_output = QUtil::string_to_int(parameter.c_str());
o.m->json_version = QUtil::string_to_int(parameter.c_str());
}
if ((o.m->json_output < 2) || (o.m->json_output > JSON::LATEST)) {
if ((o.m->json_version < 2) || (o.m->json_version > JSON::LATEST)) {
usage(std::string("unsupported json output version ") + parameter);
}
if (!o.m->json_stream_data_set) {

View File

@ -802,7 +802,7 @@ QPDF::writeJSON(
int version,
Pipeline* p,
bool complete,
bool first_key,
bool& first_key,
qpdf_stream_decode_level_e decode_level,
qpdf_json_stream_data_e json_stream_data,
std::string const& file_prefix,
@ -892,4 +892,5 @@ QPDF::writeJSON(
*p << "\n";
p->finish();
}
first_key = false;
}

View File

@ -19,7 +19,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized
static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
static char const* flatten_choices[] = {"all", "print", "screen", 0};
static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", "qpdf", 0};
static char const* json_output_choices[] = {"2", "latest", 0};
static char const* json_stream_data_choices[] = {"none", "inline", "file", 0};
static char const* json_version_choices[] = {"1", "2", "latest", 0};

View File

@ -12,7 +12,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized
static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0};
static char const* remove_unref_choices[] = {"auto", "yes", "no", 0};
static char const* flatten_choices[] = {"all", "print", "screen", 0};
static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0};
static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", "qpdf", 0};
static char const* json_output_choices[] = {"2", "latest", 0};
static char const* json_stream_data_choices[] = {"none", "inline", "file", 0};
static char const* json_version_choices[] = {"1", "2", "latest", 0};

View File

@ -15,7 +15,7 @@ cleanup();
my $td = new TestDriver('arg-parsing');
my $n_tests = 13;
my $n_tests = 16;
$td->runtest("required argument",
{$td->COMMAND => "qpdf --password minimal.pdf"},
@ -77,6 +77,23 @@ $td->runtest("duplicated pages password",
{$td->REGEXP => ".*password already specified.*",
$td->EXIT_STATUS => 2},
$td->NORMALIZE_NEWLINES);
$td->runtest("v1-only objects json-key",
{$td->COMMAND => "qpdf --json=2 --json-key=objects minimal.pdf"},
{$td->REGEXP => ".*\"objects\" and \"objectinfo\" are " .
"only valid for json version 1.*",
$td->EXIT_STATUS => 2},
$td->NORMALIZE_NEWLINES);
$td->runtest("v1-only objectinfo json-key",
{$td->COMMAND => "qpdf --json=2 --json-key=objectinfo minimal.pdf"},
{$td->REGEXP => ".*\"objects\" and \"objectinfo\" are " .
"only valid for json version 1.*",
$td->EXIT_STATUS => 2},
$td->NORMALIZE_NEWLINES);
$td->runtest("v2-only qpdf json-key",
{$td->COMMAND => "qpdf --json=1 --json-key=qpdf minimal.pdf"},
{$td->REGEXP => ".*\"qpdf\" is only valid for json version > 1.*",
$td->EXIT_STATUS => 2},
$td->NORMALIZE_NEWLINES);
# Ignoring -- at the top level was never intended but turned out to
# have been there for a long time so that people relied on it. It is
# intentionally not documented.

View File

@ -61,6 +61,10 @@ foreach my $d (@json_files)
@$xargs, $in]},
{$td->FILE => "$out-v1.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
for (@$xargs)
{
s/--json-key=objects/--json-key=qpdf/;
}
$td->runtest("json v2 $out",
{$td->COMMAND =>
['qpdf', '--json=2', '--test-json-schema', @$xargs, $in]},

View File

@ -14,7 +14,7 @@ cleanup();
my $td = new TestDriver('pages-tree');
my $n_tests = 13;
my $n_tests = 17;
$td->runtest("linearize duplicated pages",
{$td->COMMAND =>
@ -58,19 +58,29 @@ foreach my $f (qw(page_api_2 direct-pages))
$td->runtest("json for $f (objects only)",
{$td->COMMAND =>
"qpdf --json=latest $f.pdf" .
" --json-key=objects"},
" --json-key=qpdf"},
{$td->FILE => "$f-json-objects.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("json for $f (with pages)",
{$td->COMMAND =>
"qpdf --json=latest $f.pdf" .
" --json-key=objects --json-key=pages 2>warn.tmpout"},
" --json-key=qpdf --json-key=pages 2>warn.tmpout"},
{$td->FILE => "$f-json-pages.out", $td->EXIT_STATUS => 3},
$td->NORMALIZE_NEWLINES);
$td->runtest("check page warnings",
{$td->FILE => "warn.tmpout"},
{$td->FILE => "$f-json-warning.out"},
$td->NORMALIZE_NEWLINES);
$td->runtest("json for $f (with push)",
{$td->COMMAND =>
"qpdf --pages . -- --json=latest $f.pdf" .
" --json-key=qpdf --json-key=pages 2>warn2.tmpout"},
{$td->FILE => "$f-json-pages-push.out", $td->EXIT_STATUS => 3},
$td->NORMALIZE_NEWLINES);
$td->runtest("check page warnings",
{$td->FILE => "warn2.tmpout"},
{$td->FILE => "$f-json-warning.out"},
$td->NORMALIZE_NEWLINES);
}
cleanup();

View File

@ -3,7 +3,15 @@
"parameters": {
"decodelevel": "generalized"
},
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": false,
"maxobjectid": 6
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@ -88,4 +96,5 @@
}
}
}
]
}

View File

@ -0,0 +1,128 @@
{
"version": 2,
"parameters": {
"decodelevel": "generalized"
},
"pages": [
{
"contents": [
"3 0 R"
],
"images": [],
"label": null,
"object": "7 0 R",
"outlines": [],
"pageposfrom1": 1
},
{
"contents": [
"3 0 R"
],
"images": [],
"label": null,
"object": "8 0 R",
"outlines": [],
"pageposfrom1": 2
}
],
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": true,
"calledgetallpages": true,
"maxobjectid": 8
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
"/Type": "/Catalog"
}
},
"obj:2 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"7 0 R",
"8 0 R"
],
"/Type": "/Pages"
}
},
"obj:3 0 R": {
"stream": {
"dict": {
"/Length": "4 0 R"
}
}
},
"obj:4 0 R": {
"value": 44
},
"obj:5 0 R": {
"value": {
"/BaseFont": "/Helvetica",
"/Encoding": "/WinAnsiEncoding",
"/Name": "/F1",
"/Subtype": "/Type1",
"/Type": "/Font"
}
},
"obj:6 0 R": {
"value": [
"/PDF",
"/Text"
]
},
"obj:7 0 R": {
"value": {
"/Contents": "3 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "2 0 R",
"/Resources": {
"/Font": {
"/F1": "5 0 R"
},
"/ProcSet": "6 0 R"
},
"/Type": "/Page"
}
},
"obj:8 0 R": {
"value": {
"/Contents": "3 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "2 0 R",
"/Resources": {
"/Font": {
"/F1": "5 0 R"
},
"/ProcSet": "6 0 R"
},
"/Type": "/Page"
}
},
"trailer": {
"value": {
"/ID": [
"b:1323a5937c577a66735583a93698ce3c",
"b:372cbf44f6db88ab60d9263c0f0bd26a"
],
"/Root": "1 0 R",
"/Size": 7
}
}
}
]
}

View File

@ -25,7 +25,15 @@
"pageposfrom1": 2
}
],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 8
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@ -116,4 +124,5 @@
}
}
}
]
}

View File

@ -100,7 +100,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 14
},
{
"obj:1 0 R": {
"value": {
"/Names": {
@ -239,4 +247,5 @@
}
}
}
]
}

View File

@ -432,7 +432,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.5",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 196
},
{
"obj:1 0 R": {
"value": {
"/AcroForm": {
@ -3172,4 +3180,5 @@
}
}
}
]
}

View File

@ -432,7 +432,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.5",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 196
},
{
"obj:1 0 R": {
"value": {
"/AcroForm": {
@ -3172,4 +3180,5 @@
}
}
}
]
}

View File

@ -275,7 +275,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 30
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@ -739,4 +747,5 @@
}
}
}
]
}

View File

@ -275,7 +275,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 30
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@ -751,4 +759,5 @@
}
}
}
]
}

View File

@ -275,7 +275,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 30
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@ -739,4 +747,5 @@
}
}
}
]
}

View File

@ -275,7 +275,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 30
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@ -739,4 +747,5 @@
}
}
}
]
}

View File

@ -620,7 +620,15 @@
"title": "Salad 2 -> 15: /XYZ 66 756 3"
}
],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 108
},
{
"obj:1 0 R": {
"value": {
"/Names": {
@ -1768,4 +1776,5 @@
}
}
}
]
}

View File

@ -725,7 +725,15 @@
"title": "•Salad 2 -> 15: /XYZ 66 756 3"
}
],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 107
},
{
"obj:1 0 R": {
"value": {
"/Dests": "107 0 R",
@ -1876,4 +1884,5 @@
}
}
}
]
}

View File

@ -3,7 +3,15 @@
"parameters": {
"decodelevel": "generalized"
},
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": false,
"maxobjectid": 106
},
{
"obj:2 0 R": {
"value": {
"/Count": 30,
@ -49,4 +57,5 @@
}
}
}
]
}

View File

@ -3,7 +3,15 @@
"parameters": {
"decodelevel": "generalized"
},
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": false,
"maxobjectid": 106
},
{
"trailer": {
"value": {
"/Root": "1 0 R",
@ -11,4 +19,5 @@
}
}
}
]
}

View File

@ -3,7 +3,15 @@
"parameters": {
"decodelevel": "generalized"
},
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": false,
"maxobjectid": 106
},
{
"obj:1 0 R": {
"value": {
"/Outlines": "95 0 R",
@ -1183,4 +1191,5 @@
}
}
}
]
}

View File

@ -795,7 +795,15 @@
"title": "Trepak 2 -> 15: /XYZ 66 756 3"
}
],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 106
},
{
"obj:1 0 R": {
"value": {
"/Outlines": "95 0 R",
@ -1975,4 +1983,5 @@
}
}
}
]
}

View File

@ -538,7 +538,15 @@
"userpasswordmatched": false
},
"outlines": [],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 99
},
{
"obj:1 0 R": {
"value": {
"/PageLabels": "2 0 R",
@ -1596,4 +1604,5 @@
}
}
}
]
}

View File

@ -3,7 +3,15 @@
"parameters": {
"decodelevel": "generalized"
},
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": false,
"maxobjectid": 10
},
{
"obj:1 0 R": {
"value": {
"/Pages": "3 0 R",
@ -111,4 +119,5 @@
}
}
}
]
}

View File

@ -0,0 +1,177 @@
{
"version": 2,
"parameters": {
"decodelevel": "generalized"
},
"pages": [
{
"contents": [
"6 0 R"
],
"images": [],
"label": null,
"object": "4 0 R",
"outlines": [],
"pageposfrom1": 1
},
{
"contents": [
"6 0 R"
],
"images": [],
"label": null,
"object": "11 0 R",
"outlines": [],
"pageposfrom1": 2
},
{
"contents": [
"9 0 R"
],
"images": [],
"label": null,
"object": "5 0 R",
"outlines": [],
"pageposfrom1": 3
}
],
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": true,
"calledgetallpages": true,
"maxobjectid": 11
},
{
"obj:1 0 R": {
"value": {
"/Pages": "3 0 R",
"/Type": "/Catalog"
}
},
"obj:2 0 R": {
"value": {
"/CreationDate": "u:D:20120621124041",
"/Producer": "u:Apex PDFWriter"
}
},
"obj:3 0 R": {
"value": {
"/Count": 3,
"/Kids": [
"4 0 R",
"11 0 R",
"5 0 R"
],
"/Type": "/Pages"
}
},
"obj:4 0 R": {
"value": {
"/Contents": "6 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Resources": {
"/Font": {
"/F1": "8 0 R"
},
"/ProcSet": [
"/PDF",
"/Text"
]
},
"/Type": "/Page"
}
},
"obj:5 0 R": {
"value": {
"/Contents": "9 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Resources": {
"/Font": {
"/F1": "8 0 R"
},
"/ProcSet": [
"/PDF",
"/Text"
]
},
"/Type": "/Page"
}
},
"obj:6 0 R": {
"stream": {
"dict": {
"/Length": "7 0 R"
}
}
},
"obj:7 0 R": {
"value": 47
},
"obj:8 0 R": {
"value": {
"/BaseFont": "/Times-Roman",
"/Encoding": "/WinAnsiEncoding",
"/Subtype": "/Type1",
"/Type": "/Font"
}
},
"obj:9 0 R": {
"stream": {
"dict": {
"/Length": "10 0 R"
}
}
},
"obj:10 0 R": {
"value": 47
},
"obj:11 0 R": {
"value": {
"/Contents": "6 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Resources": {
"/Font": {
"/F1": "8 0 R"
},
"/ProcSet": [
"/PDF",
"/Text"
]
},
"/Type": "/Page"
}
},
"trailer": {
"value": {
"/ID": [
"b:fb18b786ff7b358705da8a532aba8f6f",
"b:f7179eb35159bfd4c00f128abcfd1f02"
],
"/Info": "2 0 R",
"/Root": "1 0 R",
"/Size": 11
}
}
}
]
}

View File

@ -35,7 +35,15 @@
"pageposfrom1": 3
}
],
"objects": {
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 11
},
{
"obj:1 0 R": {
"value": {
"/Pages": "3 0 R",
@ -165,4 +173,5 @@
}
}
}
]
}