QPDFPageObjectHelper::removeUnreferencedResources()
{
    NameWatcher nw;
    try
    {
        filterPageContents(&nw);
    }
    catch (std::exception& e)
    {
        this->oh.warnIfPossible(
            std::string("Unable to parse content stream: ") + e.what() +
            "; not attempting to remove unreferenced objects from this page");
        return;
    }
    if (nw.saw_bad)
    {
        QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names");
        this->oh.warnIfPossible(
            "Bad token found while scanning content stream; "
            "not attempting to remove unreferenced objects from this page");
        return;
    }
    // Walk through /Font and /XObject dictionaries, removing any
    // resources that are not referenced. We must make copies of
    // resource dictionaries down into the dictionaries are mutating
    // to prevent mutating one dictionary from having the side effect
    // of mutating the one it was copied from.
    std::vector<std::string> to_filter;
    to_filter.push_back("/Font");
    to_filter.push_back("/XObject");
    QPDFObjectHandle resources = getAttribute("/Resources", true);
    for (std::vector<std::string>::iterator d_iter = to_filter.begin();
         d_iter != to_filter.end(); ++d_iter)
    {
        QPDFObjectHandle dict = resources.getKey(*d_iter);
        if (! dict.isDictionary())
        {
            continue;
        }
        dict = dict.shallowCopy();
        resources.replaceKey(*d_iter, dict);
        std::set<std::string> keys = dict.getKeys();
        for (std::set<std::string>::iterator k_iter = keys.begin();
             k_iter != keys.end(); ++k_iter)
        {
            if (! nw.names.count(*k_iter))
            {
                dict.removeKey(*k_iter);
            }
        }
    }
}
QPDFPageObjectHelper::removeUnreferencedResources()
{
    NameWatcher nw;
    try
    {
        filterPageContents(&nw);
    }
    catch (std::exception& e)
    {
        this->oh.warnIfPossible(
            std::string("Unable to parse content stream: ") + e.what() +
            "; not attempting to remove unreferenced objects from this page");
        return;
    }
    if (nw.saw_bad)
    {
        QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names");
        this->oh.warnIfPossible(
            "Bad token found while scanning content stream; "
            "not attempting to remove unreferenced objects from this page");
        return;
    }
     
     
     
     
     
    std::vector<std::string> to_filter;
    to_filter.push_back("/Font");
    to_filter.push_back("/XObject");
    QPDFObjectHandle resources = getAttribute("/Resources", true);
    for (std::vector<std::string>::iterator d_iter = to_filter.begin();
         d_iter != to_filter.end(); ++d_iter)
    {
        QPDFObjectHandle dict = resources.getKey(*d_iter);
        if (! dict.isDictionary())
        {
            continue;
        }
        dict = dict.shallowCopy();
        resources.replaceKey(*d_iter, dict);
        std::set<std::string> keys = dict.getKeys();
        for (std::set<std::string>::iterator k_iter = keys.begin();
             k_iter != keys.end(); ++k_iter)
        {
            if (! nw.names.count(*k_iter))
            {
                dict.removeKey(*k_iter);
            }
        }
    }
}