mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add method QPDF::Writer::getCompressibleObjSet
Create set without creation of an intermediate vector.
This commit is contained in:
parent
ae00ee6119
commit
0df0d00c58
@ -756,7 +756,13 @@ class QPDF
|
||||
static std::vector<QPDFObjGen>
|
||||
getCompressibleObjGens(QPDF& qpdf)
|
||||
{
|
||||
return qpdf.getCompressibleObjGens();
|
||||
return qpdf.getCompressibleObjVector();
|
||||
}
|
||||
|
||||
static std::vector<bool>
|
||||
getCompressibleObjSet(QPDF& qpdf)
|
||||
{
|
||||
return qpdf.getCompressibleObjSet();
|
||||
}
|
||||
|
||||
static std::map<QPDFObjGen, QPDFXRefEntry> const&
|
||||
@ -1110,7 +1116,10 @@ class QPDF
|
||||
bool compressed);
|
||||
|
||||
// Get a list of objects that would be permitted in an object stream.
|
||||
std::vector<QPDFObjGen> getCompressibleObjGens();
|
||||
template <typename T>
|
||||
std::vector<T> getCompressibleObjGens();
|
||||
std::vector<QPDFObjGen> getCompressibleObjVector();
|
||||
std::vector<bool> getCompressibleObjSet();
|
||||
|
||||
// methods to support page handling
|
||||
|
||||
|
@ -2397,6 +2397,19 @@ QPDF::tableSize()
|
||||
}
|
||||
|
||||
std::vector<QPDFObjGen>
|
||||
QPDF::getCompressibleObjVector()
|
||||
{
|
||||
return getCompressibleObjGens<QPDFObjGen>();
|
||||
}
|
||||
|
||||
std::vector<bool>
|
||||
QPDF::getCompressibleObjSet()
|
||||
{
|
||||
return getCompressibleObjGens<bool>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T>
|
||||
QPDF::getCompressibleObjGens()
|
||||
{
|
||||
// Return a list of objects that are allowed to be in object streams. Walk through the objects
|
||||
@ -2414,7 +2427,14 @@ QPDF::getCompressibleObjGens()
|
||||
std::vector<QPDFObjectHandle> queue;
|
||||
queue.reserve(512);
|
||||
queue.push_back(m->trailer);
|
||||
std::vector<QPDFObjGen> result;
|
||||
std::vector<T> result;
|
||||
if constexpr (std::is_same_v<T, QPDFObjGen>) {
|
||||
result.reserve(m->obj_cache.size());
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
result.resize(max_obj + 1U, false);
|
||||
} else {
|
||||
throw std::logic_error("Unsupported type in QPDF::getCompressibleObjGens");
|
||||
}
|
||||
while (!queue.empty()) {
|
||||
auto obj = queue.back();
|
||||
queue.pop_back();
|
||||
@ -2446,7 +2466,11 @@ QPDF::getCompressibleObjGens()
|
||||
} else if (!(obj.isStream() ||
|
||||
(obj.isDictionaryOfType("/Sig") && obj.hasKey("/ByteRange") &&
|
||||
obj.hasKey("/Contents")))) {
|
||||
result.push_back(og);
|
||||
if constexpr (std::is_same_v<T, QPDFObjGen>) {
|
||||
result.push_back(og);
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
result[id + 1U] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj.isStream()) {
|
||||
|
@ -1964,13 +1964,11 @@ QPDFWriter::preserveObjectStreams()
|
||||
}
|
||||
}
|
||||
} 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());
|
||||
auto eligible = QPDF::Writer::getCompressibleObjSet(m->pdf);
|
||||
for (; iter != end; ++iter) {
|
||||
if (iter->second.getType() == 2) {
|
||||
QPDFObjGen og(iter->first.getObj(), 0);
|
||||
if (eligible.count(og)) {
|
||||
auto id = static_cast<size_t>(iter->first.getObj());
|
||||
if (id < eligible.size() && eligible[id]) {
|
||||
m->obj[iter->first].object_stream = iter->second.getObjStreamNumber();
|
||||
} else {
|
||||
QTC::TC("qpdf", "QPDFWriter exclude from object stream");
|
||||
@ -2009,22 +2007,18 @@ QPDFWriter::generateObjectStreams()
|
||||
++n_per;
|
||||
}
|
||||
unsigned int n = 0;
|
||||
int cur_ostream = 0;
|
||||
for (auto const& iter: eligible) {
|
||||
if ((n % n_per) == 0) {
|
||||
if (n > 0) {
|
||||
QTC::TC("qpdf", "QPDFWriter generate >1 ostream");
|
||||
}
|
||||
int cur_ostream = m->pdf.newIndirectNull().getObjectID();
|
||||
for (auto const& item: eligible) {
|
||||
if (n == n_per) {
|
||||
QTC::TC("qpdf", "QPDFWriter generate >1 ostream");
|
||||
n = 0;
|
||||
}
|
||||
if (n == 0) {
|
||||
// Construct a new null object as the "original" object stream. The rest of the code
|
||||
// knows that this means we're creating the object stream from scratch.
|
||||
cur_ostream = m->pdf.makeIndirectObject(QPDFObjectHandle::newNull()).getObjectID();
|
||||
cur_ostream = m->pdf.newIndirectNull().getObjectID();
|
||||
}
|
||||
auto& obj = m->obj[iter];
|
||||
auto& obj = m->obj[item];
|
||||
obj.object_stream = cur_ostream;
|
||||
obj.gen = iter.getGen();
|
||||
obj.gen = item.getGen();
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user