Commit 654c0e8caf5e75119534de5d93d1ee28bd13325a

Authored by Jay Berkenbilt
1 parent 53d8e916

Allow adding the same page more than once in --pages (fixes #272)

ChangeLog
1 1 2019-01-12 Jay Berkenbilt <ejb@ql.org>
2 2  
  3 + * In the --pages option, allow the same page to be specified more
  4 + than once. You can now do "--pages A.pdf 1,1 --" or
  5 + "--pages A.pdf 1 A.pdf 1" instead of having to use two different
  6 + paths to specify A.pdf. Fixes #272.
  7 +
  8 + * Add QPDFPageObjectHelper::shallowCopyPage(). This method creates
  9 + a new page object that is a "shallow copy" of the given page as
  10 + described in the comments in QPDFPageObjectHelper. The resulting
  11 + object has not been added anywhere but is ready to be passed to
  12 + QPDFPageDocumentHelper::addPage of its own QPDF or another QPDF
  13 + object.
  14 +
  15 + * Add QPDF::getUniqueId() method to return an identifier that is
  16 + intended to be unique within the scope of all QPDF objects created
  17 + by the calling application in a single run.
  18 +
3 19 * In --pages, allow "." as a replacement for the current input
4 20 file, making it possible to say "qpdf A.pdf --pages . 1-3 --"
5 21 instead of having to repeat the input filename.
... ...
include/qpdf/QPDF.hh
... ... @@ -203,6 +203,16 @@ class QPDF
203 203 QPDF_DLL
204 204 std::vector<QPDFExc> getWarnings();
205 205  
  206 + // Return an application-scoped unique ID for this QPDF object.
  207 + // This is not a globally unique ID. It is constructing using a
  208 + // timestamp and a random number and is intended to be unique
  209 + // among QPDF objects that are created by a single run of an
  210 + // application. While it's very likely that these are actually
  211 + // globally unique, it is not recommended to use them for
  212 + // long-term purposes.
  213 + QPDF_DLL
  214 + unsigned long long getUniqueId() const;
  215 +
206 216 QPDF_DLL
207 217 std::string getFilename() const;
208 218 QPDF_DLL
... ...
include/qpdf/QPDFPageObjectHelper.hh
... ... @@ -140,6 +140,19 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
140 140 QPDF_DLL
141 141 void removeUnreferencedResources();
142 142  
  143 + // Return a new QPDFPageDocumentHelper that is a duplicate of the
  144 + // page. The returned object is an indirect object that is ready
  145 + // to be inserted into the same or a different QPDF object using
  146 + // any of the addPage methods in QPDFPageDocumentHelper or QPDF.
  147 + // Without calling one of those methods, the page will not be
  148 + // added anywhere. Thew new page object shares all content streams
  149 + // and indirect objet resources with the original page, so if you
  150 + // are going to modify the contents or other aspects of the page,
  151 + // you will need to handling copying of the component parts
  152 + // separately.
  153 + QPDF_DLL
  154 + QPDFPageObjectHelper shallowCopyPage();
  155 +
143 156 private:
144 157 class Members
145 158 {
... ...
libqpdf/QPDF.cc
... ... @@ -2470,6 +2470,12 @@ QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2)
2470 2470 this->m->obj_cache[og2] = t;
2471 2471 }
2472 2472  
  2473 +unsigned long long
  2474 +QPDF::getUniqueId() const
  2475 +{
  2476 + return this->m->unique_id;
  2477 +}
  2478 +
