From a3a55be9cdebd517f4dce9ff66aeda78b136b003 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 24 Dec 2017 19:18:52 -0500 Subject: Correct errors in PNG filters and make use from library --- libqpdf/QPDF_Stream.cc | 64 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'libqpdf/QPDF_Stream.cc') diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index cf26f001..62d6a553 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -114,7 +114,9 @@ QPDF_Stream::getRawStreamData() bool QPDF_Stream::understandDecodeParams( std::string const& filter, QPDFObjectHandle decode_obj, - int& predictor, int& columns, bool& early_code_change) + int& predictor, int& columns, + int& colors, int& bits_per_component, + bool& early_code_change) { bool filterable = true; std::set keys = decode_obj.getKeys(); @@ -122,13 +124,15 @@ QPDF_Stream::understandDecodeParams( iter != keys.end(); ++iter) { std::string const& key = *iter; - if ((filter == "/FlateDecode") && (key == "/Predictor")) + if (((filter == "/FlateDecode") || (filter == "/LZWDecode")) && + (key == "/Predictor")) { QPDFObjectHandle predictor_obj = decode_obj.getKey(key); if (predictor_obj.isInteger()) { predictor = predictor_obj.getIntValue(); - if (! ((predictor == 1) || (predictor == 12))) + if (! ((predictor == 1) || + ((predictor >= 10) && (predictor <= 15)))) { filterable = false; } @@ -155,12 +159,26 @@ QPDF_Stream::understandDecodeParams( filterable = false; } } - else if (key == "/Columns") + else if ((key == "/Columns") || + (key == "/Colors") || + (key == "/BitsPerComponent")) { - QPDFObjectHandle columns_obj = decode_obj.getKey(key); - if (columns_obj.isInteger()) + QPDFObjectHandle param_obj = decode_obj.getKey(key); + if (param_obj.isInteger()) { - columns = columns_obj.getIntValue(); + int val = param_obj.getIntValue(); + if (key == "/Columns") + { + columns = val; + } + else if (key == "/Colors") + { + colors = val; + } + else if (key == "/BitsPerComponent") + { + bits_per_component = val; + } } else { @@ -190,6 +208,7 @@ QPDF_Stream::filterable(std::vector& filters, bool& specialized_compression, bool& lossy_compression, int& predictor, int& columns, + int& colors, int& bits_per_component, bool& early_code_change) { if (filter_abbreviations.empty()) @@ -295,6 +314,8 @@ QPDF_Stream::filterable(std::vector& filters, // Initialize values to their defaults as per the PDF spec predictor = 1; columns = 0; + colors = 1; + bits_per_component = 8; early_code_change = true; // See if we can support any decode parameters that are specified. @@ -344,7 +365,8 @@ QPDF_Stream::filterable(std::vector& filters, { if (! understandDecodeParams( filters.at(i), decode_item, - predictor, columns, early_code_change)) + predictor, columns, colors, bits_per_component, + early_code_change)) { filterable = false; } @@ -378,6 +400,8 @@ QPDF_Stream::pipeStreamData(Pipeline* pipeline, std::vector filters; int predictor = 1; int columns = 0; + int colors = 1; + int bits_per_component = 8; bool early_code_change = true; bool specialized_compression = false; bool lossy_compression = false; @@ -385,7 +409,9 @@ QPDF_Stream::pipeStreamData(Pipeline* pipeline, if (filter) { filter = filterable(filters, specialized_compression, lossy_compression, - predictor, columns, early_code_change); + predictor, columns, + colors, bits_per_component, + early_code_change); if ((decode_level < qpdf_dl_all) && lossy_compression) { filter = false; @@ -430,21 +456,23 @@ QPDF_Stream::pipeStreamData(Pipeline* pipeline, iter != filters.rend(); ++iter) { std::string const& filter = *iter; + + if (((filter == "/FlateDecode") || (filter == "/LZWDecode")) && + ((predictor >= 10) && (predictor <= 15))) + { + QTC::TC("qpdf", "QPDF_Stream PNG filter"); + pipeline = new Pl_PNGFilter( + "png decode", pipeline, Pl_PNGFilter::a_decode, + columns, colors, bits_per_component); + to_delete.push_back(pipeline); + } + if (filter == "/Crypt") { // Ignore -- handled by pipeStreamData } else if (filter == "/FlateDecode") { - if (predictor == 12) - { - QTC::TC("qpdf", "QPDF_Stream PNG filter"); - pipeline = new Pl_PNGFilter( - "png decode", pipeline, Pl_PNGFilter::a_decode, - columns, 0 /* not used */); - to_delete.push_back(pipeline); - } - pipeline = new Pl_Flate("stream inflate", pipeline, Pl_Flate::a_inflate); to_delete.push_back(pipeline); -- cgit v1.2.3-54-g00ecf