Commit ae00ee6119dcaabcebeeea4f6ec50a076eff3ca1

Authored by m-holger
1 parent ef3a8025

Replace QPDF::Writer::getObjectStreamData with getXRefTable

include/qpdf/QPDF.hh
... ... @@ -753,18 +753,18 @@ class QPDF
753 753 return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);
754 754 }
755 755  
756   - static void
757   - getObjectStreamData(QPDF& qpdf, std::map<int, int>& omap)
758   - {
759   - qpdf.getObjectStreamData(omap);
760   - }
761   -
762 756 static std::vector<QPDFObjGen>
763 757 getCompressibleObjGens(QPDF& qpdf)
764 758 {
765 759 return qpdf.getCompressibleObjGens();
766 760 }
767 761  
  762 + static std::map<QPDFObjGen, QPDFXRefEntry> const&
  763 + getXRefTable(QPDF& qpdf)
  764 + {
  765 + return qpdf.getXRefTableInternal();
  766 + }
  767 +
768 768 static size_t
769 769 tableSize(QPDF& qpdf)
770 770 {
... ... @@ -1088,6 +1088,7 @@ class QPDF
1088 1088  
1089 1089 // For QPDFWriter:
1090 1090  
  1091 + std::map<QPDFObjGen, QPDFXRefEntry> const& getXRefTableInternal();
1091 1092 size_t tableSize();
1092 1093  
1093 1094 // Get lists of all objects in order according to the part of a linearized file that they belong
... ... @@ -1108,9 +1109,6 @@ class QPDF
1108 1109 int& O,
1109 1110 bool compressed);
1110 1111  
1111   - // Map object to object stream that contains it
1112   - void getObjectStreamData(std::map<int, int>&);
1113   -
1114 1112 // Get a list of objects that would be permitted in an object stream.
1115 1113 std::vector<QPDFObjGen> getCompressibleObjGens();
1116 1114  
... ...
libqpdf/QPDF.cc
... ... @@ -2370,6 +2370,12 @@ QPDF::getRoot()
2370 2370 std::map<QPDFObjGen, QPDFXRefEntry>
2371 2371 QPDF::getXRefTable()
2372 2372 {
  2373 + return getXRefTableInternal();
  2374 +}
  2375 +
  2376 +std::map<QPDFObjGen, QPDFXRefEntry> const&
  2377 +QPDF::getXRefTableInternal()
  2378 +{
2373 2379 if (!m->parsed) {
2374 2380 throw std::logic_error("QPDF::getXRefTable called before parsing.");
2375 2381 }
... ... @@ -2390,18 +2396,6 @@ QPDF::tableSize()
2390 2396 return toS(++max_xref);
2391 2397 }
2392 2398  
2393   -void
2394   -QPDF::getObjectStreamData(std::map<int, int>& omap)
2395   -{
2396   - for (auto const& iter: m->xref_table) {
2397   - QPDFObjGen const& og = iter.first;
2398   - QPDFXRefEntry const& entry = iter.second;
2399   - if (entry.getType() == 2) {
2400   - omap[og.getObj()] = entry.getObjStreamNumber();
2401   - }
2402   - }
2403   -}
2404   -
2405 2399 std::vector<QPDFObjGen>
2406 2400 QPDF::getCompressibleObjGens()
2407 2401 {
... ...
libqpdf/QPDFWriter.cc
... ... @@ -1936,12 +1936,7 @@ QPDFWriter::initializeSpecialStreams()
1936 1936 void
1937 1937 QPDFWriter::preserveObjectStreams()
1938 1938 {
1939   - std::map<int, int> omap;
1940   - QPDF::Writer::getObjectStreamData(m->pdf, omap);
1941   - if (omap.empty()) {
1942   - m->obj.streams_empty = true;
1943   - return;
1944   - }
  1939 + auto const& xref = QPDF::Writer::getXRefTable(m->pdf);
1945 1940 // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object
1946 1941 // streams out of old objects that have generation numbers greater than zero. However in an
1947 1942 // existing PDF, all object stream objects and all objects in them must have generation 0
... ... @@ -1949,20 +1944,45 @@ QPDFWriter::preserveObjectStreams()
1949 1944 // that are not allowed to be in object streams. In addition to removing objects that were
1950 1945 // erroneously included in object streams in the source PDF, it also prevents unreferenced
1951 1946 // objects from being included.
1952   - std::set<QPDFObjGen> eligible;
1953   - if (!m->preserve_unreferenced_objects) {
1954   - std::vector<QPDFObjGen> eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf);
1955   - eligible = std::set<QPDFObjGen>(eligible_v.begin(), eligible_v.end());
1956   - }
1957   - QTC::TC("qpdf", "QPDFWriter preserve object streams", m->preserve_unreferenced_objects ? 0 : 1);
1958   - for (auto iter: omap) {
1959   - QPDFObjGen og(iter.first, 0);
1960   - if (eligible.count(og) || m->preserve_unreferenced_objects) {
1961   - m->obj[iter.first].object_stream = iter.second;
1962   - } else {
1963   - QTC::TC("qpdf", "QPDFWriter exclude from object stream");
  1947 + auto iter = xref.cbegin();
  1948 + auto end = xref.cend();
  1949 +
  1950 + // Start by scanning for first compressed object in case we don't have any object streams to
  1951 + // process.
  1952 + for (; iter != end; ++iter) {
  1953 + if (iter->second.getType() == 2) {
  1954 + // Pdf contains object streams.
  1955 + QTC::TC(
  1956 + "qpdf",
  1957 + "QPDFWriter preserve object streams",
  1958 + m->preserve_unreferenced_objects ? 0 : 1);
  1959 +
  1960 + if (m->preserve_unreferenced_objects) {
  1961 + for (; iter != end; ++iter) {
  1962 + if (iter->second.getType() == 2) {
  1963 + m->obj[iter->first].object_stream = iter->second.getObjStreamNumber();
  1964 + }
  1965 + }
  1966 + } else {
  1967 + std::set<QPDFObjGen> eligible;
  1968 + std::vector<QPDFObjGen> eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf);
  1969 + eligible = std::set<QPDFObjGen>(eligible_v.begin(), eligible_v.end());
  1970 + for (; iter != end; ++iter) {
  1971 + if (iter->second.getType() == 2) {
  1972 + QPDFObjGen og(iter->first.getObj(), 0);
  1973 + if (eligible.count(og)) {
  1974 + m->obj[iter->first].object_stream = iter->second.getObjStreamNumber();
  1975 + } else {
  1976 + QTC::TC("qpdf", "QPDFWriter exclude from object stream");
  1977 + }
  1978 + }
  1979 + }
  1980 + }
  1981 + return;
1964 1982 }
1965 1983 }
  1984 + // No compressed objects found.
  1985 + m->obj.streams_empty = true;
1966 1986 }
1967 1987  
1968 1988 void
... ...