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,18 +753,18 @@ class QPDF | ||
| 753 | return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed); | 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 | static std::vector<QPDFObjGen> | 756 | static std::vector<QPDFObjGen> |
| 763 | getCompressibleObjGens(QPDF& qpdf) | 757 | getCompressibleObjGens(QPDF& qpdf) |
| 764 | { | 758 | { |
| 765 | return qpdf.getCompressibleObjGens(); | 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 | static size_t | 768 | static size_t |
| 769 | tableSize(QPDF& qpdf) | 769 | tableSize(QPDF& qpdf) |
| 770 | { | 770 | { |
| @@ -1088,6 +1088,7 @@ class QPDF | @@ -1088,6 +1088,7 @@ class QPDF | ||
| 1088 | 1088 | ||
| 1089 | // For QPDFWriter: | 1089 | // For QPDFWriter: |
| 1090 | 1090 | ||
| 1091 | + std::map<QPDFObjGen, QPDFXRefEntry> const& getXRefTableInternal(); | ||
| 1091 | size_t tableSize(); | 1092 | size_t tableSize(); |
| 1092 | 1093 | ||
| 1093 | // Get lists of all objects in order according to the part of a linearized file that they belong | 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,9 +1109,6 @@ class QPDF | ||
| 1108 | int& O, | 1109 | int& O, |
| 1109 | bool compressed); | 1110 | bool compressed); |
| 1110 | 1111 | ||
| 1111 | - // Map object to object stream that contains it | ||
| 1112 | - void getObjectStreamData(std::map<int, int>&); | ||
| 1113 | - | ||
| 1114 | // Get a list of objects that would be permitted in an object stream. | 1112 | // Get a list of objects that would be permitted in an object stream. |
| 1115 | std::vector<QPDFObjGen> getCompressibleObjGens(); | 1113 | std::vector<QPDFObjGen> getCompressibleObjGens(); |
| 1116 | 1114 |
libqpdf/QPDF.cc
| @@ -2370,6 +2370,12 @@ QPDF::getRoot() | @@ -2370,6 +2370,12 @@ QPDF::getRoot() | ||
| 2370 | std::map<QPDFObjGen, QPDFXRefEntry> | 2370 | std::map<QPDFObjGen, QPDFXRefEntry> |
| 2371 | QPDF::getXRefTable() | 2371 | QPDF::getXRefTable() |
| 2372 | { | 2372 | { |
| 2373 | + return getXRefTableInternal(); | ||
| 2374 | +} | ||
| 2375 | + | ||
| 2376 | +std::map<QPDFObjGen, QPDFXRefEntry> const& | ||
| 2377 | +QPDF::getXRefTableInternal() | ||
| 2378 | +{ | ||
| 2373 | if (!m->parsed) { | 2379 | if (!m->parsed) { |
| 2374 | throw std::logic_error("QPDF::getXRefTable called before parsing."); | 2380 | throw std::logic_error("QPDF::getXRefTable called before parsing."); |
| 2375 | } | 2381 | } |
| @@ -2390,18 +2396,6 @@ QPDF::tableSize() | @@ -2390,18 +2396,6 @@ QPDF::tableSize() | ||
| 2390 | return toS(++max_xref); | 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 | std::vector<QPDFObjGen> | 2399 | std::vector<QPDFObjGen> |
| 2406 | QPDF::getCompressibleObjGens() | 2400 | QPDF::getCompressibleObjGens() |
| 2407 | { | 2401 | { |
libqpdf/QPDFWriter.cc
| @@ -1936,12 +1936,7 @@ QPDFWriter::initializeSpecialStreams() | @@ -1936,12 +1936,7 @@ QPDFWriter::initializeSpecialStreams() | ||
| 1936 | void | 1936 | void |
| 1937 | QPDFWriter::preserveObjectStreams() | 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 | // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object | 1940 | // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object |
| 1946 | // streams out of old objects that have generation numbers greater than zero. However in an | 1941 | // streams out of old objects that have generation numbers greater than zero. However in an |
| 1947 | // existing PDF, all object stream objects and all objects in them must have generation 0 | 1942 | // existing PDF, all object stream objects and all objects in them must have generation 0 |
| @@ -1949,20 +1944,45 @@ QPDFWriter::preserveObjectStreams() | @@ -1949,20 +1944,45 @@ QPDFWriter::preserveObjectStreams() | ||
| 1949 | // that are not allowed to be in object streams. In addition to removing objects that were | 1944 | // that are not allowed to be in object streams. In addition to removing objects that were |
| 1950 | // erroneously included in object streams in the source PDF, it also prevents unreferenced | 1945 | // erroneously included in object streams in the source PDF, it also prevents unreferenced |
| 1951 | // objects from being included. | 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 | void | 1988 | void |