2473 2479 std::string
2474 2480 QPDF::getFilename() const
2475 2481 {
... ...
libqpdf/QPDFPageObjectHelper.cc
1 1 #include <qpdf/QPDFPageObjectHelper.hh>
2 2 #include <qpdf/QTC.hh>
  3 +#include <qpdf/QPDF.hh>
3 4  
4 5 QPDFPageObjectHelper::Members::~Members()
5 6 {
... ... @@ -167,3 +168,17 @@ QPDFPageObjectHelper::removeUnreferencedResources()
167 168 }
168 169 }
169 170 }
  171 +
  172 +QPDFPageObjectHelper
  173 +QPDFPageObjectHelper::shallowCopyPage()
  174 +{
  175 + QPDF* qpdf = this->oh.getOwningQPDF();
  176 + if (! qpdf)
  177 + {
  178 + throw std::runtime_error(
  179 + "QPDFPageObjectHelper::shallowCopyPage"
  180 + " called with a direct objet");
  181 + }
  182 + QPDFObjectHandle new_page = this->oh.shallowCopy();
  183 + return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page));
  184 +}
... ...
manual/qpdf-manual.xml
... ... @@ -983,15 +983,6 @@ make
983 983 <command>qpdf --empty out.pdf --pages *.pdf --</command>.
984 984 </para>
985 985 <para>
986   - It is not presently possible to specify the same page from the
987   - same file directly more than once, but you can make this work by
988   - specifying two different paths to the same file (such as by
989   - putting <filename>./</filename> somewhere in the path). This can
990   - also be used if you want to repeat a page from one of the input
991   - files in the output file. This may be made more convenient in a
992   - future version of qpdf if there is enough demand for this feature.
993   - </para>
994   - <para>
995 986 The page range is a set of numbers separated by commas, ranges of
996 987 numbers separated dashes, or combinations of those. The character
997 988 &ldquo;z&rdquo; represents the last page. A number preceded by an
... ... @@ -1112,6 +1103,12 @@ outfile.pdf&lt;/option&gt;
1112 1103 are all corner cases that most users should hopefully never have
1113 1104 to be bothered with.
1114 1105 </para>
  1106 + <para>
  1107 + Prior to version 8.4, it was not possible to specify the same page
  1108 + from the same file directly more than once, and the workaround of
  1109 + specifying the same file in more than one way was required.
  1110 + Version 8.4 removes this limitation.
  1111 + </para>
1115 1112 </sect1>
1116 1113 <sect1 id="ref.advanced-parsing">
1117 1114 <title>Advanced Parsing Options</title>
... ...
qpdf/qpdf.cc
... ... @@ -3731,6 +3731,7 @@ static void handle_page_specs(QPDF&amp; pdf, Options&amp; o)
3731 3731 std::map<std::string, ClosedFileInputSource*> page_spec_cfis;
3732 3732 page_spec_qpdfs[o.infilename] = &pdf;
3733 3733 std::vector<QPDFPageData> parsed_specs;
  3734 + std::map<unsigned long long, std::set<QPDFObjGen> > copied_pages;
