1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:57:45 +00:00

LibPDF: Implement png predictor decoding for flate filter

For flate and lzw filters, the data can be transformed by this
predictor function to make it compress better. For us this means that
we have to undo this step in order to get the right result.

Although this feature is meant for images, I found at least a few
documents that use it all over the place, making this step very
important.
This commit is contained in:
Julian Offenhäuser 2022-11-10 23:32:41 +01:00 committed by Andreas Kling
parent 4bd79338e8
commit c2ad29c85f
4 changed files with 137 additions and 15 deletions

View file

@ -488,8 +488,32 @@ PDFErrorOr<NonnullRefPtr<StreamObject>> Parser::parse_stream(NonnullRefPtr<DictO
filters.append(filter_object->cast<NameObject>()->name());
}
for (auto const& filter_type : filters)
stream_object->buffer() = TRY(Filter::decode(stream_object->bytes(), filter_type));
// Every filter may get its own parameter dictionary
Vector<RefPtr<DictObject>> decode_parms_vector;
RefPtr<Object> decode_parms_object;
if (dict->contains(CommonNames::DecodeParms)) {
decode_parms_object = TRY(dict->get_object(m_document, CommonNames::DecodeParms));
if (decode_parms_object->is<ArrayObject>()) {
auto decode_parms_array = decode_parms_object->cast<ArrayObject>();
for (size_t i = 0; i < decode_parms_array->size(); ++i) {
// FIXME: This entry may be the null object instead
RefPtr<DictObject> decode_parms = decode_parms_array->at(i).get<NonnullRefPtr<Object>>()->cast<DictObject>();
decode_parms_vector.append(decode_parms);
}
} else {
decode_parms_vector.append(decode_parms_object->cast<DictObject>());
}
}
VERIFY(decode_parms_vector.is_empty() || decode_parms_vector.size() == filters.size());
for (size_t i = 0; i < filters.size(); ++i) {
RefPtr<DictObject> decode_parms;
if (!decode_parms_vector.is_empty())
decode_parms = decode_parms_vector.at(i);
stream_object->buffer() = TRY(Filter::decode(stream_object->bytes(), filters.at(i), decode_parms));
}
}
return stream_object;