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 319 private:
320 320 static void
321 321 removeUnreferencedResourcesHelper(
322   - QPDFPageObjectHelper ph, std::set<QPDFObjGen>& seen);
  322 + QPDFPageObjectHelper ph);
323 323  
324 324 class Members
325 325 {
... ...
libqpdf/QPDFPageObjectHelper.cc
... ... @@ -703,13 +703,8 @@ NameWatcher::handleToken(QPDFTokenizer::Token const&amp; token)
703 703  
704 704 void
705 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 708 NameWatcher nw;
714 709 try
715 710 {
... ... @@ -730,39 +725,35 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper(
730 725 "not attempting to remove unreferenced objects from this page");
731 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 731 // resource dictionaries down into the dictionaries are mutating
736 732 // to prevent mutating one dictionary from having the side effect
737 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 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 762 void
772 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 776 QPDFPageObjectHelper
... ...