aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--include/qpdf/QPDF.hh7
-rw-r--r--include/qpdf/QPDFWriter.hh9
-rw-r--r--libqpdf/QPDF.cc18
-rw-r--r--libqpdf/QPDFWriter.cc7
-rw-r--r--qpdf/qtest/qpdf.test9
-rw-r--r--qpdf/qtest/qpdf/custom-pipeline.pdfbin0 -> 799 bytes
-rw-r--r--qpdf/test_driver.cc14
8 files changed, 64 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index fd15bda1..f023b09b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-09-23 Jay Berkenbilt <ejb@ql.org>
+
+ * Add public methods QPDF::processInputSource and
+ QPDFWriter::setOutputPipeline to allow users to read from custom
+ input sources and to write to custom pipelines. This allows the
+ maximum flexibility in sources for reading and writing PDF files.
+
2012-09-06 Jay Berkenbilt <ejb@ql.org>
* 3.0.2: release
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index e594a44a..64858625 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -72,6 +72,13 @@ class QPDF
char const* buf, size_t length,
char const* password = 0);
+ // Parse a PDF file loaded from a custom InputSource. If you have
+ // your own method of retrieving a PDF file, you can subclass
+ // InputSource and use this method.
+ QPDF_DLL
+ void processInputSource(PointerHolder<InputSource>,
+ char const* password = 0);
+
// Create a QPDF object for an empty PDF. This PDF has no pages
// or objects other than a minimal trailer, a document catalog,
// and a /Pages tree containing zero pages. Pages and other
diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh
index 2c1c32f6..725b2be8 100644
--- a/include/qpdf/QPDFWriter.hh
+++ b/include/qpdf/QPDFWriter.hh
@@ -95,6 +95,15 @@ class QPDFWriter
QPDF_DLL
Buffer* getBuffer();
+ // Supply your own pipeline object. Output will be written to
+ // this pipeline, and QPDFWriter will call finish() on the
+ // pipeline. It is the caller's responsibility to manage the
+ // memory for the pipeline. The pipeline is never deleted by
+ // QPDFWriter, which makes it possible for you to call additional
+ // methods on the pipeline after the writing is finished.
+ QPDF_DLL
+ void setOutputPipeline(Pipeline*);
+
// Setting Parameters
// Set the value of object stream mode. In disable mode, we never
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 472e0c13..678f773e 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -138,9 +138,8 @@ void
QPDF::processFile(char const* filename, char const* password)
{
FileInputSource* fi = new FileInputSource();
- this->file = fi;
fi->setFilename(filename);
- parse(password);
+ processInputSource(fi, password);
}
void
@@ -148,9 +147,8 @@ QPDF::processFile(char const* description, FILE* filep,
bool close_file, char const* password)
{
FileInputSource* fi = new FileInputSource();
- this->file = fi;
fi->setFile(description, filep, close_file);
- parse(password);
+ processInputSource(fi, password);
}
void
@@ -158,10 +156,18 @@ QPDF::processMemoryFile(char const* description,
char const* buf, size_t length,
char const* password)
{
- this->file =
+ processInputSource(
new BufferInputSource(description,
new Buffer((unsigned char*)buf, length),
- true);
+ true),
+ password);
+}
+
+void
+QPDF::processInputSource(PointerHolder<InputSource> source,
+ char const* password)
+{
+ this->file = source;
parse(password);
}
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index eb08488a..c1e4e1dd 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -135,6 +135,13 @@ QPDFWriter::getBuffer()
}
void
+QPDFWriter::setOutputPipeline(Pipeline* p)
+{
+ this->filename = "custom pipeline";
+ initializePipelineStack(p);
+}
+
+void
QPDFWriter::setObjectStreamMode(qpdf_object_stream_e mode)
{
this->object_stream_mode = mode;
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index d12f0644..e510eded 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -149,7 +149,7 @@ $td->runtest("remove page we don't have",
$td->NORMALIZE_NEWLINES);
# ----------
$td->notify("--- Miscellaneous Tests ---");
-$n_tests += 53;
+$n_tests += 55;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@@ -403,6 +403,13 @@ $td->runtest("check output",
$td->runtest("check output",
{$td->FILE => "d.pdf"},
{$td->FILE => "extra-header-lin-newline.pdf"});
+$td->runtest("output to custom pipeline",
+ {$td->COMMAND => "test_driver 33 minimal.pdf"},
+ {$td->STRING => "test 33 done\n", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "custom-pipeline.pdf"});
show_ntests();
# ----------
diff --git a/qpdf/qtest/qpdf/custom-pipeline.pdf b/qpdf/qtest/qpdf/custom-pipeline.pdf
new file mode 100644
index 00000000..b8c692ed
--- /dev/null
+++ b/qpdf/qtest/qpdf/custom-pipeline.pdf
Binary files differ
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 311097f6..2c729987 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -1112,6 +1112,20 @@ void runtest(int n, char const* filename1, char const* filename2)
w.write();
}
}
+ else if (n == 33)
+ {
+ // Test writing to a custom pipeline
+ Pl_Buffer p("buffer");
+ QPDFWriter w(pdf);
+ w.setStaticID(true);
+ w.setOutputPipeline(&p);
+ w.write();
+ PointerHolder<Buffer> b = p.getBuffer();
+ FILE* f = QUtil::fopen_wrapper("open a.pdf",
+ fopen("a.pdf", "wb"));
+ fwrite(b->getBuffer(), b->getSize(), 1, f);
+ fclose(f);
+ }
else
{
throw std::runtime_error(std::string("invalid test ") +