aboutsummaryrefslogtreecommitdiffstats
path: root/qpdf
diff options
context:
space:
mode:
Diffstat (limited to 'qpdf')
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test7
-rw-r--r--qpdf/qtest/qpdf/nested-form-xobjects.out49
-rw-r--r--qpdf/qtest/qpdf/nested-form-xobjects.pdf397
-rw-r--r--qpdf/test_driver.cc51
5 files changed, 504 insertions, 1 deletions
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 2fddc87c..78ddc304 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -521,3 +521,4 @@ qpdf-c called qpdf_oh_unparse 0
qpdf-c called qpdf_oh_unparse_resolved 0
qpdf-c called qpdf_oh_unparse_binary 0
QPDFWriter getFilterOnWrite false 0
+QPDFPageObjectHelper::forEachXObject 3
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 1fdc5f09..32751a98 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -423,7 +423,7 @@ foreach my $i (@choice_values)
show_ntests();
# ----------
$td->notify("--- Form XObject, underlay, overlay ---");
-$n_tests += 18;
+$n_tests += 19;
$td->runtest("form xobject creation",
{$td->COMMAND => "test_driver 55 fxo-red.pdf"},
@@ -486,6 +486,11 @@ for (my $i = 1; $i <= scalar(@uo_cases); ++$i)
{$td->FILE => "a.pdf"},
{$td->FILE => "$outbase.pdf"});
}
+$td->runtest("foreach",
+ {$td->COMMAND => "test_driver 71 nested-form-xobjects.pdf"},
+ {$td->FILE => "nested-form-xobjects.out",
+ $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
show_ntests();
# ----------
diff --git a/qpdf/qtest/qpdf/nested-form-xobjects.out b/qpdf/qtest/qpdf/nested-form-xobjects.out
new file mode 100644
index 00000000..0fa2ebb1
--- /dev/null
+++ b/qpdf/qtest/qpdf/nested-form-xobjects.out
@@ -0,0 +1,49 @@
+--- recursive, all ---
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Fx1 -> 12 0 R
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im1 -> 14 0 R
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im2 -> 16 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Fx1 -> 20 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im1 -> 22 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im2 -> 24 0 R
+<< /Im1 26 0 R /Im2 28 0 R >> -> /Im1 -> 26 0 R
+<< /Im1 26 0 R /Im2 28 0 R >> -> /Im2 -> 28 0 R
+--- non-recursive, all ---
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Fx1 -> 12 0 R
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im1 -> 14 0 R
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im2 -> 16 0 R
+--- recursive, images ---
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im1 -> 14 0 R
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im2 -> 16 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im1 -> 22 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im2 -> 24 0 R
+<< /Im1 26 0 R /Im2 28 0 R >> -> /Im1 -> 26 0 R
+<< /Im1 26 0 R /Im2 28 0 R >> -> /Im2 -> 28 0 R
+--- non-recursive, images ---
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im1 -> 14 0 R
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Im2 -> 16 0 R
+--- recursive, form XObjects ---
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Fx1 -> 12 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Fx1 -> 20 0 R
+--- non-recursive, form XObjects ---
+<< /Fx1 12 0 R /Im1 14 0 R /Im2 16 0 R >> -> /Fx1 -> 12 0 R
+--- recursive, all, from fx1 ---
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Fx1 -> 20 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im1 -> 22 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im2 -> 24 0 R
+<< /Im1 26 0 R /Im2 28 0 R >> -> /Im1 -> 26 0 R
+<< /Im1 26 0 R /Im2 28 0 R >> -> /Im2 -> 28 0 R
+--- non-recursive, all, from fx1 ---
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Fx1 -> 20 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im1 -> 22 0 R
+<< /Fx1 20 0 R /Im1 22 0 R /Im2 24 0 R >> -> /Im2 -> 24 0 R
+--- get images, page ---
+/Im1 -> 14 0 R
+/Im2 -> 16 0 R
+--- get images, fx ---
+/Im1 -> 22 0 R
+/Im2 -> 24 0 R
+--- get form XObjects, page ---
+/Fx1 -> 12 0 R
+--- get form XObjects, fx ---
+/Fx1 -> 20 0 R
+test 71 done
diff --git a/qpdf/qtest/qpdf/nested-form-xobjects.pdf b/qpdf/qtest/qpdf/nested-form-xobjects.pdf
new file mode 100644
index 00000000..f4c761b7
--- /dev/null
+++ b/qpdf/qtest/qpdf/nested-form-xobjects.pdf
@@ -0,0 +1,397 @@
+%PDF-1.3
+%¿÷¢þ
+%QDF-1.0
+
+1 0 obj
+<<
+ /Pages 2 0 R
+ /Type /Catalog
+>>
+endobj
+
+2 0 obj
+<<
+ /Count 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+3 0 obj
+<<
+ /Contents [
+ 4 0 R
+ 6 0 R
+ 8 0 R
+ ]
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 10 0 R
+ >>
+ /ProcSet 11 0 R
+ /XObject <<
+ /Fx1 12 0 R
+ /Im1 14 0 R
+ /Im2 16 0 R
+ >>
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+q
+endstream
+endobj
+
+5 0 obj
+2
+endobj
+
+%% Contents for page 1
+6 0 obj
+<<
+ /Length 7 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Page) Tj
+ET
+q
+100 0 0 100 72 600 cm
+/Im1 Do
+Q
+q
+100 0 0 100 192 600 cm
+/Im2 Do
+Q
+endstream
+endobj
+
+7 0 obj
+111
+endobj
+
+%% Contents for page 1
+8 0 obj
+<<
+ /Length 9 0 R
+>>
+stream
+
+Q
+q
+1.00000 0.00000 0.00000 1.00000 72.00000 200.00000 cm
+/Fx1 Do
+Q
+endstream
+endobj
+
+9 0 obj
+69
+endobj
+
+10 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+11 0 obj
+[
+ /PDF
+ /Text
+ /ImageC
+]
+endobj
+
+12 0 obj
+<<
+ /BBox [
+ 0
+ 0
+ 300
+ 500
+ ]
+ /Resources <<
+ /Font <<
+ /F1 18 0 R
+ >>
+ /ProcSet 19 0 R
+ /XObject <<
+ /Fx1 20 0 R
+ /Im1 22 0 R
+ /Im2 24 0 R
+ >>
+ >>
+ /Subtype /Form
+ /Type /XObject
+ /Length 13 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 0 320 Td
+ (FX1) Tj
+ET
+q
+100 0 0 100 000 200 cm
+/Im1 Do
+Q
+q
+100 0 0 100 120 200 cm
+/Im2 Do
+Q
+q
+1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 cm
+/Fx1 Do
+Q
+endstream
+endobj
+
+13 0 obj
+173
+endobj
+
+14 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 15
+ /Subtype /Image
+ /Type /XObject
+ /Width 15
+ /Length 15 0 R
+>>
+stream
+`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+endstream
+endobj
+
+%QDF: ignore_newline
+15 0 obj
+225
+endobj
+
+16 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 15
+ /Subtype /Image
+ /Type /XObject
+ /Width 15
+ /Length 17 0 R
+>>
+stream
+@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+endstream
+endobj
+
+%QDF: ignore_newline
+17 0 obj
+225
+endobj
+
+18 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+19 0 obj
+[
+ /PDF
+ /Text
+ /ImageC
+]
+endobj
+
+20 0 obj
+<<
+ /BBox [
+ 0
+ 0
+ 300
+ 200
+ ]
+ /Resources <<
+ /Font <<
+ /F1 18 0 R
+ >>
+ /ProcSet 19 0 R
+ /XObject <<
+ /Im1 26 0 R
+ /Im2 28 0 R
+ >>
+ >>
+ /Subtype /Form
+ /Type /XObject
+ /Length 21 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 0 120 Td
+ (FX2) Tj
+ET
+q
+100 0 0 100 0 0 cm
+/Im1 Do
+Q
+q
+100 0 0 100 120 0 cm
+/Im2 Do
+Q
+endstream
+endobj
+
+21 0 obj
+104
+endobj
+
+22 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 15
+ /Subtype /Image
+ /Type /XObject
+ /Width 15
+ /Length 23 0 R
+>>
+stream
+@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+endstream
+endobj
+
+%QDF: ignore_newline
+23 0 obj
+225
+endobj
+
+24 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 15
+ /Subtype /Image
+ /Type /XObject
+ /Width 15
+ /Length 25 0 R
+>>
+stream
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+endstream
+endobj
+
+%QDF: ignore_newline
+25 0 obj
+225
+endobj
+
+26 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 15
+ /Subtype /Image
+ /Type /XObject
+ /Width 15
+ /Length 27 0 R
+>>
+stream
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+endstream
+endobj
+
+%QDF: ignore_newline
+27 0 obj
+225
+endobj
+
+28 0 obj
+<<
+ /BitsPerComponent 8
+ /ColorSpace /DeviceGray
+ /Height 15
+ /Subtype /Image
+ /Type /XObject
+ /Width 15
+ /Length 29 0 R
+>>
+stream
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+endstream
+endobj
+
+%QDF: ignore_newline
+29 0 obj
+225
+endobj
+
+xref
+0 30
+0000000000 65535 f
+0000000025 00000 n
+0000000079 00000 n
+0000000161 00000 n
+0000000485 00000 n
+0000000542 00000 n
+0000000583 00000 n
+0000000749 00000 n
+0000000792 00000 n
+0000000916 00000 n
+0000000935 00000 n
+0000001054 00000 n
+0000001100 00000 n
+0000001561 00000 n
+0000001582 00000 n
+0000001994 00000 n
+0000002015 00000 n
+0000002427 00000 n
+0000002448 00000 n
+0000002567 00000 n
+0000002613 00000 n
+0000002987 00000 n
+0000003008 00000 n
+0000003420 00000 n
+0000003441 00000 n
+0000003853 00000 n
+0000003874 00000 n
+0000004286 00000 n
+0000004307 00000 n
+0000004719 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 30
+ /ID [<55269d37282af9edc76855e4cb859987><633b13d949c2f1d115e24c686f36e362>]
+>>
+startxref
+4740
+%%EOF
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index d8b40a0f..ff55e63f 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -2228,6 +2228,57 @@ void runtest(int n, char const* filename1, char const* arg2)
w.setDecodeLevel(qpdf_dl_specialized);
w.write();
}
+ else if (n == 71)
+ {
+ auto show = [](QPDFObjectHandle& obj,
+ QPDFObjectHandle& xobj_dict,
+ std::string const& key) {
+ std::cout << xobj_dict.unparse() << " -> "
+ << key << " -> " << obj.unparse() << std::endl;
+ };
+ auto page = QPDFPageDocumentHelper(pdf).getAllPages().at(0);
+ std::cout << "--- recursive, all ---" << std::endl;
+ page.forEachXObject(true, show);
+ std::cout << "--- non-recursive, all ---" << std::endl;
+ page.forEachXObject(false, show);
+ std::cout << "--- recursive, images ---" << std::endl;
+ page.forEachImage(true, show);
+ std::cout << "--- non-recursive, images ---" << std::endl;
+ page.forEachImage(false, show);
+ std::cout << "--- recursive, form XObjects ---" << std::endl;
+ page.forEachFormXObject(true, show);
+ std::cout << "--- non-recursive, form XObjects ---" << std::endl;
+ page.forEachFormXObject(false, show);
+ auto fx1 = QPDFPageObjectHelper(
+ page.getObjectHandle()
+ .getKey("/Resources")
+ .getKey("/XObject")
+ .getKey("/Fx1"));
+ std::cout << "--- recursive, all, from fx1 ---" << std::endl;
+ fx1.forEachXObject(true, show);
+ std::cout << "--- non-recursive, all, from fx1 ---" << std::endl;
+ fx1.forEachXObject(false, show);
+ std::cout << "--- get images, page ---" << std::endl;
+ for (auto& i: page.getImages())
+ {
+ std::cout << i.first << " -> " << i.second.unparse() << std::endl;
+ }
+ std::cout << "--- get images, fx ---" << std::endl;
+ for (auto& i: fx1.getImages())
+ {
+ std::cout << i.first << " -> " << i.second.unparse() << std::endl;
+ }
+ std::cout << "--- get form XObjects, page ---" << std::endl;
+ for (auto& i: page.getFormXObjects())
+ {
+ std::cout << i.first << " -> " << i.second.unparse() << std::endl;
+ }
+ std::cout << "--- get form XObjects, fx ---" << std::endl;
+ for (auto& i: fx1.getFormXObjects())
+ {
+ std::cout << i.first << " -> " << i.second.unparse() << std::endl;
+ }
+ }
else
{
throw std::runtime_error(std::string("invalid test ") +