aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--TODO3
-rw-r--r--include/qpdf/qpdf-c.h13
-rw-r--r--libqpdf/qpdf-c.cc8
-rw-r--r--qpdf/qpdf-ctest.c14
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test10
-rw-r--r--qpdf/qtest/qpdf/c-empty.pdf17
8 files changed, 61 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 3bc733e0..7b40e1c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
2022-02-05 Jay Berkenbilt <ejb@ql.org>
+ * Expose QPDF::emptyPDF to the C API as qpdf_empty_pdf()
+
* Add comments letting people know that the version string
returned by QPDF::QPDFVersion and qpdf_get_qpdf_version is static.
diff --git a/TODO b/TODO
index 8166f090..9bbaecc7 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,6 @@
10.6
====
-* Expose emptyPDF to the C API. Ensure that qpdf_get_qpdf_version is
- always static.
-
* Consider doing one big commit to reformat the entire codebase using
clang-format or a similar tool. Consider using blame.ignoreRevsFile
or similar (or otherwise study git blame to see how to minimize the
diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h
index 5a0595b2..982f0c90 100644
--- a/include/qpdf/qpdf-c.h
+++ b/include/qpdf/qpdf-c.h
@@ -178,9 +178,9 @@ extern "C" {
char const* qpdf_get_qpdf_version();
/* Returns dynamically allocated qpdf_data pointer; must be freed
- * by calling qpdf_cleanup. You must call qpdf_read or one of the
- * other qpdf_read_* functions before calling any function that
- * would need to operate on the PDF file.
+ * by calling qpdf_cleanup. You must call qpdf_read, one of the
+ * other qpdf_read_* functions, or qpdf_empty_pdf before calling
+ * any function that would need to operate on the PDF file.
*/
QPDF_DLL
qpdf_data qpdf_init();
@@ -289,6 +289,13 @@ extern "C" {
unsigned long long size,
char const* password);
+ /* Calling qpdf_empty_pdf initializes this qpdf object with an
+ * empty PDF, making it possible to create a PDF from scratch
+ * using the C API. Added in 10.6.
+ */
+ QPDF_DLL
+ QPDF_ERROR_CODE qpdf_empty_pdf(qpdf_data qpdf);
+
/* Read functions below must be called after qpdf_read or
* qpdf_read_memory. */
diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc
index f03ed845..8ca8fb42 100644
--- a/libqpdf/qpdf-c.cc
+++ b/libqpdf/qpdf-c.cc
@@ -356,6 +356,14 @@ QPDF_ERROR_CODE qpdf_read_memory(qpdf_data qpdf,
return status;
}
+QPDF_ERROR_CODE qpdf_empty_pdf(qpdf_data qpdf)
+{
+ qpdf->filename = "empty PDF";
+ qpdf->qpdf->emptyPDF();
+ QTC::TC("qpdf", "qpdf-c called qpdf_empty_pdf");
+ return QPDF_SUCCESS;
+}
+
char const* qpdf_get_pdf_version(qpdf_data qpdf)
{
QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_version");
diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c
index 414c0eaa..502cede9 100644
--- a/qpdf/qpdf-ctest.c
+++ b/qpdf/qpdf-ctest.c
@@ -1242,6 +1242,19 @@ static void test40(char const* infile,
report_errors();
}
+static void test41(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* xarg)
+{
+ /* Empty PDF -- infile is ignored*/
+ assert(qpdf_empty_pdf(qpdf) == 0);
+ qpdf_init_write(qpdf, outfile);
+ qpdf_set_static_ID(qpdf, QPDF_TRUE);
+ qpdf_write(qpdf);
+ report_errors();
+}
+
int main(int argc, char* argv[])
{
char* p = 0;
@@ -1322,6 +1335,7 @@ int main(int argc, char* argv[])
(n == 38) ? test38 :
(n == 39) ? test39 :
(n == 40) ? test40 :
+ (n == 41) ? test41 :
0);
if (fn == 0)
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 1e0f336e..77ef2fc9 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -639,3 +639,4 @@ QPDFJob json encrypt no key length 0
QPDFJob json encrypt duplicate key length 0
QPDFJob json encrypt missing password 0
QPDFJob json pages no file 0
+qpdf-c called qpdf_empty_pdf 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index bf386168..b211f33f 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -3553,7 +3553,7 @@ my @capi = (
[8, 'no original object ids'],
[9, 'uncompressed streams'],
);
-$n_tests += (2 * @capi) + 3;
+$n_tests += (2 * @capi) + 5;
foreach my $d (@capi)
{
my ($n, $description) = @$d;
@@ -3590,6 +3590,14 @@ $td->runtest("write damaged",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+$td->runtest("empty PDF",
+ {$td->COMMAND => "qpdf-ctest 41 - '' a.pdf"},
+ {$td->STRING => "C test 41 done\n", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "c-empty.pdf"});
+
show_ntests();
# ----------
$td->notify("--- Deterministic ID Tests ---");
diff --git a/qpdf/qtest/qpdf/c-empty.pdf b/qpdf/qtest/qpdf/c-empty.pdf
new file mode 100644
index 00000000..a60e8169
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-empty.pdf
@@ -0,0 +1,17 @@
+%PDF-1.3
+%¿÷¢þ
+1 0 obj
+<< /Pages 2 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /Count 0 /Kids [ ] /Type /Pages >>
+endobj
+xref
+0 3
+0000000000 65535 f
+0000000015 00000 n
+0000000064 00000 n
+trailer << /Root 1 0 R /Size 3 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] >>
+startxref
+117
+%%EOF