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

This commit is contained in:
m-holger 2024-03-04 11:19:45 +00:00
parent 0df0d00c58
commit 97d78c75ff
3 changed files with 79 additions and 1 deletions

View File

@ -727,6 +727,15 @@ class QPDF
friend class QPDFWriter;
private:
static void
optimize(
QPDF& qpdf,
QPDFWriter::ObjTable const& obj,
std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
{
return qpdf.optimize(obj, skip_stream_parameters);
}
static void
getLinearizedParts(
QPDF& qpdf,
@ -1095,6 +1104,14 @@ class QPDF
// For QPDFWriter:
std::map<QPDFObjGen, QPDFXRefEntry> const& getXRefTableInternal();
template <typename T>
void optimize_internal(
T const& object_stream_data,
bool allow_changes = true,
std::function<int(QPDFObjectHandle&)> skip_stream_parameters = nullptr);
void optimize(
QPDFWriter::ObjTable const& obj,
std::function<int(QPDFObjectHandle&)> skip_stream_parameters);
size_t tableSize();
// Get lists of all objects in order according to the part of a linearized file that they belong
@ -1413,6 +1430,7 @@ class QPDF
QPDFObjGen::set& visited,
bool top);
void filterCompressedObjects(std::map<int, int> const& object_stream_data);
void filterCompressedObjects(QPDFWriter::ObjTable const& object_stream_data);
// JSON import
void importJSON(std::shared_ptr<InputSource>, bool must_be_complete);

View File

@ -2576,7 +2576,7 @@ QPDFWriter::writeLinearized()
}
};
m->pdf.optimize(m->object_to_object_stream_no_gen, true, skip_stream_parameters);
QPDF::Writer::optimize(m->pdf, m->obj, skip_stream_parameters);
std::vector<QPDFObjectHandle> part4;
std::vector<QPDFObjectHandle> part6;

View File

@ -5,6 +5,7 @@
#include <qpdf/QPDF.hh>
#include <qpdf/QPDFExc.hh>
#include <qpdf/QPDFWriter_private.hh>
#include <qpdf/QPDF_Array.hh>
#include <qpdf/QPDF_Dictionary.hh>
#include <qpdf/QTC.hh>
@ -58,6 +59,23 @@ QPDF::optimize(
std::map<int, int> const& object_stream_data,
bool allow_changes,
std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
{
optimize_internal(object_stream_data, allow_changes, skip_stream_parameters);
}
void
QPDF::optimize(
QPDFWriter::ObjTable const& obj, std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
{
optimize_internal(obj, true, skip_stream_parameters);
}
template <typename T>
void
QPDF::optimize_internal(
T const& object_stream_data,
bool allow_changes,
std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
{
if (!m->obj_user_to_objects.empty()) {
// already optimized
@ -379,3 +397,45 @@ QPDF::filterCompressedObjects(std::map<int, int> const& object_stream_data)
m->obj_user_to_objects = t_obj_user_to_objects;
m->object_to_obj_users = t_object_to_obj_users;
}
void
QPDF::filterCompressedObjects(QPDFWriter::ObjTable const& obj)
{
if (obj.getStreamsEmpty()) {
return;
}
// Transform object_to_obj_users and obj_user_to_objects so that they refer only to uncompressed
// objects. If something is a user of a compressed object, then it is really a user of the
// object stream that contains it.
std::map<ObjUser, std::set<QPDFObjGen>> t_obj_user_to_objects;
std::map<QPDFObjGen, std::set<ObjUser>> t_object_to_obj_users;
for (auto const& i1: m->obj_user_to_objects) {
ObjUser const& ou = i1.first;
// Loop over objects.
for (auto const& og: i1.second) {
if (auto const& i2 = obj[og].object_stream; i2 <= 0) {
t_obj_user_to_objects[ou].insert(og);
} else {
t_obj_user_to_objects[ou].insert(QPDFObjGen(i2, 0));
}
}
}
for (auto const& i1: m->object_to_obj_users) {
QPDFObjGen const& og = i1.first;
// Loop over obj_users.
for (auto const& ou: i1.second) {
if (auto i2 = obj[og].object_stream; i2 <= 0) {
t_object_to_obj_users[og].insert(ou);
} else {
t_object_to_obj_users[QPDFObjGen(i2, 0)].insert(ou);
}
}
}
m->obj_user_to_objects = t_obj_user_to_objects;
m->object_to_obj_users = t_object_to_obj_users;
}