2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-10-31 19:02:30 +00:00

Use calledgetallpages and pushedinheritedpageresources

This commit is contained in:
Jay Berkenbilt 2022-07-31 15:09:48 -04:00
parent 5f4224f31a
commit 13cf35ce2f
16 changed files with 980 additions and 4 deletions

4
TODO
View File

@ -71,10 +71,6 @@ JSON v2 fixes
* Rethink QPDF::writeJSON. Maybe provide a simpler overload?
* When reading back in, we'll have to call
pushInheritedAttributesToPage or getAllPages based on the values
of the metadata.
* 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

@ -473,6 +473,30 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
QTC::TC("qpdf", "QPDF_json bad json version");
error(value.getStart(), "invalid JSON version (must be 2)");
}
} else if (key == "pushedinheritedpageresources") {
bool v;
if (value.getBool(v)) {
if ((!this->must_be_complete) && v) {
this->pdf.pushInheritedAttributesToPage();
}
} else {
QTC::TC("qpdf", "QPDF_json bad pushedinheritedpageresources");
error(
value.getStart(),
"pushedinheritedpageresources must be a boolean");
}
} else if (key == "calledgetallpages") {
bool v;
if (value.getBool(v)) {
if ((!this->must_be_complete) && v) {
this->pdf.getAllPages();
}
} else {
QTC::TC("qpdf", "QPDF_json bad calledgetallpages");
error(
value.getStart(),
"calledgetallpages must be a boolean");
}
} else {
// ignore unknown keys for forward compatibility and to
// skip keys we don't care about like "maxobjectid".

View File

@ -672,3 +672,5 @@ QPDF_json qpdf not array 0
QPDF_json more than two qpdf elements 0
QPDF_json missing json version 0
QPDF_json bad json version 0
QPDF_json bad calledgetallpages 0
QPDF_json bad pushedinheritedpageresources 0

View File

@ -214,5 +214,73 @@ $td->runtest("update-from-json object description",
{$td->FILE => "test-90.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
# Exercise pushedinheritedpageresources and calledgetallpages
$n_tests += 12;
$td->runtest("call getAllPages",
{$td->COMMAND =>
"qpdf --json-output duplicate-page-inherited.pdf" .
" --json-key=pages a.json"},
{$td->FILE => "duplicate-page-inherited.out",
$td->EXIT_STATUS => 3},
$td->NORMALIZE_NEWLINES);
$td->runtest("check json (1)",
{$td->FILE => "a.json"},
{$td->FILE => "duplicate-page-inherited-1.json"},
$td->NORMALIZE_NEWLINES);
$td->runtest("update (1)",
{$td->COMMAND =>
"qpdf" .
" --update-from-json=duplicate-page-inherited-update.json" .
" --json-output duplicate-page-inherited.pdf" .
" a.json"},
{$td->FILE => "duplicate-page-inherited.out",
$td->EXIT_STATUS => 3},
$td->NORMALIZE_NEWLINES);
$td->runtest("check json (2)",
{$td->FILE => "a.json"},
{$td->FILE => "duplicate-page-inherited-1-fixed.json"},
$td->NORMALIZE_NEWLINES);
$td->runtest("create PDF (1)",
{$td->COMMAND =>
"qpdf --qdf --static-id --json-input a.json a.pdf"},
{$td->STRING => "", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("check PDF (1)",
{$td->FILE => "a.pdf"},
{$td->FILE => "duplicate-page-inherited-1-fixed.pdf"});
$td->runtest("call pushInheritedAttributesToPage",
{$td->COMMAND =>
"qpdf --json-output duplicate-page-inherited.pdf" .
" --json-key=pages --pages . -- a.json"},
{$td->FILE => "duplicate-page-inherited.out",
$td->EXIT_STATUS => 3},
$td->NORMALIZE_NEWLINES);
$td->runtest("check json (2)",
{$td->FILE => "a.json"},
{$td->FILE => "duplicate-page-inherited-2.json"},
$td->NORMALIZE_NEWLINES);
$td->runtest("update (2)",
{$td->COMMAND =>
"qpdf" .
" --update-from-json=duplicate-page-inherited-update2.json" .
" --json-output duplicate-page-inherited.pdf" .
" a.json"},
{$td->FILE => "duplicate-page-inherited.out",
$td->EXIT_STATUS => 3},
$td->NORMALIZE_NEWLINES);
$td->runtest("check json (3)",
{$td->FILE => "a.json"},
{$td->FILE => "duplicate-page-inherited-2-fixed.json"},
$td->NORMALIZE_NEWLINES);
$td->runtest("create PDF (2)",
{$td->COMMAND =>
"qpdf --qdf --static-id --json-input a.json a.pdf"},
{$td->STRING => "", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("check PDF (2)",
{$td->FILE => "a.pdf"},
{$td->FILE => "duplicate-page-inherited-2-fixed.pdf"});
cleanup();
$td->report($n_tests);

View File

@ -0,0 +1,96 @@
{
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 8
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
"/Type": "/Catalog"
}
},
"obj:2 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"3 0 R"
],
"/Resources": {
"/Font": {
"/F1": "6 0 R"
}
},
"/Type": "/Pages"
}
},
"obj:3 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"4 0 R",
"7 0 R"
],
"/Parent": "2 0 R",
"/Type": "/Pages"
}
},
"obj:4 0 R": {
"value": {
"/Contents": "5 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Type": "/Page"
}
},
"obj:5 0 R": {
"stream": {
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
"dict": {}
}
},
"obj:6 0 R": {
"value": {
"/BaseFont": "/Helvetica",
"/Encoding": "/WinAnsiEncoding",
"/Subtype": "/Type1",
"/Type": "/Font"
}
},
"obj:7 0 R": {
"value": {
"/Contents": "8 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Type": "/Page"
}
},
"obj:8 0 R": {
"stream": {
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
"dict": {}
}
},
"trailer": {
"value": {
"/Root": "1 0 R",
"/Size": 7
}
}
}
]
}

