mirror of
https://github.com/qpdf/qpdf.git
synced 2024-06-01 01:40:51 +00:00
Replace QPDF::Writer::getObjectStreamData with getXRefTable
This commit is contained in:
parent
ef3a8025fb
commit
ae00ee6119
|
@ -753,18 +753,18 @@ class QPDF
|
||||||
return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);
|
return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
getObjectStreamData(QPDF& qpdf, std::map<int, int>& omap)
|
|
||||||
{
|
|
||||||
qpdf.getObjectStreamData(omap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<QPDFObjGen>
|
static std::vector<QPDFObjGen>
|
||||||
getCompressibleObjGens(QPDF& qpdf)
|
getCompressibleObjGens(QPDF& qpdf)
|
||||||
{
|
{
|
||||||
return qpdf.getCompressibleObjGens();
|
return qpdf.getCompressibleObjGens();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::map<QPDFObjGen, QPDFXRefEntry> const&
|
||||||
|
getXRefTable(QPDF& qpdf)
|
||||||
|
{
|
||||||
|
return qpdf.getXRefTableInternal();
|
||||||
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
tableSize(QPDF& qpdf)
|
tableSize(QPDF& qpdf)
|
||||||
{
|
{
|
||||||
|
@ -1088,6 +1088,7 @@ class QPDF
|
||||||
|
|
||||||
// For QPDFWriter:
|
// For QPDFWriter:
|
||||||
|
|
||||||
|
std::map<QPDFObjGen, QPDFXRefEntry> const& getXRefTableInternal();
|
||||||
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
|
||||||
|
@ -1108,9 +1109,6 @@ class QPDF
|
||||||
int& O,
|
int& O,
|
||||||
bool compressed);
|
bool compressed);
|
||||||
|
|
||||||
// Map object to object stream that contains it
|
|
||||||
void getObjectStreamData(std::map<int, int>&);
|
|
||||||
|
|
||||||
// Get a list of objects that would be permitted in an object stream.
|
// Get a list of objects that would be permitted in an object stream.
|
||||||
std::vector<QPDFObjGen> getCompressibleObjGens();
|
std::vector<QPDFObjGen> getCompressibleObjGens();
|
||||||
|
|
||||||
|
|
|
@ -2369,6 +2369,12 @@ QPDF::getRoot()
|
||||||
|
|
||||||
std::map<QPDFObjGen, QPDFXRefEntry>
|
std::map<QPDFObjGen, QPDFXRefEntry>
|
||||||
QPDF::getXRefTable()
|
QPDF::getXRefTable()
|
||||||
|
{
|
||||||
|
return getXRefTableInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<QPDFObjGen, QPDFXRefEntry> const&
|
||||||
|
QPDF::getXRefTableInternal()
|
||||||
{
|
{
|
||||||
if (!m->parsed) {
|
if (!m->parsed) {
|
||||||
throw std::logic_error("QPDF::getXRefTable called before parsing.");
|
throw std::logic_error("QPDF::getXRefTable called before parsing.");
|
||||||
|
@ -2390,18 +2396,6 @@ QPDF::tableSize()
|
||||||
return toS(++max_xref);
|
return toS(++max_xref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
QPDF::getObjectStreamData(std::map<int, int>& omap)
|
|
||||||
{
|
|
||||||
for (auto const& iter: m->xref_table) {
|
|
||||||
QPDFObjGen const& og = iter.first;
|
|
||||||
QPDFXRefEntry const& entry = iter.second;
|
|
||||||
if (entry.getType() == 2) {
|
|
||||||
omap[og.getObj()] = entry.getObjStreamNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<QPDFObjGen>
|
std::vector<QPDFObjGen>
|
||||||
QPDF::getCompressibleObjGens()
|
QPDF::getCompressibleObjGens()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1936,12 +1936,7 @@ QPDFWriter::initializeSpecialStreams()
|
||||||
void
|
void
|
||||||
QPDFWriter::preserveObjectStreams()
|
QPDFWriter::preserveObjectStreams()
|
||||||
{
|
{
|
||||||
std::map<int, int> omap;
|
auto const& xref = QPDF::Writer::getXRefTable(m->pdf);
|
||||||
QPDF::Writer::getObjectStreamData(m->pdf, omap);
|
|
||||||
if (omap.empty()) {
|
|
||||||
m->obj.streams_empty = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object
|
// Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object
|
||||||
// streams out of old objects that have generation numbers greater than zero. However in an
|
// streams out of old objects that have generation numbers greater than zero. However in an
|
||||||
// existing PDF, all object stream objects and all objects in them must have generation 0
|
// existing PDF, all object stream objects and all objects in them must have generation 0
|
||||||
|
@ -1949,20 +1944,45 @@ QPDFWriter::preserveObjectStreams()
|
||||||
// that are not allowed to be in object streams. In addition to removing objects that were
|
// that are not allowed to be in object streams. In addition to removing objects that were
|
||||||
// erroneously included in object streams in the source PDF, it also prevents unreferenced
|
// erroneously included in object streams in the source PDF, it also prevents unreferenced
|
||||||
// objects from being included.
|
// objects from being included.
|
||||||
std::set<QPDFObjGen> eligible;
|
auto iter = xref.cbegin();
|
||||||
if (!m->preserve_unreferenced_objects) {
|
auto end = xref.cend();
|
||||||
std::vector<QPDFObjGen> eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf);
|
|
||||||
eligible = std::set<QPDFObjGen>(eligible_v.begin(), eligible_v.end());
|
// Start by scanning for first compressed object in case we don't have any object streams to
|
||||||
}
|
// process.
|
||||||
QTC::TC("qpdf", "QPDFWriter preserve object streams", m->preserve_unreferenced_objects ? 0 : 1);
|
for (; iter != end; ++iter) {
|
||||||
for (auto iter: omap) {
|
if (iter->second.getType() == 2) {
|
||||||
QPDFObjGen og(iter.first, 0);
|
// Pdf contains object streams.
|
||||||
if (eligible.count(og) || m->preserve_unreferenced_objects) {
|
QTC::TC(
|
||||||
m->obj[iter.first].object_stream = iter.second;
|
"qpdf",
|
||||||
} else {
|
"QPDFWriter preserve object streams",
|
||||||
QTC::TC("qpdf", "QPDFWriter exclude from object stream");
|
m->preserve_unreferenced_objects ? 0 : 1);
|
||||||
|
|
||||||
|
if (m->preserve_unreferenced_objects) {
|
||||||
|
for (; iter != end; ++iter) {
|
||||||
|
if (iter->second.getType() == 2) {
|
||||||
|
m->obj[iter->first].object_stream = iter->second.getObjStreamNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::set<QPDFObjGen> eligible;
|
||||||
|
std::vector<QPDFObjGen> eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf);
|
||||||
|
eligible = std::set<QPDFObjGen>(eligible_v.begin(), eligible_v.end());
|
||||||
|
for (; iter != end; ++iter) {
|
||||||
|
if (iter->second.getType() == 2) {
|
||||||
|
QPDFObjGen og(iter->first.getObj(), 0);
|
||||||
|
if (eligible.count(og)) {
|
||||||
|
m->obj[iter->first].object_stream = iter->second.getObjStreamNumber();
|
||||||
|
} else {
|
||||||
|
QTC::TC("qpdf", "QPDFWriter exclude from object stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// No compressed objects found.
|
||||||
|
m->obj.streams_empty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue
Block a user