Commit 98c14e7740cb879be05ce95a22a3c1f2c403bea0
1 parent
7775aec3
Refactor QPDF::checkLinearizationInternal
Showing
3 changed files
with
64 additions
and
12 deletions
include/qpdf/QPDF.hh
| ... | ... | @@ -836,6 +836,7 @@ class QPDF |
| 836 | 836 | void optimize( |
| 837 | 837 | QPDFWriter::ObjTable const& obj, |
| 838 | 838 | std::function<int(QPDFObjectHandle&)> skip_stream_parameters); |
| 839 | + void optimize(Xref_table const& obj); | |
| 839 | 840 | size_t tableSize(); |
| 840 | 841 | |
| 841 | 842 | // Get lists of all objects in order according to the part of a linearized file that they belong |
| ... | ... | @@ -935,6 +936,7 @@ class QPDF |
| 935 | 936 | QPDFObjectHandle |
| 936 | 937 | getUncompressedObject(QPDFObjectHandle&, std::map<int, int> const& object_stream_data); |
| 937 | 938 | QPDFObjectHandle getUncompressedObject(QPDFObjectHandle&, QPDFWriter::ObjTable const& obj); |
| 939 | + QPDFObjectHandle getUncompressedObject(QPDFObjectHandle&, Xref_table const& obj); | |
| 938 | 940 | int lengthNextN(int first_object, int n); |
| 939 | 941 | void |
| 940 | 942 | checkHPageOffset(std::vector<QPDFObjectHandle> const& pages, std::map<int, int>& idx_to_obj); |
| ... | ... | @@ -980,6 +982,7 @@ class QPDF |
| 980 | 982 | std::function<int(QPDFObjectHandle&)> skip_stream_parameters); |
| 981 | 983 | void filterCompressedObjects(std::map<int, int> const& object_stream_data); |
| 982 | 984 | void filterCompressedObjects(QPDFWriter::ObjTable const& object_stream_data); |
| 985 | + void filterCompressedObjects(Xref_table const& object_stream_data); | |
| 983 | 986 | |
| 984 | 987 | // JSON import |
| 985 | 988 | void importJSON(std::shared_ptr<InputSource>, bool must_be_complete); | ... | ... |
libqpdf/QPDF_linearization.cc
| ... | ... | @@ -484,18 +484,9 @@ QPDF::checkLinearizationInternal() |
| 484 | 484 | // Further checking requires optimization and order calculation. Don't allow optimization to |
| 485 | 485 | // make changes. If it has to, then the file is not properly linearized. We use the xref table |
| 486 | 486 | // to figure out which objects are compressed and which are uncompressed. |
| 487 | - { // local scope | |
| 488 | - std::map<int, int> object_stream_data; | |
| 489 | - for (auto const& iter: m->xref_table.as_map()) { | |
| 490 | - QPDFObjGen const& og = iter.first; | |
| 491 | - QPDFXRefEntry const& entry = iter.second; | |
| 492 | - if (entry.getType() == 2) { | |
| 493 | - object_stream_data[og.getObj()] = entry.getObjStreamNumber(); | |
| 494 | - } | |
| 495 | - } | |
| 496 | - optimize(object_stream_data, false); | |
| 497 | - calculateLinearizationData(object_stream_data); | |
| 498 | - } | |
| 487 | + | |
| 488 | + optimize(m->xref_table); | |
| 489 | + calculateLinearizationData(m->xref_table); | |
| 499 | 490 | |
| 500 | 491 | // E: offset of end of first page -- Implementation note 123 says Acrobat includes on extra |
| 501 | 492 | // object here by mistake. pdlin fails to place thumbnail images in section 9, so when |
| ... | ... | @@ -582,6 +573,16 @@ QPDF::getUncompressedObject(QPDFObjectHandle& obj, std::map<int, int> const& obj |
| 582 | 573 | } |
| 583 | 574 | |
| 584 | 575 | QPDFObjectHandle |
| 576 | +QPDF::getUncompressedObject(QPDFObjectHandle& obj, Xref_table const& xref) | |
| 577 | +{ | |
| 578 | + auto og = obj.getObjGen(); | |
| 579 | + if (obj.isNull() || xref.type(og) != 2) { | |
| 580 | + return obj; | |
| 581 | + } | |
| 582 | + return getObject(xref.stream_number(og.getObj()), 0); | |
| 583 | +} | |
| 584 | + | |
| 585 | +QPDFObjectHandle | |
| 585 | 586 | QPDF::getUncompressedObject(QPDFObjectHandle& oh, QPDFWriter::ObjTable const& obj) |
| 586 | 587 | { |
| 587 | 588 | if (obj.contains(oh)) { | ... | ... |
libqpdf/QPDF_optimization.cc
| ... | ... | @@ -78,6 +78,12 @@ QPDF::optimize( |
| 78 | 78 | optimize_internal(obj, true, skip_stream_parameters); |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | +void | |
| 82 | +QPDF::optimize(QPDF::Xref_table const& xref) | |
| 83 | +{ | |
| 84 | + optimize_internal(xref, false, nullptr); | |
| 85 | +} | |
| 86 | + | |
| 81 | 87 | template <typename T> |
| 82 | 88 | void |
| 83 | 89 | QPDF::optimize_internal( |
| ... | ... | @@ -442,3 +448,45 @@ QPDF::filterCompressedObjects(QPDFWriter::ObjTable const& obj) |
| 442 | 448 | m->obj_user_to_objects = t_obj_user_to_objects; |
| 443 | 449 | m->object_to_obj_users = t_object_to_obj_users; |
| 444 | 450 | } |
| 451 | + | |
| 452 | +void | |
| 453 | +QPDF::filterCompressedObjects(QPDF::Xref_table const& xref) | |
| 454 | +{ | |
| 455 | + if (!xref.object_streams()) { | |
| 456 | + return; | |
| 457 | + } | |
| 458 | + | |
| 459 | + // Transform object_to_obj_users and obj_user_to_objects so that they refer only to uncompressed | |
| 460 | + // objects. If something is a user of a compressed object, then it is really a user of the | |
| 461 | + // object stream that contains it. | |
| 462 | + | |
| 463 | + std::map<ObjUser, std::set<QPDFObjGen>> t_obj_user_to_objects; | |
| 464 | + std::map<QPDFObjGen, std::set<ObjUser>> t_object_to_obj_users; | |
| 465 | + | |
| 466 | + for (auto const& i1: m->obj_user_to_objects) { | |
| 467 | + ObjUser const& ou = i1.first; | |
| 468 | + // Loop over objects. | |
| 469 | + for (auto const& og: i1.second) { | |
| 470 | + if (auto stream = xref.stream_number(og.getObj())) { | |
| 471 | + t_obj_user_to_objects[ou].insert(QPDFObjGen(stream, 0)); | |
| 472 | + } else { | |
| 473 | + t_obj_user_to_objects[ou].insert(og); | |
| 474 | + } | |
| 475 | + } | |
| 476 | + } | |
| 477 | + | |
| 478 | + for (auto const& i1: m->object_to_obj_users) { | |
| 479 | + QPDFObjGen const& og = i1.first; | |
| 480 | + // Loop over obj_users. | |
| 481 | + for (auto const& ou: i1.second) { | |
| 482 | + if (auto stream = xref.stream_number(og.getObj())) { | |
| 483 | + t_object_to_obj_users[QPDFObjGen(stream, 0)].insert(ou); | |
| 484 | + } else { | |
| 485 | + t_object_to_obj_users[og].insert(ou); | |
| 486 | + } | |
| 487 | + } | |
| 488 | + } | |
| 489 | + | |
| 490 | + m->obj_user_to_objects = t_obj_user_to_objects; | |
| 491 | + m->object_to_obj_users = t_object_to_obj_users; | |
| 492 | +} | ... | ... |