Commit 81025e499893c38b40aa824a5abc43393a8afed1
1 parent
5fdf37b1
Refactor removal of unreferenced resources
Refactor in preparation for resolving unresolved resources in form xobjects from page.
Showing
2 changed files
with
31 additions
and
33 deletions
include/qpdf/QPDFPageObjectHelper.hh
| @@ -319,7 +319,7 @@ class QPDFPageObjectHelper: public QPDFObjectHelper | @@ -319,7 +319,7 @@ class QPDFPageObjectHelper: public QPDFObjectHelper | ||
| 319 | private: | 319 | private: |
| 320 | static void | 320 | static void |
| 321 | removeUnreferencedResourcesHelper( | 321 | removeUnreferencedResourcesHelper( |
| 322 | - QPDFPageObjectHelper ph, std::set<QPDFObjGen>& seen); | 322 | + QPDFPageObjectHelper ph); |
| 323 | 323 | ||
| 324 | class Members | 324 | class Members |
| 325 | { | 325 | { |
libqpdf/QPDFPageObjectHelper.cc
| @@ -703,13 +703,8 @@ NameWatcher::handleToken(QPDFTokenizer::Token const& token) | @@ -703,13 +703,8 @@ NameWatcher::handleToken(QPDFTokenizer::Token const& token) | ||
| 703 | 703 | ||
| 704 | void | 704 | void |
| 705 | QPDFPageObjectHelper::removeUnreferencedResourcesHelper( | 705 | QPDFPageObjectHelper::removeUnreferencedResourcesHelper( |
| 706 | - QPDFPageObjectHelper ph, std::set<QPDFObjGen>& seen) | 706 | + QPDFPageObjectHelper ph) |
| 707 | { | 707 | { |
| 708 | - if (seen.count(ph.oh.getObjGen())) | ||
| 709 | - { | ||
| 710 | - return; | ||
| 711 | - } | ||
| 712 | - seen.insert(ph.oh.getObjGen()); | ||
| 713 | NameWatcher nw; | 708 | NameWatcher nw; |
| 714 | try | 709 | try |
| 715 | { | 710 | { |
| @@ -730,39 +725,35 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( | @@ -730,39 +725,35 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( | ||
| 730 | "not attempting to remove unreferenced objects from this page"); | 725 | "not attempting to remove unreferenced objects from this page"); |
| 731 | return; | 726 | return; |
| 732 | } | 727 | } |
| 733 | - // Walk through /Font and /XObject dictionaries, removing any | ||
| 734 | - // resources that are not referenced. We must make copies of | 728 | + |
| 729 | + // We will walk through /Font and /XObject dictionaries, removing | ||
| 730 | + // any resources that are not referenced. We must make copies of | ||
| 735 | // resource dictionaries down into the dictionaries are mutating | 731 | // resource dictionaries down into the dictionaries are mutating |
| 736 | // to prevent mutating one dictionary from having the side effect | 732 | // to prevent mutating one dictionary from having the side effect |
| 737 | // of mutating the one it was copied from. | 733 | // of mutating the one it was copied from. |
| 738 | - std::vector<std::string> to_filter; | ||
| 739 | - to_filter.push_back("/Font"); | ||
| 740 | - to_filter.push_back("/XObject"); | ||
| 741 | QPDFObjectHandle resources = ph.getAttribute("/Resources", true); | 734 | QPDFObjectHandle resources = ph.getAttribute("/Resources", true); |
| 742 | - for (std::vector<std::string>::iterator d_iter = to_filter.begin(); | ||
| 743 | - d_iter != to_filter.end(); ++d_iter) | 735 | + std::vector<QPDFObjectHandle> rdicts; |
| 736 | + if (resources.isDictionary()) | ||
| 744 | { | 737 | { |
| 745 | - QPDFObjectHandle dict = resources.getKey(*d_iter); | ||
| 746 | - if (! dict.isDictionary()) | ||
| 747 | - { | ||
| 748 | - continue; | ||
| 749 | - } | ||
| 750 | - dict = dict.shallowCopy(); | ||
| 751 | - resources.replaceKey(*d_iter, dict); | ||
| 752 | - std::set<std::string> keys = dict.getKeys(); | ||
| 753 | - for (std::set<std::string>::iterator k_iter = keys.begin(); | ||
| 754 | - k_iter != keys.end(); ++k_iter) | 738 | + std::vector<std::string> to_filter = {"/Font", "/XObject"}; |
| 739 | + for (auto const& iter: to_filter) | ||
| 755 | { | 740 | { |
| 756 | - if (! nw.names.count(*k_iter)) | 741 | + QPDFObjectHandle dict = resources.getKey(iter); |
| 742 | + if (dict.isDictionary()) | ||
| 757 | { | 743 | { |
| 758 | - dict.removeKey(*k_iter); | 744 | + dict = dict.shallowCopy(); |
| 745 | + resources.replaceKey(iter, dict); | ||
| 746 | + rdicts.push_back(dict); | ||
| 759 | } | 747 | } |
| 760 | - QPDFObjectHandle resource = dict.getKey(*k_iter); | ||
| 761 | - if (resource.isFormXObject()) | 748 | + } |
| 749 | + } | ||
| 750 | + for (auto& dict: rdicts) | ||
| 751 | + { | ||
| 752 | + for (auto const& key: dict.getKeys()) | ||
| 753 | + { | ||
| 754 | + if (! nw.names.count(key)) | ||
| 762 | { | 755 | { |
| 763 | - QTC::TC("qpdf", "QPDFPageObjectHelper filter form xobject"); | ||
| 764 | - removeUnreferencedResourcesHelper( | ||
| 765 | - QPDFPageObjectHelper(resource), seen); | 756 | + dict.removeKey(key); |
| 766 | } | 757 | } |
| 767 | } | 758 | } |
| 768 | } | 759 | } |
| @@ -771,8 +762,15 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( | @@ -771,8 +762,15 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( | ||
| 771 | void | 762 | void |
| 772 | QPDFPageObjectHelper::removeUnreferencedResources() | 763 | QPDFPageObjectHelper::removeUnreferencedResources() |
| 773 | { | 764 | { |
| 774 | - std::set<QPDFObjGen> seen; | ||
| 775 | - removeUnreferencedResourcesHelper(*this, seen); | 765 | + forEachFormXObject( |
| 766 | + true, | ||
| 767 | + []( | ||
| 768 | + QPDFObjectHandle& obj, QPDFObjectHandle&, std::string const&) | ||
| 769 | + { | ||
| 770 | + QTC::TC("qpdf", "QPDFPageObjectHelper filter form xobject"); | ||
| 771 | + removeUnreferencedResourcesHelper(QPDFPageObjectHelper(obj)); | ||
| 772 | + }); | ||
| 773 | + removeUnreferencedResourcesHelper(*this); | ||
| 776 | } | 774 | } |
| 777 | 775 | ||
| 778 | QPDFPageObjectHelper | 776 | QPDFPageObjectHelper |