View File

@ -0,0 +1,142 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
]
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
/Type /Pages
>>
endobj
%% Original object ID: 3 0
3 0 obj
<<
/Count 2
/Kids [
5 0 R
6 0 R
]
/Parent 2 0 R
/Type /Pages
>>
endobj
%% Original object ID: 6 0
4 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Subtype /Type1
/Type /Font
>>
endobj
%% Page 1
%% Original object ID: 4 0
5 0 obj
<<
/Contents 7 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 7 0
6 0 obj
<<
/Contents 9 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 5 0
7 0 obj
<<
/Length 8 0 R
>>
stream
BT
/F1 24 Tf
72 720 Td
(Potato) Tj
ET
endstream
endobj
8 0 obj
44
endobj
%% Contents for page 2
%% Original object ID: 8 0
9 0 obj
<<
/Length 10 0 R
>>
stream
BT
/F1 24 Tf
72 720 Td
(Salad) Tj
ET
endstream
endobj
10 0 obj
43
endobj
xref
0 11
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000289 00000 n
0000000414 00000 n
0000000557 00000 n
0000000710 00000 n
0000000876 00000 n
0000000975 00000 n
0000001044 00000 n
0000001143 00000 n
trailer <<
/Root 1 0 R
/Size 11
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
>>
startxref
1163
%%EOF

View File

@ -0,0 +1,112 @@
{
"pages": [
{
"contents": [
"5 0 R"
],
"images": [],
"label": null,
"object": "4 0 R",
"outlines": [],
"pageposfrom1": 1
},
{
"contents": [
"5 0 R"
],
"images": [],
"label": null,
"object": "7 0 R",
"outlines": [],
"pageposfrom1": 2
}
],
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 7
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
"/Type": "/Catalog"
}
},
"obj:2 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"3 0 R"
],
"/Resources": {
"/Font": {
"/F1": "6 0 R"
}
},
"/Type": "/Pages"
}
},
"obj:3 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"4 0 R",
"7 0 R"
],
"/Parent": "2 0 R",
"/Type": "/Pages"
}
},
"obj:4 0 R": {
"value": {
"/Contents": "5 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Type": "/Page"
}
},
"obj:5 0 R": {
"stream": {
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
"dict": {}
}
},
"obj:6 0 R": {
"value": {
"/BaseFont": "/Helvetica",
"/Encoding": "/WinAnsiEncoding",
"/Subtype": "/Type1",
"/Type": "/Font"
}
},
"obj:7 0 R": {
"value": {
"/Contents": "5 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Type": "/Page"
}
},
"trailer": {
"value": {
"/Root": "1 0 R",
"/Size": 7
}
}
}
]
}

