Commit 306e809332f328117563e3446fd6d240e2adc112
1 parent
e7a1009d
Refactor linearization data: encapsulate `first_xref_item_offset` and `uncompres…
…sed_after_compressed` in `QPDF::Doc::Objects`, update usage in `QPDF_linearization`, and streamline related logic.
Showing
3 changed files
with
24 additions
and
11 deletions
libqpdf/QPDF_linearization.cc
| ... | ... | @@ -713,10 +713,10 @@ Lin::checkLinearizationInternal() |
| 713 | 713 | break; |
| 714 | 714 | } |
| 715 | 715 | } |
| 716 | - if (m->file->tell() != m->first_xref_item_offset) { | |
| 716 | + if (m->file->tell() != objects.first_xref_item_offset()) { | |
| 717 | 717 | linearizationWarning( |
| 718 | 718 | "space before first xref item (/T) mismatch (computed = " + |
| 719 | - std::to_string(m->first_xref_item_offset) + | |
| 719 | + std::to_string(objects.first_xref_item_offset()) + | |
| 720 | 720 | "; file = " + std::to_string(m->file->tell())); |
| 721 | 721 | } |
| 722 | 722 | |
| ... | ... | @@ -727,7 +727,7 @@ Lin::checkLinearizationInternal() |
| 727 | 727 | // compressed objects are supposed to be at the end of the containing xref section if any object |
| 728 | 728 | // streams are in use. |
| 729 | 729 | |
| 730 | - if (m->uncompressed_after_compressed) { | |
| 730 | + if (objects.uncompressed_after_compressed()) { | |
| 731 | 731 | linearizationWarning( |
| 732 | 732 | "linearized file contains an uncompressed object after a compressed " |
| 733 | 733 | "one in a cross-reference stream"); | ... | ... |
libqpdf/QPDF_objects.cc
| ... | ... | @@ -694,7 +694,7 @@ Objects::read_xrefTable(qpdf_offset_t xref_offset) |
| 694 | 694 | for (qpdf_offset_t i = obj; i - num < obj; ++i) { |
| 695 | 695 | if (i == 0) { |
| 696 | 696 | // This is needed by checkLinearization() |
| 697 | - m->first_xref_item_offset = m->file->tell(); | |
| 697 | + first_xref_item_offset_ = m->file->tell(); | |
| 698 | 698 | } |
| 699 | 699 | // For xref_table, these will always be small enough to be ints |
| 700 | 700 | qpdf_offset_t f1 = 0; |
| ... | ... | @@ -956,14 +956,14 @@ Objects::processXRefStream( |
| 956 | 956 | // object record, in which case the generation number appears as the third field. |
| 957 | 957 | if (saw_first_compressed_object) { |
| 958 | 958 | if (fields[0] != 2) { |
| 959 | - m->uncompressed_after_compressed = true; | |
| 959 | + uncompressed_after_compressed_ = true; | |
| 960 | 960 | } |
| 961 | 961 | } else if (fields[0] == 2) { |
| 962 | 962 | saw_first_compressed_object = true; |
| 963 | 963 | } |
| 964 | 964 | if (obj == 0) { |
| 965 | 965 | // This is needed by checkLinearization() |
| 966 | - m->first_xref_item_offset = xref_offset; | |
| 966 | + first_xref_item_offset_ = xref_offset; | |
| 967 | 967 | } else if (fields[0] == 0) { |
| 968 | 968 | // Ignore fields[2], which we don't care about in this case. This works around the |
| 969 | 969 | // issue of some PDF files that put invalid values, like -1, here for deleted | ... | ... |
libqpdf/qpdf/QPDF_private.hh
| ... | ... | @@ -323,6 +323,7 @@ class QPDF::Doc |
| 323 | 323 | |
| 324 | 324 | qpdf::Doc::Config& cf; |
| 325 | 325 | QPDF::Doc::Pages& pages; |
| 326 | + QPDF::Doc::Objects& objects; | |
| 326 | 327 | }; |
| 327 | 328 | |
| 328 | 329 | Doc() = delete; |
| ... | ... | @@ -957,6 +958,17 @@ class QPDF::Doc::Objects: Common |
| 957 | 958 | return streams_; |
| 958 | 959 | } |
| 959 | 960 | |
| 961 | + // actual value from file | |
| 962 | + qpdf_offset_t | |
| 963 | + first_xref_item_offset() const | |
| 964 | + { | |
| 965 | + return first_xref_item_offset_; | |
| 966 | + } | |
| 967 | + bool | |
| 968 | + uncompressed_after_compressed() const | |
| 969 | + { | |
| 970 | + return uncompressed_after_compressed_; | |
| 971 | + } | |
| 960 | 972 | void parse(char const* password); |
| 961 | 973 | std::shared_ptr<QPDFObject> const& resolve(QPDFObjGen og); |
| 962 | 974 | void inParse(bool); |
| ... | ... | @@ -1028,6 +1040,10 @@ class QPDF::Doc::Objects: Common |
| 1028 | 1040 | |
| 1029 | 1041 | Foreign foreign_; |
| 1030 | 1042 | Streams streams_; |
| 1043 | + | |
| 1044 | + // Linearization data | |
| 1045 | + qpdf_offset_t first_xref_item_offset_{0}; // actual value from file | |
| 1046 | + bool uncompressed_after_compressed_{false}; | |
| 1031 | 1047 | }; // class QPDF::Doc::Objects |
| 1032 | 1048 | |
| 1033 | 1049 | // This class is used to represent a PDF Pages tree. |
| ... | ... | @@ -1172,10 +1188,6 @@ class QPDF::Members: Doc |
| 1172 | 1188 | bool in_parse{false}; |
| 1173 | 1189 | bool parsed{false}; |
| 1174 | 1190 | std::set<int> resolved_object_streams; |
| 1175 | - | |
| 1176 | - // Linearization data | |
| 1177 | - qpdf_offset_t first_xref_item_offset{0}; // actual value from file | |
| 1178 | - bool uncompressed_after_compressed{false}; | |
| 1179 | 1191 | }; |
| 1180 | 1192 | |
| 1181 | 1193 | // The Resolver class is restricted to QPDFObject and BaseHandle so that only it can resolve |
| ... | ... | @@ -1197,7 +1209,8 @@ inline QPDF::Doc::Common::Common(QPDF& qpdf, QPDF::Members* m) : |
| 1197 | 1209 | qpdf(qpdf), |
| 1198 | 1210 | m(m), |
| 1199 | 1211 | cf(m->cf), |
| 1200 | - pages(m->pages) | |
| 1212 | + pages(m->pages), | |
| 1213 | + objects(m->objects) | |
| 1201 | 1214 | { |
| 1202 | 1215 | } |
| 1203 | 1216 | ... | ... |