From e7a85545639d6d09923abb8fb300dda5889b110b Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Thu, 31 Dec 2020 11:38:27 -0500 Subject: QPDFPageObjectHelper::getPageImages: support form XObjects --- libqpdf/QPDFPageObjectHelper.cc | 87 +++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 26 deletions(-) (limited to 'libqpdf/QPDFPageObjectHelper.cc') diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc index a80ab641..0e9792a6 100644 --- a/libqpdf/QPDFPageObjectHelper.cc +++ b/libqpdf/QPDFPageObjectHelper.cc @@ -314,33 +314,46 @@ QPDFObjectHandle QPDFPageObjectHelper::getAttribute(std::string const& name, bool copy_if_shared) { - bool inheritable = ((name == "/MediaBox") || (name == "/CropBox") || - (name == "/Resources") || (name == "/Rotate")); - - QPDFObjectHandle node = this->oh; - QPDFObjectHandle result(node.getKey(name)); - std::set seen; + QPDFObjectHandle result; + QPDFObjectHandle dict; + bool is_form_xobject = this->oh.isFormXObject(); bool inherited = false; - while (inheritable && result.isNull() && node.hasKey("/Parent")) + if (is_form_xobject) { - seen.insert(node.getObjGen()); - node = node.getKey("/Parent"); - if (seen.count(node.getObjGen())) - { - break; - } + dict = this->oh.getDict(); + result = dict.getKey(name); + } + else + { + dict = this->oh; + bool inheritable = ((name == "/MediaBox") || (name == "/CropBox") || + (name == "/Resources") || (name == "/Rotate")); + + QPDFObjectHandle node = dict; result = node.getKey(name); - if (! result.isNull()) + std::set seen; + while (inheritable && result.isNull() && node.hasKey("/Parent")) { - QTC::TC("qpdf", "QPDFPageObjectHelper non-trivial inheritance"); - inherited = true; + seen.insert(node.getObjGen()); + node = node.getKey("/Parent"); + if (seen.count(node.getObjGen())) + { + break; + } + result = node.getKey(name); + if (! result.isNull()) + { + QTC::TC("qpdf", "QPDFPageObjectHelper non-trivial inheritance"); + inherited = true; + } } } if (copy_if_shared && (inherited || result.isIndirect())) { - QTC::TC("qpdf", "QPDFPageObjectHelper copy shared attribute"); + QTC::TC("qpdf", "QPDFPageObjectHelper copy shared attribute", + is_form_xobject ? 0 : 1); result = result.shallowCopy(); - this->oh.replaceKey(name, result); + dict.replaceKey(name, result); } return result; } @@ -376,7 +389,34 @@ QPDFPageObjectHelper::getMediaBox(bool copy_if_shared) std::map QPDFPageObjectHelper::getPageImages() { - return this->oh.getPageImages(); + std::map result; + QPDFObjectHandle resources = getAttribute("/Resources", false); + if (resources.isDictionary()) + { + if (resources.hasKey("/XObject")) + { + QPDFObjectHandle xobject = resources.getKey("/XObject"); + std::set keys = xobject.getKeys(); + for (std::set::iterator iter = keys.begin(); + iter != keys.end(); ++iter) + { + std::string key = (*iter); + QPDFObjectHandle value = xobject.getKey(key); + if (value.isStream()) + { + QPDFObjectHandle dict = value.getDict(); + if (dict.hasKey("/Subtype") && + (dict.getKey("/Subtype").getName() == "/Image") && + (! dict.hasKey("/ImageMask"))) + { + result[key] = value; + } + } + } + } + } + + return result; } void @@ -571,13 +611,8 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( removeUnreferencedResourcesHelper( resource.getDict(), seen, [&resource]() { - auto result = resource.getDict().getKey("/Resources"); - if (result.isDictionary()) - { - result = result.shallowCopy(); - resource.getDict().replaceKey("/Resources", result); - } - return result; + return QPDFPageObjectHelper(resource) + .getAttribute("/Resources", true); }, [&resource](QPDFObjectHandle::TokenFilter* f) { resource.filterAsContents(f); -- cgit v1.2.3-70-g09d2