From eaacf94005ff8189e215447ffeadc341eca6c019 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Mon, 11 Sep 2017 20:11:10 -0400 Subject: [PATCH] Update C API with new QPDFWriter methods --- ChangeLog | 9 +++++++++ TODO | 2 -- include/qpdf/qpdf-c.h | 15 ++++++++++++++ libqpdf/qpdf-c.cc | 24 ++++++++++++++++++++++ qpdf/qpdf-ctest.c | 47 +++++++++++++++++++++++++++++++++++++++++++ qpdf/qpdf.testcov | 4 ++++ qpdf/qtest/qpdf.test | 34 ++++++++++++++++++++++++++++--- 7 files changed, 130 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d4f18e1..530ad51c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2017-09-12 Jay Berkenbilt + + * Add new methods to the C API to correspond to new additions to + QPDFWriter: + - qpdf_set_compress_streams + - qpdf_set_decode_level + - qpdf_set_preserve_unreferenced_objects + - qpdf_set_newline_before_endstream + 2017-08-25 Jay Berkenbilt * Re-implement parser iteratively to avoid stack overflow on very diff --git a/TODO b/TODO index 7e9f6854..f928b6de 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,6 @@ Before final 7.0.0 ================== - * Update C API - * Create release notes * See if the error message that gets generated when retrying a stream diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index 349d238f..5510fb84 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -318,6 +318,21 @@ extern "C" { void qpdf_set_stream_data_mode(qpdf_data qpdf, enum qpdf_stream_data_e mode); + QPDF_DLL + void qpdf_set_compress_streams(qpdf_data qpdf, QPDF_BOOL value); + + + QPDF_DLL + void qpdf_set_decode_level(qpdf_data qpdf, + enum qpdf_stream_decode_level_e level); + + QPDF_DLL + void qpdf_set_preserve_unreferenced_objects( + qpdf_data qpdf, QPDF_BOOL value); + + QPDF_DLL + void qpdf_set_newline_before_endstream(qpdf_data qpdf, QPDF_BOOL value); + QPDF_DLL void qpdf_set_content_normalization(qpdf_data qpdf, QPDF_BOOL value); diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index 797476c1..a9883d32 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -502,6 +502,30 @@ void qpdf_set_object_stream_mode(qpdf_data qpdf, qpdf_object_stream_e mode) qpdf->qpdf_writer->setObjectStreamMode(mode); } +void qpdf_set_compress_streams(qpdf_data qpdf, QPDF_BOOL value) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_set_compress_streams"); + qpdf->qpdf_writer->setCompressStreams(value); +} + +void qpdf_set_decode_level(qpdf_data qpdf, qpdf_stream_decode_level_e level) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_set_decode_level"); + qpdf->qpdf_writer->setDecodeLevel(level); +} + +void qpdf_set_preserve_unreferenced_objects(qpdf_data qpdf, QPDF_BOOL value) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_set_preserve_unreferenced_objects"); + qpdf->qpdf_writer->setPreserveUnreferencedObjects(value); +} + +void qpdf_set_newline_before_endstream(qpdf_data qpdf, QPDF_BOOL value) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_set_newline_before_endstream"); + qpdf->qpdf_writer->setNewlineBeforeEndstream(value); +} + void qpdf_set_stream_data_mode(qpdf_data qpdf, qpdf_stream_data_e mode) { QTC::TC("qpdf", "qpdf-c called qpdf_set_stream_data_mode"); diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c index 8bda76cc..f7bfb5c4 100644 --- a/qpdf/qpdf-ctest.c +++ b/qpdf/qpdf-ctest.c @@ -440,6 +440,50 @@ static void test19(char const* infile, report_errors(); } +static void test20(char const* infile, + char const* password, + char const* outfile, + char const* outfile2) +{ + qpdf_read(qpdf, infile, password); + qpdf_init_write(qpdf, outfile); + qpdf_set_static_ID(qpdf, QPDF_TRUE); + qpdf_set_static_aes_IV(qpdf, QPDF_TRUE); + qpdf_set_compress_streams(qpdf, QPDF_FALSE); + qpdf_set_decode_level(qpdf, qpdf_dl_specialized); + qpdf_write(qpdf); + report_errors(); +} + +static void test21(char const* infile, + char const* password, + char const* outfile, + char const* outfile2) +{ + qpdf_read(qpdf, infile, password); + qpdf_init_write(qpdf, outfile); + qpdf_set_static_ID(qpdf, QPDF_TRUE); + qpdf_set_static_aes_IV(qpdf, QPDF_TRUE); + qpdf_set_preserve_unreferenced_objects(qpdf, QPDF_TRUE); + qpdf_write(qpdf); + report_errors(); +} + +static void test22(char const* infile, + char const* password, + char const* outfile, + char const* outfile2) +{ + qpdf_read(qpdf, infile, password); + qpdf_init_write(qpdf, outfile); + qpdf_set_static_ID(qpdf, QPDF_TRUE); + qpdf_set_static_aes_IV(qpdf, QPDF_TRUE); + qpdf_set_compress_streams(qpdf, QPDF_FALSE); + qpdf_set_newline_before_endstream(qpdf, QPDF_TRUE); + qpdf_write(qpdf); + report_errors(); +} + int main(int argc, char* argv[]) { char* p = 0; @@ -499,6 +543,9 @@ int main(int argc, char* argv[]) (n == 17) ? test17 : (n == 18) ? test18 : (n == 19) ? test19 : + (n == 20) ? test20 : + (n == 21) ? test21 : + (n == 22) ? test22 : 0); if (fn == 0) diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 4bc1ad0a..a36d9706 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -297,3 +297,7 @@ QPDFWriter ignore self-referential object stream 0 QPDFObjectHandle found old angle 1 QPDF_Stream special filters 3 QPDFTokenizer block long token 0 +qpdf-c called qpdf_set_decode_level 0 +qpdf-c called qpdf_set_compress_streams 0 +qpdf-c called qpdf_set_preserve_unreferenced_objects 0 +qpdf-c called qpdf_set_newline_before_endstream 0 diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 2fc7f63a..2a8d20e7 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -687,7 +687,7 @@ $td->runtest("short /O or /U", show_ntests(); # ---------- $td->notify("--- Newline before endstream ---"); -$n_tests += 8; +$n_tests += 10; # From issue 133, http://verapdf.org/software/ is an open source # package that can verify PDF/A compliance. This could potentially be @@ -716,6 +716,16 @@ foreach my $d ( {$td->FILE => "a.pdf", $td->EXIT_STATUS => 0}); } } + +$td->runtest("newline before endstream (C)", + {$td->COMMAND => + "qpdf-ctest 22 streams-with-newlines.pdf '' a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check output", + {$td->FILE => "a.pdf"}, + {$td->FILE => "newline-before-endstream-nl.pdf"}); + show_ntests(); # ---------- $td->notify("--- Split Pages ---"); @@ -949,7 +959,7 @@ $td->runtest("check output", show_ntests(); # ---------- $td->notify("--- Decode levels ---"); -$n_tests += 12; +$n_tests += 14; # image-streams.pdf is the output of examples/pdf-create. # examples/pdf-create validates the actual image data. @@ -967,6 +977,17 @@ foreach my $l (qw(none generalized specialized all)) $td->NORMALIZE_NEWLINES); } +# C API +$td->runtest("image-streams: C", + {$td->COMMAND => "qpdf-ctest 20 image-streams.pdf '' a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check image-streams: C", + {$td->COMMAND => "test_driver 39 a.pdf"}, + {$td->FILE => "image-streams-specialized.out", + $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); + # Bad JPEG data $td->runtest("check finds bad jpeg data", {$td->COMMAND => "qpdf --check bad-jpeg.pdf"}, @@ -990,7 +1011,7 @@ $td->runtest("get data", show_ntests(); # ---------- $td->notify("--- Preserve unreferenced objects ---"); -$n_tests += 4; +$n_tests += 6; $td->runtest("drop unused objects", {$td->COMMAND => "qpdf --static-id unreferenced-objects.pdf a.pdf"}, @@ -1005,6 +1026,13 @@ $td->runtest("keep unused objects", $td->runtest("check output", {$td->FILE => "a.pdf"}, {$td->FILE => "unreferenced-preserved.pdf"}); +$td->runtest("keep unused objects (C)", + {$td->COMMAND => + "qpdf-ctest 21 unreferenced-objects.pdf '' a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}); +$td->runtest("check output", + {$td->FILE => "a.pdf"}, + {$td->FILE => "unreferenced-preserved.pdf"}); show_ntests(); # ---------- $td->notify("--- Copy Foreign Objects ---");