Commit f91b21c7d4e99d32be8e0a180821af17c8150140
1 parent
cfd5147d
Preserve input PDF version on pages/split-pages (fixes #610)
Showing
71 changed files
with
63 additions
and
30 deletions
ChangeLog
| 1 | 2022-02-08 Jay Berkenbilt <ejb@ql.org> | 1 | 2022-02-08 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | ||
| 3 | + * Bug fix: when splitting pages with --split-pages or selecting | ||
| 4 | + pages with --pages, set the output PDF version to the maximum of | ||
| 5 | + all the input PDF versions. This is a fix to QPDFJob. If you are | ||
| 6 | + creating output PDF files yourself from multiple inputs, you will | ||
| 7 | + need to code the same thing. The new PDFVersion object, its | ||
| 8 | + updateIfGreater() method, and the new QPDF and QPDFWriter methods | ||
| 9 | + described below make this very easy to do. Fixes #610. | ||
| 10 | + | ||
| 3 | * Add new class PDFVersion for more convenient comparison of PDF | 11 | * Add new class PDFVersion for more convenient comparison of PDF |
| 4 | version numbers from the %!PDF header. | 12 | version numbers from the %!PDF header. |
| 5 | 13 | ||
| 6 | * Add QPDF::getVersionAsPDFVersion() to return the PDF version and | 14 | * Add QPDF::getVersionAsPDFVersion() to return the PDF version and |
| 7 | extension together as a PDFVersion object instead of a string. | 15 | extension together as a PDFVersion object instead of a string. |
| 8 | 16 | ||
| 17 | + * Add a QPDFWriter::setMinimumPDFVersion() that takes a PDFVersion | ||
| 18 | + object. | ||
| 19 | + | ||
| 9 | 2022-02-06 Jay Berkenbilt <ejb@ql.org> | 20 | 2022-02-06 Jay Berkenbilt <ejb@ql.org> |
| 10 | 21 | ||
| 11 | * Pl_Buffer and QPDFWriter: add getBufferSharedPointer(), which | 22 | * Pl_Buffer and QPDFWriter: add getBufferSharedPointer(), which |
TODO
include/qpdf/QPDFJob.hh
| @@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
| 26 | #include <qpdf/Constants.h> | 26 | #include <qpdf/Constants.h> |
| 27 | #include <qpdf/QPDF.hh> | 27 | #include <qpdf/QPDF.hh> |
| 28 | #include <qpdf/QPDFPageObjectHelper.hh> | 28 | #include <qpdf/QPDFPageObjectHelper.hh> |
| 29 | +#include <qpdf/PDFVersion.hh> | ||
| 29 | 30 | ||
| 30 | #include <memory> | 31 | #include <memory> |
| 31 | #include <string> | 32 | #include <string> |
| @@ -587,6 +588,7 @@ class QPDFJob | @@ -587,6 +588,7 @@ class QPDFJob | ||
| 587 | int flatten_annotations_required; | 588 | int flatten_annotations_required; |
| 588 | int flatten_annotations_forbidden; | 589 | int flatten_annotations_forbidden; |
| 589 | bool generate_appearances; | 590 | bool generate_appearances; |
| 591 | + PDFVersion max_input_version; | ||
| 590 | std::string min_version; | 592 | std::string min_version; |
| 591 | std::string force_version; | 593 | std::string force_version; |
| 592 | bool show_npages; | 594 | bool show_npages; |
include/qpdf/QPDFWriter.hh
| @@ -42,11 +42,11 @@ | @@ -42,11 +42,11 @@ | ||
| 42 | #include <qpdf/QPDFObjectHandle.hh> | 42 | #include <qpdf/QPDFObjectHandle.hh> |
| 43 | #include <qpdf/QPDFObjGen.hh> | 43 | #include <qpdf/QPDFObjGen.hh> |
| 44 | #include <qpdf/QPDFXRefEntry.hh> | 44 | #include <qpdf/QPDFXRefEntry.hh> |
| 45 | - | ||
| 46 | #include <qpdf/Pl_Buffer.hh> | 45 | #include <qpdf/Pl_Buffer.hh> |
| 47 | #include <qpdf/PointerHolder.hh> | 46 | #include <qpdf/PointerHolder.hh> |
| 48 | #include <qpdf/Pipeline.hh> | 47 | #include <qpdf/Pipeline.hh> |
| 49 | #include <qpdf/Buffer.hh> | 48 | #include <qpdf/Buffer.hh> |
| 49 | +#include <qpdf/PDFVersion.hh> | ||
| 50 | 50 | ||
| 51 | class QPDF; | 51 | class QPDF; |
| 52 | class Pl_Count; | 52 | class Pl_Count; |
| @@ -265,6 +265,8 @@ class QPDFWriter | @@ -265,6 +265,8 @@ class QPDFWriter | ||
| 265 | // streams are used. | 265 | // streams are used. |
| 266 | QPDF_DLL | 266 | QPDF_DLL |
| 267 | void setMinimumPDFVersion(std::string const&, int extension_level = 0); | 267 | void setMinimumPDFVersion(std::string const&, int extension_level = 0); |
| 268 | + QPDF_DLL | ||
| 269 | + void setMinimumPDFVersion(PDFVersion const&); | ||
| 268 | 270 | ||
| 269 | // Force the PDF version of the output file to be a given version. | 271 | // Force the PDF version of the output file to be a given version. |
| 270 | // Use of this function may create PDF files that will not work | 272 | // Use of this function may create PDF files that will not work |
libqpdf/QPDFJob.cc
| @@ -2047,6 +2047,7 @@ QPDFJob::doProcessOnce( | @@ -2047,6 +2047,7 @@ QPDFJob::doProcessOnce( | ||
| 2047 | { | 2047 | { |
| 2048 | fn(pdf.get(), password); | 2048 | fn(pdf.get(), password); |
| 2049 | } | 2049 | } |
| 2050 | + this->m->max_input_version.updateIfGreater(pdf->getVersionAsPDFVersion()); | ||
| 2050 | return pdf; | 2051 | return pdf; |
| 2051 | } | 2052 | } |
| 2052 | 2053 | ||
| @@ -3472,6 +3473,7 @@ QPDFJob::setWriterOptions(QPDF& pdf, QPDFWriter& w) | @@ -3472,6 +3473,7 @@ QPDFJob::setWriterOptions(QPDF& pdf, QPDFWriter& w) | ||
| 3472 | { | 3473 | { |
| 3473 | w.setObjectStreamMode(m->object_stream_mode); | 3474 | w.setObjectStreamMode(m->object_stream_mode); |
| 3474 | } | 3475 | } |
| 3476 | + w.setMinimumPDFVersion(this->m->max_input_version); | ||
| 3475 | if (! m->min_version.empty()) | 3477 | if (! m->min_version.empty()) |
| 3476 | { | 3478 | { |
| 3477 | std::string version; | 3479 | std::string version; |
libqpdf/QPDFWriter.cc
| @@ -297,6 +297,15 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version, | @@ -297,6 +297,15 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version, | ||
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | void | 299 | void |
| 300 | +QPDFWriter::setMinimumPDFVersion(PDFVersion const& v) | ||
| 301 | +{ | ||
| 302 | + std::string version; | ||
| 303 | + int extension_level; | ||
| 304 | + v.getVersion(version, extension_level); | ||
| 305 | + setMinimumPDFVersion(version, extension_level); | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +void | ||
| 300 | QPDFWriter::forcePDFVersion(std::string const& version, | 309 | QPDFWriter::forcePDFVersion(std::string const& version, |
| 301 | int extension_level) | 310 | int extension_level) |
| 302 | { | 311 | { |
manual/release-notes.rst
| @@ -148,6 +148,14 @@ For a detailed list of changes, please see the file | @@ -148,6 +148,14 @@ For a detailed list of changes, please see the file | ||
| 148 | embedded NUL characters. Thanks to M. Holger for the | 148 | embedded NUL characters. Thanks to M. Holger for the |
| 149 | contribution. | 149 | contribution. |
| 150 | 150 | ||
| 151 | + - New ``PDFVersion`` class for representing a PDF version number | ||
| 152 | + with the ability to compare and order PDF versions. Methods | ||
| 153 | + ``QPDF::getVersionAsPDFVersion`` and a new version of | ||
| 154 | + ``QPDFWriter::setMinimumPDFVersion`` use it. This makes it | ||
| 155 | + easier to create an output file whose PDF version is the maximum | ||
| 156 | + of the versions across all the input files that contributed to | ||
| 157 | + it. | ||
| 158 | + | ||
| 151 | - The ``JSON`` object in the qpdf library has been enhanced to | 159 | - The ``JSON`` object in the qpdf library has been enhanced to |
| 152 | include a parser and the ability to get values out of the | 160 | include a parser and the ability to get values out of the |
| 153 | ``JSON`` object. Previously it was a write-only interface. Even | 161 | ``JSON`` object. Previously it was a write-only interface. Even |
| @@ -181,6 +189,10 @@ For a detailed list of changes, please see the file | @@ -181,6 +189,10 @@ For a detailed list of changes, please see the file | ||
| 181 | - Some characters were not correctly translated from PDF doc | 189 | - Some characters were not correctly translated from PDF doc |
| 182 | encoding to Unicode. | 190 | encoding to Unicode. |
| 183 | 191 | ||
| 192 | + - When splitting or combining pages, ensure that all output files | ||
| 193 | + have a PDF version greater than or equal to the maximum version | ||
| 194 | + of all the input files. | ||
| 195 | + | ||
| 184 | 10.5.0: December 21, 2021 | 196 | 10.5.0: December 21, 2021 |
| 185 | - Packaging changes | 197 | - Packaging changes |
| 186 | 198 |
qpdf/qtest/qpdf/01_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/02_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/03_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/04_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/05_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/06_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/07_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/08_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/09_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/10_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/11_split-exp.zdf
No preview for this file type
qpdf/qtest/qpdf/direct-dr-out.pdf
qpdf/qtest/qpdf/dr-with-indirect-item-out.pdf
qpdf/qtest/qpdf/fields-pages-out.pdf
No preview for this file type
qpdf/qtest/qpdf/fields-split-1.pdf
No preview for this file type
qpdf/qtest/qpdf/fields-split-2.pdf
No preview for this file type
qpdf/qtest/qpdf/indirect-r-arg.out
| 1 | -checking indirect-r-arg.pdf | ||
| 2 | WARNING: indirect-r-arg.pdf (object 1 0, offset 76): unknown token while reading object; treating as string | 1 | WARNING: indirect-r-arg.pdf (object 1 0, offset 76): unknown token while reading object; treating as string |
| 3 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake1 | 2 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake1 |
| 4 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake2 | 3 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake2 |
| 4 | +checking indirect-r-arg.pdf | ||
| 5 | PDF Version: 1.3 | 5 | PDF Version: 1.3 |
| 6 | File is not encrypted | 6 | File is not encrypted |
| 7 | File is not linearized | 7 | File is not linearized |
qpdf/qtest/qpdf/job-json-copy-attachments.pdf
No preview for this file type
qpdf/qtest/qpdf/job-json-empty-input.pdf
No preview for this file type
qpdf/qtest/qpdf/job-json-underlay-overlay-password.pdf
No preview for this file type
qpdf/qtest/qpdf/labels-split-01-06.pdf
qpdf/qtest/qpdf/labels-split-07-11.pdf
qpdf/qtest/qpdf/merge-implicit-ranges.pdf
No preview for this file type
qpdf/qtest/qpdf/merge-multiple-labels.pdf
No preview for this file type
qpdf/qtest/qpdf/merge-three-files-1.pdf
No preview for this file type
qpdf/qtest/qpdf/merge-three-files-2.pdf
No preview for this file type
qpdf/qtest/qpdf/obj0-check.out
| 1 | -checking obj0.pdf | ||
| 2 | WARNING: obj0.pdf: file is damaged | 1 | WARNING: obj0.pdf: file is damaged |
| 3 | WARNING: obj0.pdf (object 1 0, offset 77): expected n n obj | 2 | WARNING: obj0.pdf (object 1 0, offset 77): expected n n obj |
| 4 | WARNING: obj0.pdf: Attempting to reconstruct cross-reference table | 3 | WARNING: obj0.pdf: Attempting to reconstruct cross-reference table |
| 4 | +checking obj0.pdf | ||
| 5 | PDF Version: 1.3 | 5 | PDF Version: 1.3 |
| 6 | File is not encrypted | 6 | File is not encrypted |
| 7 | File is not linearized | 7 | File is not linearized |
qpdf/qtest/qpdf/overlay-copy-annotations-p1.pdf
qpdf/qtest/qpdf/overlay-copy-annotations-p2.pdf
qpdf/qtest/qpdf/overlay-copy-annotations-p5.pdf
qpdf/qtest/qpdf/overlay-copy-annotations-p6.pdf
qpdf/qtest/qpdf/overlay-copy-annotations.pdf
qpdf/qtest/qpdf/remove-labels.pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-01.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-02.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-03.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-04.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-05.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-06.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-07.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-08.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-09.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-1
No preview for this file type
qpdf/qtest/qpdf/split-exp-1.pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-10.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-11.Pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-2
No preview for this file type
qpdf/qtest/qpdf/split-exp-3
No preview for this file type
qpdf/qtest/qpdf/split-exp-4
No preview for this file type
qpdf/qtest/qpdf/split-exp-group-01-05.pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-group-06-10.pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp-group-11-11.pdf
No preview for this file type
qpdf/qtest/qpdf/split-exp.zdf_01
qpdf/qtest/qpdf/split-exp.zdf_02
qpdf/qtest/qpdf/split-exp.zdf_03
qpdf/qtest/qpdf/split-exp.zdf_04
qpdf/qtest/qpdf/split-exp.zdf_05
qpdf/qtest/qpdf/split-exp.zdf_06
qpdf/qtest/qpdf/split-exp.zdf_07
qpdf/qtest/qpdf/split-exp.zdf_08
qpdf/qtest/qpdf/split-exp.zdf_09
qpdf/qtest/qpdf/split-exp.zdf_10
qpdf/qtest/qpdf/split-exp.zdf_11