aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-12-16 20:36:21 +0100
committerJay Berkenbilt <ejb@ql.org>2021-12-16 21:07:48 +0100
commit9bb6f570ec73c6154748596d04a6f10c41c57721 (patch)
treea677b2ca53d621cd9e2030196803397ab868d12c
parentf072be032fe921617ba5f78a004ee73c75caf6bd (diff)
downloadqpdf-9bb6f570ec73c6154748596d04a6f10c41c57721.tar.zst
C API: add functions for working with pages (fixes #594)
-rw-r--r--ChangeLog7
-rw-r--r--include/qpdf/qpdf-c.h61
-rw-r--r--libqpdf/qpdf-c.cc99
-rw-r--r--manual/index.rst7
-rw-r--r--qpdf/qpdf-ctest.c136
-rw-r--r--qpdf/qpdf.testcov9
-rw-r--r--qpdf/qtest/qpdf.test30
-rw-r--r--qpdf/qtest/qpdf/c-page-errors.out8
-rw-r--r--qpdf/qtest/qpdf/c-pages.pdf599
9 files changed, 955 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index c13f4ecb..16cfd204 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2021-12-16 Jay Berkenbilt <ejb@ql.org>
+
+ * Add several functions to the C API for working with pages. C
+ wrappers around sevearl of the "Legacy" page operations from
+ QPDFObjectHandle.hh have been added. See "PAGE FUNCTIONS" in
+ qpdf-c.h for details. Fixes #594.
+
2021-12-12 Jay Berkenbilt <ejb@ql.org>
* Convert documentation from docbook to reStructuredText/Sphinx.
diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h
index 9d121060..4a6eb3a5 100644
--- a/include/qpdf/qpdf-c.h
+++ b/include/qpdf/qpdf-c.h
@@ -788,6 +788,67 @@ extern "C" {
char const* qpdf_oh_unparse_resolved(qpdf_data qpdf, qpdf_oh oh);
QPDF_DLL
char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh);
+
+ /* PAGE FUNCTIONS */
+
+ /* The first time a page function is called, qpdf will traverse
+ * the /Pages tree. Subsequent calls to retrieve the number of
+ * pages or a specific page run in constant time as they are
+ * accessing the pages cache. If you manipulate the page tree
+ * outside of these functions, you should call
+ * qpdf_update_all_pages_cache. See comments for getAllPages() and
+ * updateAllPagesCache() in QPDF.hh.
+ */
+
+ /* For each function, the corresponding method in QPDF.hh is
+ * referenced. Please see comments in QPDF.hh for details.
+ */
+
+ /* calls getAllPages(). On error, returns -1 and sets error for
+ * qpdf_get_error. */
+ QPDF_DLL
+ int qpdf_get_num_pages(qpdf_data qpdf);
+ /* returns uninitialized object if out of range */
+ QPDF_DLL
+ qpdf_oh qpdf_get_page_n(qpdf_data qpdf, size_t zero_based_index);
+
+ /* updateAllPagesCache() */
+ QPDF_DLL
+ QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf);
+
+ /* findPage() -- return zero-based index. If page is not found,
+ * return -1 and save the error to be retrieved with
+ * qpdf_get_error.
+ */
+ QPDF_DLL
+ int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation);
+ QPDF_DLL
+ int qpdf_find_page_by_oh(qpdf_data qpdf, qpdf_oh oh);
+
+ /* pushInheritedAttributesToPage() */
+ QPDF_DLL
+ QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf);
+
+ /* Functions that add pages may add pages from other files. If
+ * adding a page from the same file, newpage_qpdf and qpdf are the
+ * same.
+ /*/
+
+ /* addPage() */
+ QPDF_DLL
+ QPDF_ERROR_CODE qpdf_add_page(
+ qpdf_data qpdf,
+ qpdf_data newpage_qpdf, qpdf_oh newpage,
+ QPDF_BOOL first);
+ /* addPageAt() */
+ QPDF_DLL
+ QPDF_ERROR_CODE qpdf_add_page_at(
+ qpdf_data qpdf,
+ qpdf_data newpage_qpdf, qpdf_oh newpage,
+ QPDF_BOOL before, qpdf_oh refpage);
+ /* removePage() */
+ QPDF_DLL
+ QPDF_ERROR_CODE qpdf_remove_page(qpdf_data qpdf, qpdf_oh page);
#ifdef __cplusplus
}
#endif
diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc
index c4428d10..0ce9c39e 100644
--- a/libqpdf/qpdf-c.cc
+++ b/libqpdf/qpdf-c.cc
@@ -1579,3 +1579,102 @@ char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh)
return qpdf->tmp_string.c_str();
});
}
+
+int qpdf_get_num_pages(qpdf_data qpdf)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_num_pages");
+ int n = -1;
+ QPDF_ERROR_CODE code = trap_errors(qpdf, [&n](qpdf_data q) {
+ n = QIntC::to_int(q->qpdf->getAllPages().size());
+ });
+ if (code & QPDF_ERRORS)
+ {
+ return -1;
+ }
+ return n;
+}
+
+qpdf_oh qpdf_get_page_n(qpdf_data qpdf, size_t i)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_get_page_n");
+ qpdf_oh result = 0;
+ QPDF_ERROR_CODE code = trap_errors(qpdf, [&result, i](qpdf_data q) {
+ result = new_object(q, q->qpdf->getAllPages().at(i));
+ });
+ if ((code & QPDF_ERRORS) || (result == 0))
+ {
+ return qpdf_oh_new_uninitialized(qpdf);
+ }
+ return result;
+}
+
+QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_update_all_pages_cache");
+ return trap_errors(qpdf, [](qpdf_data q) {
+ q->qpdf->updateAllPagesCache();
+ });
+}
+
+int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_find_page_by_id");
+ int n = -1;
+ QPDFObjGen og(objid, generation);
+ QPDF_ERROR_CODE code = trap_errors(qpdf, [&n, &og](qpdf_data q) {
+ n = QIntC::to_int(q->qpdf->findPage(og));
+ });
+ if (code & QPDF_ERRORS)
+ {
+ return -1;
+ }
+ return n;
+}
+
+int qpdf_find_page_by_oh(qpdf_data qpdf, qpdf_oh oh)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_find_page_by_oh");
+ return do_with_oh<int>(
+ qpdf, oh, return_T<int>(-1), [qpdf](QPDFObjectHandle& o) {
+ return qpdf->qpdf->findPage(o);
+ });
+}
+
+QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_push_inherited_attributes_to_page");
+ return trap_errors(qpdf, [](qpdf_data q) {
+ q->qpdf->pushInheritedAttributesToPage();
+ });
+}
+
+QPDF_ERROR_CODE qpdf_add_page(
+ qpdf_data qpdf, qpdf_data newpage_qpdf, qpdf_oh newpage, QPDF_BOOL first)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_add_page");
+ auto page = qpdf_oh_item_internal(newpage_qpdf, newpage);
+ return trap_errors(qpdf, [&page, first](qpdf_data q) {
+ q->qpdf->addPage(page, first);
+ });
+}
+
+QPDF_ERROR_CODE qpdf_add_page_at(
+ qpdf_data qpdf, qpdf_data newpage_qpdf, qpdf_oh newpage,
+ QPDF_BOOL before, qpdf_oh refpage)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_add_page_at");
+ auto page = qpdf_oh_item_internal(newpage_qpdf, newpage);
+ auto ref = qpdf_oh_item_internal(qpdf, refpage);
+ return trap_errors(qpdf, [&page, before, &ref](qpdf_data q) {
+ q->qpdf->addPageAt(page, before, ref);
+ });
+}
+
+QPDF_ERROR_CODE qpdf_remove_page(qpdf_data qpdf, qpdf_oh page)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_remove_page");
+ auto p = qpdf_oh_item_internal(qpdf, page);
+ return trap_errors(qpdf, [&p](qpdf_data q) {
+ q->qpdf->removePage(p);
+ });
+}
diff --git a/manual/index.rst b/manual/index.rst
index 8fcb18f9..155d64b0 100644
--- a/manual/index.rst
+++ b/manual/index.rst
@@ -3626,7 +3626,9 @@ For a detailed list of changes, please see the file
more detail what the behavior is. See :ref:`ref.object-accessors` for a more in-depth
discussion.
- - Overhaul error handling for the object handle functions in the
+ - C API Enhancements
+
+ - Overhaul error handling for the object handle functions
C API. See comments in the "Object handling" section of
:file:`include/qpdf/qpdf-c.h` for details.
In particular, exceptions thrown by the underlying C++ code
@@ -3650,6 +3652,9 @@ For a detailed list of changes, please see the file
and ``qpdf_replace_object``, exposing the corresponding methods
in ``QPDF`` and ``QPDFObjectHandle``.
+ - Add several functions for working with pages. See ``PAGE
+ FUNCTIONS`` in ``include/qpdf/qpdf-c.h`` for details.
+
- Documentation change
- The documentation sources have been switched from docbook to
diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c
index 307b57c7..a0819599 100644
--- a/qpdf/qpdf-ctest.c
+++ b/qpdf/qpdf-ctest.c
@@ -931,6 +931,138 @@ static void test33(char const* infile,
report_errors();
}
+static void test34(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* xarg)
+{
+ /* This test expects 11-pages.pdf as file1 and minimal.pdf as xarg. */
+
+ /* Non-error cases for page API */
+
+ qpdf_data qpdf2 = qpdf_init();
+ assert(qpdf_read(qpdf, infile, password) == 0);
+ assert(qpdf_read(qpdf2, xarg, "") == 0);
+ assert(qpdf_get_num_pages(qpdf) == 11);
+ assert(qpdf_get_num_pages(qpdf2) == 1);
+
+ /* At this time, there is no C API for accessing stream data, so
+ * we hard-code object IDs from a known input file.
+ */
+ assert(qpdf_oh_get_object_id(qpdf, qpdf_get_page_n(qpdf, 0)) == 4);
+ assert(qpdf_oh_get_object_id(qpdf, qpdf_get_page_n(qpdf, 10)) == 14);
+ qpdf_oh page3 = qpdf_get_page_n(qpdf, 3);
+ assert(qpdf_find_page_by_oh(qpdf, page3) == 3);
+ assert(qpdf_find_page_by_id(
+ qpdf, qpdf_oh_get_object_id(qpdf, page3), 0) == 3);
+
+ /* Add other page to the end */
+ qpdf_oh opage0 = qpdf_get_page_n(qpdf2, 0);
+ assert(qpdf_add_page(qpdf, qpdf2, opage0, QPDF_FALSE) == 0);
+ /* Add other page before page 3 */
+ assert(qpdf_add_page_at(qpdf, qpdf2, opage0, QPDF_TRUE, page3) == 0);
+ /* Remove page 3 */
+ assert(qpdf_remove_page(qpdf, page3) == 0);
+ /* At page 3 back at the beginning */
+ assert(qpdf_add_page(qpdf, qpdf, page3, QPDF_TRUE) == 0);
+
+ qpdf_init_write(qpdf, outfile);
+ qpdf_set_static_ID(qpdf, QPDF_TRUE);
+ qpdf_set_qdf_mode(qpdf, QPDF_TRUE);
+ qpdf_set_suppress_original_object_IDs(qpdf, QPDF_TRUE);
+ qpdf_write(qpdf);
+ report_errors();
+ qpdf_cleanup(&qpdf2);
+}
+
+static void test35(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* xarg)
+{
+ /* This test uses 11-pages.pdf */
+
+ assert(qpdf_get_num_pages(qpdf) == -1);
+ assert(qpdf_has_error(qpdf));
+ qpdf_error e = qpdf_get_error(qpdf);
+ assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS);
+ assert(! qpdf_has_error(qpdf));
+
+ assert(qpdf_read(qpdf, infile, password) == 0);
+
+ qpdf_oh range = qpdf_get_page_n(qpdf, 11);
+ assert(! qpdf_oh_is_initialized(qpdf, range));
+ assert(qpdf_has_error(qpdf));
+ e = qpdf_get_error(qpdf);
+ assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS);
+ assert(! qpdf_has_error(qpdf));
+
+ assert(qpdf_find_page_by_id(qpdf, 100, 0) == -1);
+ assert(qpdf_has_error(qpdf));
+ e = qpdf_get_error(qpdf);
+ assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS);
+ assert(! qpdf_has_error(qpdf));
+
+ assert(qpdf_find_page_by_oh(qpdf, qpdf_get_root(qpdf)) == -1);
+ assert(qpdf_more_warnings(qpdf));
+ e = qpdf_next_warning(qpdf);
+ assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS);
+ assert(! qpdf_has_error(qpdf));
+
+ assert(qpdf_find_page_by_id(qpdf, 100, 0) == -1);
+ assert(qpdf_has_error(qpdf));
+ e = qpdf_get_error(qpdf);
+ assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS);
+ assert(! qpdf_has_error(qpdf));
+
+ assert(qpdf_add_page(qpdf, qpdf, 1000, QPDF_FALSE) != 0);
+
+ report_errors();
+}
+
+static void test36(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* xarg)
+{
+ /* This test uses inherited-rotate.pdf */
+
+ assert(qpdf_read(qpdf, infile, password) == 0);
+
+ /* Non-trivially push inherited attributes */
+ qpdf_oh page0 = qpdf_get_object_by_id(qpdf, 3, 0);
+ assert(qpdf_oh_is_dictionary(qpdf, page0));
+ qpdf_oh r = qpdf_oh_get_key(qpdf, page0, "/Rotate");
+ assert(qpdf_oh_get_int_value(qpdf, r) == 90);
+ qpdf_oh_remove_key(qpdf, page0, "/Rotate");
+ assert(! qpdf_oh_has_key(qpdf, page0, "/Rotate"));
+
+ assert(qpdf_push_inherited_attributes_to_page(qpdf) == 0);
+ r = qpdf_oh_get_key(qpdf, page0, "/Rotate");
+ assert(qpdf_oh_get_int_value(qpdf, r) == 270);
+
+ assert(qpdf_add_page(qpdf, qpdf, page0, QPDF_TRUE) == 0);
+}
+
+static void test37(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* xarg)
+{
+ /* This test uses 11-pages.pdf */
+
+ /* Manually manipulate pages tree */
+ assert(qpdf_read(qpdf, infile, password) == 0);
+ assert(qpdf_get_num_pages(qpdf) == 11);
+ qpdf_oh pages = qpdf_get_object_by_id(qpdf, 3, 0);
+ qpdf_oh kids = qpdf_oh_get_key(qpdf, pages, "/Kids");
+ assert(qpdf_oh_get_array_n_items(qpdf, kids) == 11);
+ qpdf_oh_erase_item(qpdf, kids, 0);
+ assert(qpdf_get_num_pages(qpdf) == 11);
+ assert(qpdf_update_all_pages_cache(qpdf) == 0);
+ assert(qpdf_get_num_pages(qpdf) == 10);
+}
+
int main(int argc, char* argv[])
{
char* p = 0;
@@ -1004,6 +1136,10 @@ int main(int argc, char* argv[])
(n == 31) ? test31 :
(n == 32) ? test32 :
(n == 33) ? test33 :
+ (n == 34) ? test34 :
+ (n == 35) ? test35 :
+ (n == 36) ? test36 :
+ (n == 37) ? test37 :
0);
if (fn == 0)
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 9b4e3cea..315c1200 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -608,3 +608,12 @@ qpdf-c registered oh error handler 0
qpdf-c cleanup warned about unhandled error 0
qpdf-c called qpdf_get_object_by_id 0
qpdf-c called qpdf_replace_object 0
+qpdf-c called qpdf_num_pages 0
+qpdf-c called qpdf_get_page_n 0
+qpdf-c called qpdf_update_all_pages_cache 0
+qpdf-c called qpdf_find_page_by_id 0
+qpdf-c called qpdf_find_page_by_oh 0
+qpdf-c called qpdf_push_inherited_attributes_to_page 0
+qpdf-c called qpdf_add_page 0
+qpdf-c called qpdf_add_page_at 0
+qpdf-c called qpdf_remove_page 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index d4b3f2a5..c975f2c1 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -4870,6 +4870,36 @@ $td->runtest("C get object by ID",
show_ntests();
# ----------
+$td->notify("--- C API Page Functions ---");
+$n_tests += 5;
+
+$td->runtest("C page normal",
+ {$td->COMMAND =>
+ "qpdf-ctest 34 11-pages.pdf '' a.pdf minimal.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check output",
+ {$td->FILE => 'a.pdf'},
+ {$td->FILE => 'c-pages.pdf'});
+
+$td->runtest("C page errors",
+ {$td->COMMAND =>
+ "qpdf-ctest 35 11-pages.pdf '' ''"},
+ {$td->FILE => "c-page-errors.out", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("C inherited page resources",
+ {$td->COMMAND =>
+ "qpdf-ctest 36 inherited-rotate.pdf '' ''"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("C pages cache",
+ {$td->COMMAND =>
+ "qpdf-ctest 37 11-pages.pdf '' ''"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+
+show_ntests();
+# ----------
$td->notify("--- Content Preservation Tests ---");
# $n_tests incremented below
diff --git a/qpdf/qtest/qpdf/c-page-errors.out b/qpdf/qtest/qpdf/c-page-errors.out
new file mode 100644
index 00000000..36afa406
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-page-errors.out
@@ -0,0 +1,8 @@
+11-pages.pdf (page object: object 1 0): page object not referenced in /Pages tree
+11-pages.pdf (C API object handle 1000): attempted access to unknown object handle
+WARNING: object 27 0: operation for dictionary attempted on object of type null: ignoring key replacement request
+warning: object 27 0: operation for dictionary attempted on object of type null: ignoring key replacement request
+ code: 7
+ file:
+ pos : 0
+ text: operation for dictionary attempted on object of type null: ignoring key replacement request
diff --git a/qpdf/qtest/qpdf/c-pages.pdf b/qpdf/qtest/qpdf/c-pages.pdf
new file mode 100644
index 00000000..40f9bc56
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-pages.pdf
@@ -0,0 +1,599 @@
+%PDF-1.4
+%¿÷¢þ
+%QDF-1.0
+
+1 0 obj
+<<
+ /Pages 3 0 R
+ /Type /Catalog
+>>
+endobj
+
+2 0 obj
+<<
+ /CreationDate (D:20120721200217)
+ /Producer (Apex PDFWriter)
+>>
+endobj
+
+3 0 obj
+<<
+ /Count 13
+ /Kids [
+ 4 0 R
+ 5 0 R
+ 6 0 R
+ 7 0 R
+ 8 0 R
+ 9 0 R
+ 10 0 R
+ 11 0 R
+ 12 0 R
+ 13 0 R
+ 14 0 R
+ 15 0 R
+ 16 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+4 0 obj
+<<
+ /Contents 17 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 2
+5 0 obj
+<<
+ /Contents 20 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 3
+6 0 obj
+<<
+ /Contents 22 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 4
+7 0 obj
+<<
+ /Contents 24 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 5
+8 0 obj
+<<
+ /Contents 26 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 28 0 R
+ >>
+ /ProcSet 29 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 6
+9 0 obj
+<<
+ /Contents 30 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 7
+10 0 obj
+<<
+ /Contents 32 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 8
+11 0 obj
+<<
+ /Contents 34 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 9
+12 0 obj
+<<
+ /Contents 36 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 10
+13 0 obj
+<<
+ /Contents 38 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 11
+14 0 obj
+<<
+ /Contents 40 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 12
+15 0 obj
+<<
+ /Contents 42 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 19 0 R
+ >>
+ /ProcSet [
+ /PDF
+ /Text
+ ]
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Page 13
+16 0 obj
+<<
+ /Contents 26 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources <<
+ /Font <<
+ /F1 28 0 R
+ >>
+ /ProcSet 29 0 R
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+17 0 obj
+<<
+ /Length 18 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 4) Tj ET
+endstream
+endobj
+
+18 0 obj
+47
+endobj
+
+19 0 obj
+<<
+ /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Contents for page 2
+20 0 obj
+<<
+ /Length 21 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 1) Tj ET
+endstream
+endobj
+
+21 0 obj
+47
+endobj
+
+%% Contents for page 3
+22 0 obj
+<<
+ /Length 23 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 2) Tj ET
+endstream
+endobj
+
+23 0 obj
+47
+endobj
+
+%% Contents for page 4
+24 0 obj
+<<
+ /Length 25 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 3) Tj ET
+endstream
+endobj
+
+25 0 obj
+47
+endobj
+
+%% Contents for page 13
+26 0 obj
+<<
+ /Length 27 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+27 0 obj
+44
+endobj
+
+28 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+29 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+%% Contents for page 6
+30 0 obj
+<<
+ /Length 31 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET
+endstream
+endobj
+
+31 0 obj
+47
+endobj
+
+%% Contents for page 7
+32 0 obj
+<<
+ /Length 33 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET
+endstream
+endobj
+
+33 0 obj
+47
+endobj
+
+%% Contents for page 8
+34 0 obj
+<<
+ /Length 35 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 7) Tj ET
+endstream
+endobj
+
+35 0 obj
+47
+endobj
+
+%% Contents for page 9
+36 0 obj
+<<
+ /Length 37 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 8) Tj ET
+endstream
+endobj
+
+37 0 obj
+47
+endobj
+
+%% Contents for page 10
+38 0 obj
+<<
+ /Length 39 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 9) Tj ET
+endstream
+endobj
+
+39 0 obj
+47
+endobj
+
+%% Contents for page 11
+40 0 obj
+<<
+ /Length 41 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 10) Tj ET
+endstream
+endobj
+
+41 0 obj
+48
+endobj
+
+%% Contents for page 12
+42 0 obj
+<<
+ /Length 43 0 R
+>>
+stream
+BT /F1 15 Tf 72 720 Td (Original page 11) Tj ET
+endstream
+endobj
+
+43 0 obj
+48
+endobj
+
+xref
+0 44
+0000000000 65535 f
+0000000025 00000 n
+0000000079 00000 n
+0000000165 00000 n
+0000000375 00000 n
+0000000604 00000 n
+0000000833 00000 n
+0000001062 00000 n
+0000001291 00000 n
+0000001496 00000 n
+0000001725 00000 n
+0000001955 00000 n
+0000002185 00000 n
+0000002416 00000 n
+0000002647 00000 n
+0000002878 00000 n
+0000003109 00000 n
+0000003328 00000 n
+0000003432 00000 n
+0000003452 00000 n
+0000003584 00000 n
+0000003688 00000 n
+0000003731 00000 n
+0000003835 00000 n
+0000003878 00000 n
+0000003982 00000 n
+0000004026 00000 n
+0000004127 00000 n
+0000004147 00000 n
+0000004266 00000 n
+0000004325 00000 n
+0000004429 00000 n
+0000004472 00000 n
+0000004576 00000 n
+0000004619 00000 n
+0000004723 00000 n
+0000004766 00000 n
+0000004870 00000 n
+0000004914 00000 n
+0000005018 00000 n
+0000005062 00000 n
+0000005167 00000 n
+0000005211 00000 n
+0000005316 00000 n
+trailer <<
+ /Info 2 0 R
+ /Root 1 0 R
+ /Size 44
+ /ID [<e032a88c7a987db6ca3abee555506ccc><31415926535897932384626433832795>]
+>>
+startxref
+5336
+%%EOF