Commit 81025e499893c38b40aa824a5abc43393a8afed1

Authored by Jay Berkenbilt
1 parent 5fdf37b1

Refactor removal of unreferenced resources

Refactor in preparation for resolving unresolved resources in form
xobjects from page.
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&amp; token) @@ -703,13 +703,8 @@ NameWatcher::handleToken(QPDFTokenizer::Token const&amp; 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