aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2012-09-06 21:30:13 +0200
committerJay Berkenbilt <ejb@ql.org>2012-09-06 21:31:12 +0200
commitc1627d04385a02045e7a1a5462f2a632fc529a2e (patch)
tree5d0943df09ae6548932c12654a42d66095ee3b1f
parentfc4c82a9501d13a398682c308fc24c4427cfd77e (diff)
downloadqpdf-c1627d04385a02045e7a1a5462f2a632fc529a2e.tar.zst
Add QPDFWriter::setExtraHeaderText
-rw-r--r--ChangeLog6
-rw-r--r--include/qpdf/QPDFWriter.hh13
-rw-r--r--libqpdf/QPDFWriter.cc31
-rw-r--r--qpdf/qpdf.testcov2
-rw-r--r--qpdf/qtest/qpdf.test18
-rw-r--r--qpdf/qtest/qpdf/extra-header-lin-newline.pdfbin0 -> 1334 bytes
-rw-r--r--qpdf/qtest/qpdf/extra-header-lin-no-newline.pdfbin0 -> 1334 bytes
-rw-r--r--qpdf/qtest/qpdf/extra-header-newline.pdfbin0 -> 823 bytes
-rw-r--r--qpdf/qtest/qpdf/extra-header-no-newline.pdfbin0 -> 823 bytes
-rw-r--r--qpdf/qtest/qpdf/test-32.out13
-rw-r--r--qpdf/test_driver.cc21
11 files changed, 102 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index ad86b396..ce6018dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2012-09-06 Jay Berkenbilt <ejb@ql.org>
+ * Add new method QPDFWriter::setExtraHeaderText to add extra text,
+ such as application-specific comments, to near the beginning of a
+ PDF file. For linearized files, this appears after the
+ linearization parameter dictionary. For non-linearized files, it
+ appears right after the PDF header and non-ASCII comment.
+
* Make it possible to write the same QPDF object with two
different QPDFWriter objects that have both called
setLinearization(true) by making private method
diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh
index 5ee90262..2c1c32f6 100644
--- a/include/qpdf/QPDFWriter.hh
+++ b/include/qpdf/QPDFWriter.hh
@@ -163,6 +163,18 @@ class QPDFWriter
QPDF_DLL
void forcePDFVersion(std::string const&);
+ // Provide additional text to insert in the PDF file somewhere
+ // near the beginning of the file. This can be used to add
+ // comments to the beginning of a PDF file, for example, if those
+ // comments are to be consumed by some other application. No
+ // checks are performed to ensure that the text inserted here is
+ // valid PDF. If you want to insert multiline comments, you will
+ // need to include \n in the string yourself and start each line
+ // with %. An extra newline will be appended if one is not
+ // already present at the end of your text.
+ QPDF_DLL
+ void setExtraHeaderText(std::string const&);
+
// Cause a static /ID value to be generated. Use only in test
// suites.
QPDF_DLL
@@ -354,6 +366,7 @@ class QPDFWriter
std::string id2; // trailer dictionary
std::string min_pdf_version;
std::string forced_pdf_version;
+ std::string extra_header_text;
int encryption_dict_objid;
std::string cur_data_key;
std::list<PointerHolder<Pipeline> > to_delete;
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 19ab1359..eb08488a 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -196,6 +196,22 @@ QPDFWriter::forcePDFVersion(std::string const& version)
}
void
+QPDFWriter::setExtraHeaderText(std::string const& text)
+{
+ this->extra_header_text = text;
+ if ((this->extra_header_text.length() > 0) &&
+ (*(this->extra_header_text.rbegin()) != '\n'))
+ {
+ QTC::TC("qpdf", "QPDFWriter extra header text add newline");
+ this->extra_header_text += "\n";
+ }
+ else
+ {
+ QTC::TC("qpdf", "QPDFWriter extra header text no newline");
+ }
+}
+
+void
QPDFWriter::setStaticID(bool val)
{
this->static_id = val;
@@ -1832,6 +1848,12 @@ QPDFWriter::writeHeader()
// it really should be treated as binary.
writeString("\n%\xbf\xf7\xa2\xfe\n");
writeStringQDF("%QDF-1.0\n\n");
+
+ // Note: do not write extra header text here. Linearized PDFs
+ // must include the entire linearization parameter dictionary
+ // within the first 1024 characters of the PDF file, so for
+ // linearized files, we have to write extra header text after the
+ // linearization parameter dictionary.
}
void
@@ -2189,7 +2211,9 @@ QPDFWriter::writeLinearized()
// space to write real dictionary. 200 characters is enough
// space if all numerical values in the parameter dictionary
// that contain offsets are 20 digits long plus a few extra
- // characters for safety.
+ // characters for safety. The entire linearization parameter
+ // dictionary must appear within the first 1024 characters of
+ // the file.
qpdf_offset_t pos = this->pipeline->getCount();
openObject(lindict_id);
@@ -2225,6 +2249,10 @@ QPDFWriter::writeLinearized()
writePad(spaces);
writeString("\n");
+ // If the user supplied any additional header text, write it
+ // here after the linearization parameter dictionary.
+ writeString(this->extra_header_text);
+
// Part 3: first page cross reference table and trailer.
qpdf_offset_t first_xref_offset = this->pipeline->getCount();
@@ -2396,6 +2424,7 @@ QPDFWriter::writeStandard()
// Start writing
writeHeader();
+ writeString(this->extra_header_text);
// Put root first on queue.
QPDFObjectHandle trailer = pdf.getTrailer();
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 0e062af4..f9663375 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -240,3 +240,5 @@ QPDFObjectHandle trailing data in parse 0
qpdf pages encryption password 0
QPDF_Tokenizer EOF reading token 0
QPDF_Tokenizer EOF reading appendable token 0
+QPDFWriter extra header text no newline 0
+QPDFWriter extra header text add newline 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index b2ee28eb..d12f0644 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 += 48;
+$n_tests += 53;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@@ -387,6 +387,22 @@ $td->runtest("EOF reading token",
{$td->COMMAND => "qpdf --check eof-reading-token.pdf"},
{$td->FILE => "eof-reading-token.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+$td->runtest("extra header text",
+ {$td->COMMAND => "test_driver 32 minimal.pdf"},
+ {$td->FILE => "test-32.out", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "extra-header-no-newline.pdf"});
+$td->runtest("check output",
+ {$td->FILE => "b.pdf"},
+ {$td->FILE => "extra-header-lin-no-newline.pdf"});
+$td->runtest("check output",
+ {$td->FILE => "c.pdf"},
+ {$td->FILE => "extra-header-newline.pdf"});
+$td->runtest("check output",
+ {$td->FILE => "d.pdf"},
+ {$td->FILE => "extra-header-lin-newline.pdf"});
show_ntests();
# ----------
diff --git a/qpdf/qtest/qpdf/extra-header-lin-newline.pdf b/qpdf/qtest/qpdf/extra-header-lin-newline.pdf
new file mode 100644
index 00000000..7a5ff3e6
--- /dev/null
+++ b/qpdf/qtest/qpdf/extra-header-lin-newline.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/extra-header-lin-no-newline.pdf b/qpdf/qtest/qpdf/extra-header-lin-no-newline.pdf
new file mode 100644
index 00000000..e115c462
--- /dev/null
+++ b/qpdf/qtest/qpdf/extra-header-lin-no-newline.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/extra-header-newline.pdf b/qpdf/qtest/qpdf/extra-header-newline.pdf
new file mode 100644
index 00000000..427623a7
--- /dev/null
+++ b/qpdf/qtest/qpdf/extra-header-newline.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/extra-header-no-newline.pdf b/qpdf/qtest/qpdf/extra-header-no-newline.pdf
new file mode 100644
index 00000000..1df11d30
--- /dev/null
+++ b/qpdf/qtest/qpdf/extra-header-no-newline.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/test-32.out b/qpdf/qtest/qpdf/test-32.out
new file mode 100644
index 00000000..ff8d922b
--- /dev/null
+++ b/qpdf/qtest/qpdf/test-32.out
@@ -0,0 +1,13 @@
+file: a.pdf
+linearized: no
+newline: no
+file: b.pdf
+linearized: yes
+newline: no
+file: c.pdf
+linearized: no
+newline: yes
+file: d.pdf
+linearized: yes
+newline: yes
+test 32 done
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index b277cdf1..311097f6 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -1091,6 +1091,27 @@ void runtest(int n, char const* filename1, char const* filename2)
<< std::endl;
}
}
+ else if (n == 32)
+ {
+ // Extra header text
+ char const* filenames[] = {"a.pdf", "b.pdf", "c.pdf", "d.pdf"};
+ for (int i = 0; i < 4; ++i)
+ {
+ bool linearized = ((i & 1) != 0);
+ bool newline = ((i & 2) != 0);
+ QPDFWriter w(pdf, filenames[i]);
+ w.setStaticID(true);
+ std::cout
+ << "file: " << filenames[i] << std::endl
+ << "linearized: " << (linearized ? "yes" : "no") << std::endl
+ << "newline: " << (newline ? "yes" : "no") << std::endl;
+ w.setLinearization(linearized);
+ w.setExtraHeaderText(newline
+ ? "%% Comment with newline\n"
+ : "%% Comment\n% No newline");
+ w.write();
+ }
+ }
else
{
throw std::runtime_error(std::string("invalid test ") +