Commit c54837e2c47bddc7801429f756005d7f9d41f71c

Authored by m-holger
1 parent efde6274

Refactor `Writer` usage: encapsulate `Linearization` and `Objects` inside `impl:…

…:Doc`, rename related methods, and streamline usage across QPDFWriter and linearization modules.
libqpdf/QPDF.cc
@@ -723,11 +723,11 @@ QPDF::getRoot() @@ -723,11 +723,11 @@ QPDF::getRoot()
723 std::map<QPDFObjGen, QPDFXRefEntry> 723 std::map<QPDFObjGen, QPDFXRefEntry>
724 QPDF::getXRefTable() 724 QPDF::getXRefTable()
725 { 725 {
726 - return m->objects.getXRefTableInternal(); 726 + return m->objects.xref_table();
727 } 727 }
728 728
729 std::map<QPDFObjGen, QPDFXRefEntry> const& 729 std::map<QPDFObjGen, QPDFXRefEntry> const&
730 -Objects::getXRefTableInternal() 730 +Objects::xref_table()
731 { 731 {
732 if (!m->parsed) { 732 if (!m->parsed) {
733 throw std::logic_error("QPDF::getXRefTable called before parsing."); 733 throw std::logic_error("QPDF::getXRefTable called before parsing.");
libqpdf/QPDFWriter.cc
@@ -262,75 +262,17 @@ Pl_stack::Popper::pop() @@ -262,75 +262,17 @@ Pl_stack::Popper::pop()
262 } 262 }
263 263
264 // Writer class is restricted to QPDFWriter so that only it can call certain methods. 264 // Writer class is restricted to QPDFWriter so that only it can call certain methods.
265 -class QPDF::Doc::Writer: QPDF::Doc::Common 265 +class impl::Doc::Writer: impl::Doc::Common
266 { 266 {
267 friend class QPDFWriter; 267 friend class QPDFWriter;
268 Writer(QPDF& qpdf) : 268 Writer(QPDF& qpdf) :
269 Common(qpdf, qpdf.doc().m), 269 Common(qpdf, qpdf.doc().m),
270 - lin(m->lin),  
271 - objects(m->objects) 270 + lin(m->lin)
272 { 271 {
273 } 272 }
274 273
275 protected: 274 protected:
276 - void  
277 - optimize(  
278 - QPDFWriter::ObjTable const& obj,  
279 - std::function<int(QPDFObjectHandle&)> skip_stream_parameters)  
280 - {  
281 - lin.optimize(obj, skip_stream_parameters);  
282 - }  
283 -  
284 - void  
285 - getLinearizedParts(  
286 - QPDFWriter::ObjTable const& obj,  
287 - std::vector<QPDFObjectHandle>& part4,  
288 - std::vector<QPDFObjectHandle>& part6,  
289 - std::vector<QPDFObjectHandle>& part7,  
290 - std::vector<QPDFObjectHandle>& part8,  
291 - std::vector<QPDFObjectHandle>& part9)  
292 - {  
293 - lin.getLinearizedParts(obj, part4, part6, part7, part8, part9);  
294 - }  
295 -  
296 - void  
297 - generateHintStream(  
298 - QPDFWriter::NewObjTable const& new_obj,  
299 - QPDFWriter::ObjTable const& obj,  
300 - std::string& hint_stream,  
301 - int& S,  
302 - int& O,  
303 - bool compressed)  
304 - {  
305 - lin.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);  
306 - }  
307 -  
308 - std::vector<QPDFObjGen>  
309 - getCompressibleObjGens()  
310 - {  
311 - return objects.getCompressibleObjVector();  
312 - }  
313 -  
314 - std::vector<bool>  
315 - getCompressibleObjSet()  
316 - {  
317 - return objects.getCompressibleObjSet();  
318 - }  
319 -  
320 - std::map<QPDFObjGen, QPDFXRefEntry> const&  
321 - getXRefTable()  
322 - {  
323 - return objects.getXRefTableInternal();  
324 - }  
325 -  
326 - size_t  
327 - tableSize()  
328 - {  
329 - return qpdf.m->objects.tableSize();  
330 - }  
331 -  
332 - QPDF::Doc::Linearization& lin;  
333 - QPDF::Doc::Objects& objects; 275 + impl::Doc::Linearization& lin;
334 }; 276 };
335 277
336 class QPDFWriter::Members: QPDF::Doc::Writer 278 class QPDFWriter::Members: QPDF::Doc::Writer
@@ -2151,7 +2093,7 @@ QPDFWriter::Members::initializeSpecialStreams() @@ -2151,7 +2093,7 @@ QPDFWriter::Members::initializeSpecialStreams()
2151 void 2093 void
2152 QPDFWriter::Members::preserveObjectStreams() 2094 QPDFWriter::Members::preserveObjectStreams()
2153 { 2095 {
2154 - auto const& xref = getXRefTable(); 2096 + auto const& xref = objects.xref_table();
2155 // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object 2097 // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object
2156 // streams out of old objects that have generation numbers greater than zero. However in an 2098 // streams out of old objects that have generation numbers greater than zero. However in an
2157 // existing PDF, all object stream objects and all objects in them must have generation 0 2099 // existing PDF, all object stream objects and all objects in them must have generation 0
@@ -2176,9 +2118,9 @@ QPDFWriter::Members::preserveObjectStreams() @@ -2176,9 +2118,9 @@ QPDFWriter::Members::preserveObjectStreams()
2176 if (iter->second.getType() == 2) { 2118 if (iter->second.getType() == 2) {
2177 // Pdf contains object streams. 2119 // Pdf contains object streams.
2178 obj.streams_empty = false; 2120 obj.streams_empty = false;
2179 - auto eligible = getCompressibleObjSet(); 2121 + auto eligible = objects.compressible_set();
2180 // The object pointed to by iter may be a previous generation, in which case it is 2122 // The object pointed to by iter may be a previous generation, in which case it is
2181 - // removed by getCompressibleObjSet. We need to restart the loop (while the object 2123 + // removed by compressible_set. We need to restart the loop (while the object
2182 // table may contain multiple generations of an object). 2124 // table may contain multiple generations of an object).
2183 for (iter = xref.cbegin(); iter != end; ++iter) { 2125 for (iter = xref.cbegin(); iter != end; ++iter) {
2184 if (iter->second.getType() == 2) { 2126 if (iter->second.getType() == 2) {
@@ -2207,7 +2149,7 @@ QPDFWriter::Members::generateObjectStreams() @@ -2207,7 +2149,7 @@ QPDFWriter::Members::generateObjectStreams()
2207 2149
2208 // This code doesn't do anything with /Extends. 2150 // This code doesn't do anything with /Extends.
2209 2151
2210 - std::vector<QPDFObjGen> eligible = getCompressibleObjGens(); 2152 + auto eligible = objects.compressible_vector();
2211 size_t n_object_streams = (eligible.size() + 99U) / 100U; 2153 size_t n_object_streams = (eligible.size() + 99U) / 100U;
2212 2154
2213 initializeTables(2U * n_object_streams); 2155 initializeTables(2U * n_object_streams);
@@ -2288,7 +2230,7 @@ QPDFWriter::Members::prepareFileForWrite() @@ -2288,7 +2230,7 @@ QPDFWriter::Members::prepareFileForWrite()
2288 void 2230 void
2289 QPDFWriter::Members::initializeTables(size_t extra) 2231 QPDFWriter::Members::initializeTables(size_t extra)
2290 { 2232 {
2291 - auto size = QIntC::to_size(tableSize() + 100) + extra; 2233 + auto size = objects.table_size() + 100u + extra;
2292 obj.resize(size); 2234 obj.resize(size);
2293 new_obj.resize(size); 2235 new_obj.resize(size);
2294 } 2236 }
@@ -2568,7 +2510,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) @@ -2568,7 +2510,7 @@ QPDFWriter::Members::writeHintStream(int hint_id)
2568 int S = 0; 2510 int S = 0;
2569 int O = 0; 2511 int O = 0;
2570 bool compressed = compress_streams; 2512 bool compressed = compress_streams;
2571 - generateHintStream(new_obj, obj, hint_buffer, S, O, compressed); 2513 + lin.generateHintStream(new_obj, obj, hint_buffer, S, O, compressed);
2572 2514
2573 openObject(hint_id); 2515 openObject(hint_id);
2574 setDataKey(hint_id); 2516 setDataKey(hint_id);
@@ -2771,14 +2713,14 @@ QPDFWriter::Members::writeLinearized() @@ -2771,14 +2713,14 @@ QPDFWriter::Members::writeLinearized()
2771 } 2713 }
2772 }; 2714 };
2773 2715
2774 - optimize(obj, skip_stream_parameters); 2716 + lin.optimize(obj, skip_stream_parameters);
2775 2717
2776 std::vector<QPDFObjectHandle> part4; 2718 std::vector<QPDFObjectHandle> part4;
2777 std::vector<QPDFObjectHandle> part6; 2719 std::vector<QPDFObjectHandle> part6;
2778 std::vector<QPDFObjectHandle> part7; 2720 std::vector<QPDFObjectHandle> part7;
2779 std::vector<QPDFObjectHandle> part8; 2721 std::vector<QPDFObjectHandle> part8;
2780 std::vector<QPDFObjectHandle> part9; 2722 std::vector<QPDFObjectHandle> part9;
2781 - getLinearizedParts(obj, part4, part6, part7, part8, part9); 2723 + lin.parts(obj, part4, part6, part7, part8, part9);
2782 2724
2783 // Object number sequence: 2725 // Object number sequence:
2784 // 2726 //
libqpdf/QPDF_linearization.cc
@@ -1681,7 +1681,7 @@ Lin::pushOutlinesToPart( @@ -1681,7 +1681,7 @@ Lin::pushOutlinesToPart(
1681 } 1681 }
1682 1682
1683 void 1683 void
1684 -Lin::getLinearizedParts( 1684 +Lin::parts(
1685 QPDFWriter::ObjTable const& obj, 1685 QPDFWriter::ObjTable const& obj,
1686 std::vector<QPDFObjectHandle>& part4, 1686 std::vector<QPDFObjectHandle>& part4,
1687 std::vector<QPDFObjectHandle>& part6, 1687 std::vector<QPDFObjectHandle>& part6,
libqpdf/QPDF_objects.cc
@@ -1916,7 +1916,7 @@ QPDF::swapObjects(QPDFObjGen og1, QPDFObjGen og2) @@ -1916,7 +1916,7 @@ QPDF::swapObjects(QPDFObjGen og1, QPDFObjGen og2)
1916 } 1916 }
1917 1917
1918 size_t 1918 size_t
1919 -Objects::tableSize() 1919 +Objects::table_size()
1920 { 1920 {
1921 // If obj_cache is dense, accommodate all object in tables,else accommodate only original 1921 // If obj_cache is dense, accommodate all object in tables,else accommodate only original
1922 // objects. 1922 // objects.
@@ -1936,20 +1936,20 @@ Objects::tableSize() @@ -1936,20 +1936,20 @@ Objects::tableSize()
1936 } 1936 }
1937 1937
1938 std::vector<QPDFObjGen> 1938 std::vector<QPDFObjGen>
1939 -Objects::getCompressibleObjVector() 1939 +Objects::compressible_vector()
1940 { 1940 {
1941 - return getCompressibleObjGens<QPDFObjGen>(); 1941 + return compressible<QPDFObjGen>();
1942 } 1942 }
1943 1943
1944 std::vector<bool> 1944 std::vector<bool>
1945 -Objects::getCompressibleObjSet() 1945 +Objects::compressible_set()
1946 { 1946 {
1947 - return getCompressibleObjGens<bool>(); 1947 + return compressible<bool>();
1948 } 1948 }
1949 1949
1950 template <typename T> 1950 template <typename T>
1951 std::vector<T> 1951 std::vector<T>
1952 -Objects::getCompressibleObjGens() 1952 +Objects::compressible()
1953 { 1953 {
1954 // Return a list of objects that are allowed to be in object streams. Walk through the objects 1954 // Return a list of objects that are allowed to be in object streams. Walk through the objects
1955 // by traversing the document from the root, including a traversal of the pages tree. This 1955 // by traversing the document from the root, including a traversal of the pages tree. This
@@ -1969,10 +1969,9 @@ Objects::getCompressibleObjGens() @@ -1969,10 +1969,9 @@ Objects::getCompressibleObjGens()
1969 std::vector<T> result; 1969 std::vector<T> result;
1970 if constexpr (std::is_same_v<T, QPDFObjGen>) { 1970 if constexpr (std::is_same_v<T, QPDFObjGen>) {
1971 result.reserve(m->obj_cache.size()); 1971 result.reserve(m->obj_cache.size());
1972 - } else if constexpr (std::is_same_v<T, bool>) {  
1973 - result.resize(max_obj + 1U, false);  
1974 } else { 1972 } else {
1975 - throw std::logic_error("Unsupported type in QPDF::getCompressibleObjGens"); 1973 + qpdf_static_expect(std::is_same_v<T, bool>);
  1974 + result.resize(max_obj + 1U, false);
1976 } 1975 }
1977 while (!queue.empty()) { 1976 while (!queue.empty()) {
1978 auto obj = queue.back(); 1977 auto obj = queue.back();
libqpdf/qpdf/QPDF_private.hh
@@ -573,7 +573,7 @@ class QPDF::Doc::Linearization: Common @@ -573,7 +573,7 @@ class QPDF::Doc::Linearization: Common
573 573
574 // Get lists of all objects in order according to the part of a linearized file that they 574 // Get lists of all objects in order according to the part of a linearized file that they
575 // belong to. 575 // belong to.
576 - void getLinearizedParts( 576 + void parts(
577 QPDFWriter::ObjTable const& obj, 577 QPDFWriter::ObjTable const& obj,
578 std::vector<QPDFObjectHandle>& part4, 578 std::vector<QPDFObjectHandle>& part4,
579 std::vector<QPDFObjectHandle>& part6, 579 std::vector<QPDFObjectHandle>& part6,
@@ -993,18 +993,19 @@ class QPDF::Doc::Objects: Common @@ -993,18 +993,19 @@ class QPDF::Doc::Objects: Common
993 QPDFObjectHandle makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj); 993 QPDFObjectHandle makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj);
994 std::shared_ptr<QPDFObject> getObjectForParser(int id, int gen, bool parse_pdf); 994 std::shared_ptr<QPDFObject> getObjectForParser(int id, int gen, bool parse_pdf);
995 std::shared_ptr<QPDFObject> getObjectForJSON(int id, int gen); 995 std::shared_ptr<QPDFObject> getObjectForJSON(int id, int gen);
996 - size_t tableSize(); 996 + size_t table_size();
997 997
998 // For QPDFWriter: 998 // For QPDFWriter:
999 999
1000 - std::map<QPDFObjGen, QPDFXRefEntry> const& getXRefTableInternal(); 1000 + std::map<QPDFObjGen, QPDFXRefEntry> const& xref_table();
  1001 + std::vector<QPDFObjGen> compressible_vector();
  1002 + std::vector<bool> compressible_set();
  1003 +
  1004 + private:
1001 // Get a list of objects that would be permitted in an object stream. 1005 // Get a list of objects that would be permitted in an object stream.
1002 template <typename T> 1006 template <typename T>
1003 - std::vector<T> getCompressibleObjGens();  
1004 - std::vector<QPDFObjGen> getCompressibleObjVector();  
1005 - std::vector<bool> getCompressibleObjSet(); 1007 + std::vector<T> compressible();
1006 1008
1007 - private:  
1008 void setTrailer(QPDFObjectHandle obj); 1009 void setTrailer(QPDFObjectHandle obj);
1009 void reconstruct_xref(QPDFExc& e, bool found_startxref = true); 1010 void reconstruct_xref(QPDFExc& e, bool found_startxref = true);
1010 void read_xref(qpdf_offset_t offset, bool in_stream_recovery = false); 1011 void read_xref(qpdf_offset_t offset, bool in_stream_recovery = false);