Commit 97d78c75ff04e3db7801b6e609ee4f9d2e70c3fd

Authored by m-holger
1 parent 0df0d00c

In QPDFWriter::writeLinearized use object table obj in call to optimize

include/qpdf/QPDF.hh
... ... @@ -728,6 +728,15 @@ class QPDF
728 728  
729 729 private:
730 730 static void
  731 + optimize(
  732 + QPDF& qpdf,
  733 + QPDFWriter::ObjTable const& obj,
  734 + std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
  735 + {
  736 + return qpdf.optimize(obj, skip_stream_parameters);
  737 + }
  738 +
  739 + static void
731 740 getLinearizedParts(
732 741 QPDF& qpdf,
733 742 std::map<int, int> const& object_stream_data,
... ... @@ -1095,6 +1104,14 @@ class QPDF
1095 1104 // For QPDFWriter:
1096 1105  
1097 1106 std::map<QPDFObjGen, QPDFXRefEntry> const& getXRefTableInternal();
  1107 + template <typename T>
  1108 + void optimize_internal(
  1109 + T const& object_stream_data,
  1110 + bool allow_changes = true,
  1111 + std::function<int(QPDFObjectHandle&)> skip_stream_parameters = nullptr);
  1112 + void optimize(
  1113 + QPDFWriter::ObjTable const& obj,
  1114 + std::function<int(QPDFObjectHandle&)> skip_stream_parameters);
1098 1115 size_t tableSize();
1099 1116  
1100 1117 // Get lists of all objects in order according to the part of a linearized file that they belong
... ... @@ -1413,6 +1430,7 @@ class QPDF
1413 1430 QPDFObjGen::set& visited,
1414 1431 bool top);
1415 1432 void filterCompressedObjects(std::map<int, int> const& object_stream_data);
  1433 + void filterCompressedObjects(QPDFWriter::ObjTable const& object_stream_data);
1416 1434  
1417 1435 // JSON import
1418 1436 void importJSON(std::shared_ptr<InputSource>, bool must_be_complete);
... ...
libqpdf/QPDFWriter.cc
... ... @@ -2576,7 +2576,7 @@ QPDFWriter::writeLinearized()
2576 2576 }
2577 2577 };
2578 2578  
2579   - m->pdf.optimize(m->object_to_object_stream_no_gen, true, skip_stream_parameters);
  2579 + QPDF::Writer::optimize(m->pdf, m->obj, skip_stream_parameters);
2580 2580  
2581 2581 std::vector<QPDFObjectHandle> part4;
2582 2582 std::vector<QPDFObjectHandle> part6;
... ...
libqpdf/QPDF_optimization.cc
... ... @@ -5,6 +5,7 @@
5 5 #include <qpdf/QPDF.hh>
6 6  
7 7 #include <qpdf/QPDFExc.hh>
  8 +#include <qpdf/QPDFWriter_private.hh>
8 9 #include <qpdf/QPDF_Array.hh>
9 10 #include <qpdf/QPDF_Dictionary.hh>
10 11 #include <qpdf/QTC.hh>
... ... @@ -59,6 +60,23 @@ QPDF::optimize(
59 60 bool allow_changes,
60 61 std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
61 62 {
  63 + optimize_internal(object_stream_data, allow_changes, skip_stream_parameters);
  64 +}
  65 +
  66 +void
  67 +QPDF::optimize(
  68 + QPDFWriter::ObjTable const& obj, std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
  69 +{
  70 + optimize_internal(obj, true, skip_stream_parameters);
  71 +}
  72 +
  73 +template <typename T>
  74 +void
  75 +QPDF::optimize_internal(
  76 + T const& object_stream_data,
  77 + bool allow_changes,
  78 + std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
  79 +{
62 80 if (!m->obj_user_to_objects.empty()) {
63 81 // already optimized
64 82 return;
... ... @@ -379,3 +397,45 @@ QPDF::filterCompressedObjects(std::map&lt;int, int&gt; const&amp; object_stream_data)
379 397 m->obj_user_to_objects = t_obj_user_to_objects;
380 398 m->object_to_obj_users = t_object_to_obj_users;
381 399 }
  400 +
  401 +void
  402 +QPDF::filterCompressedObjects(QPDFWriter::ObjTable const& obj)
  403 +{
  404 + if (obj.getStreamsEmpty()) {
  405 + return;
  406 + }
  407 +
  408 + // Transform object_to_obj_users and obj_user_to_objects so that they refer only to uncompressed
  409 + // objects. If something is a user of a compressed object, then it is really a user of the
  410 + // object stream that contains it.
  411 +
  412 + std::map<ObjUser, std::set<QPDFObjGen>> t_obj_user_to_objects;
  413 + std::map<QPDFObjGen, std::set<ObjUser>> t_object_to_obj_users;
  414 +
  415 + for (auto const& i1: m->obj_user_to_objects) {
  416 + ObjUser const& ou = i1.first;
  417 + // Loop over objects.
  418 + for (auto const& og: i1.second) {
  419 + if (auto const& i2 = obj[og].object_stream; i2 <= 0) {
  420 + t_obj_user_to_objects[ou].insert(og);
  421 + } else {
  422 + t_obj_user_to_objects[ou].insert(QPDFObjGen(i2, 0));
  423 + }
  424 + }
  425 + }
  426 +
  427 + for (auto const& i1: m->object_to_obj_users) {
  428 + QPDFObjGen const& og = i1.first;
  429 + // Loop over obj_users.
  430 + for (auto const& ou: i1.second) {
  431 + if (auto i2 = obj[og].object_stream; i2 <= 0) {
  432 + t_object_to_obj_users[og].insert(ou);
  433 + } else {
  434 + t_object_to_obj_users[QPDFObjGen(i2, 0)].insert(ou);
  435 + }
  436 + }
  437 + }
  438 +
  439 + m->obj_user_to_objects = t_obj_user_to_objects;
  440 + m->object_to_obj_users = t_object_to_obj_users;
  441 +}
... ...