Commit aa2e0d23f0a09b2f1c37bd09d31147b6fb08fada

Authored by m-holger
1 parent 97d78c75

In QPDFWriter::writeLinearized use object table obj in call to getLinearizedParts

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&amp; obj, std::map&lt;int, int&gt; const&amp; 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&amp; 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&lt;int, int&gt; const&amp; 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;
... ...