Commit 352ce9b22ba32fa50e22258f7d61557ae0d53cc5
1 parent
6ef9e312
Preserve page labels (numbers) when splitting and merging
Showing
12 changed files
with
806 additions
and
144 deletions
ChangeLog
| 1 | 1 | 2018-12-18 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | |
| 3 | + * Preserve page labels when merging and splitting files. Prior | |
| 4 | + versions of qpdf simply preserved the page label information from | |
| 5 | + the first file, which usually wouldn't make any sense in the | |
| 6 | + merged file. Now any page that had a page number in any original | |
| 7 | + file will have the same page number after merging or splitting. | |
| 8 | + | |
| 3 | 9 | * Add QPDFPageLabelDocumentHelper class. This is a document helper |
| 4 | 10 | class that provides useful methods for dealing with page labels. |
| 5 | 11 | It abstracts the fact that they are stored as number trees and | ... | ... |
manual/qpdf-manual.xml
| ... | ... | @@ -911,23 +911,23 @@ make |
| 911 | 911 | </itemizedlist> |
| 912 | 912 | </para> |
| 913 | 913 | <para> |
| 914 | - Note that qpdf doesn't presently do anything special about other | |
| 915 | - constructs in a PDF file that may know about pages, so semantics | |
| 916 | - of splitting and merging vary across features. For example, the | |
| 917 | - document's outlines (bookmarks) point to actual page objects, so | |
| 918 | - if you select some pages and not others, bookmarks that point to | |
| 919 | - pages that are in the output file will work, and remaining | |
| 920 | - bookmarks will not work. On the other hand, page labels (page | |
| 921 | - numbers specified in the file) are just sequential, so page labels | |
| 922 | - will be messed up in the output file. A future version of | |
| 923 | - <command>qpdf</command> may do a better job at handling these | |
| 924 | - issues. (Note that the qpdf library already contains all of the | |
| 925 | - APIs required in order to implement this in your own application | |
| 926 | - if you need it.) In the mean time, you can always use | |
| 927 | - <option>--empty</option> as the primary input file to avoid | |
| 928 | - copying all of that from the first file. For example, to take | |
| 929 | - pages 1 through 5 from a <filename>infile.pdf</filename> while | |
| 930 | - preserving all metadata associated with that file, you could use | |
| 914 | + Starting in qpdf version 8.3, when you split and merge files, any | |
| 915 | + page labels (page numbers) are preserved in the final file. It is | |
| 916 | + expected that more document features will be preserved by | |
| 917 | + splitting and merging. In the mean time, semantics of splitting | |
| 918 | + and merging vary across features. For example, the document's | |
| 919 | + outlines (bookmarks) point to actual page objects, so if you | |
| 920 | + select some pages and not others, bookmarks that point to pages | |
| 921 | + that are in the output file will work, and remaining bookmarks | |
| 922 | + will not work. A future version of <command>qpdf</command> may do | |
| 923 | + a better job at handling these issues. (Note that the qpdf library | |
| 924 | + already contains all of the APIs required in order to implement | |
| 925 | + this in your own application if you need it.) In the mean time, | |
| 926 | + you can always use <option>--empty</option> as the primary input | |
| 927 | + file to avoid copying all of that from the first file. For | |
| 928 | + example, to take pages 1 through 5 from a | |
| 929 | + <filename>infile.pdf</filename> while preserving all metadata | |
| 930 | + associated with that file, you could use | |
| 931 | 931 | |
| 932 | 932 | <programlisting><command>qpdf</command> <option>infile.pdf --pages infile.pdf 1-5 -- outfile.pdf</option> |
| 933 | 933 | </programlisting> |
| ... | ... | @@ -946,8 +946,8 @@ make |
| 946 | 946 | If, for some reason, you wanted to take the first page of an |
| 947 | 947 | encrypted file called <filename>encrypted.pdf</filename> with |
| 948 | 948 | password <literal>pass</literal> and repeat it twice in an output |
| 949 | - file, and if you wanted to drop metadata (like page numbers and | |
| 950 | - outlines) but preserve encryption, you would use | |
| 949 | + file, and if you wanted to drop document-level metadata but | |
| 950 | + preserve encryption, you would use | |
| 951 | 951 | |
| 952 | 952 | <programlisting><command>qpdf</command> <option>--empty --copy-encryption=encrypted.pdf --encryption-file-password=pass |
| 953 | 953 | --pages encrypted.pdf --password=pass 1 ./encrypted.pdf --password=pass 1 -- | ... | ... |
qpdf/qpdf.cc
| ... | ... | @@ -16,6 +16,7 @@ |
| 16 | 16 | #include <qpdf/QPDF.hh> |
| 17 | 17 | #include <qpdf/QPDFPageDocumentHelper.hh> |
| 18 | 18 | #include <qpdf/QPDFPageObjectHelper.hh> |
| 19 | +#include <qpdf/QPDFPageLabelDocumentHelper.hh> | |
| 19 | 20 | #include <qpdf/QPDFExc.hh> |
| 20 | 21 | |
| 21 | 22 | #include <qpdf/QPDFWriter.hh> |
| ... | ... | @@ -2296,11 +2297,25 @@ static void handle_page_specs(QPDF& pdf, Options& o, |
| 2296 | 2297 | // Keep track of any pages from the original file that we are |
| 2297 | 2298 | // selecting. |
| 2298 | 2299 | std::set<int> selected_from_orig; |
| 2300 | + std::vector<QPDFObjectHandle> new_labels; | |
| 2301 | + bool any_page_labels = false; | |
| 2302 | + int out_pageno = 0; | |
| 2299 | 2303 | for (std::vector<QPDFPageData>::iterator iter = |
| 2300 | 2304 | parsed_specs.begin(); |
| 2301 | 2305 | iter != parsed_specs.end(); ++iter) |
| 2302 | 2306 | { |
| 2303 | 2307 | QPDFPageData& page_data = *iter; |
| 2308 | + ClosedFileInputSource* cis = 0; | |
| 2309 | + if (page_spec_cfis.count(page_data.filename)) | |
| 2310 | + { | |
| 2311 | + cis = page_spec_cfis[page_data.filename]; | |
| 2312 | + cis->stayOpen(true); | |
| 2313 | + } | |
| 2314 | + QPDFPageLabelDocumentHelper pldh(*page_data.qpdf); | |
| 2315 | + if (pldh.hasPageLabels()) | |
| 2316 | + { | |
| 2317 | + any_page_labels = true; | |
| 2318 | + } | |
| 2304 | 2319 | if (o.verbose) |
| 2305 | 2320 | { |
| 2306 | 2321 | std::cout << whoami << ": adding pages from " |
| ... | ... | @@ -2309,22 +2324,14 @@ static void handle_page_specs(QPDF& pdf, Options& o, |
| 2309 | 2324 | for (std::vector<int>::iterator pageno_iter = |
| 2310 | 2325 | page_data.selected_pages.begin(); |
| 2311 | 2326 | pageno_iter != page_data.selected_pages.end(); |
| 2312 | - ++pageno_iter) | |
| 2327 | + ++pageno_iter, ++out_pageno) | |
| 2313 | 2328 | { |
| 2314 | 2329 | // Pages are specified from 1 but numbered from 0 in the |
| 2315 | 2330 | // vector |
| 2316 | 2331 | int pageno = *pageno_iter - 1; |
| 2317 | - ClosedFileInputSource* cis = 0; | |
| 2318 | - if (page_spec_cfis.count(page_data.filename)) | |
| 2319 | - { | |
| 2320 | - cis = page_spec_cfis[page_data.filename]; | |
| 2321 | - cis->stayOpen(true); | |
| 2322 | - } | |
| 2332 | + pldh.getLabelsForPageRange(pageno, pageno, out_pageno, | |
| 2333 | + new_labels); | |
| 2323 | 2334 | dh.addPage(page_data.orig_pages.at(pageno), false); |
| 2324 | - if (cis) | |
| 2325 | - { | |
| 2326 | - cis->stayOpen(false); | |
| 2327 | - } | |
| 2328 | 2335 | if (page_data.qpdf == &pdf) |
| 2329 | 2336 | { |
| 2330 | 2337 | // This is a page from the original file. Keep track |
| ... | ... | @@ -2332,6 +2339,18 @@ static void handle_page_specs(QPDF& pdf, Options& o, |
| 2332 | 2339 | selected_from_orig.insert(pageno); |
| 2333 | 2340 | } |
| 2334 | 2341 | } |
| 2342 | + if (cis) | |
| 2343 | + { | |
| 2344 | + cis->stayOpen(false); | |
| 2345 | + } | |
| 2346 | + } | |
| 2347 | + if (any_page_labels) | |
| 2348 | + { | |
| 2349 | + QPDFObjectHandle page_labels = | |
| 2350 | + QPDFObjectHandle::newDictionary(); | |
| 2351 | + page_labels.replaceKey( | |
| 2352 | + "/Nums", QPDFObjectHandle::newArray(new_labels)); | |
| 2353 | + pdf.getRoot().replaceKey("/PageLabels", page_labels); | |
| 2335 | 2354 | } |
| 2336 | 2355 | |
| 2337 | 2356 | // Delete page objects for unused page in primary. This prevents |
| ... | ... | @@ -2574,6 +2593,7 @@ static void write_outfile(QPDF& pdf, Options& o) |
| 2574 | 2593 | dh.pushInheritedAttributesToPage(); |
| 2575 | 2594 | dh.removeUnreferencedResources(); |
| 2576 | 2595 | } |
| 2596 | + QPDFPageLabelDocumentHelper pldh(pdf); | |
| 2577 | 2597 | std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages(); |
| 2578 | 2598 | int pageno_len = QUtil::int_to_string(pages.size()).length(); |
| 2579 | 2599 | unsigned int num_pages = pages.size(); |
| ... | ... | @@ -2592,6 +2612,16 @@ static void write_outfile(QPDF& pdf, Options& o) |
| 2592 | 2612 | QPDFObjectHandle page = pages.at(pageno - 1); |
| 2593 | 2613 | outpdf.addPage(page, false); |
| 2594 | 2614 | } |
| 2615 | + if (pldh.hasPageLabels()) | |
| 2616 | + { | |
| 2617 | + std::vector<QPDFObjectHandle> labels; | |
| 2618 | + pldh.getLabelsForPageRange(first - 1, last - 1, 0, labels); | |
| 2619 | + QPDFObjectHandle page_labels = | |
| 2620 | + QPDFObjectHandle::newDictionary(); | |
| 2621 | + page_labels.replaceKey( | |
| 2622 | + "/Nums", QPDFObjectHandle::newArray(labels)); | |
| 2623 | + outpdf.getRoot().replaceKey("/PageLabels", page_labels); | |
| 2624 | + } | |
| 2595 | 2625 | std::string page_range = QUtil::int_to_string(first, pageno_len); |
| 2596 | 2626 | if (o.split_pages > 1) |
| 2597 | 2627 | { | ... | ... |
qpdf/qpdf.testcov
qpdf/qtest/qpdf.test
| ... | ... | @@ -1137,7 +1137,7 @@ my @sp_cases = ( |
| 1137 | 1137 | [11, 'pdf extension', '', 'split-out.Pdf'], |
| 1138 | 1138 | [4, 'fallback', '--pages 11-pages.pdf 1-3 minimal.pdf --', 'split-out'], |
| 1139 | 1139 | ); |
| 1140 | -$n_tests += 9; | |
| 1140 | +$n_tests += 12; | |
| 1141 | 1141 | for (@sp_cases) |
| 1142 | 1142 | { |
| 1143 | 1143 | $n_tests += 1 + $_->[0]; |
| ... | ... | @@ -1171,6 +1171,17 @@ foreach my $i (qw(01-04 05-08 09-10)) |
| 1171 | 1171 | {$td->FILE => "shared-split-$i.pdf"}); |
| 1172 | 1172 | } |
| 1173 | 1173 | |
| 1174 | +$td->runtest("split page with labels", | |
| 1175 | + {$td->COMMAND => "qpdf --qdf --static-id --split-pages=6". | |
| 1176 | + " 11-pages-with-labels.pdf split-out-labels.pdf"}, | |
| 1177 | + {$td->STRING => "", $td->EXIT_STATUS => 0}); | |
| 1178 | +foreach my $i (qw(01-06 07-11)) | |
| 1179 | +{ | |
| 1180 | + $td->runtest("check output ($i)", | |
| 1181 | + {$td->FILE => "split-out-labels-$i.pdf"}, | |
| 1182 | + {$td->FILE => "labels-split-$i.pdf"}); | |
| 1183 | +} | |
| 1184 | + | |
| 1174 | 1185 | foreach my $d (@sp_cases) |
| 1175 | 1186 | { |
| 1176 | 1187 | my ($n, $description, $xargs, $out) = @$d; |
| ... | ... | @@ -1335,7 +1346,7 @@ foreach my $d (@nrange_tests) |
| 1335 | 1346 | show_ntests(); |
| 1336 | 1347 | # ---------- |
| 1337 | 1348 | $td->notify("--- Merging and Splitting ---"); |
| 1338 | -$n_tests += 16; | |
| 1349 | +$n_tests += 18; | |
| 1339 | 1350 | |
| 1340 | 1351 | # Select pages from the same file multiple times including selecting |
| 1341 | 1352 | # twice from an encrypted file and specifying the password only the |
| ... | ... | @@ -1368,8 +1379,7 @@ $td->runtest("merge three files", |
| 1368 | 1379 | " $pages_options --static-id"}, |
| 1369 | 1380 | {$td->STRING => "", $td->EXIT_STATUS => 0}); |
| 1370 | 1381 | # Manually verified about this file: it has the same pages but does |
| 1371 | -# not contain outlines, page labels, or other things from the original | |
| 1372 | -# file. | |
| 1382 | +# not contain outlines or other things from the original file. | |
| 1373 | 1383 | $td->runtest("check output", |
| 1374 | 1384 | {$td->FILE => "a.pdf"}, |
| 1375 | 1385 | {$td->FILE => "merge-three-files-2.pdf"}); |
| ... | ... | @@ -1392,6 +1402,17 @@ $td->runtest("merge with implicit ranges", |
| 1392 | 1402 | $td->runtest("check output", |
| 1393 | 1403 | {$td->FILE => "a.pdf"}, |
| 1394 | 1404 | {$td->FILE => "merge-implicit-ranges.pdf"}); |
| 1405 | +$td->runtest("merge with multiple labels", | |
| 1406 | + {$td->COMMAND => | |
| 1407 | + "qpdf --empty a.pdf" . | |
| 1408 | + " --pages 11-pages-with-labels.pdf 8-11" . | |
| 1409 | + " minimal.pdf " . | |
| 1410 | + " page-labels-and-outlines.pdf 17-19 --" . | |
| 1411 | + " --static-id"}, | |
| 1412 | + {$td->STRING => "", $td->EXIT_STATUS => 0}); | |
| 1413 | +$td->runtest("check output", | |
| 1414 | + {$td->FILE => "a.pdf"}, | |
| 1415 | + {$td->FILE => "merge-multiple-labels.pdf"}); | |
| 1395 | 1416 | |
| 1396 | 1417 | $td->runtest("split with shared resources", |
| 1397 | 1418 | {$td->COMMAND => | ... | ... |
qpdf/qtest/qpdf/11-pages-with-labels.pdf
0 → 100644
No preview for this file type
qpdf/qtest/qpdf/labels-split-01-06.pdf
0 → 100644
| 1 | +%PDF-1.3 | |
| 2 | +%¿÷¢þ | |
| 3 | +%QDF-1.0 | |
| 4 | + | |
| 5 | +%% Original object ID: 1 0 | |
| 6 | +1 0 obj | |
| 7 | +<< | |
| 8 | + /PageLabels << | |
| 9 | + /Nums [ | |
| 10 | + 0 | |
| 11 | + << | |
| 12 | + /P (pre-) | |
| 13 | + /St 1 | |
| 14 | + >> | |
| 15 | + 4 | |
| 16 | + << | |
| 17 | + /S /r | |
| 18 | + /St 4 | |
| 19 | + >> | |
| 20 | + ] | |
| 21 | + >> | |
| 22 | + /Pages 2 0 R | |
| 23 | + /Type /Catalog | |
| 24 | +>> | |
| 25 | +endobj | |
| 26 | + | |
| 27 | +%% Original object ID: 2 0 | |
| 28 | +2 0 obj | |
| 29 | +<< | |
| 30 | + /Count 6 | |
| 31 | + /Kids [ | |
| 32 | + 3 0 R | |
| 33 | + 4 0 R | |
| 34 | + 5 0 R | |
| 35 | + 6 0 R | |
| 36 | + 7 0 R | |
| 37 | + 8 0 R | |
| 38 | + ] | |
| 39 | + /Type /Pages | |
| 40 | +>> | |
| 41 | +endobj | |
| 42 | + | |
| 43 | +%% Page 1 | |
| 44 | +%% Original object ID: 3 0 | |
| 45 | +3 0 obj | |
| 46 | +<< | |
| 47 | + /Contents 9 0 R | |
| 48 | + /MediaBox [ | |
| 49 | + 0 | |
| 50 | + 0 | |
| 51 | + 612 | |
| 52 | + 792 | |
| 53 | + ] | |
| 54 | + /Parent 2 0 R | |
| 55 | + /Resources << | |
| 56 | + /Font << | |
| 57 | + /F1 11 0 R | |
| 58 | + >> | |
| 59 | + /ProcSet [ | |
| 60 | ||
| 61 | + /Text | |
| 62 | + ] | |
| 63 | + >> | |
| 64 | + /Type /Page | |
| 65 | +>> | |
| 66 | +endobj | |
| 67 | + | |
| 68 | +%% Page 2 | |
| 69 | +%% Original object ID: 6 0 | |
| 70 | +4 0 obj | |
| 71 | +<< | |
| 72 | + /Contents 12 0 R | |
| 73 | + /MediaBox [ | |
| 74 | + 0 | |
| 75 | + 0 | |
| 76 | + 612 | |
| 77 | + 792 | |
| 78 | + ] | |
| 79 | + /Parent 2 0 R | |
| 80 | + /Resources << | |
| 81 | + /Font << | |
| 82 | + /F1 11 0 R | |
| 83 | + >> | |
| 84 | + /ProcSet [ | |
| 85 | ||
| 86 | + /Text | |
| 87 | + ] | |
| 88 | + >> | |
| 89 | + /Type /Page | |
| 90 | +>> | |
| 91 | +endobj | |
| 92 | + | |
| 93 | +%% Page 3 | |
| 94 | +%% Original object ID: 8 0 | |
| 95 | +5 0 obj | |
| 96 | +<< | |
| 97 | + /Contents 14 0 R | |
| 98 | + /MediaBox [ | |
| 99 | + 0 | |
| 100 | + 0 | |
| 101 | + 612 | |
| 102 | + 792 | |
| 103 | + ] | |
| 104 | + /Parent 2 0 R | |
| 105 | + /Resources << | |
| 106 | + /Font << | |
| 107 | + /F1 11 0 R | |
| 108 | + >> | |
| 109 | + /ProcSet [ | |
| 110 | ||
| 111 | + /Text | |
| 112 | + ] | |
| 113 | + >> | |
| 114 | + /Type /Page | |
| 115 | +>> | |
| 116 | +endobj | |
| 117 | + | |
| 118 | +%% Page 4 | |
| 119 | +%% Original object ID: 10 0 | |
| 120 | +6 0 obj | |
| 121 | +<< | |
| 122 | + /Contents 16 0 R | |
| 123 | + /MediaBox [ | |
| 124 | + 0 | |
| 125 | + 0 | |
| 126 | + 612 | |
| 127 | + 792 | |
| 128 | + ] | |
| 129 | + /Parent 2 0 R | |
| 130 | + /Resources << | |
| 131 | + /Font << | |
| 132 | + /F1 11 0 R | |
| 133 | + >> | |
| 134 | + /ProcSet [ | |
| 135 | ||
| 136 | + /Text | |
| 137 | + ] | |
| 138 | + >> | |
| 139 | + /Type /Page | |
| 140 | +>> | |
| 141 | +endobj | |
| 142 | + | |
| 143 | +%% Page 5 | |
| 144 | +%% Original object ID: 12 0 | |
| 145 | +7 0 obj | |
| 146 | +<< | |
| 147 | + /Contents 18 0 R | |
| 148 | + /MediaBox [ | |
| 149 | + 0 | |
| 150 | + 0 | |
| 151 | + 612 | |
| 152 | + 792 | |
| 153 | + ] | |
| 154 | + /Parent 2 0 R | |
| 155 | + /Resources << | |
| 156 | + /Font << | |
| 157 | + /F1 11 0 R | |
| 158 | + >> | |
| 159 | + /ProcSet [ | |
| 160 | ||
| 161 | + /Text | |
| 162 | + ] | |
| 163 | + >> | |
| 164 | + /Type /Page | |
| 165 | +>> | |
| 166 | +endobj | |
| 167 | + | |
| 168 | +%% Page 6 | |
| 169 | +%% Original object ID: 14 0 | |
| 170 | +8 0 obj | |
| 171 | +<< | |
| 172 | + /Contents 20 0 R | |
| 173 | + /MediaBox [ | |
| 174 | + 0 | |
| 175 | + 0 | |
| 176 | + 612 | |
| 177 | + 792 | |
| 178 | + ] | |
| 179 | + /Parent 2 0 R | |
| 180 | + /Resources << | |
| 181 | + /Font << | |
| 182 | + /F1 11 0 R | |
| 183 | + >> | |
| 184 | + /ProcSet [ | |
| 185 | ||
| 186 | + /Text | |
| 187 | + ] | |
| 188 | + >> | |
| 189 | + /Type /Page | |
| 190 | +>> | |
| 191 | +endobj | |
| 192 | + | |
| 193 | +%% Contents for page 1 | |
| 194 | +%% Original object ID: 4 0 | |
| 195 | +9 0 obj | |
| 196 | +<< | |
| 197 | + /Length 10 0 R | |
| 198 | +>> | |
| 199 | +stream | |
| 200 | +BT /F1 15 Tf 72 720 Td (Original page 1) Tj ET | |
| 201 | +endstream | |
| 202 | +endobj | |
| 203 | + | |
| 204 | +10 0 obj | |
| 205 | +47 | |
| 206 | +endobj | |
| 207 | + | |
| 208 | +%% Original object ID: 5 0 | |
| 209 | +11 0 obj | |
| 210 | +<< | |
| 211 | + /BaseFont /Times-Roman | |
| 212 | + /Encoding /WinAnsiEncoding | |
| 213 | + /Subtype /Type1 | |
| 214 | + /Type /Font | |
| 215 | +>> | |
| 216 | +endobj | |
| 217 | + | |
| 218 | +%% Contents for page 2 | |
| 219 | +%% Original object ID: 7 0 | |
| 220 | +12 0 obj | |
| 221 | +<< | |
| 222 | + /Length 13 0 R | |
| 223 | +>> | |
| 224 | +stream | |
| 225 | +BT /F1 15 Tf 72 720 Td (Original page 2) Tj ET | |
| 226 | +endstream | |
| 227 | +endobj | |
| 228 | + | |
| 229 | +13 0 obj | |
| 230 | +47 | |
| 231 | +endobj | |
| 232 | + | |
| 233 | +%% Contents for page 3 | |
| 234 | +%% Original object ID: 9 0 | |
| 235 | +14 0 obj | |
| 236 | +<< | |
| 237 | + /Length 15 0 R | |
| 238 | +>> | |
| 239 | +stream | |
| 240 | +BT /F1 15 Tf 72 720 Td (Original page 3) Tj ET | |
| 241 | +endstream | |
| 242 | +endobj | |
| 243 | + | |
| 244 | +15 0 obj | |
| 245 | +47 | |
| 246 | +endobj | |
| 247 | + | |
| 248 | +%% Contents for page 4 | |
| 249 | +%% Original object ID: 11 0 | |
| 250 | +16 0 obj | |
| 251 | +<< | |
| 252 | + /Length 17 0 R | |
| 253 | +>> | |
| 254 | +stream | |
| 255 | +BT /F1 15 Tf 72 720 Td (Original page 4) Tj ET | |
| 256 | +endstream | |
| 257 | +endobj | |
| 258 | + | |
| 259 | +17 0 obj | |
| 260 | +47 | |
| 261 | +endobj | |
| 262 | + | |
| 263 | +%% Contents for page 5 | |
| 264 | +%% Original object ID: 13 0 | |
| 265 | +18 0 obj | |
| 266 | +<< | |
| 267 | + /Length 19 0 R | |
| 268 | +>> | |
| 269 | +stream | |
| 270 | +BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET | |
| 271 | +endstream | |
| 272 | +endobj | |
| 273 | + | |
| 274 | +19 0 obj | |
| 275 | +47 | |
| 276 | +endobj | |
| 277 | + | |
| 278 | +%% Contents for page 6 | |
| 279 | +%% Original object ID: 15 0 | |
| 280 | +20 0 obj | |
| 281 | +<< | |
| 282 | + /Length 21 0 R | |
| 283 | +>> | |
| 284 | +stream | |
| 285 | +BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET | |
| 286 | +endstream | |
| 287 | +endobj | |
| 288 | + | |
| 289 | +21 0 obj | |
| 290 | +47 | |
| 291 | +endobj | |
| 292 | + | |
| 293 | +xref | |
| 294 | +0 22 | |
| 295 | +0000000000 65535 f | |
| 296 | +0000000052 00000 n | |
| 297 | +0000000285 00000 n | |
| 298 | +0000000444 00000 n | |
| 299 | +0000000699 00000 n | |
| 300 | +0000000955 00000 n | |
| 301 | +0000001212 00000 n | |
| 302 | +0000001469 00000 n | |
| 303 | +0000001726 00000 n | |
| 304 | +0000001995 00000 n | |
| 305 | +0000002098 00000 n | |
| 306 | +0000002145 00000 n | |
| 307 | +0000002304 00000 n | |
| 308 | +0000002408 00000 n | |
| 309 | +0000002478 00000 n | |
| 310 | +0000002582 00000 n | |
| 311 | +0000002653 00000 n | |
| 312 | +0000002757 00000 n | |
| 313 | +0000002828 00000 n | |
| 314 | +0000002932 00000 n | |
| 315 | +0000003003 00000 n | |
| 316 | +0000003107 00000 n | |
| 317 | +trailer << | |
| 318 | + /Root 1 0 R | |
| 319 | + /Size 22 | |
| 320 | + /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] | |
| 321 | +>> | |
| 322 | +startxref | |
| 323 | +3127 | |
| 324 | +%%EOF | ... | ... |
qpdf/qtest/qpdf/labels-split-07-11.pdf
0 → 100644
| 1 | +%PDF-1.3 | |
| 2 | +%¿÷¢þ | |
| 3 | +%QDF-1.0 | |
| 4 | + | |
| 5 | +%% Original object ID: 1 0 | |
| 6 | +1 0 obj | |
| 7 | +<< | |
| 8 | + /PageLabels << | |
| 9 | + /Nums [ | |
| 10 | + 0 | |
| 11 | + << | |
| 12 | + /S /r | |
| 13 | + /St 6 | |
| 14 | + >> | |
| 15 | + 2 | |
| 16 | + << | |
| 17 | + /S /a | |
| 18 | + /St 16 | |
| 19 | + >> | |
| 20 | + ] | |
| 21 | + >> | |
| 22 | + /Pages 2 0 R | |
| 23 | + /Type /Catalog | |
| 24 | +>> | |
| 25 | +endobj | |
| 26 | + | |
| 27 | +%% Original object ID: 2 0 | |
| 28 | +2 0 obj | |
| 29 | +<< | |
| 30 | + /Count 5 | |
| 31 | + /Kids [ | |
| 32 | + 3 0 R | |
| 33 | + 4 0 R | |
| 34 | + 5 0 R | |
| 35 | + 6 0 R | |
| 36 | + 7 0 R | |
| 37 | + ] | |
| 38 | + /Type /Pages | |
| 39 | +>> | |
| 40 | +endobj | |
| 41 | + | |
| 42 | +%% Page 1 | |
| 43 | +%% Original object ID: 3 0 | |
| 44 | +3 0 obj | |
| 45 | +<< | |
| 46 | + /Contents 8 0 R | |
| 47 | + /MediaBox [ | |
| 48 | + 0 | |
| 49 | + 0 | |
| 50 | + 612 | |
| 51 | + 792 | |
| 52 | + ] | |
| 53 | + /Parent 2 0 R | |
| 54 | + /Resources << | |
| 55 | + /Font << | |
| 56 | + /F1 10 0 R | |
| 57 | + >> | |
| 58 | + /ProcSet [ | |
| 59 | ||
| 60 | + /Text | |
| 61 | + ] | |
| 62 | + >> | |
| 63 | + /Type /Page | |
| 64 | +>> | |
| 65 | +endobj | |
| 66 | + | |
| 67 | +%% Page 2 | |
| 68 | +%% Original object ID: 6 0 | |
| 69 | +4 0 obj | |
| 70 | +<< | |
| 71 | + /Contents 11 0 R | |
| 72 | + /MediaBox [ | |
| 73 | + 0 | |
| 74 | + 0 | |
| 75 | + 612 | |
| 76 | + 792 | |
| 77 | + ] | |
| 78 | + /Parent 2 0 R | |
| 79 | + /Resources << | |
| 80 | + /Font << | |
| 81 | + /F1 10 0 R | |
| 82 | + >> | |
| 83 | + /ProcSet [ | |
| 84 | ||
| 85 | + /Text | |
| 86 | + ] | |
| 87 | + >> | |
| 88 | + /Type /Page | |
| 89 | +>> | |
| 90 | +endobj | |
| 91 | + | |
| 92 | +%% Page 3 | |
| 93 | +%% Original object ID: 8 0 | |
| 94 | +5 0 obj | |
| 95 | +<< | |
| 96 | + /Contents 13 0 R | |
| 97 | + /MediaBox [ | |
| 98 | + 0 | |
| 99 | + 0 | |
| 100 | + 612 | |
| 101 | + 792 | |
| 102 | + ] | |
| 103 | + /Parent 2 0 R | |
| 104 | + /Resources << | |
| 105 | + /Font << | |
| 106 | + /F1 10 0 R | |
| 107 | + >> | |
| 108 | + /ProcSet [ | |
| 109 | ||
| 110 | + /Text | |
| 111 | + ] | |
| 112 | + >> | |
| 113 | + /Type /Page | |
| 114 | +>> | |
| 115 | +endobj | |
| 116 | + | |
| 117 | +%% Page 4 | |
| 118 | +%% Original object ID: 10 0 | |
| 119 | +6 0 obj | |
| 120 | +<< | |
| 121 | + /Contents 15 0 R | |
| 122 | + /MediaBox [ | |
| 123 | + 0 | |
| 124 | + 0 | |
| 125 | + 612 | |
| 126 | + 792 | |
| 127 | + ] | |
| 128 | + /Parent 2 0 R | |
| 129 | + /Resources << | |
| 130 | + /Font << | |
| 131 | + /F1 10 0 R | |
| 132 | + >> | |
| 133 | + /ProcSet [ | |
| 134 | ||
| 135 | + /Text | |
| 136 | + ] | |
| 137 | + >> | |
| 138 | + /Type /Page | |
| 139 | +>> | |
| 140 | +endobj | |
| 141 | + | |
| 142 | +%% Page 5 | |
| 143 | +%% Original object ID: 12 0 | |
| 144 | +7 0 obj | |
| 145 | +<< | |
| 146 | + /Contents 17 0 R | |
| 147 | + /MediaBox [ | |
| 148 | + 0 | |
| 149 | + 0 | |
| 150 | + 612 | |
| 151 | + 792 | |
| 152 | + ] | |
| 153 | + /Parent 2 0 R | |
| 154 | + /Resources << | |
| 155 | + /Font << | |
| 156 | + /F1 10 0 R | |
| 157 | + >> | |
| 158 | + /ProcSet [ | |
| 159 | ||
| 160 | + /Text | |
| 161 | + ] | |
| 162 | + >> | |
| 163 | + /Type /Page | |
| 164 | +>> | |
| 165 | +endobj | |
| 166 | + | |
| 167 | +%% Contents for page 1 | |
| 168 | +%% Original object ID: 4 0 | |
| 169 | +8 0 obj | |
| 170 | +<< | |
| 171 | + /Length 9 0 R | |
| 172 | +>> | |
| 173 | +stream | |
| 174 | +BT /F1 15 Tf 72 720 Td (Original page 7) Tj ET | |
| 175 | +endstream | |
| 176 | +endobj | |
| 177 | + | |
| 178 | +9 0 obj | |
| 179 | +47 | |
| 180 | +endobj | |
| 181 | + | |
| 182 | +%% Original object ID: 5 0 | |
| 183 | +10 0 obj | |
| 184 | +<< | |
| 185 | + /BaseFont /Times-Roman | |
| 186 | + /Encoding /WinAnsiEncoding | |
| 187 | + /Subtype /Type1 | |
| 188 | + /Type /Font | |
| 189 | +>> | |
| 190 | +endobj | |
| 191 | + | |
| 192 | +%% Contents for page 2 | |
| 193 | +%% Original object ID: 7 0 | |
| 194 | +11 0 obj | |
| 195 | +<< | |
| 196 | + /Length 12 0 R | |
| 197 | +>> | |
| 198 | +stream | |
| 199 | +BT /F1 15 Tf 72 720 Td (Original page 8) Tj ET | |
| 200 | +endstream | |
| 201 | +endobj | |
| 202 | + | |
| 203 | +12 0 obj | |
| 204 | +47 | |
| 205 | +endobj | |
| 206 | + | |
| 207 | +%% Contents for page 3 | |
| 208 | +%% Original object ID: 9 0 | |
| 209 | +13 0 obj | |
| 210 | +<< | |
| 211 | + /Length 14 0 R | |
| 212 | +>> | |
| 213 | +stream | |
| 214 | +BT /F1 15 Tf 72 720 Td (Original page 9) Tj ET | |
| 215 | +endstream | |
| 216 | +endobj | |
| 217 | + | |
| 218 | +14 0 obj | |
| 219 | +47 | |
| 220 | +endobj | |
| 221 | + | |
| 222 | +%% Contents for page 4 | |
| 223 | +%% Original object ID: 11 0 | |
| 224 | +15 0 obj | |
| 225 | +<< | |
| 226 | + /Length 16 0 R | |
| 227 | +>> | |
| 228 | +stream | |
| 229 | +BT /F1 15 Tf 72 720 Td (Original page 10) Tj ET | |
| 230 | +endstream | |
| 231 | +endobj | |
| 232 | + | |
| 233 | +16 0 obj | |
| 234 | +48 | |
| 235 | +endobj | |
| 236 | + | |
| 237 | +%% Contents for page 5 | |
| 238 | +%% Original object ID: 13 0 | |
| 239 | +17 0 obj | |
| 240 | +<< | |
| 241 | + /Length 18 0 R | |
| 242 | +>> | |
| 243 | +stream | |
| 244 | +BT /F1 15 Tf 72 720 Td (Original page 11) Tj ET | |
| 245 | +endstream | |
| 246 | +endobj | |
| 247 | + | |
| 248 | +18 0 obj | |
| 249 | +48 | |
| 250 | +endobj | |
| 251 | + | |
| 252 | +xref | |
| 253 | +0 19 | |
| 254 | +0000000000 65535 f | |
| 255 | +0000000052 00000 n | |
| 256 | +0000000282 00000 n | |
| 257 | +0000000431 00000 n | |
| 258 | +0000000686 00000 n | |
| 259 | +0000000942 00000 n | |
| 260 | +0000001199 00000 n | |
| 261 | +0000001456 00000 n | |
| 262 | +0000001725 00000 n | |
| 263 | +0000001827 00000 n | |
| 264 | +0000001873 00000 n | |
| 265 | +0000002032 00000 n | |
| 266 | +0000002136 00000 n | |
| 267 | +0000002206 00000 n | |
| 268 | +0000002310 00000 n | |
| 269 | +0000002381 00000 n | |
| 270 | +0000002486 00000 n | |
| 271 | +0000002557 00000 n | |
| 272 | +0000002662 00000 n | |
| 273 | +trailer << | |
| 274 | + /Root 1 0 R | |
| 275 | + /Size 19 | |
| 276 | + /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] | |
| 277 | +>> | |
| 278 | +startxref | |
| 279 | +2682 | |
| 280 | +%%EOF | ... | ... |
qpdf/qtest/qpdf/merge-implicit-ranges.pdf
No preview for this file type
qpdf/qtest/qpdf/merge-multiple-labels.pdf
0 → 100644
No preview for this file type
qpdf/qtest/qpdf/merge-three-files-1.pdf
No preview for this file type
qpdf/qtest/qpdf/merge-three-files-2.pdf
No preview for this file type