aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDFWriter.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2018-06-22 21:22:29 +0200
committerJay Berkenbilt <ejb@ql.org>2018-06-22 22:14:54 +0200
commita433ed24f978d6e0ae1b87e997dcb511b001b12e (patch)
tree589cedfb96e86f0ca1240daaccc791fce42c55bb /libqpdf/QPDFWriter.cc
parent2a82f6e1e05b5791c264efd8f70a20aeadca7501 (diff)
downloadqpdf-a433ed24f978d6e0ae1b87e997dcb511b001b12e.tar.zst
Add progress reporting for QPDFWriter (fixes #200)
Diffstat (limited to 'libqpdf/QPDFWriter.cc')
-rw-r--r--libqpdf/QPDFWriter.cc60
1 files changed, 59 insertions, 1 deletions
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 3dcff164..447b6627 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -62,7 +62,10 @@ QPDFWriter::Members::Members(QPDF& pdf) :
added_newline(false),
max_ostream_index(0),
deterministic_id(false),
- md5_pipeline(0)
+ md5_pipeline(0),
+ events_expected(0),
+ events_seen(0),
+ next_progress_report(0)
{
}
@@ -1856,6 +1859,10 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
if (pass == 1)
{
offsets.push_back(this->m->pipeline->getCount());
+ // To avoid double-counting objects being written in
+ // object streams for progress reporting, decrement in
+ // pass 1.
+ indicateProgress(true, false);
}
writeObject(this->m->pdf.getObjectByObjGen(obj), count);
@@ -1929,6 +1936,7 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
return;
}
+ indicateProgress(false, false);
int new_id = this->m->obj_renumber[old_og];
if (this->m->qdf_mode)
{
@@ -2253,6 +2261,7 @@ QPDFWriter::prepareFileForWrite()
{
continue;
}
+ indicateProgress(false, false);
visited.insert(node.getObjectID());
}
@@ -2500,6 +2509,15 @@ QPDFWriter::write()
setMinimumPDFVersion("1.5");
}
+ // Set up progress reporting. We spent about equal amounts of time
+ // preparing and writing one pass. To get a rough estimate of
+ // progress, we track handling of indirect objects. For linearized
+ // files, we write two passes. events_expected is an
+ // approximation, but it's good enough for progress reporting,
+ // which is mostly a guess anyway.
+ this->m->events_expected = (
+ this->m->pdf.getObjectCount() * (this->m->linearized ? 3 : 2));
+
prepareFileForWrite();
if (this->m->linearized)
@@ -2522,6 +2540,7 @@ QPDFWriter::write()
this->m->output_buffer = this->m->buffer_pipeline->getBuffer();
this->m->buffer_pipeline = 0;
}
+ indicateProgress(false, true);
}
void
@@ -3312,6 +3331,45 @@ QPDFWriter::enqueueObjectsPCLm()
}
void
+QPDFWriter::indicateProgress(bool decrement, bool finished)
+{
+ if (decrement)
+ {
+ --this->m->events_seen;
+ return;
+ }
+
+ ++this->m->events_seen;
+
+ if (! this->m->progress_reporter.getPointer())
+ {
+ return;
+ }
+
+ if (finished || (this->m->events_seen >= this->m->next_progress_report))
+ {
+ int percentage = (
+ finished
+ ? 100
+ : this->m->next_progress_report == 0
+ ? 0
+ : std::min(99, 1 + ((100 * this->m->events_seen) /
+ this->m->events_expected)));
+ this->m->progress_reporter->reportProgress(percentage);
+ }
+ while (this->m->events_seen >= this->m->next_progress_report)
+ {
+ this->m->next_progress_report += (this->m->events_expected / 100);
+ }
+}
+
+void
+QPDFWriter::registerProgressReporter(PointerHolder<ProgressReporter> pr)
+{
+ this->m->progress_reporter = pr;
+}
+
+void
QPDFWriter::writeStandard()
{
if (this->m->deterministic_id)