3734 3735 for (std::vector<PageSpec>::iterator iter = o.page_specs.begin();
3735 3736 iter != o.page_specs.end(); ++iter)
3736 3737 {
... ... @@ -3905,7 +3906,20 @@ static void handle_page_specs(QPDF&amp; pdf, Options&amp; o)
3905 3906 int pageno = *pageno_iter - 1;
3906 3907 pldh.getLabelsForPageRange(pageno, pageno, out_pageno,
3907 3908 new_labels);
3908   - dh.addPage(page_data.orig_pages.at(pageno), false);
  3909 + QPDFPageObjectHelper to_copy = page_data.orig_pages.at(pageno);
  3910 + QPDFObjGen to_copy_og = to_copy.getObjectHandle().getObjGen();
  3911 + unsigned long long from_uuid = page_data.qpdf->getUniqueId();
  3912 + if (copied_pages[from_uuid].count(to_copy_og))
  3913 + {
  3914 + QTC::TC("qpdf", "qpdf copy same page more than once",
  3915 + (page_data.qpdf == &pdf) ? 0 : 1);
  3916 + to_copy = to_copy.shallowCopyPage();
  3917 + }
  3918 + else
  3919 + {
  3920 + copied_pages[from_uuid].insert(to_copy_og);
  3921 + }
  3922 + dh.addPage(to_copy, false);
3909 3923 if (page_data.qpdf == &pdf)
3910 3924 {
3911 3925 // This is a page from the original file. Keep track
... ...
qpdf/qpdf.testcov
... ... @@ -411,3 +411,4 @@ QPDF pipe foreign encrypted stream 0
411 411 QPDF copy foreign stream with provider 0
412 412 QPDF copy foreign stream with buffer 0
413 413 QPDF immediate copy stream data 0
  414 +qpdf copy same page more than once 1
... ...
qpdf/qtest/qpdf.test
... ... @@ -1624,7 +1624,7 @@ foreach my $f (qw(screen print))
1624 1624 show_ntests();
1625 1625 # ----------
1626 1626 $td->notify("--- Merging and Splitting ---");
1627   -$n_tests += 18;
  1627 +$n_tests += 22;
1628 1628  
1629 1629 # Select pages from the same file multiple times including selecting
1630 1630 # twice from an encrypted file and specifying the password only the
... ... @@ -1692,7 +1692,7 @@ $td-&gt;runtest(&quot;check output&quot;,
1692 1692 {$td->FILE => "a.pdf"},
1693 1693 {$td->FILE => "merge-multiple-labels.pdf"});
1694 1694  
1695   -$td->runtest("split with shared resources", # QXXXQ
  1695 +$td->runtest("split with shared resources",
1696 1696 {$td->COMMAND =>
1697 1697 "qpdf --qdf --static-id" .
1698 1698 " shared-images.pdf --pages . 1,3" .
... ... @@ -1702,6 +1702,16 @@ $td-&gt;runtest(&quot;check output&quot;,
1702 1702 {$td->FILE => "a.pdf"},
1703 1703 {$td->FILE => "shared-images-pages-out.pdf"});
1704 1704  
  1705 +$td->runtest("split with really shared resources",
  1706 + {$td->COMMAND =>
  1707 + "qpdf --qdf --static-id" .
  1708 + " shared-images.pdf --pages . 1,3" .
  1709 + " . 1,2 -- a.pdf"},
  1710 + {$td->STRING => "", $td->EXIT_STATUS => 0});
  1711 +$td->runtest("check output",
  1712 + {$td->FILE => "a.pdf"},
  1713 + {$td->FILE => "really-shared-images-pages-out.pdf"});
  1714 +
1705 1715 $td->runtest("shared resources relevant errors",
1706 1716 {$td->COMMAND =>
1707 1717 "qpdf --qdf --static-id" .
... ... @@ -1733,6 +1743,16 @@ $td-&gt;runtest(&quot;check output&quot;,
1733 1743 {$td->FILE => "a.pdf"},
1734 1744 {$td->FILE => "shared-images-errors-1-3-out.pdf"});
1735 1745  
  1746 +$td->runtest("duplicate pages",
  1747 + {$td->COMMAND =>
  1748 + "qpdf --qdf --static-id 11-pages-with-labels.pdf" .
  1749 + " --pages . 6,5,6 . 5 minimal.pdf 1,1 minimal.pdf 1 --" .
  1750 + " a.pdf"},
  1751 + {$td->STRING => "", $td->EXIT_STATUS => 0});
  1752 +$td->runtest("check output",
  1753 + {$td->FILE => "a.pdf"},
  1754 + {$td->FILE => "duplicate-pages.pdf"});
  1755 +
1736 1756 show_ntests();
1737 1757 # ----------
1738 1758 $td->notify("--- Collating ---");
... ...
qpdf/qtest/qpdf/duplicate-pages.pdf 0 → 100644
  1 +%PDF-1.4
  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 5
  14 + >>
  15 + 1
  16 + <<
  17 + /S /r
  18 + /St 4
  19 + >>
  20 + 3
  21 + <<
  22 + /S /r
  23 + /St 4
  24 + >>
  25 + 4
  26 + <<
  27 + /St 5
  28 + >>
  29 + ]
  30 + >>
  31 + /Pages 3 0 R
  32 + /Type /Catalog
  33 +>>
  34 +endobj
  35 +
  36 +%% Original object ID: 2 0
  37 +2 0 obj
  38 +<<
  39 + /CreationDate (D:20120721200217)
  40 + /Producer (Apex PDFWriter)
  41 +>>
  42 +endobj
  43 +
  44 +%% Original object ID: 3 0
  45 +3 0 obj
  46 +<<
  47 + /Count 7
  48 + /Kids [
  49 + 4 0 R
  50 + 5 0 R
  51 + 6 0 R
  52 + 7 0 R
  53 + 8 0 R
  54 + 9 0 R
  55 + 10 0 R
  56 + ]
  57 + /Type /Pages
  58 +>>
  59 +endobj
  60 +
  61 +%% Page 1
  62 +%% Original object ID: 9 0
  63 +4 0 obj
  64 +<<
  65 + /Contents 11 0 R
  66 + /MediaBox [
  67 + 0
  68 + 0
  69 + 612
  70 + 792
  71 + ]
  72 + /Parent 3 0 R
  73 + /Resources <<
  74 + /Font <<
  75 + /F1 13 0 R
  76 + >>
  77 + /ProcSet [
  78 + /PDF
  79 + /Text
  80 + ]
  81 + >>
  82 + /Type /Page
  83 +>>
  84 +endobj
  85 +
  86 +%% Page 2
  87 +%% Original object ID: 8 0
  88 +5 0 obj
  89 +<<
  90 + /Contents 14 0 R
  91 + /MediaBox [
  92 + 0
  93 + 0
  94 + 612
  95 + 792
  96 + ]
  97 + /Parent 3 0 R
  98 + /Resources <<
  99 + /Font <<
  100 + /F1 13 0 R
  101 + >>
  102 + /ProcSet [
  103 + /PDF
  104 + /Text
  105 + ]
  106 + >>
  107 + /Type /Page
  108 +>>
  109 +endobj
  110 +
  111 +%% Page 3
  112 +%% Original object ID: 27 0
  113 +6 0 obj
  114 +<<
  115 + /Contents 11 0 R
  116 + /MediaBox [
  117 + 0
  118 + 0
  119 + 612
  120 + 792
  121 + ]
  122 + /Parent 3 0 R
  123 + /Resources <<
  124 + /Font <<
  125 + /F1 13 0 R
  126 + >>
  127 + /ProcSet [
  128 + /PDF
  129 + /Text
  130 + ]
  131 + >>
  132 + /Type /Page
  133 +>>
  134 +endobj
  135 +
  136 +%% Page 4
  137 +%% Original object ID: 28 0
  138 +7 0 obj
  139 +<<
  140 + /Contents 14 0 R
  141 + /MediaBox [
  142 + 0
  143 + 0
  144 + 612
  145 + 792
  146 + ]
  147 + /Parent 3 0 R
  148 + /Resources <<
  149 + /Font <<
  150 + /F1 13 0 R
  151 + >>
  152 + /ProcSet [
  153 + /PDF
  154 + /Text
  155 + ]
  156 + >>
  157 + /Type /Page
  158 +>>
  159 +endobj
  160 +
  161 +%% Page 5
  162 +%% Original object ID: 29 0
  163 +8 0 obj
  164 +<<
  165 + /Contents 16 0 R
  166 + /MediaBox [
  167 + 0
  168 + 0
  169 + 612
  170 + 792
  171 + ]
  172 + /Parent 3 0 R
  173 + /Resources <<
  174 + /Font <<
  175 + /F1 18 0 R
  176 + >>
  177 + /ProcSet 19 0 R
  178 + >>
  179 + /Type /Page
  180 +>>
  181 +endobj
  182 +
  183 +%% Page 6
  184 +%% Original object ID: 33 0
  185 +9 0 obj
  186 +<<
  187 + /Contents 16 0 R
  188 + /MediaBox [
  189 + 0
  190 + 0
  191 + 612
  192 + 792
  193 + ]
  194 + /Parent 3 0 R
  195 + /Resources <<
  196 + /Font <<
  197 + /F1 18 0 R
  198 + >>
  199 + /ProcSet 19 0 R
  200 + >>
  201 + /Type /Page
  202 +>>
  203 +endobj
  204 +
  205 +%% Page 7
  206 +%% Original object ID: 34 0
  207 +10 0 obj
  208 +<<
  209 + /Contents 16 0 R
  210 + /MediaBox [
  211 + 0
  212 + 0
  213 + 612
  214 + 792
  215 + ]
  216 + /Parent 3 0 R
  217 + /Resources <<
  218 + /Font <<
  219 + /F1 18 0 R
  220 + >>
  221 + /ProcSet 19 0 R
  222 + >>
  223 + /Type /Page
  224 +>>
  225 +endobj
  226 +
  227 +%% Contents for page 3
  228 +%% Original object ID: 21 0
  229 +11 0 obj
  230 +<<
  231 + /Length 12 0 R
  232 +>>
  233 +stream
  234 +BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET
  235 +endstream
  236 +endobj
  237 +
  238 +12 0 obj
  239 +47
  240 +endobj
  241 +
  242 +%% Original object ID: 16 0
  243 +13 0 obj
  244 +<<
  245 + /BaseFont /Times-Roman
  246 + /Encoding /WinAnsiEncoding
  247 + /Subtype /Type1
  248 + /Type /Font
  249 +>>
  250 +endobj
  251 +
  252 +%% Contents for page 4
  253 +%% Original object ID: 20 0
  254 +14 0 obj
  255 +<<
  256 + /Length 15 0 R
  257 +>>
  258 +stream
  259 +BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET
  260 +endstream
  261 +endobj
  262 +
  263 +15 0 obj
  264 +47
  265 +endobj
  266 +
  267 +%% Contents for page 7
  268 +%% Original object ID: 30 0
  269 +16 0 obj
  270 +<<
  271 + /Length 17 0 R
  272 +>>
  273 +stream
  274 +BT
  275 + /F1 24 Tf
  276 + 72 720 Td
  277 + (Potato) Tj
  278 +ET
  279 +endstream
  280 +endobj
  281 +
  282 +17 0 obj
  283 +44
  284 +endobj
  285 +
  286 +%% Original object ID: 31 0
  287 +18 0 obj
  288 +<<
  289 + /BaseFont /Helvetica
  290 + /Encoding /WinAnsiEncoding
  291 + /Name /F1
  292 + /Subtype /Type1
  293 + /Type /Font
  294 +>>
  295 +endobj
  296 +
  297 +%% Original object ID: 32 0
  298 +19 0 obj
  299 +[
  300 + /PDF
  301 + /Text
  302 +]
  303 +endobj
  304 +
  305 +xref
  306 +0 20
  307 +0000000000 65535 f
  308 +0000000052 00000 n
  309 +0000000375 00000 n
  310 +0000000488 00000 n
  311 +0000000658 00000 n
  312 +0000000914 00000 n
  313 +0000001171 00000 n
  314 +0000001428 00000 n
  315 +0000001685 00000 n
  316 +0000001918 00000 n
  317 +0000002151 00000 n
  318 +0000002398 00000 n
  319 +0000002502 00000 n
  320 +0000002550 00000 n
  321 +0000002710 00000 n
  322 +0000002814 00000 n
  323 +0000002885 00000 n
  324 +0000002986 00000 n
  325 +0000003034 00000 n
  326 +0000003181 00000 n
  327 +trailer <<
  328 + /Info 2 0 R
  329 + /Root 1 0 R
  330 + /Size 20
  331 + /ID [<e032a88c7a987db6ca3abee555506ccc><31415926535897932384626433832795>]
  332 +>>
  333 +startxref
  334 +3217
  335 +%%EOF
... ...
qpdf/qtest/qpdf/really-shared-images-pages-out.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 + /Pages 2 0 R
  9 + /Type /Catalog
  10 +>>
  11 +endobj
  12 +
  13 +%% Original object ID: 2 0
  14 +2 0 obj
  15 +<<
  16 + /Count 4
  17 + /Kids [
  18 + 3 0 R
  19 + 4 0 R
  20 + 5 0 R
  21 + 6 0 R
  22 + ]
  23 + /Type /Pages
  24 +>>
  25 +endobj
  26 +
  27 +%% Page 1
  28 +%% Original object ID: 3 0
  29 +3 0 obj
  30 +<<
  31 + /Contents 7 0 R
  32 + /MediaBox [
  33 + 0
  34 + 0
  35 + 612
  36 + 792
  37 + ]
  38 + /Parent 2 0 R
  39 + /Resources <<
  40 + /Font <<
  41 + /F1 9 0 R
  42 + >>
  43 + /ProcSet 10 0 R
  44 + /XObject <<
  45 + /Im1 11 0 R
  46 + >>
  47 + >>
  48 + /Type /Page
  49 +>>
  50 +endobj
  51 +
  52 +%% Page 2
  53 +%% Original object ID: 5 0
  54 +4 0 obj
  55 +<<
  56 + /Contents 13 0 R
  57 + /MediaBox [
  58 + 0
  59 + 0
  60 + 612
  61 + 792
  62 + ]
  63 + /Parent 2 0 R
  64 + /Resources <<
  65 + /Font <<
  66 + /F1 9 0 R
  67 + >>
  68 + /ProcSet 10 0 R
  69 + /XObject <<
  70 + /Im3 15 0 R
  71 + >>
  72 + >>
  73 + /Type /Page
  74 +>>
  75 +endobj
  76 +
  77 +%% Page 3
  78 +%% Original object ID: 56 0
  79 +5 0 obj
  80 +<<
  81 + /Contents 7 0 R
  82 + /MediaBox [
  83 + 0
  84 + 0
  85 + 612
  86 + 792
  87 + ]
  88 + /Parent 2 0 R
  89 + /Resources <<
  90 + /Font <<
  91 + /F1 9 0 R
  92 + >>
  93 + /ProcSet 10 0 R
  94 + /XObject <<
  95 + /Im1 11 0 R
  96 + >>
  97 + >>
  98 + /Type /Page
  99 +>>
  100 +endobj
  101 +
  102 +%% Page 4
  103 +%% Original object ID: 4 0
  104 +6 0 obj
  105 +<<
  106 + /Contents 17 0 R
  107 + /MediaBox [
  108 + 0
  109 + 0
  110 + 612
  111 + 792
  112 + ]
  113 + /Parent 2 0 R
  114 + /Resources <<
  115 + /Font <<
  116 + /F1 9 0 R
  117 + >>
  118 + /ProcSet 10 0 R
  119 + /XObject <<
  120 + /Im2 19 0 R
  121 + >>
  122 + >>
  123 + /Type /Page
  124 +>>
  125 +endobj
  126 +
  127 +%% Contents for page 3
  128 +%% Original object ID: 13 0
  129 +7 0 obj
  130 +<<
  131 + /Length 8 0 R
  132 +>>
  133 +stream
  134 +BT /F1 24 Tf 72 720 Td (page 1) Tj ET
  135 +q 468 0 0 468 72 72 cm /Im1 Do Q
  136 +endstream
  137 +endobj
  138 +
  139 +8 0 obj
  140 +71
  141 +endobj
  142 +
  143 +%% Original object ID: 15 0
  144 +9 0 obj
  145 +<<
  146 + /BaseFont /Helvetica
  147 + /Encoding /WinAnsiEncoding
  148 + /Name /F1
  149 + /Subtype /Type1
  150 + /Type /Font
  151 +>>
  152 +endobj
  153 +
  154 +%% Original object ID: 16 0
  155 +10 0 obj
  156 +[
  157 + /PDF
  158 + /Text
  159 + /ImageC
  160 +]
  161 +endobj
  162 +
  163 +%% Original object ID: 17 0
  164 +11 0 obj
  165 +<<
  166 + /BitsPerComponent 8
  167 + /ColorSpace /DeviceGray
  168 + /Height 50
  169 + /Subtype /Image
  170 + /Type /XObject
  171 + /Width 50
  172 + /Length 12 0 R
  173 +>>
  174 +stream
  175 +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
  176 +endstream
  177 +endobj
  178 +
  179 +%QDF: ignore_newline
  180 +12 0 obj
  181 +2500
  182 +endobj
  183 +
  184 +%% Contents for page 2
  185 +%% Original object ID: 23 0
  186 +13 0 obj
  187 +<<
  188 + /Length 14 0 R
  189 +>>
  190 +stream
  191 +BT /F1 24 Tf 72 720 Td (page 3) Tj ET
  192 +q 468 0 0 468 72 72 cm /Im3 Do Q
  193 +endstream
  194 +endobj
  195 +
  196 +14 0 obj
  197 +71
  198 +endobj
  199 +
  200 +%% Original object ID: 25 0
  201 +15 0 obj
  202 +<<
  203 + /BitsPerComponent 8
  204 + /ColorSpace /DeviceGray
  205 + /Height 50
  206 + /Subtype /Image
  207 + /Type /XObject
  208 + /Width 50
  209 + /Length 16 0 R
  210 +>>
  211 +stream
  212 +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
  213 +endstream
  214 +endobj
  215 +
  216 +%QDF: ignore_newline
  217 +16 0 obj
  218 +2500
  219 +endobj
  220 +
  221 +%% Contents for page 4
  222 +%% Original object ID: 19 0
  223 +17 0 obj
  224 +<<
  225 + /Length 18 0 R
  226 +>>
  227 +stream
  228 +BT /F1 24 Tf 72 720 Td (page 2) Tj ET
  229 +q 468 0 0 468 72 72 cm /Im2 Do Q
  230 +endstream
  231 +endobj
  232 +
  233 +18 0 obj
  234 +71
  235 +endobj
  236 +
  237 +%% Original object ID: 21 0
  238 +19 0 obj
  239 +<<
  240 + /BitsPerComponent 8
  241 + /ColorSpace /DeviceGray
  242 + /Height 50
  243 + /Subtype /Image
  244 + /Type /XObject
  245 + /Width 50
  246 + /Length 20 0 R
  247 +>>
  248 +stream
  249 +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  250 +endstream
  251 +endobj
  252 +
  253 +%QDF: ignore_newline
  254 +20 0 obj
  255 +2500
  256 +endobj
  257 +
  258 +xref
  259 +0 21
  260 +0000000000 65535 f
  261 +0000000052 00000 n
  262 +0000000133 00000 n
  263 +0000000272 00000 n
  264 +0000000543 00000 n
  265 +0000000816 00000 n
  266 +0000001087 00000 n
  267 +0000001373 00000 n
  268 +0000001499 00000 n
  269 +0000001546 00000 n
  270 +0000001692 00000 n
  271 +0000001766 00000 n
  272 +0000004453 00000 n
  273 +0000004526 00000 n
  274 +0000004654 00000 n
  275 +0000004702 00000 n
  276 +0000007389 00000 n
  277 +0000007462 00000 n
  278 +0000007590 00000 n
  279 +0000007638 00000 n
  280 +0000010325 00000 n
  281 +trailer <<
  282 + /Root 1 0 R
  283 + /Size 21
  284 + /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
  285 +>>
  286 +startxref
  287 +10347
  288 +%%EOF
... ...