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 | 2018-12-18 Jay Berkenbilt <ejb@ql.org> | 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 | * Add QPDFPageLabelDocumentHelper class. This is a document helper | 9 | * Add QPDFPageLabelDocumentHelper class. This is a document helper |
| 4 | class that provides useful methods for dealing with page labels. | 10 | class that provides useful methods for dealing with page labels. |
| 5 | It abstracts the fact that they are stored as number trees and | 11 | It abstracts the fact that they are stored as number trees and |
manual/qpdf-manual.xml
| @@ -911,23 +911,23 @@ make | @@ -911,23 +911,23 @@ make | ||
| 911 | </itemizedlist> | 911 | </itemizedlist> |
| 912 | </para> | 912 | </para> |
| 913 | <para> | 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 | <programlisting><command>qpdf</command> <option>infile.pdf --pages infile.pdf 1-5 -- outfile.pdf</option> | 932 | <programlisting><command>qpdf</command> <option>infile.pdf --pages infile.pdf 1-5 -- outfile.pdf</option> |
| 933 | </programlisting> | 933 | </programlisting> |
| @@ -946,8 +946,8 @@ make | @@ -946,8 +946,8 @@ make | ||
| 946 | If, for some reason, you wanted to take the first page of an | 946 | If, for some reason, you wanted to take the first page of an |
| 947 | encrypted file called <filename>encrypted.pdf</filename> with | 947 | encrypted file called <filename>encrypted.pdf</filename> with |
| 948 | password <literal>pass</literal> and repeat it twice in an output | 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 | <programlisting><command>qpdf</command> <option>--empty --copy-encryption=encrypted.pdf --encryption-file-password=pass | 952 | <programlisting><command>qpdf</command> <option>--empty --copy-encryption=encrypted.pdf --encryption-file-password=pass |
| 953 | --pages encrypted.pdf --password=pass 1 ./encrypted.pdf --password=pass 1 -- | 953 | --pages encrypted.pdf --password=pass 1 ./encrypted.pdf --password=pass 1 -- |
qpdf/qpdf.cc
| @@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
| 16 | #include <qpdf/QPDF.hh> | 16 | #include <qpdf/QPDF.hh> |
| 17 | #include <qpdf/QPDFPageDocumentHelper.hh> | 17 | #include <qpdf/QPDFPageDocumentHelper.hh> |
| 18 | #include <qpdf/QPDFPageObjectHelper.hh> | 18 | #include <qpdf/QPDFPageObjectHelper.hh> |
| 19 | +#include <qpdf/QPDFPageLabelDocumentHelper.hh> | ||
| 19 | #include <qpdf/QPDFExc.hh> | 20 | #include <qpdf/QPDFExc.hh> |
| 20 | 21 | ||
| 21 | #include <qpdf/QPDFWriter.hh> | 22 | #include <qpdf/QPDFWriter.hh> |
| @@ -2296,11 +2297,25 @@ static void handle_page_specs(QPDF& pdf, Options& o, | @@ -2296,11 +2297,25 @@ static void handle_page_specs(QPDF& pdf, Options& o, | ||
| 2296 | // Keep track of any pages from the original file that we are | 2297 | // Keep track of any pages from the original file that we are |
| 2297 | // selecting. | 2298 | // selecting. |
| 2298 | std::set<int> selected_from_orig; | 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 | for (std::vector<QPDFPageData>::iterator iter = | 2303 | for (std::vector<QPDFPageData>::iterator iter = |
| 2300 | parsed_specs.begin(); | 2304 | parsed_specs.begin(); |
| 2301 | iter != parsed_specs.end(); ++iter) | 2305 | iter != parsed_specs.end(); ++iter) |
| 2302 | { | 2306 | { |
| 2303 | QPDFPageData& page_data = *iter; | 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 | if (o.verbose) | 2319 | if (o.verbose) |
| 2305 | { | 2320 | { |
| 2306 | std::cout << whoami << ": adding pages from " | 2321 | std::cout << whoami << ": adding pages from " |
| @@ -2309,22 +2324,14 @@ static void handle_page_specs(QPDF& pdf, Options& o, | @@ -2309,22 +2324,14 @@ static void handle_page_specs(QPDF& pdf, Options& o, | ||
| 2309 | for (std::vector<int>::iterator pageno_iter = | 2324 | for (std::vector<int>::iterator pageno_iter = |
| 2310 | page_data.selected_pages.begin(); | 2325 | page_data.selected_pages.begin(); |
| 2311 | pageno_iter != page_data.selected_pages.end(); | 2326 | pageno_iter != page_data.selected_pages.end(); |
| 2312 | - ++pageno_iter) | 2327 | + ++pageno_iter, ++out_pageno) |
| 2313 | { | 2328 | { |
| 2314 | // Pages are specified from 1 but numbered from 0 in the | 2329 | // Pages are specified from 1 but numbered from 0 in the |
| 2315 | // vector | 2330 | // vector |
| 2316 | int pageno = *pageno_iter - 1; | 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 | dh.addPage(page_data.orig_pages.at(pageno), false); | 2334 | dh.addPage(page_data.orig_pages.at(pageno), false); |
| 2324 | - if (cis) | ||
| 2325 | - { | ||
| 2326 | - cis->stayOpen(false); | ||
| 2327 | - } | ||
| 2328 | if (page_data.qpdf == &pdf) | 2335 | if (page_data.qpdf == &pdf) |
| 2329 | { | 2336 | { |
| 2330 | // This is a page from the original file. Keep track | 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,6 +2339,18 @@ static void handle_page_specs(QPDF& pdf, Options& o, | ||
| 2332 | selected_from_orig.insert(pageno); | 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 | // Delete page objects for unused page in primary. This prevents | 2356 | // Delete page objects for unused page in primary. This prevents |
| @@ -2574,6 +2593,7 @@ static void write_outfile(QPDF& pdf, Options& o) | @@ -2574,6 +2593,7 @@ static void write_outfile(QPDF& pdf, Options& o) | ||
| 2574 | dh.pushInheritedAttributesToPage(); | 2593 | dh.pushInheritedAttributesToPage(); |
| 2575 | dh.removeUnreferencedResources(); | 2594 | dh.removeUnreferencedResources(); |
| 2576 | } | 2595 | } |
| 2596 | + QPDFPageLabelDocumentHelper pldh(pdf); | ||
| 2577 | std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages(); | 2597 | std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages(); |
| 2578 | int pageno_len = QUtil::int_to_string(pages.size()).length(); | 2598 | int pageno_len = QUtil::int_to_string(pages.size()).length(); |
| 2579 | unsigned int num_pages = pages.size(); | 2599 | unsigned int num_pages = pages.size(); |
| @@ -2592,6 +2612,16 @@ static void write_outfile(QPDF& pdf, Options& o) | @@ -2592,6 +2612,16 @@ static void write_outfile(QPDF& pdf, Options& o) | ||
| 2592 | QPDFObjectHandle page = pages.at(pageno - 1); | 2612 | QPDFObjectHandle page = pages.at(pageno - 1); |
| 2593 | outpdf.addPage(page, false); | 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 | std::string page_range = QUtil::int_to_string(first, pageno_len); | 2625 | std::string page_range = QUtil::int_to_string(first, pageno_len); |
| 2596 | if (o.split_pages > 1) | 2626 | if (o.split_pages > 1) |
| 2597 | { | 2627 | { |
qpdf/qpdf.testcov
| @@ -360,3 +360,4 @@ qpdf disable keep files open 0 | @@ -360,3 +360,4 @@ qpdf disable keep files open 0 | ||
| 360 | qpdf keep files open n 0 | 360 | qpdf keep files open n 0 |
| 361 | qpdf keep files open y 0 | 361 | qpdf keep files open y 0 |
| 362 | qpdf don't disable keep files open 0 | 362 | qpdf don't disable keep files open 0 |
| 363 | +QPDFPageLabelDocumentHelper skip first 0 |
qpdf/qtest/qpdf.test
| @@ -1137,7 +1137,7 @@ my @sp_cases = ( | @@ -1137,7 +1137,7 @@ my @sp_cases = ( | ||
| 1137 | [11, 'pdf extension', '', 'split-out.Pdf'], | 1137 | [11, 'pdf extension', '', 'split-out.Pdf'], |
| 1138 | [4, 'fallback', '--pages 11-pages.pdf 1-3 minimal.pdf --', 'split-out'], | 1138 | [4, 'fallback', '--pages 11-pages.pdf 1-3 minimal.pdf --', 'split-out'], |
| 1139 | ); | 1139 | ); |
| 1140 | -$n_tests += 9; | 1140 | +$n_tests += 12; |
| 1141 | for (@sp_cases) | 1141 | for (@sp_cases) |
| 1142 | { | 1142 | { |
| 1143 | $n_tests += 1 + $_->[0]; | 1143 | $n_tests += 1 + $_->[0]; |
| @@ -1171,6 +1171,17 @@ foreach my $i (qw(01-04 05-08 09-10)) | @@ -1171,6 +1171,17 @@ foreach my $i (qw(01-04 05-08 09-10)) | ||
| 1171 | {$td->FILE => "shared-split-$i.pdf"}); | 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 | foreach my $d (@sp_cases) | 1185 | foreach my $d (@sp_cases) |
| 1175 | { | 1186 | { |
| 1176 | my ($n, $description, $xargs, $out) = @$d; | 1187 | my ($n, $description, $xargs, $out) = @$d; |
| @@ -1335,7 +1346,7 @@ foreach my $d (@nrange_tests) | @@ -1335,7 +1346,7 @@ foreach my $d (@nrange_tests) | ||
| 1335 | show_ntests(); | 1346 | show_ntests(); |
| 1336 | # ---------- | 1347 | # ---------- |
| 1337 | $td->notify("--- Merging and Splitting ---"); | 1348 | $td->notify("--- Merging and Splitting ---"); |
| 1338 | -$n_tests += 16; | 1349 | +$n_tests += 18; |
| 1339 | 1350 | ||
| 1340 | # Select pages from the same file multiple times including selecting | 1351 | # Select pages from the same file multiple times including selecting |
| 1341 | # twice from an encrypted file and specifying the password only the | 1352 | # twice from an encrypted file and specifying the password only the |
| @@ -1368,8 +1379,7 @@ $td->runtest("merge three files", | @@ -1368,8 +1379,7 @@ $td->runtest("merge three files", | ||
| 1368 | " $pages_options --static-id"}, | 1379 | " $pages_options --static-id"}, |
| 1369 | {$td->STRING => "", $td->EXIT_STATUS => 0}); | 1380 | {$td->STRING => "", $td->EXIT_STATUS => 0}); |
| 1370 | # Manually verified about this file: it has the same pages but does | 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 | $td->runtest("check output", | 1383 | $td->runtest("check output", |
| 1374 | {$td->FILE => "a.pdf"}, | 1384 | {$td->FILE => "a.pdf"}, |
| 1375 | {$td->FILE => "merge-three-files-2.pdf"}); | 1385 | {$td->FILE => "merge-three-files-2.pdf"}); |
| @@ -1392,6 +1402,17 @@ $td->runtest("merge with implicit ranges", | @@ -1392,6 +1402,17 @@ $td->runtest("merge with implicit ranges", | ||
| 1392 | $td->runtest("check output", | 1402 | $td->runtest("check output", |
| 1393 | {$td->FILE => "a.pdf"}, | 1403 | {$td->FILE => "a.pdf"}, |
| 1394 | {$td->FILE => "merge-implicit-ranges.pdf"}); | 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 | $td->runtest("split with shared resources", | 1417 | $td->runtest("split with shared resources", |
| 1397 | {$td->COMMAND => | 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