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,14 +739,14 @@ class QPDF | ||
| 739 | static void | 739 | static void |
| 740 | getLinearizedParts( | 740 | getLinearizedParts( |
| 741 | QPDF& qpdf, | 741 | QPDF& qpdf, |
| 742 | - std::map<int, int> const& object_stream_data, | 742 | + QPDFWriter::ObjTable const& obj, |
| 743 | std::vector<QPDFObjectHandle>& part4, | 743 | std::vector<QPDFObjectHandle>& part4, |
| 744 | std::vector<QPDFObjectHandle>& part6, | 744 | std::vector<QPDFObjectHandle>& part6, |
| 745 | std::vector<QPDFObjectHandle>& part7, | 745 | std::vector<QPDFObjectHandle>& part7, |
| 746 | std::vector<QPDFObjectHandle>& part8, | 746 | std::vector<QPDFObjectHandle>& part8, |
| 747 | std::vector<QPDFObjectHandle>& part9) | 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 | static void | 752 | static void |
| @@ -1117,7 +1117,7 @@ class QPDF | @@ -1117,7 +1117,7 @@ class QPDF | ||
| 1117 | // Get lists of all objects in order according to the part of a linearized file that they belong | 1117 | // Get lists of all objects in order according to the part of a linearized file that they belong |
| 1118 | // to. | 1118 | // to. |
| 1119 | void getLinearizedParts( | 1119 | void getLinearizedParts( |
| 1120 | - std::map<int, int> const& object_stream_data, | 1120 | + QPDFWriter::ObjTable const& obj, |
| 1121 | std::vector<QPDFObjectHandle>& part4, | 1121 | std::vector<QPDFObjectHandle>& part4, |
| 1122 | std::vector<QPDFObjectHandle>& part6, | 1122 | std::vector<QPDFObjectHandle>& part6, |
| 1123 | std::vector<QPDFObjectHandle>& part7, | 1123 | std::vector<QPDFObjectHandle>& part7, |
| @@ -1382,6 +1382,7 @@ class QPDF | @@ -1382,6 +1382,7 @@ class QPDF | ||
| 1382 | qpdf_offset_t getLinearizationOffset(QPDFObjGen const&); | 1382 | qpdf_offset_t getLinearizationOffset(QPDFObjGen const&); |
| 1383 | QPDFObjectHandle | 1383 | QPDFObjectHandle |
| 1384 | getUncompressedObject(QPDFObjectHandle&, std::map<int, int> const& object_stream_data); | 1384 | getUncompressedObject(QPDFObjectHandle&, std::map<int, int> const& object_stream_data); |
| 1385 | + QPDFObjectHandle getUncompressedObject(QPDFObjectHandle&, QPDFWriter::ObjTable const& obj); | ||
| 1385 | int lengthNextN(int first_object, int n); | 1386 | int lengthNextN(int first_object, int n); |
| 1386 | void | 1387 | void |
| 1387 | checkHPageOffset(std::vector<QPDFObjectHandle> const& pages, std::map<int, int>& idx_to_obj); | 1388 | checkHPageOffset(std::vector<QPDFObjectHandle> const& pages, std::map<int, int>& idx_to_obj); |
| @@ -1392,11 +1393,13 @@ class QPDF | @@ -1392,11 +1393,13 @@ class QPDF | ||
| 1392 | void dumpHSharedObject(); | 1393 | void dumpHSharedObject(); |
| 1393 | void dumpHGeneric(HGeneric&); | 1394 | void dumpHGeneric(HGeneric&); |
| 1394 | qpdf_offset_t adjusted_offset(qpdf_offset_t offset); | 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 | void pushOutlinesToPart( | 1399 | void pushOutlinesToPart( |
| 1397 | std::vector<QPDFObjectHandle>& part, | 1400 | std::vector<QPDFObjectHandle>& part, |
| 1398 | std::set<QPDFObjGen>& lc_outlines, | 1401 | std::set<QPDFObjGen>& lc_outlines, |
| 1399 | - std::map<int, int> const& object_stream_data); | 1402 | + T const& object_stream_data); |
| 1400 | int outputLengthNextN( | 1403 | int outputLengthNextN( |
| 1401 | int in_object, | 1404 | int in_object, |
| 1402 | int n, | 1405 | int n, |
include/qpdf/QPDFWriter.hh
| @@ -611,8 +611,6 @@ class QPDFWriter | @@ -611,8 +611,6 @@ class QPDFWriter | ||
| 611 | void pushMD5Pipeline(PipelinePopper&); | 611 | void pushMD5Pipeline(PipelinePopper&); |
| 612 | void computeDeterministicIDData(); | 612 | void computeDeterministicIDData(); |
| 613 | 613 | ||
| 614 | - void discardGeneration(std::map<int, int>& out); | ||
| 615 | - | ||
| 616 | class Members; | 614 | class Members; |
| 617 | 615 | ||
| 618 | // Keep all member variables inside the Members object, which we dynamically allocate. This | 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,32 +2540,10 @@ QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | ||
| 2540 | } | 2540 | } |
| 2541 | 2541 | ||
| 2542 | void | 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 | QPDFWriter::writeLinearized() | 2543 | QPDFWriter::writeLinearized() |
| 2564 | { | 2544 | { |
| 2565 | // Optimize file and enqueue objects in order | 2545 | // Optimize file and enqueue objects in order |
| 2566 | 2546 | ||
| 2567 | - discardGeneration(m->object_to_object_stream_no_gen); | ||
| 2568 | - | ||
| 2569 | auto skip_stream_parameters = [this](QPDFObjectHandle& stream) { | 2547 | auto skip_stream_parameters = [this](QPDFObjectHandle& stream) { |
| 2570 | bool compress_stream; | 2548 | bool compress_stream; |
| 2571 | bool is_metadata; | 2549 | bool is_metadata; |
| @@ -2583,8 +2561,7 @@ QPDFWriter::writeLinearized() | @@ -2583,8 +2561,7 @@ QPDFWriter::writeLinearized() | ||
| 2583 | std::vector<QPDFObjectHandle> part7; | 2561 | std::vector<QPDFObjectHandle> part7; |
| 2584 | std::vector<QPDFObjectHandle> part8; | 2562 | std::vector<QPDFObjectHandle> part8; |
| 2585 | std::vector<QPDFObjectHandle> part9; | 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 | // Object number sequence: | 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,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 | int | 600 | int |
| 590 | QPDF::lengthNextN(int first_object, int n) | 601 | QPDF::lengthNextN(int first_object, int n) |
| 591 | { | 602 | { |
| @@ -960,8 +971,9 @@ QPDF::dumpHGeneric(HGeneric& t) | @@ -960,8 +971,9 @@ QPDF::dumpHGeneric(HGeneric& t) | ||
| 960 | << "group_length: " << t.group_length << "\n"; | 971 | << "group_length: " << t.group_length << "\n"; |
| 961 | } | 972 | } |
| 962 | 973 | ||
| 974 | +template <typename T> | ||
| 963 | void | 975 | void |
| 964 | -QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) | 976 | +QPDF::calculateLinearizationData(T const& object_stream_data) |
| 965 | { | 977 | { |
| 966 | // This function calculates the ordering of objects, divides them into the appropriate parts, | 978 | // This function calculates the ordering of objects, divides them into the appropriate parts, |
| 967 | // and computes some values for the linearization parameter dictionary and hint tables. The | 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,11 +1415,12 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) | ||
| 1403 | } | 1415 | } |
| 1404 | } | 1416 | } |
| 1405 | 1417 | ||
| 1418 | +template <typename T> | ||
| 1406 | void | 1419 | void |
| 1407 | QPDF::pushOutlinesToPart( | 1420 | QPDF::pushOutlinesToPart( |
| 1408 | std::vector<QPDFObjectHandle>& part, | 1421 | std::vector<QPDFObjectHandle>& part, |
| 1409 | std::set<QPDFObjGen>& lc_outlines, | 1422 | std::set<QPDFObjGen>& lc_outlines, |
| 1410 | - std::map<int, int> const& object_stream_data) | 1423 | + T const& object_stream_data) |
| 1411 | { | 1424 | { |
| 1412 | QPDFObjectHandle root = getRoot(); | 1425 | QPDFObjectHandle root = getRoot(); |
| 1413 | QPDFObjectHandle outlines = root.getKey("/Outlines"); | 1426 | QPDFObjectHandle outlines = root.getKey("/Outlines"); |
| @@ -1434,14 +1447,14 @@ QPDF::pushOutlinesToPart( | @@ -1434,14 +1447,14 @@ QPDF::pushOutlinesToPart( | ||
| 1434 | 1447 | ||
| 1435 | void | 1448 | void |
| 1436 | QPDF::getLinearizedParts( | 1449 | QPDF::getLinearizedParts( |
| 1437 | - std::map<int, int> const& object_stream_data, | 1450 | + QPDFWriter::ObjTable const& obj, |
| 1438 | std::vector<QPDFObjectHandle>& part4, | 1451 | std::vector<QPDFObjectHandle>& part4, |
| 1439 | std::vector<QPDFObjectHandle>& part6, | 1452 | std::vector<QPDFObjectHandle>& part6, |
| 1440 | std::vector<QPDFObjectHandle>& part7, | 1453 | std::vector<QPDFObjectHandle>& part7, |
| 1441 | std::vector<QPDFObjectHandle>& part8, | 1454 | std::vector<QPDFObjectHandle>& part8, |
| 1442 | std::vector<QPDFObjectHandle>& part9) | 1455 | std::vector<QPDFObjectHandle>& part9) |
| 1443 | { | 1456 | { |
| 1444 | - calculateLinearizationData(object_stream_data); | 1457 | + calculateLinearizationData(obj); |
| 1445 | part4 = m->part4; | 1458 | part4 = m->part4; |
| 1446 | part6 = m->part6; | 1459 | part6 = m->part6; |
| 1447 | part7 = m->part7; | 1460 | part7 = m->part7; |
libqpdf/qpdf/QPDFWriter_private.hh
| @@ -121,7 +121,6 @@ class QPDFWriter::Members | @@ -121,7 +121,6 @@ class QPDFWriter::Members | ||
| 121 | 121 | ||
| 122 | // For linearization only | 122 | // For linearization only |
| 123 | std::string lin_pass1_filename; | 123 | std::string lin_pass1_filename; |
| 124 | - std::map<int, int> object_to_object_stream_no_gen; | ||
| 125 | 124 | ||
| 126 | // For progress reporting | 125 | // For progress reporting |
| 127 | std::shared_ptr<QPDFWriter::ProgressReporter> progress_reporter; | 126 | std::shared_ptr<QPDFWriter::ProgressReporter> progress_reporter; |