Commit 84e25919cb9e3303670d23320dcc4071759a9634

Authored by m-holger
1 parent 8791b5f8

In QPDFWriter replace map obj_renumber_no_gen with ObjTable obj

include/qpdf/QPDF.hh
... ... @@ -41,6 +41,7 @@
41 41 #include <qpdf/QPDFObjectHandle.hh>
42 42 #include <qpdf/QPDFStreamFilter.hh>
43 43 #include <qpdf/QPDFTokenizer.hh>
  44 +#include <qpdf/QPDFWriter.hh>
44 45 #include <qpdf/QPDFXRefEntry.hh>
45 46  
46 47 class QPDF_Stream;
... ... @@ -744,14 +745,13 @@ class QPDF
744 745 QPDF& qpdf,
745 746 std::map<int, QPDFXRefEntry> const& xref,
746 747 std::map<int, qpdf_offset_t> const& lengths,
747   - std::map<int, int> const& obj_renumber,
  748 + QPDFWriter::ObjTable const& obj,
748 749 std::shared_ptr<Buffer>& hint_stream,
749 750 int& S,
750 751 int& O,
751 752 bool compressed)
752 753 {
753   - return qpdf.generateHintStream(
754   - xref, lengths, obj_renumber, hint_stream, S, O, compressed);
  754 + return qpdf.generateHintStream(xref, lengths, obj, hint_stream, S, O, compressed);
755 755 }
756 756  
757 757 static void
... ... @@ -1104,7 +1104,7 @@ class QPDF
1104 1104 void generateHintStream(
1105 1105 std::map<int, QPDFXRefEntry> const& xref,
1106 1106 std::map<int, qpdf_offset_t> const& lengths,
1107   - std::map<int, int> const& obj_renumber,
  1107 + QPDFWriter::ObjTable const& obj,
1108 1108 std::shared_ptr<Buffer>& hint_stream,
1109 1109 int& S,
1110 1110 int& O,
... ... @@ -1379,19 +1379,19 @@ class QPDF
1379 1379 int in_object,
1380 1380 int n,
1381 1381 std::map<int, qpdf_offset_t> const& lengths,
1382   - std::map<int, int> const& obj_renumber);
  1382 + QPDFWriter::ObjTable const& obj);
1383 1383 void calculateHPageOffset(
1384 1384 std::map<int, QPDFXRefEntry> const& xref,
1385 1385 std::map<int, qpdf_offset_t> const& lengths,
1386   - std::map<int, int> const& obj_renumber);
  1386 + QPDFWriter::ObjTable const& obj);
1387 1387 void calculateHSharedObject(
1388 1388 std::map<int, QPDFXRefEntry> const& xref,
1389 1389 std::map<int, qpdf_offset_t> const& lengths,
1390   - std::map<int, int> const& obj_renumber);
  1390 + QPDFWriter::ObjTable const& obj);
1391 1391 void calculateHOutline(
1392 1392 std::map<int, QPDFXRefEntry> const& xref,
1393 1393 std::map<int, qpdf_offset_t> const& lengths,
1394   - std::map<int, int> const& obj_renumber);
  1394 + QPDFWriter::ObjTable const& obj);
1395 1395 void writeHPageOffset(BitWriter&);
1396 1396 void writeHSharedObject(BitWriter&);
1397 1397 void writeHGeneric(BitWriter&, HGeneric&);
... ...
include/qpdf/QPDFWriter.hh
... ... @@ -610,7 +610,6 @@ class QPDFWriter
610 610 void computeDeterministicIDData();
611 611  
612 612 void discardGeneration(std::map<QPDFObjGen, int> const& in, std::map<int, int>& out);
613   - void discardGeneration(std::map<int, int>& out);
614 613  
615 614 class Members;
616 615  
... ...
libqpdf/QPDFWriter.cc
... ... @@ -2303,7 +2303,7 @@ QPDFWriter::writeHintStream(int hint_id)
2303 2303 int O = 0;
2304 2304 bool compressed = (m->compress_streams && !m->qdf_mode);
2305 2305 QPDF::Writer::generateHintStream(
2306   - m->pdf, m->xref, m->lengths, m->obj_renumber_no_gen, hint_buffer, S, O, compressed);
  2306 + m->pdf, m->xref, m->lengths, m->obj, hint_buffer, S, O, compressed);
