mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-31 14:01:59 +00:00
Refactor QPDF::checkLinearizationInternal
This commit is contained in:
parent
7775aec33e
commit
98c14e7740
@ -836,6 +836,7 @@ class QPDF
|
|||||||
void optimize(
|
void optimize(
|
||||||
QPDFWriter::ObjTable const& obj,
|
QPDFWriter::ObjTable const& obj,
|
||||||
std::function<int(QPDFObjectHandle&)> skip_stream_parameters);
|
std::function<int(QPDFObjectHandle&)> skip_stream_parameters);
|
||||||
|
void optimize(Xref_table const& obj);
|
||||||
size_t tableSize();
|
size_t tableSize();
|
||||||
|
|
||||||
// Get lists of all objects in order according to the part of a linearized file that they belong
|
// Get lists of all objects in order according to the part of a linearized file that they belong
|
||||||
@ -935,6 +936,7 @@ class QPDF
|
|||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
getUncompressedObject(QPDFObjectHandle&, std::map<int, int> const& object_stream_data);
|
getUncompressedObject(QPDFObjectHandle&, std::map<int, int> const& object_stream_data);
|
||||||
QPDFObjectHandle getUncompressedObject(QPDFObjectHandle&, QPDFWriter::ObjTable const& obj);
|
QPDFObjectHandle getUncompressedObject(QPDFObjectHandle&, QPDFWriter::ObjTable const& obj);
|
||||||
|
QPDFObjectHandle getUncompressedObject(QPDFObjectHandle&, Xref_table const& obj);
|
||||||
int lengthNextN(int first_object, int n);
|
int lengthNextN(int first_object, int n);
|
||||||
void
|
void
|
||||||
checkHPageOffset(std::vector<QPDFObjectHandle> const& pages, std::map<int, int>& idx_to_obj);
|
checkHPageOffset(std::vector<QPDFObjectHandle> const& pages, std::map<int, int>& idx_to_obj);
|
||||||
@ -980,6 +982,7 @@ class QPDF
|
|||||||
std::function<int(QPDFObjectHandle&)> skip_stream_parameters);
|
std::function<int(QPDFObjectHandle&)> skip_stream_parameters);
|
||||||
void filterCompressedObjects(std::map<int, int> const& object_stream_data);
|
void filterCompressedObjects(std::map<int, int> const& object_stream_data);
|
||||||
void filterCompressedObjects(QPDFWriter::ObjTable const& object_stream_data);
|
void filterCompressedObjects(QPDFWriter::ObjTable const& object_stream_data);
|
||||||
|
void filterCompressedObjects(Xref_table const& object_stream_data);
|
||||||
|
|
||||||
// JSON import
|
// JSON import
|
||||||
void importJSON(std::shared_ptr<InputSource>, bool must_be_complete);
|
void importJSON(std::shared_ptr<InputSource>, bool must_be_complete);
|
||||||
|
@ -484,18 +484,9 @@ QPDF::checkLinearizationInternal()
|
|||||||
// Further checking requires optimization and order calculation. Don't allow optimization to
|
// Further checking requires optimization and order calculation. Don't allow optimization to
|
||||||
// make changes. If it has to, then the file is not properly linearized. We use the xref table
|
// make changes. If it has to, then the file is not properly linearized. We use the xref table
|
||||||
// to figure out which objects are compressed and which are uncompressed.
|
// to figure out which objects are compressed and which are uncompressed.
|
||||||
{ // local scope
|
|
||||||
std::map<int, int> object_stream_data;
|
optimize(m->xref_table);
|
||||||
for (auto const& iter: m->xref_table.as_map()) {
|
calculateLinearizationData(m->xref_table);
|
||||||
QPDFObjGen const& og = iter.first;
|
|
||||||
QPDFXRefEntry const& entry = iter.second;
|
|
||||||
if (entry.getType() == 2) {
|
|
||||||
object_stream_data[og.getObj()] = entry.getObjStreamNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
optimize(object_stream_data, false);
|
|
||||||
calculateLinearizationData(object_stream_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// E: offset of end of first page -- Implementation note 123 says Acrobat includes on extra
|
// E: offset of end of first page -- Implementation note 123 says Acrobat includes on extra
|
||||||
// object here by mistake. pdlin fails to place thumbnail images in section 9, so when
|
// object here by mistake. pdlin fails to place thumbnail images in section 9, so when
|
||||||
@ -581,6 +572,16 @@ QPDF::getUncompressedObject(QPDFObjectHandle& obj, std::map<int, int> const& obj
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPDFObjectHandle
|
||||||
|
QPDF::getUncompressedObject(QPDFObjectHandle& obj, Xref_table const& xref)
|
||||||
|
{
|
||||||
|
auto og = obj.getObjGen();
|
||||||
|
if (obj.isNull() || xref.type(og) != 2) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
return getObject(xref.stream_number(og.getObj()), 0);
|
||||||
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
QPDF::getUncompressedObject(QPDFObjectHandle& oh, QPDFWriter::ObjTable const& obj)
|
QPDF::getUncompressedObject(QPDFObjectHandle& oh, QPDFWriter::ObjTable const& obj)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,12 @@ QPDF::optimize(
|
|||||||
optimize_internal(obj, true, skip_stream_parameters);
|
optimize_internal(obj, true, skip_stream_parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDF::optimize(QPDF::Xref_table const& xref)
|
||||||
|
{
|
||||||
|
optimize_internal(xref, false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
QPDF::optimize_internal(
|
QPDF::optimize_internal(
|
||||||
@ -442,3 +448,45 @@ QPDF::filterCompressedObjects(QPDFWriter::ObjTable const& obj)
|
|||||||
m->obj_user_to_objects = t_obj_user_to_objects;
|
m->obj_user_to_objects = t_obj_user_to_objects;
|
||||||
m->object_to_obj_users = t_object_to_obj_users;
|
m->object_to_obj_users = t_object_to_obj_users;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDF::filterCompressedObjects(QPDF::Xref_table const& xref)
|
||||||
|
{
|
||||||
|
if (!xref.object_streams()) {
|
||||||
|
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 stream = xref.stream_number(og.getObj())) {
|
||||||
|
t_obj_user_to_objects[ou].insert(QPDFObjGen(stream, 0));
|
||||||
|
} else {
|
||||||
|
t_obj_user_to_objects[ou].insert(og);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 stream = xref.stream_number(og.getObj())) {
|
||||||
|
t_object_to_obj_users[QPDFObjGen(stream, 0)].insert(ou);
|
||||||
|
} else {
|
||||||
|
t_object_to_obj_users[og].insert(ou);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m->obj_user_to_objects = t_obj_user_to_objects;
|
||||||
|
m->object_to_obj_users = t_object_to_obj_users;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user