View File

@ -0,0 +1,104 @@
{
"qpdf": [
{
"jsonversion": 2,
"pdfversion": "1.3",
"pushedinheritedpageresources": true,
"calledgetallpages": true,
"maxobjectid": 9
},
{
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
"/Type": "/Catalog"
}
},
"obj:2 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"3 0 R"
],
"/Type": "/Pages"
}
},
"obj:3 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"4 0 R",
"7 0 R"
],
"/Parent": "2 0 R",
"/Type": "/Pages"
}
},
"obj:4 0 R": {
"value": {
"/Contents": "5 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Resources": "8 0 R",
"/Type": "/Page"
}
},
"obj:5 0 R": {
"stream": {
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
"dict": {}
}
},
"obj:6 0 R": {
"value": {
"/BaseFont": "/Helvetica",
"/Encoding": "/WinAnsiEncoding",
"/Subtype": "/Type1",
"/Type": "/Font"
}
},
"obj:7 0 R": {
"value": {
"/Contents": "9 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "2 0 R",
"/Resources": {
"/Font": {
"/F2": "6 0 R"
}
},
"/Type": "/Page"
}
},
"obj:8 0 R": {
"value": {
"/Font": {
"/F1": "6 0 R"
}
}
},
"obj:9 0 R": {
"stream": {
"data": "QlQKICAvRjIgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
"dict": {}
}
},
"trailer": {
"value": {
"/Root": "1 0 R",
"/Size": 7
}
}
}
]
}

View File

@ -0,0 +1,153 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
]
/Type /Pages
>>
endobj
%% Original object ID: 3 0
3 0 obj
<<
/Count 2
/Kids [
4 0 R
5 0 R
]
/Parent 2 0 R
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 4 0
4 0 obj
<<
/Contents 6 0 R
/MediaBox [
0
0
612
792
]
/Parent 3 0 R
/Resources 8 0 R
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 7 0
5 0 obj
<<
/Contents 9 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F2 11 0 R
>>
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 5 0
6 0 obj
<<
/Length 7 0 R
>>
stream
BT
/F1 24 Tf
72 720 Td
(Potato) Tj
ET
endstream
endobj
7 0 obj
44
endobj
%% Original object ID: 8 0
8 0 obj
<<
/Font <<
/F1 11 0 R
>>
>>
endobj
%% Contents for page 2
%% Original object ID: 9 0
9 0 obj
<<
/Length 10 0 R
>>
stream
BT
/F2 24 Tf
72 720 Td
(Salad) Tj
ET
endstream
endobj
10 0 obj
43
endobj
%% Original object ID: 6 0
11 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Subtype /Type1
/Type /Font
>>
endobj
xref
0 12
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000232 00000 n
0000000367 00000 n
0000000539 00000 n
0000000763 00000 n
0000000862 00000 n
0000000908 00000 n
0000001011 00000 n
0000001110 00000 n
0000001157 00000 n
trailer <<
/Root 1 0 R
/Size 12
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
>>
startxref
1264
%%EOF

View File

