diff options
Diffstat (limited to 'libqpdf/QPDF_Stream.cc')
-rw-r--r-- | libqpdf/QPDF_Stream.cc | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 31d583b8..bcf9be92 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -9,6 +9,8 @@ #include <qpdf/Pl_ASCII85Decoder.hh> #include <qpdf/Pl_ASCIIHexDecoder.hh> #include <qpdf/Pl_LZWDecoder.hh> +#include <qpdf/Pl_RunLength.hh> +#include <qpdf/Pl_DCT.hh> #include <qpdf/Pl_Count.hh> #include <qpdf/QTC.hh> @@ -82,10 +84,10 @@ QPDF_Stream::getDict() const } PointerHolder<Buffer> -QPDF_Stream::getStreamData() +QPDF_Stream::getStreamData(qpdf_stream_decode_level_e decode_level) { Pl_Buffer buf("stream data buffer"); - if (! pipeStreamData(&buf, true, false, false, false)) + if (! pipeStreamData(&buf, 0, decode_level, false)) { throw std::logic_error("getStreamData called on unfilterable stream"); } @@ -97,7 +99,7 @@ PointerHolder<Buffer> QPDF_Stream::getRawStreamData() { Pl_Buffer buf("stream data buffer"); - pipeStreamData(&buf, false, false, false, false); + pipeStreamData(&buf, 0, qpdf_dl_none, false); QTC::TC("qpdf", "QPDF_Stream getRawStreamData"); return buf.getBuffer(); } @@ -178,6 +180,8 @@ QPDF_Stream::understandDecodeParams( bool QPDF_Stream::filterable(std::vector<std::string>& filters, + bool& specialized_compression, + bool& lossy_compression, int& predictor, int& columns, bool& early_code_change) { @@ -254,11 +258,20 @@ QPDF_Stream::filterable(std::vector<std::string>& filters, filter = filter_abbreviations[filter]; } - if (! ((filter == "/Crypt") || - (filter == "/FlateDecode") || - (filter == "/LZWDecode") || - (filter == "/ASCII85Decode") || - (filter == "/ASCIIHexDecode"))) + if (filter == "/RunLengthDecode") + { + specialized_compression = true; + } + else if (filter == "/DCTDecode") + { + specialized_compression = true; + lossy_compression = true; + } + else if (! ((filter == "/Crypt") || + (filter == "/FlateDecode") || + (filter == "/LZWDecode") || + (filter == "/ASCII85Decode") || + (filter == "/ASCIIHexDecode"))) { filterable = false; } @@ -350,17 +363,35 @@ QPDF_Stream::filterable(std::vector<std::string>& filters, } bool -QPDF_Stream::pipeStreamData(Pipeline* pipeline, bool filter, - bool normalize, bool compress, +QPDF_Stream::pipeStreamData(Pipeline* pipeline, + unsigned long encode_flags, + qpdf_stream_decode_level_e decode_level, bool suppress_warnings) { std::vector<std::string> filters; int predictor = 1; int columns = 0; bool early_code_change = true; + bool specialized_compression = false; + bool lossy_compression = false; + bool filter = (! ((encode_flags == 0) && (decode_level == qpdf_dl_none))); if (filter) { - filter = filterable(filters, predictor, columns, early_code_change); + filter = filterable(filters, specialized_compression, lossy_compression, + predictor, columns, early_code_change); + if ((decode_level < qpdf_dl_all) && lossy_compression) + { + filter = false; + } + if ((decode_level < qpdf_dl_specialized) && specialized_compression) + { + filter = false; + } + QTC::TC("qpdf", "QPDF_Stream special filters", + (! filter) ? 0 : + lossy_compression ? 1 : + specialized_compression ? 2 : + 3); } if (pipeline == 0) @@ -375,14 +406,14 @@ QPDF_Stream::pipeStreamData(Pipeline* pipeline, bool filter, if (filter) { - if (compress) + if (encode_flags & qpdf_ef_compress) { pipeline = new Pl_Flate("compress object stream", pipeline, Pl_Flate::a_deflate); to_delete.push_back(pipeline); } - if (normalize) + if (encode_flags & qpdf_ef_normalize) { pipeline = new Pl_QPDFTokenizer("normalizer", pipeline); to_delete.push_back(pipeline); @@ -427,6 +458,17 @@ QPDF_Stream::pipeStreamData(Pipeline* pipeline, bool filter, early_code_change); to_delete.push_back(pipeline); } + else if (filter == "/RunLengthDecode") + { + pipeline = new Pl_RunLength("runlength decode", pipeline, + Pl_RunLength::a_decode); + to_delete.push_back(pipeline); + } + else if (filter == "/DCTDecode") + { + pipeline = new Pl_DCT("DCT decode", pipeline); + to_delete.push_back(pipeline); + } else { throw std::logic_error( |