aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/ResourceFinder.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-03-01 22:43:35 +0100
committerJay Berkenbilt <ejb@ql.org>2021-03-03 23:05:49 +0100
commite17585c2d2df9fea296364c0768c2ce5adbc4b91 (patch)
tree356a5b3c7096175ed1ed08d1535a1e4d50f0484d /libqpdf/ResourceFinder.cc
parenta15ec6967dd3312223a6ab7d4198655234e1a4bf (diff)
downloadqpdf-e17585c2d2df9fea296364c0768c2ce5adbc4b91.tar.zst
Remove unreferenced: ignore names that are not Fonts or XObjects
Converted ResourceFinder to ParserCallbacks so we can better detect the name that precedes various operators and use the operators to sort the names into resource types. This enables us to be smarter about detecting unreferenced resources in pages and also sets the stage for reconciling differences in /DR across documents.
Diffstat (limited to 'libqpdf/ResourceFinder.cc')
-rw-r--r--libqpdf/ResourceFinder.cc55
1 files changed, 43 insertions, 12 deletions
diff --git a/libqpdf/ResourceFinder.cc b/libqpdf/ResourceFinder.cc
index 74ba671f..6b9929e4 100644
--- a/libqpdf/ResourceFinder.cc
+++ b/libqpdf/ResourceFinder.cc
@@ -1,28 +1,53 @@
#include <qpdf/ResourceFinder.hh>
ResourceFinder::ResourceFinder() :
+ last_name_offset(0),
saw_bad(false)
{
}
void
-ResourceFinder::handleToken(QPDFTokenizer::Token const& token)
+ResourceFinder::handleObject(QPDFObjectHandle obj, size_t offset, size_t)
{
- if ((token.getType() == QPDFTokenizer::tt_word) &&
- (! this->last_name.empty()))
+ if (obj.isOperator() && (! this->last_name.empty()))
{
- this->names.insert(this->last_name);
+ static std::map<std::string, std::string> op_to_rtype = {
+ {"CS", "/ColorSpace"},
+ {"cs", "/ColorSpace"},
+ {"gs", "/ExtGState"},
+ {"Tf", "/Font"},
+ {"SCN", "/Pattern"},
+ {"scn", "/Pattern"},
+ {"BDC", "/Properties"},
+ {"DP", "/Properties"},
+ {"sh", "/Shading"},
+ {"Do", "/XObject"},
+ };
+ std::string op = obj.getOperatorValue();
+ std::string resource_type;
+ auto iter = op_to_rtype.find(op);
+ if (iter != op_to_rtype.end())
+ {
+ resource_type = iter->second;
+ }
+ if (! resource_type.empty())
+ {
+ this->names.insert(this->last_name);
+ this->names_by_resource_type[
+ resource_type][this->last_name].insert(this->last_name_offset);
+ }
}
- else if (token.getType() == QPDFTokenizer::tt_name)
+ else if (obj.isName())
{
- this->last_name =
- QPDFObjectHandle::newName(token.getValue()).getName();
+ this->last_name = obj.getName();
+ this->last_name_offset = offset;
}
- else if (token.getType() == QPDFTokenizer::tt_bad)
- {
- saw_bad = true;
- }
- writeToken(token);
+}
+
+void
+ResourceFinder::handleWarning()
+{
+ this->saw_bad = true;
}
std::set<std::string> const&
@@ -31,6 +56,12 @@ ResourceFinder::getNames() const
return this->names;
}
+std::map<std::string, std::map<std::string, std::set<size_t>>> const&
+ResourceFinder::getNamesByResourceType() const
+{
+ return this->names_by_resource_type;
+}
+
bool
ResourceFinder::sawBad() const
{