@ -0,0 +1,125 @@
{
"pages": [
{
"contents": [
"5 0 R"
],
"images": [],
"label": null,
"object": "4 0 R",
"outlines": [],
"pageposfrom1": 1
},
{
"contents": [
"5 0 R"
],
"images": [],
"label": null,
"object": "7 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": [
"4 0 R",
"7 0 R"
],
"/Type": "/Pages"
}
},
"obj:3 0 R": {
"value": {
"/Count": 2,
"/Kids": [
"4 0 R",
"7 0 R"
],
"/Parent": "2 0 R",
"/Type": "/Pages"
}
},
"obj:4 0 R": {
"value": {
"/Contents": "5 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "2 0 R",
"/Resources": {
"/Font": {
"/F1": "6 0 R"
}
},
"/Type": "/Page"
}
},
"obj:5 0 R": {
"stream": {
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
"dict": {}
}
},
"obj:6 0 R": {
"value": {
"/BaseFont": "/Helvetica",
"/Encoding": "/WinAnsiEncoding",
"/Subtype": "/Type1",
"/Type": "/Font"
}
},
"obj:7 0 R": {
"value": {
"/Contents": "5 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "2 0 R",
"/Resources": {
"/Font": {
"/F1": "6 0 R"
}
},
"/Type": "/Page"
}
},
"obj:8 0 R": {
"value": {
"/Font": {
"/F1": "6 0 R"
}
}
},
"trailer": {
"value": {
"/Root": "1 0 R",
"/Size": 7
}
}
}
]
}

View File

@ -0,0 +1,31 @@
{
"qpdf": [
{
"jsonversion": 2,
"pushedinheritedpageresources": false,
"calledgetallpages": true,
"maxobjectid": 7
},
{
"obj:8 0 R": {
"stream": {
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
"dict": {}
}
},
"obj:7 0 R": {
"value": {
"/Contents": "8 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "3 0 R",
"/Type": "/Page"
}
}
}
]
}

View File

@ -0,0 +1,35 @@
{
"qpdf": [
{
"jsonversion": 2,
"pushedinheritedpageresources": true,
"calledgetallpages": true
},
{
"obj:9 0 R": {
"stream": {
"data": "QlQKICAvRjIgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
"dict": {}
}
},
"obj:7 0 R": {
"value": {
"/Contents": "9 0 R",
"/MediaBox": [
0,
0,
612,
792
],
"/Parent": "2 0 R",
"/Resources": {
"/Font": {
"/F2": "6 0 R"
}
},
"/Type": "/Page"
}
}
}
]
}

View File

@ -0,0 +1,2 @@
WARNING: duplicate-page-inherited.pdf, object 3 0 at offset 202: kid 1 (from 0) appears more than once in the pages tree; creating a new page object as a copy
qpdf: operation succeeded with warnings; resulting file may have some problems

View File

@ -0,0 +1,82 @@
%PDF-1.3
1 0 obj
<<
/Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Resources <<
/Font <<
/F1 6 0 R
>>
>>
/Kids [
3 0 R
]
/Count 2
>>
endobj
3 0 obj
<<
/Type /Pages
/Parent 2 0 R
/Kids [
4 0 R
4 0 R
]
/Count 2
>>
endobj
4 0 obj
<<
/Type /Page
/Parent 3 0 R
/MediaBox [0 0 612 792]
/Contents 5 0 R
>>
endobj
5 0 obj
<<
/Length 44
>>
stream
BT
/F1 24 Tf
72 720 Td
(Potato) Tj
ET
endstream
endobj
6 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
xref
0 7
0000000000 65535 f
0000000009 00000 n
0000000063 00000 n
0000000192 00000 n
0000000290 00000 n
0000000386 00000 n
0000000482 00000 n
trailer <<
/Size 7
/Root 1 0 R
>>
startxref
588
%%EOF

View File

@ -3,6 +3,8 @@
{
"jsonversion": 850,
"pdfversion": [],
"calledgetallpages": 3,
"pushedinheritedpageresources": "potato",
"maxobjectid": 6
},
{

View File

@ -1,3 +1,5 @@
WARNING: qjson-bad-pdf-version2.json (offset 41): invalid JSON version (must be 2)
WARNING: qjson-bad-pdf-version2.json (offset 66): invalid PDF version (must be x.y)
WARNING: qjson-bad-pdf-version2.json (offset 97): calledgetallpages must be a boolean
WARNING: qjson-bad-pdf-version2.json (offset 138): pushedinheritedpageresources must be a boolean
qpdf: qjson-bad-pdf-version2.json: errors found in JSON