2307 2307  
2308 2308 openObject(hint_id);
2309 2309 setDataKey(hint_id);
... ... @@ -2546,26 +2546,6 @@ QPDFWriter::discardGeneration(std::map&lt;QPDFObjGen, int&gt; const&amp; in, std::map&lt;int,
2546 2546 }
2547 2547  
2548 2548 void
2549   -QPDFWriter::discardGeneration(std::map<int, int>& out)
2550   -{
2551   - // There are deep assumptions in the linearization code in QPDF that there is only one object
2552   - // with each object number; i.e., you can't have two objects with the same object number and
2553   - // different generations. This is a pretty safe assumption because Adobe Reader and Acrobat
2554   - // can't actually handle this case. There is not much if any code in QPDF outside linearization
2555   - // that assumes this, but the linearization code as currently implemented would do weird things
2556   - // if we found such a case. In order to avoid breaking ABI changes in QPDF, we will first
2557   - // assert that this condition holds. Then we can create new maps for QPDF that throw away
2558   - // generation numbers.
2559   -
2560   - out.clear();
2561   - m->obj.forEach([&out](auto id, auto const& item) -> void {
2562   - if (item.renumber > 0) {
2563   - out[id] = item.renumber;
2564   - }
2565   - });
2566   -}
2567   -
2568   -void
2569 2549 QPDFWriter::writeLinearized()
2570 2550 {
2571 2551 // Optimize file and enqueue objects in order
... ... @@ -2887,8 +2867,6 @@ QPDFWriter::writeLinearized()
2887 2867 writeString(std::to_string(first_xref_offset));
2888 2868 writeString("\n%%EOF\n");
2889 2869  
2890   - discardGeneration(m->obj_renumber_no_gen);
2891   -
2892 2870 if (pass == 1) {
2893 2871 if (m->deterministic_id) {
2894 2872 QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1);
... ...
libqpdf/QPDF_linearization.cc
... ... @@ -9,6 +9,7 @@
9 9 #include <qpdf/Pl_Flate.hh>
10 10 #include <qpdf/QPDFExc.hh>
11 11 #include <qpdf/QPDFLogger.hh>
  12 +#include <qpdf/QPDFWriter_private.hh>
12 13 #include <qpdf/QTC.hh>
13 14 #include <qpdf/QUtil.hh>
14 15  
... ... @@ -1459,15 +1460,15 @@ QPDF::outputLengthNextN(
1459 1460 int in_object,
1460 1461 int n,
1461 1462 std::map<int, qpdf_offset_t> const& lengths,
1462   - std::map<int, int> const& obj_renumber)
  1463 + QPDFWriter::ObjTable const& obj)
1463 1464 {
1464 1465 // Figure out the length of a series of n consecutive objects in the output file starting with
1465 1466 // whatever object in_object from the input file mapped to.
1466 1467  
1467   - if (obj_renumber.count(in_object) == 0) {
  1468 + int first = obj[in_object].renumber;
  1469 + if (first <= 0) {
1468 1470 stopOnError("found object that is not renumbered while writing linearization data");
1469 1471 }
1470   - int first = (*(obj_renumber.find(in_object))).second;
1471 1472 int length = 0;
1472 1473 for (int i = 0; i < n; ++i) {
1473 1474 if (lengths.count(first + i) == 0) {
... ... @@ -1482,7 +1483,7 @@ void
1482 1483 QPDF::calculateHPageOffset(
1483 1484 std::map<int, QPDFXRefEntry> const& xref,
1484 1485 std::map<int, qpdf_offset_t> const& lengths,
1485   - std::map<int, int> const& obj_renumber)
  1486 + QPDFWriter::ObjTable const& obj)
1486 1487 {
1487 1488 // Page Offset Hint Table
1488 1489  
... ... @@ -1497,8 +1498,7 @@ QPDF::calculateHPageOffset(
1497 1498  
1498 1499 int min_nobjects = cphe.at(0).nobjects;
1499 1500 int max_nobjects = min_nobjects;
1500   - int min_length =
1501   - outputLengthNextN(pages.at(0).getObjectID(), min_nobjects, lengths, obj_renumber);
  1501 + int min_length = outputLengthNextN(pages.at(0).getObjectID(), min_nobjects, lengths, obj);
1502 1502 int max_length = min_length;
1503 1503 int max_shared = cphe.at(0).nshared_objects;
1504 1504  
... ... @@ -1515,7 +1515,7 @@ QPDF::calculateHPageOffset(
1515 1515 // assignments.
1516 1516  
1517 1517 int nobjects = cphe.at(i).nobjects;
1518   - int length = outputLengthNextN(pages.at(i).getObjectID(), nobjects, lengths, obj_renumber);
  1518 + int length = outputLengthNextN(pages.at(i).getObjectID(), nobjects, lengths, obj);
1519 1519 int nshared = cphe.at(i).nshared_objects;
1520 1520  
1521 1521 min_nobjects = std::min(min_nobjects, nobjects);
... ... @@ -1530,8 +1530,7 @@ QPDF::calculateHPageOffset(
1530 1530 }
1531 1531  
1532 1532 ph.min_nobjects = min_nobjects;
1533   - int in_page0_id = pages.at(0).getObjectID();
1534   - int out_page0_id = (*(obj_renumber.find(in_page0_id))).second;
  1533 + int out_page0_id = obj[pages.at(0)].renumber;
1535 1534 ph.first_page_offset = (*(xref.find(out_page0_id))).second.getOffset();
1536 1535 ph.nbits_delta_nobjects = nbits(max_nobjects - min_nobjects);
1537 1536 ph.min_page_length = min_length;
... ... @@ -1569,7 +1568,7 @@ void
1569 1568 QPDF::calculateHSharedObject(
1570 1569 std::map<int, QPDFXRefEntry> const& xref,
1571 1570 std::map<int, qpdf_offset_t> const& lengths,
1572   - std::map<int, int> const& obj_renumber)
  1571 + QPDFWriter::ObjTable const& obj)
1573 1572 {
1574 1573 CHSharedObject& cso = m->c_shared_object_data;
1575 1574 std::vector<CHSharedObjectEntry>& csoe = cso.entries;
... ... @@ -1577,12 +1576,12 @@ QPDF::calculateHSharedObject(
1577 1576 std::vector<HSharedObjectEntry>& soe = so.entries;
1578 1577 soe.clear();
1579 1578  
1580   - int min_length = outputLengthNextN(csoe.at(0).object, 1, lengths, obj_renumber);
  1579 + int min_length = outputLengthNextN(csoe.at(0).object, 1, lengths, obj);
1581 1580 int max_length = min_length;
1582 1581  
1583 1582 for (size_t i = 0; i < toS(cso.nshared_total); ++i) {
1584 1583 // Assign absolute numbers to deltas; adjust later
1585   - int length = outputLengthNextN(csoe.at(i).object, 1, lengths, obj_renumber);
  1584 + int length = outputLengthNextN(csoe.at(i).object, 1, lengths, obj);
1586 1585 min_length = std::min(min_length, length);
1587 1586 max_length = std::max(max_length, length);
1588 1587 soe.emplace_back();
... ... @@ -1595,7 +1594,7 @@ QPDF::calculateHSharedObject(
1595 1594 so.nshared_total = cso.nshared_total;
1596 1595 so.nshared_first_page = cso.nshared_first_page;
1597 1596 if (so.nshared_total > so.nshared_first_page) {
1598   - so.first_shared_obj = (*(obj_renumber.find(cso.first_shared_obj))).second;
  1597 + so.first_shared_obj = obj[cso.first_shared_obj].renumber;
1599 1598 so.first_shared_offset = (*(xref.find(so.first_shared_obj))).second.getOffset();
1600 1599 }
1601 1600 so.min_group_length = min_length;
... ... @@ -1614,7 +1613,7 @@ void
1614 1613 QPDF::calculateHOutline(
1615 1614 std::map<int, QPDFXRefEntry> const& xref,
1616 1615 std::map<int, qpdf_offset_t> const& lengths,
1617   - std::map<int, int> const& obj_renumber)
  1616 + QPDFWriter::ObjTable const& obj)
1618 1617 {
1619 1618 HGeneric& cho = m->c_outline_data;
1620 1619  
... ... @@ -1624,10 +1623,10 @@ QPDF::calculateHOutline(
1624 1623  
1625 1624 HGeneric& ho = m->outline_hints;
1626 1625  
1627   - ho.first_object = (*(obj_renumber.find(cho.first_object))).second;
  1626 + ho.first_object = obj[cho.first_object].renumber;
1628 1627 ho.first_object_offset = (*(xref.find(ho.first_object))).second.getOffset();
1629 1628 ho.nobjects = cho.nobjects;
1630   - ho.group_length = outputLengthNextN(cho.first_object, ho.nobjects, lengths, obj_renumber);
  1629 + ho.group_length = outputLengthNextN(cho.first_object, ho.nobjects, lengths, obj);
1631 1630 }
1632 1631  
1633 1632 template <class T, class int_type>
... ... @@ -1758,16 +1757,16 @@ void
1758 1757 QPDF::generateHintStream(
1759 1758 std::map<int, QPDFXRefEntry> const& xref,
1760 1759 std::map<int, qpdf_offset_t> const& lengths,
1761   - std::map<int, int> const& obj_renumber,
  1760 + QPDFWriter::ObjTable const& obj,
1762 1761 std::shared_ptr<Buffer>& hint_buffer,
1763 1762 int& S,
1764 1763 int& O,
1765 1764 bool compressed)
1766 1765 {
1767 1766 // Populate actual hint table values
1768   - calculateHPageOffset(xref, lengths, obj_renumber);
1769   - calculateHSharedObject(xref, lengths, obj_renumber);
1770   - calculateHOutline(xref, lengths, obj_renumber);
  1767 + calculateHPageOffset(xref, lengths, obj);
  1768 + calculateHSharedObject(xref, lengths, obj);
  1769 + calculateHOutline(xref, lengths, obj);
1771 1770  
1772 1771 // Write the hint stream itself into a compressed memory buffer. Write through a counter so we
1773 1772 // can get offsets.
... ...
libqpdf/qpdf/QPDFWriter_private.hh
... ... @@ -99,7 +99,6 @@ class QPDFWriter::Members
99 99  
100 100 // For linearization only
101 101 std::string lin_pass1_filename;
102   - std::map<int, int> obj_renumber_no_gen;
103 102 std::map<int, int> object_to_object_stream_no_gen;
104 103  
105 104 // For progress reporting
... ...