From 573b6eb8b1801b40a4b6eb32cfd159f532876510 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 20 Dec 2020 14:43:08 -0500 Subject: [PATCH] Provide qpdf write progress reporting from C API (fixes #487) --- ChangeLog | 5 +++++ examples/pdf-linearize.c | 6 ++++++ examples/qtest/linearize.test | 3 ++- include/qpdf/qpdf-c.h | 12 ++++++++++++ libqpdf/qpdf-c.cc | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ae5dd5c3..3639e889 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2020-12-20 Jay Berkenbilt + + * Add qpdf_register_progress_reporter method to C API, + corresponding to QPDFWriter::registerProgressReporter. Fixes #487. + 2020-11-28 Jay Berkenbilt * Add new functions to the C API for manipulating diff --git a/examples/pdf-linearize.c b/examples/pdf-linearize.c index 1eb56600..adeaffb4 100644 --- a/examples/pdf-linearize.c +++ b/examples/pdf-linearize.c @@ -15,6 +15,11 @@ static void usage() exit(2); } +static void write_progress(int percent, void* data) +{ + printf("%s progress: %d%%\n", (char const*)(data), percent); +} + int main(int argc, char* argv[]) { char* infile = NULL; @@ -55,6 +60,7 @@ int main(int argc, char* argv[]) * qpdf_set_deterministic_ID. */ qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */ qpdf_set_linearization(qpdf, QPDF_TRUE); + qpdf_register_progress_reporter(qpdf, write_progress, infile); qpdf_write(qpdf); } while (qpdf_more_warnings(qpdf)) diff --git a/examples/qtest/linearize.test b/examples/qtest/linearize.test index 700cdca3..94fbcd05 100644 --- a/examples/qtest/linearize.test +++ b/examples/qtest/linearize.test @@ -15,7 +15,8 @@ my $qpdf = $ENV{'QPDF_BIN'} or die; $td->runtest("linearize", {$td->COMMAND => "pdf-linearize input.pdf '' a.pdf"}, - {$td->STRING => "", $td->EXIT_STATUS => 0}); + {$td->REGEXP => '(?s).*input\.pdf progress: \d+\%.*', + $td->EXIT_STATUS => 0}); $td->runtest("check", {$td->COMMAND => "$qpdf --check a.pdf"}, diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index 961cfa4a..5319b424 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -467,6 +467,18 @@ extern "C" { void qpdf_force_pdf_version_and_extension( qpdf_data qpdf, char const* version, int extension_level); + /* During write, your report_progress function will be called with + * a value between 0 and 100 representing the approximate write + * progress. The data object you pass to + * qpdf_register_progress_reporter will be handed back to your + * function. + */ + QPDF_DLL + void qpdf_register_progress_reporter( + qpdf_data qpdf, + void (*report_progress)(int percent, void* data), + void* data); + /* Do actual write operation. */ QPDF_DLL QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf); diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index d3ada5fd..0d37f732 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -57,6 +57,30 @@ _qpdf_data::~_qpdf_data() { } +class ProgressReporter: public QPDFWriter::ProgressReporter +{ + public: + ProgressReporter(void (*handler)(int, void*), void* data); + virtual ~ProgressReporter() = default; + virtual void reportProgress(int); + + private: + void (*handler)(int, void*); + void* data; +}; + +ProgressReporter::ProgressReporter(void (*handler)(int, void*), void* data) : + handler(handler), + data(data) +{ +} + +void +ProgressReporter::reportProgress(int progress) +{ + this->handler(progress, this->data); +} + // must set qpdf->filename and qpdf->password static void call_read(qpdf_data qpdf) { @@ -752,6 +776,15 @@ void qpdf_force_pdf_version_and_extension( qpdf->qpdf_writer->forcePDFVersion(version, extension_level); } +void qpdf_register_progress_reporter( + qpdf_data qpdf, + void (*report_progress)(int percent, void* data), + void* data) +{ + qpdf->qpdf_writer->registerProgressReporter( + new ProgressReporter(report_progress, data)); +} + QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf) { QPDF_ERROR_CODE status = QPDF_SUCCESS;