aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--include/qpdf/QPDF.hh10
-rw-r--r--include/qpdf/QPDFPageObjectHelper.hh13
-rw-r--r--libqpdf/QPDF.cc6
-rw-r--r--libqpdf/QPDFPageObjectHelper.cc15
-rw-r--r--manual/qpdf-manual.xml15
-rw-r--r--qpdf/qpdf.cc16
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test24
-rw-r--r--qpdf/qtest/qpdf/duplicate-pages.pdf335
-rw-r--r--qpdf/qtest/qpdf/really-shared-images-pages-out.pdf288
11 files changed, 727 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index d74e9b01..8edf51c3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2019-01-12 Jay Berkenbilt <ejb@ql.org>
+ * In the --pages option, allow the same page to be specified more
+ than once. You can now do "--pages A.pdf 1,1 --" or
+ "--pages A.pdf 1 A.pdf 1" instead of having to use two different
+ paths to specify A.pdf. Fixes #272.
+
+ * Add QPDFPageObjectHelper::shallowCopyPage(). This method creates
+ a new page object that is a "shallow copy" of the given page as
+ described in the comments in QPDFPageObjectHelper. The resulting
+ object has not been added anywhere but is ready to be passed to
+ QPDFPageDocumentHelper::addPage of its own QPDF or another QPDF
+ object.
+
+ * Add QPDF::getUniqueId() method to return an identifier that is
+ intended to be unique within the scope of all QPDF objects created
+ by the calling application in a single run.
+
* In --pages, allow "." as a replacement for the current input
file, making it possible to say "qpdf A.pdf --pages . 1-3 --"
instead of having to repeat the input filename.
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index 8a79b6a3..ef0f0eb7 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -203,6 +203,16 @@ class QPDF
QPDF_DLL
std::vector<QPDFExc> getWarnings();
+ // Return an application-scoped unique ID for this QPDF object.
+ // This is not a globally unique ID. It is constructing using a
+ // timestamp and a random number and is intended to be unique
+ // among QPDF objects that are created by a single run of an
+ // application. While it's very likely that these are actually
+ // globally unique, it is not recommended to use them for
+ // long-term purposes.
+ QPDF_DLL
+ unsigned long long getUniqueId() const;
+
QPDF_DLL
std::string getFilename() const;
QPDF_DLL
diff --git a/include/qpdf/QPDFPageObjectHelper.hh b/include/qpdf/QPDFPageObjectHelper.hh
index 5238fa30..e17453fa 100644
--- a/include/qpdf/QPDFPageObjectHelper.hh
+++ b/include/qpdf/QPDFPageObjectHelper.hh
@@ -140,6 +140,19 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
QPDF_DLL
void removeUnreferencedResources();
+ // Return a new QPDFPageDocumentHelper that is a duplicate of the
+ // page. The returned object is an indirect object that is ready
+ // to be inserted into the same or a different QPDF object using
+ // any of the addPage methods in QPDFPageDocumentHelper or QPDF.
+ // Without calling one of those methods, the page will not be
+ // added anywhere. Thew new page object shares all content streams
+ // and indirect objet resources with the original page, so if you
+ // are going to modify the contents or other aspects of the page,
+ // you will need to handling copying of the component parts
+ // separately.
+ QPDF_DLL
+ QPDFPageObjectHelper shallowCopyPage();
+
private:
class Members
{
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 95ae9cab..0dbce669 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -2470,6 +2470,12 @@ QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2)
this->m->obj_cache[og2] = t;
}
+unsigned long long
+QPDF::getUniqueId() const
+{
+ return this->m->unique_id;
+}
+
std::string
QPDF::getFilename() const
{
diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc
index 4093622d..611f33ea 100644
--- a/libqpdf/QPDFPageObjectHelper.cc
+++ b/libqpdf/QPDFPageObjectHelper.cc
@@ -1,5 +1,6 @@
#include <qpdf/QPDFPageObjectHelper.hh>
#include <qpdf/QTC.hh>
+#include <qpdf/QPDF.hh>
QPDFPageObjectHelper::Members::~Members()
{
@@ -167,3 +168,17 @@ QPDFPageObjectHelper::removeUnreferencedResources()
}
}
}
+
+QPDFPageObjectHelper
+QPDFPageObjectHelper::shallowCopyPage()
+{
+ QPDF* qpdf = this->oh.getOwningQPDF();
+ if (! qpdf)
+ {
+ throw std::runtime_error(
+ "QPDFPageObjectHelper::shallowCopyPage"
+ " called with a direct objet");
+ }
+ QPDFObjectHandle new_page = this->oh.shallowCopy();
+ return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page));
+}
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index f7c528b7..034111c2 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -983,15 +983,6 @@ make
<command>qpdf --empty out.pdf --pages *.pdf --</command>.
</para>
<para>
- It is not presently possible to specify the same page from the
- same file directly more than once, but you can make this work by
- specifying two different paths to the same file (such as by
- putting <filename>./</filename> somewhere in the path). This can
- also be used if you want to repeat a page from one of the input
- files in the output file. This may be made more convenient in a
- future version of qpdf if there is enough demand for this feature.
- </para>
- <para>
The page range is a set of numbers separated by commas, ranges of
numbers separated dashes, or combinations of those. The character
&ldquo;z&rdquo; represents the last page. A number preceded by an
@@ -1112,6 +1103,12 @@ outfile.pdf</option>
are all corner cases that most users should hopefully never have
to be bothered with.
</para>
+ <para>
+ Prior to version 8.4, it was not possible to specify the same page
+ from the same file directly more than once, and the workaround of
+ specifying the same file in more than one way was required.
+ Version 8.4 removes this limitation.
+ </para>
</sect1>
<sect1 id="ref.advanced-parsing">
<title>Advanced Parsing Options</title>
diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc
index db3193d5..81ccdd0f 100644
--- a/qpdf/qpdf.cc
+++ b/qpdf/qpdf.cc
@@ -3731,6 +3731,7 @@ static void handle_page_specs(QPDF& pdf, Options& o)
std::map<std::string, ClosedFileInputSource*> page_spec_cfis;
page_spec_qpdfs[o.infilename] = &pdf;
std::vector<QPDFPageData> parsed_specs;
+ std::map<unsigned long long, std::set<QPDFObjGen> > copied_pages;
for (std::vector<PageSpec>::iterator iter = o.page_specs.begin();
iter != o.page_specs.end(); ++iter)
{
@@ -3905,7 +3906,20 @@ static void handle_page_specs(QPDF& pdf, Options& o)
int pageno = *pageno_iter - 1;
pldh.getLabelsForPageRange(pageno, pageno, out_pageno,
new_labels);
- dh.addPage(page_data.orig_pages.at(pageno), false);
+ QPDFPageObjectHelper to_copy = page_data.orig_pages.at(pageno);
+ QPDFObjGen to_copy_og = to_copy.getObjectHandle().getObjGen();
+ unsigned long long from_uuid = page_data.qpdf->getUniqueId();
+ if (copied_pages[from_uuid].count(to_copy_og))
+ {
+ QTC::TC("qpdf", "qpdf copy same page more than once",
+ (page_data.qpdf == &pdf) ? 0 : 1);
+ to_copy = to_copy.shallowCopyPage();
+ }
+ else
+ {
+ copied_pages[from_uuid].insert(to_copy_og);
+ }
+ dh.addPage(to_copy, false);
if (page_data.qpdf == &pdf)
{
// This is a page from the original file. Keep track
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 43f5c5a7..58f2cdca 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -411,3 +411,4 @@ QPDF pipe foreign encrypted stream 0
QPDF copy foreign stream with provider 0
QPDF copy foreign stream with buffer 0
QPDF immediate copy stream data 0
+qpdf copy same page more than once 1
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index b45f32a1..15b73e5f 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -1624,7 +1624,7 @@ foreach my $f (qw(screen print))
show_ntests();
# ----------
$td->notify("--- Merging and Splitting ---");
-$n_tests += 18;
+$n_tests += 22;
# Select pages from the same file multiple times including selecting
# twice from an encrypted file and specifying the password only the
@@ -1692,7 +1692,7 @@ $td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "merge-multiple-labels.pdf"});
-$td->runtest("split with shared resources", # QXXXQ
+$td->runtest("split with shared resources",
{$td->COMMAND =>
"qpdf --qdf --static-id" .
" shared-images.pdf --pages . 1,3" .
@@ -1702,6 +1702,16 @@ $td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "shared-images-pages-out.pdf"});
+$td->runtest("split with really shared resources",
+ {$td->COMMAND =>
+ "qpdf --qdf --static-id" .
+ " shared-images.pdf --pages . 1,3" .
+ " . 1,2 -- a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+$td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "really-shared-images-pages-out.pdf"});
+
$td->runtest("shared resources relevant errors",
{$td->COMMAND =>
"qpdf --qdf --static-id" .
@@ -1733,6 +1743,16 @@ $td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "shared-images-errors-1-3-out.pdf"});
+$td->runtest("duplicate pages",
+ {$td->COMMAND =>
+ "qpdf --qdf --static-id 11-pages-with-labels.pdf" .
+ " --pages . 6,5,6 . 5 minimal.pdf 1,1 minimal.pdf 1 --" .
+ " a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+$td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "duplicate-pages.pdf"});
+
show_ntests();
# ----------
$td->notify("--- Collating ---");
diff --git a/qpdf/qtest/qpdf/duplicate-pages.pdf b/qpdf/qtest/qpdf/duplicate-pages.pdf
new file mode 100644
index 00000000..7119ef58
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-pages.pdf
@@ -0,0 +1,335 @@
+%PDF-1.4
+%¿÷¢þ
+%QDF-1.0
+
+%% Original object ID: 1 0
+1 0 obj
+<<
+ /PageLabels <<
+ /Nums [
+ 0
+ <<
+ /S /r
+ /St 5
+ >>
+ 1
+ <<
+ /S /r
+ /St 4
+ >>
+ 3
+ <<
+ /S /r
+ /St 4
+ >>
+ 4
+ <<
+ /St 5
+ >>
+ ]
+ >>
+ /Pages 3 0 R
+ /Type /Catalog
+>>
+endobj
+
+%% Original object ID: 2 0
+2 0 obj
+<<
+ /CreationDate (D:20120721200217)
+ /Producer (Apex PDFWriter)
+>>
+endobj
+
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Count 7
+ /Kids [
+ 4 0 R
+ 5 0 R
+ 6 0 R
+ 7 0 R
+ 8 0 R
+ 9 0 R
+ 10 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 9 0
+4 0 obj
+<<
+ /Contents 11 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 13 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 2
+%% Original object ID: 8 0
+5 0 obj
+<<
+ /Contents 14 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 13 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 3
+%% Original object ID: 27 0
+6 0 obj
+<<
+ /Contents 11 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 13 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 4
+%% Original object ID: 28 0
+7 0 obj
+<<
+ /Contents 14 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 13 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 5
+%% Original object ID: 29 0
+8 0 obj
+<<
+ /Contents 16 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 18 0 R
+ >>
+ /ProcSet 19 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 6
+%% Original object ID: 33 0
+9 0 obj
+<<
+ /Contents 16 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 18 0 R
+ >>
+ /ProcSet 19 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 7
+%% Original object ID: 34 0
+10 0 obj
+<<
+ /Contents 16 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 18 0 R
+ >>
+ /ProcSet 19 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 3
+%% Original object ID: 21 0
+11 0 obj
+<<
+ /Length 12 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET
+endstream
+endobj
+
+12 0 obj
+47
+endobj
+
+%% Original object ID: 16 0
+13 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Contents for page 4
+%% Original object ID: 20 0
+14 0 obj
+<<
+ /Length 15 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET
+endstream
+endobj
+
+15 0 obj
+47
+endobj
+
+%% Contents for page 7
+%% Original object ID: 30 0
+16 0 obj
+<<
+ /Length 17 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+17 0 obj
+44
+endobj
+
+%% Original object ID: 31 0
+18 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Original object ID: 32 0
+19 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+xref
+0 20
+0000000000 65535 f
+0000000052 00000 n
+0000000375 00000 n
+0000000488 00000 n
+0000000658 00000 n
+0000000914 00000 n
+0000001171 00000 n
+0000001428 00000 n
+0000001685 00000 n
+0000001918 00000 n
+0000002151 00000 n
+0000002398 00000 n
+0000002502 00000 n
+0000002550 00000 n
+0000002710 00000 n
+0000002814 00000 n
+0000002885 00000 n
+0000002986 00000 n
+0000003034 00000 n
+0000003181 00000 n
+trailer <<
+ /Info 2 0 R
+ /Root 1 0 R
+ /Size 20
+ /ID [<e032a88c7a987db6ca3abee555506ccc><31415926535897932384626433832795>]
+>>
+startxref
+3217
+%%EOF
diff --git a/qpdf/qtest/qpdf/really-shared-images-pages-out.pdf b/qpdf/qtest/qpdf/really-shared-images-pages-out.pdf
new file mode 100644
index 00000000..616532aa
--- /dev/null
+++ b/qpdf/qtest/qpdf/really-shared-images-pages-out.pdf
@@ -0,0 +1,288 @@
+%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 4
+ /Kids [
+ 3 0 R
+ 4 0 R
+ 5 0 R
+ 6 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Contents 7 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 9 0 R
+ >>
+ /ProcSet 10 0 R
+ /XObject <<
+ /Im1 11 0 R
+ >>
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 2
+%% Original object ID: 5 0
+4 0 obj
+<<
+ /Contents 13 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 9 0 R
+ >>
+ /ProcSet 10 0 R
+ /XObject <<
+ /Im3 15 0 R
+ >>
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 3
+%% Original object ID: 56 0
+5 0 obj
+<<
+ /Contents 7 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 9 0 R
+ >>
+ /ProcSet 10 0 R
+ /XObject <<
+ /Im1 11 0 R
+ >>
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 4
+%% Original object ID: 4 0
+6 0 obj
+<<
+ /Contents 17 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 9 0 R
+ >>
+ /ProcSet 10 0 R
+ /XObject <<
+ /Im2 19 0 R
+ >>
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 3
+%% Original object ID: 13 0
+7 0 obj
+<<
+ /Length 8 0 R
+>>
+stream
+BT /F1 24 Tf 72 720 Td (page 1) Tj ET
+q 468 0 0 468 72 72 cm /Im1 Do Q
+endstream
+endobj
+
+8 0 obj
+71
+endobj
+
+%% Original object ID: 15 0
+9 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Original object ID: 16 0
+10 0 obj
+[
+ /PDF
+ /Text
+ /ImageC
+]
+endobj
+
+%% Original object ID: 17 0
+11 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 50
+ /Subtype /Image
+ /Type /XObject
+ /Width 50
+ /Length 12 0 R
+>>
+stream
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
+endstream
+endobj
+
+%QDF: ignore_newline
+12 0 obj
+2500
+endobj
+
+%% Contents for page 2
+%% Original object ID: 23 0
+13 0 obj
+<<
+ /Length 14 0 R
+>>
+stream
+BT /F1 24 Tf 72 720 Td (page 3) Tj ET
+q 468 0 0 468 72 72 cm /Im3 Do Q
+endstream
+endobj
+
+14 0 obj
+71
+endobj
+
+%% Original object ID: 25 0
+15 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 50
+ /Subtype /Image
+ /Type /XObject
+ /Width 50
+ /Length 16 0 R
+>>
+stream
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
+endstream
+endobj
+
+%QDF: ignore_newline
+16 0 obj
+2500
+endobj
+
+%% Contents for page 4
+%% Original object ID: 19 0
+17 0 obj
+<<
+ /Length 18 0 R
+>>
+stream
+BT /F1 24 Tf 72 720 Td (page 2) Tj ET
+q 468 0 0 468 72 72 cm /Im2 Do Q
+endstream
+endobj
+
+18 0 obj
+71
+endobj
+
+%% Original object ID: 21 0
+19 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 50
+ /Subtype /Image
+ /Type /XObject
+ /Width 50
+ /Length 20 0 R
+>>
+stream
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+endstream
+endobj
+
+%QDF: ignore_newline
+20 0 obj
+2500
+endobj
+
+xref
+0 21
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000272 00000 n
+0000000543 00000 n
+0000000816 00000 n
+0000001087 00000 n
+0000001373 00000 n
+0000001499 00000 n
+0000001546 00000 n
+0000001692 00000 n
+0000001766 00000 n
+0000004453 00000 n
+0000004526 00000 n
+0000004654 00000 n
+0000004702 00000 n
+0000007389 00000 n
+0000007462 00000 n
+0000007590 00000 n
+0000007638 00000 n
+0000010325 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 21
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+10347
+%%EOF