aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-08-05 16:01:34 +0200
committerJay Berkenbilt <ejb@ql.org>2017-08-05 16:22:33 +0200
commit49825e5cb67e589060de435f59203fa2f29b0476 (patch)
tree9392de891e2ecca4d2b495c6c937d51b17deade9
parent8fe261d8b4c26c0cb9f863ec3850c4b82755a42f (diff)
downloadqpdf-49825e5cb67e589060de435f59203fa2f29b0476.tar.zst
Add --split-pages option (fixes #30)
-rw-r--r--ChangeLog3
-rw-r--r--examples/pdf-split-pages.cc4
-rw-r--r--manual/qpdf-manual.xml69
-rw-r--r--qpdf/qpdf.cc79
-rw-r--r--qpdf/qpdf.testcov3
-rw-r--r--qpdf/qtest/qpdf.test56
-rw-r--r--qpdf/qtest/qpdf/01_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/02_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/03_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/04_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/05_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/06_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/07_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/08_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/09_single-exp.zdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/10_single-exp.zdfbin0 -> 756 bytes
-rw-r--r--qpdf/qtest/qpdf/11-pages.pdfbin0 -> 4128 bytes
-rw-r--r--qpdf/qtest/qpdf/11_single-exp.zdfbin0 -> 756 bytes
-rw-r--r--qpdf/qtest/qpdf/a-01-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-02-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-03-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-04-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-05-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-06-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-07-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-08-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-09-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-10-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/a-11-single-exp.zdf35
-rw-r--r--qpdf/qtest/qpdf/single-exp-01.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-02.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-03.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-04.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-05.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-06.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-07.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-08.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-09.Pdfbin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-1bin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-10.Pdfbin0 -> 756 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-11.Pdfbin0 -> 756 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-2bin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-3bin0 -> 755 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp-4bin0 -> 799 bytes
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0190
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0290
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0390
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0490
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0590
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0690
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0790
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0890
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_0990
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_1090
-rw-r--r--qpdf/qtest/qpdf/single-exp.zdf_1190
-rw-r--r--qpdf/qtest/qpdf/single-pages-stdout.out6
56 files changed, 1588 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 52209824..f790baa1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2017-08-05 Jay Berkenbilt <ejb@ql.org>
+ * Add --single-pages option to cause output to be written to a
+ separate file for each page rather than one big file.
+
* Process --pages options earlier so that certain inspection
options, like --show-pages, can show the state after the merging
operations.
diff --git a/examples/pdf-split-pages.cc b/examples/pdf-split-pages.cc
index 05a9fdc5..f062691a 100644
--- a/examples/pdf-split-pages.cc
+++ b/examples/pdf-split-pages.cc
@@ -1,7 +1,7 @@
//
// This is a stand-alone example of splitting a PDF into individual
-// pages. It is much faster than using the qpdf command-line tool to
-// split into separate files per page.
+// pages. It does essentially the same thing that qpdf --split-pages
+// does.
//
#include <qpdf/QPDF.hh>
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index 830231b2..5f1a90e2 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -354,6 +354,75 @@ make
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--single-pages</option></term>
+ <listitem>
+ <para>
+ Write each page to a separate output file. Output file names
+ are generated as follows:
+ <itemizedlist>
+ <listitem>
+ <para>
+ If the string <literal>%d</literal> appears in the output
+ file name, it is replaced with a zero-padded page number
+ starting from 1.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, if the output file name ends in
+ <filename>.pdf</filename> (case insensitive), a zero-padded
+ page number, preceded by a dash, is inserted before the
+ file extension.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, the file name is appended with a zero-padded
+ page number preceded by a dash.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ For example, if <filename>infile.pdf</filename> has 12 pages
+ <itemizedlist>
+ <listitem>
+ <para>
+ <command>qpdf infile.pdf %d-out</command> would generate
+ files <filename>01-out</filename> through
+ <filename>12-out</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>qpdf infile.pdf outfile.pdf
+ --single-pages</command> would generate files
+ <filename>outfile-01.pdf</filename> through
+ <filename>outfile-12.pdf</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>qpdf infile.pdf something.else</command> would generate
+ files <filename>something.else-01</filename> through
+ <filename>something.else-12</filename>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Note that outlines, threads, and other global features of the
+ original PDF file are not preserved. For each page of output,
+ this option creates an empty PDF and copies a single page from
+ the output into it. If you require the global data, you will
+ have to run <command>qpdf</command> with the
+ <option>--pages</option> option once for each file. Using
+ <option>--single-pages</option> is much faster if you don't
+ require the global data.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
<para>
diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc
index 4fb60966..a5724fed 100644
--- a/qpdf/qpdf.cc
+++ b/qpdf/qpdf.cc
@@ -43,6 +43,7 @@ struct Options
password(0),
linearize(false),
decrypt(false),
+ single_pages(false),
copy_encryption(false),
encryption_file(0),
encryption_file_password(0),
@@ -97,6 +98,7 @@ struct Options
char const* password;
bool linearize;
bool decrypt;
+ bool single_pages;
bool copy_encryption;
char const* encryption_file;
char const* encryption_file_password;
@@ -204,6 +206,7 @@ Basic Options\n\
--encrypt options -- generate an encrypted file\n\
--decrypt remove any encryption on the file\n\
--pages options -- select specific pages from one or more files\n\
+--single-pages write each output page to a separate file\n\
\n\
If none of --copy-encryption, --encrypt or --decrypt are given, qpdf will\n\
preserve any encryption data associated with a file.\n\
@@ -213,6 +216,16 @@ parameters will be copied, including both user and owner passwords, even\n\
if the user password is used to open the other file. This works even if\n\
the owner password is not known.\n\
\n\
+If --single-pages is specified, each page is written to a separate output\n\
+file. File names are generated as follows:\n\
+* If the string %d appears in the output file name, it is replaced with a\n\
+ zero-padded page number starting from 1\n\
+* Otherwise, if the output file name ends in .pdf (case insensitive), a\n\
+ zero-padded page number, preceded by a dash, is inserted before the file\n\
+ extension\n\
+* Otherwise, the file name is appended with a zero-padded page number\n\
+ preceded by a dash.\n\
+\n\
\n\
Encryption Options\n\
------------------\n\
@@ -1321,6 +1334,10 @@ static void parse_options(int argc, char* argv[], Options& o)
}
o.force_version = parameter;
}
+ else if (strcmp(arg, "single-pages") == 0)
+ {
+ o.single_pages = true;
+ }
else if (strcmp(arg, "deterministic-id") == 0)
{
o.deterministic_id = true;
@@ -1433,6 +1450,12 @@ static void parse_options(int argc, char* argv[], Options& o)
usage("no output file may be given for this option");
}
+ if (o.require_outfile && (strcmp(o.outfilename, "-") == 0) &&
+ o.single_pages)
+ {
+ usage("--single-pages may not be used when writing to standard output");
+ }
+
if (QUtil::same_file(o.infilename, o.outfilename))
{
QTC::TC("qpdf", "qpdf same file error");
@@ -1954,13 +1977,59 @@ static void set_writer_options(QPDF& pdf, Options& o, QPDFWriter& w)
static void write_outfile(QPDF& pdf, Options& o)
{
- if (strcmp(o.outfilename, "-") == 0)
+ if (o.single_pages)
+ {
+ // Generate output file pattern
+ std::string before;
+ std::string after;
+ size_t len = strlen(o.outfilename);
+ char* num_spot = strstr(const_cast<char*>(o.outfilename), "%d");
+ if (num_spot != 0)
+ {
+ QTC::TC("qpdf", "qpdf single-pages %d");
+ before = std::string(o.outfilename, (num_spot - o.outfilename));
+ after = num_spot + 2;
+ }
+ else if ((len >= 4) &&
+ (QUtil::strcasecmp(o.outfilename + len - 4, ".pdf") == 0))
+ {
+ QTC::TC("qpdf", "qpdf single-pages .pdf");
+ before = std::string(o.outfilename, len - 4) + "-";
+ after = o.outfilename + len - 4;
+ }
+ else
+ {
+ QTC::TC("qpdf", "qpdf single-pages other");
+ before = std::string(o.outfilename) + "-";
+ }
+
+ std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages();
+ int pageno_len = QUtil::int_to_string(pages.size()).length();
+ int pageno = 0;
+ for (std::vector<QPDFObjectHandle>::const_iterator iter = pages.begin();
+ iter != pages.end(); ++iter)
+ {
+ QPDFObjectHandle page = *iter;
+ std::string outfile =
+ before + QUtil::int_to_string(++pageno, pageno_len) + after;
+ QPDF outpdf;
+ outpdf.emptyPDF();
+ outpdf.addPage(page, false);
+ QPDFWriter w(outpdf, outfile.c_str());
+ set_writer_options(outpdf, o, w);
+ w.write();
+ }
+ }
+ else
{
- o.outfilename = 0;
+ if (strcmp(o.outfilename, "-") == 0)
+ {
+ o.outfilename = 0;
+ }
+ QPDFWriter w(pdf, o.outfilename);
+ set_writer_options(pdf, o, w);
+ w.write();
}
- QPDFWriter w(pdf, o.outfilename);
- set_writer_options(pdf, o, w);
- w.write();
}
int main(int argc, char* argv[])
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 55e3033a..f5690fd6 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -287,3 +287,6 @@ QPDF stream with non-space 0
qpdf same file error 0
qpdf read args from stdin 0
qpdf read args from file 0
+qpdf single-pages %d 0
+qpdf single-pages .pdf 0
+qpdf single-pages other 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 0b75559c..25b5b160 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -664,6 +664,61 @@ $td->runtest("combine show and --pages",
show_ntests();
# ----------
+$td->notify("--- Single Page ---");
+# sp = single-pages
+my @sp_cases = (
+ [11, '%d at beginning', '', '%d_single-out.zdf'],
+ [11, '%d at end', '--qdf', 'single-out.zdf_%d'],
+ [11, '%d in middle', '--encrypt u o 128 --', 'a-%d-single-out.zdf'],
+ [11, 'pdf extension', '', 'single-out.Pdf'],
+ [4, 'fallback', '--pages 11-pages.pdf 1-3 minimal.pdf --', 'single-out'],
+ );
+$n_tests += 1;
+for (@sp_cases)
+{
+ $n_tests += 1 + $_->[0];
+}
+
+$td->runtest("no single-pages to stdout",
+ {$td->COMMAND => "qpdf --single-pages 11-pages.pdf -"},
+ {$td->FILE => "single-pages-stdout.out", $td->EXIT_STATUS => 2},
+ $td->NORMALIZE_NEWLINES);
+
+foreach my $d (@sp_cases)
+{
+ my ($n, $description, $xargs, $out) = @$d;
+ $td->runtest("single pages " . $description,
+ {$td->COMMAND =>
+ "qpdf --static-id --single-pages 11-pages.pdf" .
+ " $xargs $out"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+ my $pattern = $out;
+ my $nlen = length($n);
+ if ($pattern =~ m/\%d/)
+ {
+ $pattern =~ s/\%d/\%0${nlen}d/;
+ }
+ elsif ($pattern =~ m/\.pdf$/i)
+ {
+ $pattern =~ s/(\.pdf$)/-%0${nlen}d$1/i;
+ }
+ else
+ {
+ $pattern .= "-%0${nlen}d";
+ }
+ for (my $i = 1; $i <= $n; ++$i)
+ {
+ my $actual = sprintf($pattern, $i);
+ my $expected = $actual;
+ $expected =~ s/single-out/single-exp/;
+ $td->runtest("checkout output page $i",
+ {$td->FILE => $actual},
+ {$td->FILE => $expected});
+ }
+}
+
+show_ntests();
+# ----------
$td->notify("--- Numeric range parsing tests ---");
my @nrange_tests = (
[",5",
@@ -2426,4 +2481,5 @@ sub get_md5_checksum
sub cleanup
{
system("rm -rf *.ps *.pnm ?.pdf ?.qdf *.enc* tif1 tif2 tiff-cache");
+ system("rm -rf *single-out*");
}
diff --git a/qpdf/qtest/qpdf/01_single-exp.zdf b/qpdf/qtest/qpdf/01_single-exp.zdf
new file mode 100644
index 00000000..7c37942f
--- /dev/null
+++ b/qpdf/qtest/qpdf/01_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/02_single-exp.zdf b/qpdf/qtest/qpdf/02_single-exp.zdf
new file mode 100644
index 00000000..cced06c3
--- /dev/null
+++ b/qpdf/qtest/qpdf/02_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/03_single-exp.zdf b/qpdf/qtest/qpdf/03_single-exp.zdf
new file mode 100644
index 00000000..7206ff55
--- /dev/null
+++ b/qpdf/qtest/qpdf/03_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/04_single-exp.zdf b/qpdf/qtest/qpdf/04_single-exp.zdf
new file mode 100644
index 00000000..d8a652ef
--- /dev/null
+++ b/qpdf/qtest/qpdf/04_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/05_single-exp.zdf b/qpdf/qtest/qpdf/05_single-exp.zdf
new file mode 100644
index 00000000..498596f8
--- /dev/null
+++ b/qpdf/qtest/qpdf/05_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/06_single-exp.zdf b/qpdf/qtest/qpdf/06_single-exp.zdf
new file mode 100644
index 00000000..016d83a9
--- /dev/null
+++ b/qpdf/qtest/qpdf/06_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/07_single-exp.zdf b/qpdf/qtest/qpdf/07_single-exp.zdf
new file mode 100644
index 00000000..bb1ed0ba
--- /dev/null
+++ b/qpdf/qtest/qpdf/07_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/08_single-exp.zdf b/qpdf/qtest/qpdf/08_single-exp.zdf
new file mode 100644
index 00000000..bd6b7f22
--- /dev/null
+++ b/qpdf/qtest/qpdf/08_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/09_single-exp.zdf b/qpdf/qtest/qpdf/09_single-exp.zdf
new file mode 100644
index 00000000..1b63f675
--- /dev/null
+++ b/qpdf/qtest/qpdf/09_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/10_single-exp.zdf b/qpdf/qtest/qpdf/10_single-exp.zdf
new file mode 100644
index 00000000..f3d209a4
--- /dev/null
+++ b/qpdf/qtest/qpdf/10_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/11-pages.pdf b/qpdf/qtest/qpdf/11-pages.pdf
new file mode 100644
index 00000000..e4b14efd
--- /dev/null
+++ b/qpdf/qtest/qpdf/11-pages.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/11_single-exp.zdf b/qpdf/qtest/qpdf/11_single-exp.zdf
new file mode 100644
index 00000000..158f9c78
--- /dev/null
+++ b/qpdf/qtest/qpdf/11_single-exp.zdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/a-01-single-exp.zdf b/qpdf/qtest/qpdf/a-01-single-exp.zdf
new file mode 100644
index 00000000..eb9aafce
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-01-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-02-single-exp.zdf b/qpdf/qtest/qpdf/a-02-single-exp.zdf
new file mode 100644
index 00000000..d94d70d5
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-02-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙʤ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-03-single-exp.zdf b/qpdf/qtest/qpdf/a-03-single-exp.zdf
new file mode 100644
index 00000000..c3b8ca0e
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-03-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-04-single-exp.zdf b/qpdf/qtest/qpdf/a-04-single-exp.zdf
new file mode 100644
index 00000000..c03531a7
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-04-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-05-single-exp.zdf b/qpdf/qtest/qpdf/a-05-single-exp.zdf
new file mode 100644
index 00000000..7fb266dd
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-05-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-06-single-exp.zdf b/qpdf/qtest/qpdf/a-06-single-exp.zdf
new file mode 100644
index 00000000..af3432f0
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-06-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙڤ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-07-single-exp.zdf b/qpdf/qtest/qpdf/a-07-single-exp.zdf
new file mode 100644
index 00000000..fb86b06f
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-07-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-08-single-exp.zdf b/qpdf/qtest/qpdf/a-08-single-exp.zdf
new file mode 100644
index 00000000..ad0d7451
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-08-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-09-single-exp.zdf b/qpdf/qtest/qpdf/a-09-single-exp.zdf
new file mode 100644
index 00000000..76bf1db5
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-09-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 53 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ aȊ1endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000398 00000 n
+0000000497 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+704
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-10-single-exp.zdf b/qpdf/qtest/qpdf/a-10-single-exp.zdf
new file mode 100644
index 00000000..7f9c55c2
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-10-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 54 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ|HM-endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000399 00000 n
+0000000498 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+705
+%%EOF
diff --git a/qpdf/qtest/qpdf/a-11-single-exp.zdf b/qpdf/qtest/qpdf/a-11-single-exp.zdf
new file mode 100644
index 00000000..be8f3a7f
--- /dev/null
+++ b/qpdf/qtest/qpdf/a-11-single-exp.zdf
@@ -0,0 +1,35 @@
+%PDF-1.4
+%
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet [ /PDF /Text ] >> /Type /Page >>
+endobj
+4 0 obj
+<< /Filter /FlateDecode /Length 54 >>
+stream
+x 휏nyA?(=2?&ꍕ>(ٙ|HM- endstream
+endobj
+5 0 obj
+<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Filter /Standard /Length 128 /O <2a2f0a1990192c60114730bdcd39f37828a53c89a340dd473c85299dc5258e1c> /P -4 /R 3 /U <fbe50a471395e24b4e73472e36a4abf00122456a91bae5134273a6db134c87c4> /V 2 >>
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+0000000123 00000 n
+0000000275 00000 n
+0000000399 00000 n
+0000000498 00000 n
+trailer << /Root 1 0 R /Size 7 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] /Encrypt 6 0 R >>
+startxref
+705
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp-01.Pdf b/qpdf/qtest/qpdf/single-exp-01.Pdf
new file mode 100644
index 00000000..7c37942f
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-01.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-02.Pdf b/qpdf/qtest/qpdf/single-exp-02.Pdf
new file mode 100644
index 00000000..cced06c3
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-02.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-03.Pdf b/qpdf/qtest/qpdf/single-exp-03.Pdf
new file mode 100644
index 00000000..7206ff55
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-03.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-04.Pdf b/qpdf/qtest/qpdf/single-exp-04.Pdf
new file mode 100644
index 00000000..d8a652ef
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-04.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-05.Pdf b/qpdf/qtest/qpdf/single-exp-05.Pdf
new file mode 100644
index 00000000..498596f8
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-05.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-06.Pdf b/qpdf/qtest/qpdf/single-exp-06.Pdf
new file mode 100644
index 00000000..016d83a9
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-06.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-07.Pdf b/qpdf/qtest/qpdf/single-exp-07.Pdf
new file mode 100644
index 00000000..bb1ed0ba
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-07.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-08.Pdf b/qpdf/qtest/qpdf/single-exp-08.Pdf
new file mode 100644
index 00000000..bd6b7f22
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-08.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-09.Pdf b/qpdf/qtest/qpdf/single-exp-09.Pdf
new file mode 100644
index 00000000..1b63f675
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-09.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-1 b/qpdf/qtest/qpdf/single-exp-1
new file mode 100644
index 00000000..7c37942f
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-1
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-10.Pdf b/qpdf/qtest/qpdf/single-exp-10.Pdf
new file mode 100644
index 00000000..f3d209a4
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-10.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-11.Pdf b/qpdf/qtest/qpdf/single-exp-11.Pdf
new file mode 100644
index 00000000..158f9c78
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-11.Pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-2 b/qpdf/qtest/qpdf/single-exp-2
new file mode 100644
index 00000000..cced06c3
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-2
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-3 b/qpdf/qtest/qpdf/single-exp-3
new file mode 100644
index 00000000..7206ff55
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-3
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp-4 b/qpdf/qtest/qpdf/single-exp-4
new file mode 100644
index 00000000..b8c692ed
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp-4
Binary files differ
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_01 b/qpdf/qtest/qpdf/single-exp.zdf_01
new file mode 100644
index 00000000..31a145aa
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_01
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 1) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_02 b/qpdf/qtest/qpdf/single-exp.zdf_02
new file mode 100644
index 00000000..d70facb1
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_02
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 2) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_03 b/qpdf/qtest/qpdf/single-exp.zdf_03
new file mode 100644
index 00000000..fbb491b5
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_03
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 3) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_04 b/qpdf/qtest/qpdf/single-exp.zdf_04
new file mode 100644
index 00000000..d0ab509e
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_04
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 4) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_05 b/qpdf/qtest/qpdf/single-exp.zdf_05
new file mode 100644
index 00000000..a2d861d6
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_05
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_06 b/qpdf/qtest/qpdf/single-exp.zdf_06
new file mode 100644
index 00000000..1d5b6e56
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_06
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_07 b/qpdf/qtest/qpdf/single-exp.zdf_07
new file mode 100644
index 00000000..10a72379
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_07
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 7) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_08 b/qpdf/qtest/qpdf/single-exp.zdf_08
new file mode 100644
index 00000000..9ccb696e
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_08
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 8) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_09 b/qpdf/qtest/qpdf/single-exp.zdf_09
new file mode 100644
index 00000000..82706bc1
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_09
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 9) Tj ET
+endstream
+endobj
+
+5 0 obj
+47
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000611 00000 n
+0000000657 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+765
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_10 b/qpdf/qtest/qpdf/single-exp.zdf_10
new file mode 100644
index 00000000..5deab6d7
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_10
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 10) Tj ET
+endstream
+endobj
+
+5 0 obj
+48
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000612 00000 n
+0000000658 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+766
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-exp.zdf_11 b/qpdf/qtest/qpdf/single-exp.zdf_11
new file mode 100644
index 00000000..3a3105d5
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-exp.zdf_11
@@ -0,0 +1,90 @@
+%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 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 4 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 11) Tj ET
+endstream
+endobj
+
+5 0 obj
+48
+endobj
+
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000242 00000 n
+0000000509 00000 n
+0000000612 00000 n
+0000000658 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+766
+%%EOF
diff --git a/qpdf/qtest/qpdf/single-pages-stdout.out b/qpdf/qtest/qpdf/single-pages-stdout.out
new file mode 100644
index 00000000..1efa16f1
--- /dev/null
+++ b/qpdf/qtest/qpdf/single-pages-stdout.out
@@ -0,0 +1,6 @@
+
+qpdf: --single-pages may not be used when writing to standard output
+
+Usage: qpdf [options] infile outfile
+For detailed help, run qpdf --help
+