2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-11-02 03:42:30 +00:00

Tune QPDF::getAllPagesInternal

Avoid calling getAllPagesInternal for each /Page object.
This commit is contained in:
m-holger 2022-07-12 12:35:24 +01:00
parent 4ccca20db0
commit 9dea7d3080
3 changed files with 34 additions and 28 deletions

View File

@ -82,7 +82,10 @@ QPDF::getAllPages()
getRoot().replaceKey("/Pages", pages); getRoot().replaceKey("/Pages", pages);
} }
seen.clear(); seen.clear();
getAllPagesInternal(pages, visited, seen); if (pages.hasKey("/Kids")) {
// Ensure we actually found a /Pages object.
getAllPagesInternal(pages, visited, seen);
}
} }
return this->m->all_pages; return this->m->all_pages;
} }
@ -93,8 +96,8 @@ QPDF::getAllPagesInternal(
std::set<QPDFObjGen>& visited, std::set<QPDFObjGen>& visited,
std::set<QPDFObjGen>& seen) std::set<QPDFObjGen>& seen)
{ {
QPDFObjGen this_og = cur_node.getObjGen(); QPDFObjGen cur_node_og = cur_node.getObjGen();
if (visited.count(this_og) > 0) { if (visited.count(cur_node_og) > 0) {
throw QPDFExc( throw QPDFExc(
qpdf_e_pages, qpdf_e_pages,
this->m->file->getName(), this->m->file->getName(),
@ -102,14 +105,22 @@ QPDF::getAllPagesInternal(
0, 0,
"Loop detected in /Pages structure (getAllPages)"); "Loop detected in /Pages structure (getAllPages)");
} }
visited.insert(this_og); visited.insert(cur_node_og);
std::string wanted_type; if (!cur_node.isDictionaryOfType("/Pages")) {
if (cur_node.hasKey("/Kids")) { warn(
wanted_type = "/Pages"; qpdf_e_damaged_pdf,
QPDFObjectHandle kids = cur_node.getKey("/Kids"); "page tree node",
int n = kids.getArrayNItems(); m->file->getLastOffset(),
for (int i = 0; i < n; ++i) { "/Type key should be /Pages but is not; overriding");
QPDFObjectHandle kid = kids.getArrayItem(i); cur_node.replaceKey("/Type", "/Pages"_qpdf);
}
auto kids = cur_node.getKey("/Kids");
int n = kids.getArrayNItems();
for (int i = 0; i < n; ++i) {
auto kid = kids.getArrayItem(i);
if (kid.hasKey("/Kids")) {
getAllPagesInternal(kid, visited, seen);
} else {
if (!kid.isIndirect()) { if (!kid.isIndirect()) {
QTC::TC("qpdf", "QPDF handle direct page object"); QTC::TC("qpdf", "QPDF handle direct page object");
cur_node.warnIfPossible( cur_node.warnIfPossible(
@ -128,23 +139,18 @@ QPDF::getAllPagesInternal(
kid = makeIndirectObject(QPDFObjectHandle(kid).shallowCopy()); kid = makeIndirectObject(QPDFObjectHandle(kid).shallowCopy());
kids.setArrayItem(i, kid); kids.setArrayItem(i, kid);
} }
getAllPagesInternal(kid, visited, seen); if (!kid.isDictionaryOfType("/Page")) {
warn(
qpdf_e_damaged_pdf,
"page tree node",
this->m->file->getLastOffset(),
"/Type key should be /Page but is not; overriding");
kid.replaceKey("/Type", "/Page"_qpdf);
}
seen.insert(kid.getObjGen());
m->all_pages.push_back(kid);
} }
} else {
wanted_type = "/Page";
seen.insert(this_og);
m->all_pages.push_back(cur_node);
} }
if (!cur_node.isDictionaryOfType(wanted_type)) {
warn(
qpdf_e_damaged_pdf,
"page tree node",
this->m->file->getLastOffset(),
"/Type key should be " + wanted_type + " but is not; overriding");
cur_node.replaceKey("/Type", QPDFObjectHandle::newName(wanted_type));
}
visited.erase(this_og);
} }
void void

View File

@ -1,3 +1,3 @@
WARNING: no-pages-types.pdf (page tree node, offset 307): /Type key should be /Page but is not; overriding
WARNING: no-pages-types.pdf (page tree node, offset 307): /Type key should be /Pages but is not; overriding WARNING: no-pages-types.pdf (page tree node, offset 307): /Type key should be /Pages but is not; overriding
WARNING: no-pages-types.pdf (page tree node, offset 307): /Type key should be /Page but is not; overriding
qpdf: operation succeeded with warnings; resulting file may have some problems qpdf: operation succeeded with warnings; resulting file may have some problems

View File

@ -2,6 +2,6 @@ checking no-pages-types.pdf
PDF Version: 1.3 PDF Version: 1.3
File is not encrypted File is not encrypted
File is not linearized File is not linearized
WARNING: no-pages-types.pdf (page tree node, offset 135): /Type key should be /Pages but is not; overriding
WARNING: no-pages-types.pdf (page tree node, offset 307): /Type key should be /Page but is not; overriding WARNING: no-pages-types.pdf (page tree node, offset 307): /Type key should be /Page but is not; overriding
WARNING: no-pages-types.pdf (page tree node, offset 307): /Type key should be /Pages but is not; overriding
qpdf: operation succeeded with warnings qpdf: operation succeeded with warnings