Commit ae00ee6119dcaabcebeeea4f6ec50a076eff3ca1
1 parent
ef3a8025
Replace QPDF::Writer::getObjectStreamData with getXRefTable
Showing
3 changed files
with
51 additions
and
39 deletions
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 | ... | ... |