diff options
Diffstat (limited to 'Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc')
-rw-r--r-- | Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc | 136 |
1 files changed, 78 insertions, 58 deletions
diff --git a/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc b/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc index 5f56111581e..9a53d9c9e97 100644 --- a/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc +++ b/Build/source/libs/poppler/poppler-src/poppler/StructTreeRoot.cc @@ -7,8 +7,8 @@ // Copyright 2013, 2014 Igalia S.L. // Copyright 2014 Fabio D'Urso <fabiodurso@hotmail.it> // Copyright 2017 Jan-Erik S <janerik234678@gmail.com> -// Copyright 2017 Albert Astals Cid <aacid@kde.org> -// Copyright 2017 Adrian Johnson <ajohnson@redneon.com> +// Copyright 2017, 2018 Albert Astals Cid <aacid@kde.org> +// Copyright 2017, 2018 Adrian Johnson <ajohnson@redneon.com> // //======================================================================== @@ -53,52 +53,9 @@ void StructTreeRoot::parse(Dict *root) // corresponsing structure element. Here only the references are // loaded into the array, the pointers to the StructElements will // be filled-in later when parsing them. - Object obj = root->lookup("ParentTree"); - if (obj.isDict()) { - Object nums = obj.dictLookup("Nums"); - if (nums.isArray()) { - if (nums.arrayGetLength() % 2 == 0) { - parentTree.resize(nums.arrayGetLength() / 2); - // Index numbers in even positions, references in odd ones - for (int i = 0; i < nums.arrayGetLength(); i += 2) { - Object index = nums.arrayGet(i); - - if (!index.isInt()) { - error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i, index.getTypeName()); - continue; - } - const int idx = index.getInt(); - if (idx < 0 || idx >= (int)parentTree.size()) { - error(errSyntaxError, -1, "Nums item at position {0:d} is invalid value ({1:d}): [0..{2:d}]", i, idx, parentTree.size() - 1); - continue; - } - - Object value = nums.arrayGetNF(i + 1); - if (value.isRef()) { - parentTree[idx].resize(1); - parentTree[idx][0].ref = value.getRef(); - } else { - value = nums.arrayGet(i + 1); - if (value.isArray()) { - parentTree[idx].resize(value.arrayGetLength()); - for (int j = 0; j < value.arrayGetLength(); j++) { - Object itemvalue = value.arrayGetNF(j); - if (itemvalue.isRef()) - parentTree[idx][j].ref = itemvalue.getRef(); - else - error(errSyntaxError, -1, "Nums array item at position {0:d}/{1:d} is invalid type ({2:s})", i, j, itemvalue.getTypeName()); - } - } else { - error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i + 1, value.getTypeName()); - } - } - } - } else { - error(errSyntaxError, -1, "Nums array length is not a even ({0:d})", nums.arrayGetLength()); - } - } else { - error(errSyntaxError, -1, "Nums object is wrong type ({0:s})", nums.getTypeName()); - } + const Object parentTreeObj = root->lookup("ParentTree"); + if (parentTreeObj.isDict()) { + parseNumberTreeNode(parentTreeObj.getDict()); } std::set<int> seenElements; @@ -117,7 +74,7 @@ void StructTreeRoot::parse(Dict *root) } Object obj = kids.arrayGet(i); if (obj.isDict()) { - StructElement *child = new StructElement(obj.getDict(), this, NULL, seenElements); + StructElement *child = new StructElement(obj.getDict(), this, nullptr, seenElements); if (child->isOk()) { if (marked && !(child->getType() == StructElement::Document || child->getType() == StructElement::Part || @@ -138,10 +95,7 @@ void StructTreeRoot::parse(Dict *root) } } } else if (kids.isDict()) { - if (marked) { - error(errSyntaxWarning, -1, "K has a child of wrong type for a tagged PDF ({0:s})", kids.getTypeName()); - } - StructElement *child = new StructElement(kids.getDict(), this, NULL, seenElements); + StructElement *child = new StructElement(kids.getDict(), this, nullptr, seenElements); if (child->isOk()) { appendChild(child); Object ref = root->lookupNF("K"); @@ -154,14 +108,80 @@ void StructTreeRoot::parse(Dict *root) } else if (!kids.isNull()) { error(errSyntaxWarning, -1, "K in StructTreeRoot is wrong type ({0:s})", kids.getTypeName()); } + + // refToParentMap is only used during parsing. Ensure all memory used by it is freed. + std::multimap<Ref, Parent*, RefCompare>().swap(refToParentMap); } -void StructTreeRoot::parentTreeAdd(const Ref &objectRef, StructElement *element) +void StructTreeRoot::parseNumberTreeNode(Dict *node) { - for (std::vector< std::vector<Parent> >::iterator i = parentTree.begin(); i != parentTree.end(); ++i) { - for (std::vector<Parent>::iterator j = i->begin(); j != i->end(); ++j) { - if (j->ref.num == objectRef.num && j->ref.gen == objectRef.gen) - j->element = element; + Object kids = node->lookup("Kids"); + if (kids.isArray()) { + for (int i = 0; i < kids.arrayGetLength(); i++) { + Object obj = kids.arrayGet(i); + if (obj.isDict()) { + parseNumberTreeNode(obj.getDict()); + } else { + error(errSyntaxError, -1, "Kids item at position {0:d} is wrong type ({1:s})", i, obj.getTypeName()); + } } + return; + } else if (!kids.isNull()) { + error(errSyntaxError, -1, "Kids object is wrong type ({0:s})", kids.getTypeName()); } + + Object nums = node->lookup("Nums"); + if (nums.isArray()) { + if (nums.arrayGetLength() % 2 == 0) { + // keys in even positions, references in odd ones + for (int i = 0; i < nums.arrayGetLength(); i += 2) { + Object key = nums.arrayGet(i); + + if (!key.isInt()) { + error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i, key.getTypeName()); + continue; + } + int keyVal = key.getInt(); + std::vector<Parent>& vec = parentTree[keyVal]; + + Object value = nums.arrayGet(i + 1); + if (value.isArray()) { + vec.resize(value.arrayGetLength()); + memset(vec.data(), 0, vec.size()*sizeof(Parent*)); + for (int j = 0; j < value.arrayGetLength(); j++) { + Object itemvalue = value.arrayGetNF(j); + if (itemvalue.isRef()) { + Ref ref = itemvalue.getRef(); + vec[j].ref = ref; + refToParentMap.insert(std::pair<Ref, Parent*>(ref, &vec[j])); + } else if (!itemvalue.isNull()) { + error(errSyntaxError, -1, "Nums array item at position {0:d}/{1:d} is invalid type ({2:s})", i, j, itemvalue.getTypeName()); + } + } + } else { + value = nums.arrayGetNF(i + 1); + if (value.isRef()) { + Ref ref = value.getRef(); + vec.resize(1); + vec[0].ref = ref; + refToParentMap.insert(std::pair<Ref, Parent*>(ref, &vec[0])); + } else { + error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i + 1, value.getTypeName()); + } + } + } + } else { + error(errSyntaxError, -1, "Nums array length is not a even ({0:d})", nums.arrayGetLength()); + } + } else { + error(errSyntaxError, -1, "Nums object is wrong type ({0:s})", nums.getTypeName()); + } +} + + +void StructTreeRoot::parentTreeAdd(const Ref &objectRef, StructElement *element) +{ + auto range = refToParentMap.equal_range(objectRef); + for (auto it = range.first; it !=range.second; ++it) + it->second->element = element; } |