Commit aa2e0d23f0a09b2f1c37bd09d31147b6fb08fada
1 parent
97d78c75
In QPDFWriter::writeLinearized use object table obj in call to getLinearizedParts
Showing
5 changed files
with
26 additions
and
36 deletions
include/qpdf/QPDF.hh
| ... | ... | @@ -739,14 +739,14 @@ class QPDF |
| 739 | 739 | static void |
| 740 | 740 | getLinearizedParts( |
| 741 | 741 | QPDF& qpdf, |
| 742 | - std::map<int, int> const& object_stream_data, | |
| 742 | + QPDFWriter::ObjTable const& obj, | |
| 743 | 743 | std::vector<QPDFObjectHandle>& part4, |
| 744 | 744 | std::vector<QPDFObjectHandle>& part6, |
| 745 | 745 | std::vector<QPDFObjectHandle>& part7, |
| 746 | 746 | std::vector<QPDFObjectHandle>& part8, |
| 747 | 747 | std::vector<QPDFObjectHandle>& part9) |
| 748 | 748 | { |
| 749 | - qpdf.getLinearizedParts(object_stream_data, part4, part6, part7, part8, part9); | |
| 749 | + qpdf.getLinearizedParts(obj, part4, part6, part7, part8, part9); | |
| 750 | 750 | } |
| 751 | 751 | |
| 752 | 752 | static void |
| ... | ... | @@ -1117,7 +1117,7 @@ class QPDF |
| 1117 | 1117 | // Get lists of all objects in order according to the part of a linearized file that they belong |
| 1118 | 1118 | // to. |
| 1119 | 1119 | void getLinearizedParts( |
| 1120 | - std::map<int, int> const& object_stream_data, | |
| 1120 | + QPDFWriter::ObjTable const& obj, | |
| 1121 | 1121 | std::vector<QPDFObjectHandle>& part4, |
| 1122 | 1122 | std::vector<QPDFObjectHandle>& part6, |
| 1123 | 1123 | std::vector<QPDFObjectHandle>& part7, |
| ... | ... | @@ -1382,6 +1382,7 @@ class QPDF |
| 1382 | 1382 | qpdf_offset_t getLinearizationOffset(QPDFObjGen const&); |
| 1383 | 1383 | QPDFObjectHandle |
| 1384 | 1384 | getUncompressedObject(QPDFObjectHandle&, std::map<int, int> const& object_stream_data); |
| 1385 | + QPDFObjectHandle getUncompressedObject(QPDFObjectHandle&, QPDFWriter::ObjTable const& obj); | |
| 1385 | 1386 | int lengthNextN(int first_object, int n); |
| 1386 | 1387 | void |
| 1387 | 1388 | checkHPageOffset(std::vector<QPDFObjectHandle> const& pages, std::map<int, int>& idx_to_obj); |
| ... | ... | @@ -1392,11 +1393,13 @@ class QPDF |
| 1392 | 1393 | void dumpHSharedObject(); |
| 1393 | 1394 | void dumpHGeneric(HGeneric&); |
| 1394 | 1395 | qpdf_offset_t adjusted_offset(qpdf_offset_t offset); |
| 1395 | - void calculateLinearizationData(std::map<int, int> const& object_stream_data); | |
| 1396 | + template <typename T> | |
| 1397 | + void calculateLinearizationData(T const& object_stream_data); | |
| 1398 | + template <typename T> | |
| 1396 | 1399 | void pushOutlinesToPart( |
| 1397 | 1400 | std::vector<QPDFObjectHandle>& part, |
| 1398 | 1401 | std::set<QPDFObjGen>& lc_outlines, |
| 1399 | - std::map<int, int> const& object_stream_data); | |
| 1402 | + T const& object_stream_data); | |
| 1400 | 1403 | int outputLengthNextN( |
| 1401 | 1404 | int in_object, |
| 1402 | 1405 | int n, | ... | ... |
include/qpdf/QPDFWriter.hh
| ... | ... | @@ -611,8 +611,6 @@ class QPDFWriter |
| 611 | 611 | void pushMD5Pipeline(PipelinePopper&); |
| 612 | 612 | void computeDeterministicIDData(); |
| 613 | 613 | |
| 614 | - void discardGeneration(std::map<int, int>& out); | |
| 615 | - | |
| 616 | 614 | class Members; |
| 617 | 615 | |
| 618 | 616 | // Keep all member variables inside the Members object, which we dynamically allocate. This | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -2540,32 +2540,10 @@ QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) |
| 2540 | 2540 | } |
| 2541 | 2541 | |
| 2542 | 2542 | void |
| 2543 | -QPDFWriter::discardGeneration(std::map<int, int>& out) | |
| 2544 | -{ | |
| 2545 | - // There are deep assumptions in the linearization code in QPDF that there is only one object | |
| 2546 | - // with each object number; i.e., you can't have two objects with the same object number and | |
| 2547 | - // different generations. This is a pretty safe assumption because Adobe Reader and Acrobat | |
| 2548 | - // can't actually handle this case. There is not much if any code in QPDF outside linearization | |
| 2549 | - // that assumes this, but the linearization code as currently implemented would do weird things | |
| 2550 | - // if we found such a case. In order to avoid breaking ABI changes in QPDF, we will first | |
| 2551 | - // assert that this condition holds. Then we can create new maps for QPDF that throw away | |
| 2552 | - // generation numbers. | |
| 2553 | - | |
| 2554 | - out.clear(); | |
| 2555 | - m->obj.forEach([&out](auto id, auto const& item) -> void { | |
| 2556 | - if (item.object_stream > 0) { | |
| 2557 | - out[id] = item.object_stream; | |
| 2558 | - } | |
| 2559 | - }); | |
| 2560 | -} | |
| 2561 | - | |
| 2562 | -void | |
| 2563 | 2543 | QPDFWriter::writeLinearized() |
| 2564 | 2544 | { |
| 2565 | 2545 | // Optimize file and enqueue objects in order |
| 2566 | 2546 | |
| 2567 | - discardGeneration(m->object_to_object_stream_no_gen); | |
| 2568 | - | |
| 2569 | 2547 | auto skip_stream_parameters = [this](QPDFObjectHandle& stream) { |
| 2570 | 2548 | bool compress_stream; |
| 2571 | 2549 | bool is_metadata; |
| ... | ... | @@ -2583,8 +2561,7 @@ QPDFWriter::writeLinearized() |
| 2583 | 2561 | std::vector<QPDFObjectHandle> part7; |
| 2584 | 2562 | std::vector<QPDFObjectHandle> part8; |
| 2585 | 2563 | std::vector<QPDFObjectHandle> part9; |
| 2586 | - QPDF::Writer::getLinearizedParts( | |
| 2587 | - m->pdf, m->object_to_object_stream_no_gen, part4, part6, part7, part8, part9); | |
| 2564 | + QPDF::Writer::getLinearizedParts(m->pdf, m->obj, part4, part6, part7, part8, part9); | |
| 2588 | 2565 | |
| 2589 | 2566 | // Object number sequence: |
| 2590 | 2567 | // | ... | ... |
libqpdf/QPDF_linearization.cc
| ... | ... | @@ -586,6 +586,17 @@ QPDF::getUncompressedObject(QPDFObjectHandle& obj, std::map<int, int> const& obj |
| 586 | 586 | } |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | +QPDFObjectHandle | |
| 590 | +QPDF::getUncompressedObject(QPDFObjectHandle& oh, QPDFWriter::ObjTable const& obj) | |
| 591 | +{ | |
| 592 | + if (obj.contains(oh)) { | |
| 593 | + if (auto id = obj[oh].object_stream; id > 0) { | |
| 594 | + return oh.isNull() ? oh : getObject(id, 0); | |
| 595 | + } | |
| 596 | + } | |
| 597 | + return oh; | |
| 598 | +} | |
| 599 | + | |
| 589 | 600 | int |
| 590 | 601 | QPDF::lengthNextN(int first_object, int n) |
| 591 | 602 | { |
| ... | ... | @@ -960,8 +971,9 @@ QPDF::dumpHGeneric(HGeneric& t) |
| 960 | 971 | << "group_length: " << t.group_length << "\n"; |
| 961 | 972 | } |
| 962 | 973 | |
| 974 | +template <typename T> | |
| 963 | 975 | void |
| 964 | -QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) | |
| 976 | +QPDF::calculateLinearizationData(T const& object_stream_data) | |
| 965 | 977 | { |
| 966 | 978 | // This function calculates the ordering of objects, divides them into the appropriate parts, |
| 967 | 979 | // and computes some values for the linearization parameter dictionary and hint tables. The |
| ... | ... | @@ -1403,11 +1415,12 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1403 | 1415 | } |
| 1404 | 1416 | } |
| 1405 | 1417 | |
| 1418 | +template <typename T> | |
| 1406 | 1419 | void |
| 1407 | 1420 | QPDF::pushOutlinesToPart( |
| 1408 | 1421 | std::vector<QPDFObjectHandle>& part, |
| 1409 | 1422 | std::set<QPDFObjGen>& lc_outlines, |
| 1410 | - std::map<int, int> const& object_stream_data) | |
| 1423 | + T const& object_stream_data) | |
| 1411 | 1424 | { |
| 1412 | 1425 | QPDFObjectHandle root = getRoot(); |
| 1413 | 1426 | QPDFObjectHandle outlines = root.getKey("/Outlines"); |
| ... | ... | @@ -1434,14 +1447,14 @@ QPDF::pushOutlinesToPart( |
| 1434 | 1447 | |
| 1435 | 1448 | void |
| 1436 | 1449 | QPDF::getLinearizedParts( |
| 1437 | - std::map<int, int> const& object_stream_data, | |
| 1450 | + QPDFWriter::ObjTable const& obj, | |
| 1438 | 1451 | std::vector<QPDFObjectHandle>& part4, |
| 1439 | 1452 | std::vector<QPDFObjectHandle>& part6, |
| 1440 | 1453 | std::vector<QPDFObjectHandle>& part7, |
| 1441 | 1454 | std::vector<QPDFObjectHandle>& part8, |
| 1442 | 1455 | std::vector<QPDFObjectHandle>& part9) |
| 1443 | 1456 | { |
| 1444 | - calculateLinearizationData(object_stream_data); | |
| 1457 | + calculateLinearizationData(obj); | |
| 1445 | 1458 | part4 = m->part4; |
| 1446 | 1459 | part6 = m->part6; |
| 1447 | 1460 | part7 = m->part7; | ... | ... |
libqpdf/qpdf/QPDFWriter_private.hh
| ... | ... | @@ -121,7 +121,6 @@ class QPDFWriter::Members |
| 121 | 121 | |
| 122 | 122 | // For linearization only |
| 123 | 123 | std::string lin_pass1_filename; |
| 124 | - std::map<int, int> object_to_object_stream_no_gen; | |
| 125 | 124 | |
| 126 | 125 | // For progress reporting |
| 127 | 126 | std::shared_ptr<QPDFWriter::ProgressReporter> progress_reporter; | ... | ... |