Commit 09c3dc5f92e1512ba1e3fdf221bd3be08f6654fa
1 parent
796913e9
Refactor QPDF_Stream
Move all stream-specific methods to new class qpdf::Stream
Showing
9 changed files
with
258 additions
and
213 deletions
include/qpdf/ObjectHandle.hh
| ... | ... | @@ -35,8 +35,9 @@ class QPDFObjectHandle; |
| 35 | 35 | namespace qpdf |
| 36 | 36 | { |
| 37 | 37 | class Array; |
| 38 | - class Dictionary; | |
| 39 | 38 | class BaseDictionary; |
| 39 | + class Dictionary; | |
| 40 | + class Stream; | |
| 40 | 41 | |
| 41 | 42 | enum typed : std::uint8_t { strict = 0, any_flag = 1, optional = 2, any = 3, error = 4}; |
| 42 | 43 | ... | ... |
include/qpdf/QPDF.hh
include/qpdf/QPDFObjectHandle.hh
| ... | ... | @@ -1357,6 +1357,7 @@ class QPDFObjectHandle final: public qpdf::BaseHandle |
| 1357 | 1357 | |
| 1358 | 1358 | inline qpdf::Array as_array(qpdf::typed options = qpdf::typed::any) const; |
| 1359 | 1359 | inline qpdf::Dictionary as_dictionary(qpdf::typed options = qpdf::typed::any) const; |
| 1360 | + inline qpdf::Stream as_stream(qpdf::typed options = qpdf::typed::strict) const; | |
| 1360 | 1361 | |
| 1361 | 1362 | private: |
| 1362 | 1363 | QPDF_Array* asArray() const; | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -17,9 +17,9 @@ |
| 17 | 17 | #include <qpdf/Pipeline.hh> |
| 18 | 18 | #include <qpdf/QPDFExc.hh> |
| 19 | 19 | #include <qpdf/QPDFLogger.hh> |
| 20 | +#include <qpdf/QPDFObjectHandle_private.hh> | |
| 20 | 21 | #include <qpdf/QPDFObject_private.hh> |
| 21 | 22 | #include <qpdf/QPDFParser.hh> |
| 22 | -#include <qpdf/QPDF_Array.hh> | |
| 23 | 23 | #include <qpdf/QPDF_Dictionary.hh> |
| 24 | 24 | #include <qpdf/QPDF_Null.hh> |
| 25 | 25 | #include <qpdf/QPDF_Reserved.hh> |
| ... | ... | @@ -298,7 +298,7 @@ void |
| 298 | 298 | QPDF::registerStreamFilter( |
| 299 | 299 | std::string const& filter_name, std::function<std::shared_ptr<QPDFStreamFilter>()> factory) |
| 300 | 300 | { |
| 301 | - QPDF_Stream::registerStreamFilter(filter_name, factory); | |
| 301 | + qpdf::Stream::registerStreamFilter(filter_name, factory); | |
| 302 | 302 | } |
| 303 | 303 | |
| 304 | 304 | void |
| ... | ... | @@ -2442,13 +2442,11 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) |
| 2442 | 2442 | QPDF& foreign_stream_qpdf = |
| 2443 | 2443 | foreign.getQPDF("unable to retrieve owning qpdf from foreign stream"); |
| 2444 | 2444 | |
| 2445 | - auto stream = foreign.getObjectPtr()->as<QPDF_Stream>(); | |
| 2446 | - if (stream == nullptr) { | |
| 2447 | - throw std::logic_error( | |
| 2448 | - "unable to retrieve underlying" | |
| 2449 | - " stream object from foreign stream"); | |
| 2445 | + auto stream = foreign.as_stream(); | |
| 2446 | + if (!stream) { | |
| 2447 | + throw std::logic_error("unable to retrieve underlying stream object from foreign stream"); | |
| 2450 | 2448 | } |
| 2451 | - std::shared_ptr<Buffer> stream_buffer = stream->getStreamDataBuffer(); | |
| 2449 | + std::shared_ptr<Buffer> stream_buffer = stream.getStreamDataBuffer(); | |
| 2452 | 2450 | if ((foreign_stream_qpdf.m->immediate_copy_from) && (stream_buffer == nullptr)) { |
| 2453 | 2451 | // Pull the stream data into a buffer before attempting the copy operation. Do it on the |
| 2454 | 2452 | // source stream so that if the source stream is copied multiple times, we don't have to |
| ... | ... | @@ -2458,10 +2456,10 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) |
| 2458 | 2456 | foreign.getRawStreamData(), |
| 2459 | 2457 | old_dict.getKey("/Filter"), |
| 2460 | 2458 | old_dict.getKey("/DecodeParms")); |
| 2461 | - stream_buffer = stream->getStreamDataBuffer(); | |
| 2459 | + stream_buffer = stream.getStreamDataBuffer(); | |
| 2462 | 2460 | } |
| 2463 | 2461 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> stream_provider = |
| 2464 | - stream->getStreamDataProvider(); | |
| 2462 | + stream.getStreamDataProvider(); | |
| 2465 | 2463 | if (stream_buffer.get()) { |
| 2466 | 2464 | QTC::TC("qpdf", "QPDF copy foreign stream with buffer"); |
| 2467 | 2465 | result.replaceStreamData( |
| ... | ... | @@ -2476,9 +2474,9 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) |
| 2476 | 2474 | auto foreign_stream_data = std::make_shared<ForeignStreamData>( |
| 2477 | 2475 | foreign_stream_qpdf.m->encp, |
| 2478 | 2476 | foreign_stream_qpdf.m->file, |
| 2479 | - foreign.getObjGen(), | |
| 2480 | - stream->getParsedOffset(), | |
| 2481 | - stream->getLength(), | |
| 2477 | + foreign, | |
| 2478 | + foreign.getParsedOffset(), | |
| 2479 | + stream.getLength(), | |
| 2482 | 2480 | dict); |
| 2483 | 2481 | m->copied_stream_data_provider->registerForeignStream(local_og, foreign_stream_data); |
| 2484 | 2482 | result.replaceStreamData( | ... | ... |
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -962,43 +962,43 @@ QPDFObjectHandle::getUniqueResourceName( |
| 962 | 962 | QPDFObjectHandle |
| 963 | 963 | QPDFObjectHandle::getDict() const |
| 964 | 964 | { |
| 965 | - return asStreamWithAssert()->getDict(); | |
| 965 | + return as_stream(error).getDict(); | |
| 966 | 966 | } |
| 967 | 967 | |
| 968 | 968 | void |
| 969 | 969 | QPDFObjectHandle::setFilterOnWrite(bool val) |
| 970 | 970 | { |
| 971 | - asStreamWithAssert()->setFilterOnWrite(val); | |
| 971 | + as_stream(error).setFilterOnWrite(val); | |
| 972 | 972 | } |
| 973 | 973 | |
| 974 | 974 | bool |
| 975 | 975 | QPDFObjectHandle::getFilterOnWrite() |
| 976 | 976 | { |
| 977 | - return asStreamWithAssert()->getFilterOnWrite(); | |
| 977 | + return as_stream(error).getFilterOnWrite(); | |
| 978 | 978 | } |
| 979 | 979 | |
| 980 | 980 | bool |
| 981 | 981 | QPDFObjectHandle::isDataModified() |
| 982 | 982 | { |
| 983 | - return asStreamWithAssert()->isDataModified(); | |
| 983 | + return as_stream(error).isDataModified(); | |
| 984 | 984 | } |
| 985 | 985 | |
| 986 | 986 | void |
| 987 | 987 | QPDFObjectHandle::replaceDict(QPDFObjectHandle const& new_dict) |
| 988 | 988 | { |
| 989 | - asStreamWithAssert()->replaceDict(new_dict); | |
| 989 | + as_stream(error).replaceDict(new_dict); | |
| 990 | 990 | } |
| 991 | 991 | |
| 992 | 992 | std::shared_ptr<Buffer> |
| 993 | 993 | QPDFObjectHandle::getStreamData(qpdf_stream_decode_level_e level) |
| 994 | 994 | { |
| 995 | - return asStreamWithAssert()->getStreamData(level); | |
| 995 | + return as_stream(error).getStreamData(level); | |
| 996 | 996 | } |
| 997 | 997 | |
| 998 | 998 | std::shared_ptr<Buffer> |
| 999 | 999 | QPDFObjectHandle::getRawStreamData() |
| 1000 | 1000 | { |
| 1001 | - return asStreamWithAssert()->getRawStreamData(); | |
| 1001 | + return as_stream(error).getRawStreamData(); | |
| 1002 | 1002 | } |
| 1003 | 1003 | |
| 1004 | 1004 | bool |
| ... | ... | @@ -1010,7 +1010,7 @@ QPDFObjectHandle::pipeStreamData( |
| 1010 | 1010 | bool suppress_warnings, |
| 1011 | 1011 | bool will_retry) |
| 1012 | 1012 | { |
| 1013 | - return asStreamWithAssert()->pipeStreamData( | |
| 1013 | + return as_stream(error).pipeStreamData( | |
| 1014 | 1014 | p, filtering_attempted, encode_flags, decode_level, suppress_warnings, will_retry); |
| 1015 | 1015 | } |
| 1016 | 1016 | |
| ... | ... | @@ -1023,7 +1023,7 @@ QPDFObjectHandle::pipeStreamData( |
| 1023 | 1023 | bool will_retry) |
| 1024 | 1024 | { |
| 1025 | 1025 | bool filtering_attempted; |
| 1026 | - asStreamWithAssert()->pipeStreamData( | |
| 1026 | + as_stream(error).pipeStreamData( | |
| 1027 | 1027 | p, &filtering_attempted, encode_flags, decode_level, suppress_warnings, will_retry); |
| 1028 | 1028 | return filtering_attempted; |
| 1029 | 1029 | } |
| ... | ... | @@ -1051,7 +1051,7 @@ QPDFObjectHandle::replaceStreamData( |
| 1051 | 1051 | QPDFObjectHandle const& filter, |
| 1052 | 1052 | QPDFObjectHandle const& decode_parms) |
| 1053 | 1053 | { |
| 1054 | - asStreamWithAssert()->replaceStreamData(data, filter, decode_parms); | |
| 1054 | + as_stream(error).replaceStreamData(data, filter, decode_parms); | |
| 1055 | 1055 | } |
| 1056 | 1056 | |
| 1057 | 1057 | void |
| ... | ... | @@ -1063,7 +1063,7 @@ QPDFObjectHandle::replaceStreamData( |
| 1063 | 1063 | if (bp) { |
| 1064 | 1064 | memcpy(bp, data.c_str(), data.length()); |
| 1065 | 1065 | } |
| 1066 | - asStreamWithAssert()->replaceStreamData(b, filter, decode_parms); | |
| 1066 | + as_stream(error).replaceStreamData(b, filter, decode_parms); | |
| 1067 | 1067 | } |
| 1068 | 1068 | |
| 1069 | 1069 | void |
| ... | ... | @@ -1072,7 +1072,7 @@ QPDFObjectHandle::replaceStreamData( |
| 1072 | 1072 | QPDFObjectHandle const& filter, |
| 1073 | 1073 | QPDFObjectHandle const& decode_parms) |
| 1074 | 1074 | { |
| 1075 | - asStreamWithAssert()->replaceStreamData(provider, filter, decode_parms); | |
| 1075 | + as_stream(error).replaceStreamData(provider, filter, decode_parms); | |
| 1076 | 1076 | } |
| 1077 | 1077 | |
| 1078 | 1078 | namespace |
| ... | ... | @@ -1119,7 +1119,7 @@ QPDFObjectHandle::replaceStreamData( |
| 1119 | 1119 | QPDFObjectHandle const& decode_parms) |
| 1120 | 1120 | { |
| 1121 | 1121 | auto sdp = std::shared_ptr<StreamDataProvider>(new FunctionProvider(provider)); |
| 1122 | - asStreamWithAssert()->replaceStreamData(sdp, filter, decode_parms); | |
| 1122 | + as_stream(error).replaceStreamData(sdp, filter, decode_parms); | |
| 1123 | 1123 | } |
| 1124 | 1124 | |
| 1125 | 1125 | void |
| ... | ... | @@ -1129,7 +1129,7 @@ QPDFObjectHandle::replaceStreamData( |
| 1129 | 1129 | QPDFObjectHandle const& decode_parms) |
| 1130 | 1130 | { |
| 1131 | 1131 | auto sdp = std::shared_ptr<StreamDataProvider>(new FunctionProvider(provider)); |
| 1132 | - asStreamWithAssert()->replaceStreamData(sdp, filter, decode_parms); | |
| 1132 | + as_stream(error).replaceStreamData(sdp, filter, decode_parms); | |
| 1133 | 1133 | } |
| 1134 | 1134 | |
| 1135 | 1135 | std::map<std::string, QPDFObjectHandle> |
| ... | ... | @@ -1348,8 +1348,7 @@ QPDFObjectHandle::getStreamJSON( |
| 1348 | 1348 | Pipeline* p, |
| 1349 | 1349 | std::string const& data_filename) |
| 1350 | 1350 | { |
| 1351 | - return asStreamWithAssert()->getStreamJSON( | |
| 1352 | - json_version, json_data, decode_level, p, data_filename); | |
| 1351 | + return as_stream(error).getStreamJSON(json_version, json_data, decode_level, p, data_filename); | |
| 1353 | 1352 | } |
| 1354 | 1353 | |
| 1355 | 1354 | QPDFObjectHandle |
| ... | ... | @@ -1552,7 +1551,7 @@ QPDFObjectHandle::addContentTokenFilter(std::shared_ptr<TokenFilter> filter) |
| 1552 | 1551 | void |
| 1553 | 1552 | QPDFObjectHandle::addTokenFilter(std::shared_ptr<TokenFilter> filter) |
| 1554 | 1553 | { |
| 1555 | - return asStreamWithAssert()->addTokenFilter(filter); | |
| 1554 | + return as_stream(error).addTokenFilter(filter); | |
| 1556 | 1555 | } |
| 1557 | 1556 | |
| 1558 | 1557 | QPDFObjectHandle | ... | ... |
libqpdf/QPDF_Stream.cc
| ... | ... | @@ -12,6 +12,7 @@ |
| 12 | 12 | #include <qpdf/QIntC.hh> |
| 13 | 13 | #include <qpdf/QPDF.hh> |
| 14 | 14 | #include <qpdf/QPDFExc.hh> |
| 15 | +#include <qpdf/QPDFObjectHandle_private.hh> | |
| 15 | 16 | #include <qpdf/QTC.hh> |
| 16 | 17 | #include <qpdf/QUtil.hh> |
| 17 | 18 | #include <qpdf/SF_ASCII85Decode.hh> |
| ... | ... | @@ -22,6 +23,9 @@ |
| 22 | 23 | |
| 23 | 24 | #include <stdexcept> |
| 24 | 25 | |
| 26 | +using namespace std::literals; | |
| 27 | +using namespace qpdf; | |
| 28 | + | |
| 25 | 29 | namespace |
| 26 | 30 | { |
| 27 | 31 | class SF_Crypt: public QPDFStreamFilter |
| ... | ... | @@ -60,16 +64,24 @@ namespace |
| 60 | 64 | class StreamBlobProvider |
| 61 | 65 | { |
| 62 | 66 | public: |
| 63 | - StreamBlobProvider(QPDF_Stream* stream, qpdf_stream_decode_level_e decode_level); | |
| 64 | - void operator()(Pipeline*); | |
| 67 | + StreamBlobProvider(Stream stream, qpdf_stream_decode_level_e decode_level) : | |
| 68 | + stream(stream), | |
| 69 | + decode_level(decode_level) | |
| 70 | + { | |
| 71 | + } | |
| 72 | + void | |
| 73 | + operator()(Pipeline* p) | |
| 74 | + { | |
| 75 | + stream.pipeStreamData(p, nullptr, 0, decode_level, false, false); | |
| 76 | + } | |
| 65 | 77 | |
| 66 | 78 | private: |
| 67 | - QPDF_Stream* stream; | |
| 79 | + Stream stream; | |
| 68 | 80 | qpdf_stream_decode_level_e decode_level; |
| 69 | 81 | }; |
| 70 | 82 | } // namespace |
| 71 | 83 | |
| 72 | -std::map<std::string, std::string> QPDF_Stream::filter_abbreviations = { | |
| 84 | +std::map<std::string, std::string> Stream::filter_abbreviations = { | |
| 73 | 85 | // The PDF specification provides these filter abbreviations for use in inline images, but |
| 74 | 86 | // according to table H.1 in the pre-ISO versions of the PDF specification, Adobe Reader also |
| 75 | 87 | // accepts them for stream filters. |
| ... | ... | @@ -82,8 +94,8 @@ std::map<std::string, std::string> QPDF_Stream::filter_abbreviations = { |
| 82 | 94 | {"/DCT", "/DCTDecode"}, |
| 83 | 95 | }; |
| 84 | 96 | |
| 85 | -std::map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>> | |
| 86 | - QPDF_Stream::filter_factories = { | |
| 97 | +std::map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>> Stream::filter_factories = | |
| 98 | + { | |
| 87 | 99 | {"/Crypt", []() { return std::make_shared<SF_Crypt>(); }}, |
| 88 | 100 | {"/FlateDecode", SF_FlateLzwDecode::flate_factory}, |
| 89 | 101 | {"/LZWDecode", SF_FlateLzwDecode::lzw_factory}, |
| ... | ... | @@ -93,19 +105,6 @@ std::map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>> |
| 93 | 105 | {"/ASCIIHexDecode", SF_ASCIIHexDecode::factory}, |
| 94 | 106 | }; |
| 95 | 107 | |
| 96 | -StreamBlobProvider::StreamBlobProvider( | |
| 97 | - QPDF_Stream* stream, qpdf_stream_decode_level_e decode_level) : | |
| 98 | - stream(stream), | |
| 99 | - decode_level(decode_level) | |
| 100 | -{ | |
| 101 | -} | |
| 102 | - | |
| 103 | -void | |
| 104 | -StreamBlobProvider::operator()(Pipeline* p) | |
| 105 | -{ | |
| 106 | - this->stream->pipeStreamData(p, nullptr, 0, decode_level, false, false); | |
| 107 | -} | |
| 108 | - | |
| 109 | 108 | QPDF_Stream::QPDF_Stream( |
| 110 | 109 | QPDF* qpdf, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length) : |
| 111 | 110 | QPDFValue(::ot_stream, qpdf, og), |
| ... | ... | @@ -137,25 +136,13 @@ QPDF_Stream::copy(bool shallow) |
| 137 | 136 | } |
| 138 | 137 | |
| 139 | 138 | void |
| 140 | -QPDF_Stream::registerStreamFilter( | |
| 139 | +Stream::registerStreamFilter( | |
| 141 | 140 | std::string const& filter_name, std::function<std::shared_ptr<QPDFStreamFilter>()> factory) |
| 142 | 141 | { |
| 143 | 142 | filter_factories[filter_name] = factory; |
| 144 | 143 | } |
| 145 | 144 | |
| 146 | 145 | void |
| 147 | -QPDF_Stream::setFilterOnWrite(bool val) | |
| 148 | -{ | |
| 149 | - this->filter_on_write = val; | |
| 150 | -} | |
| 151 | - | |
| 152 | -bool | |
| 153 | -QPDF_Stream::getFilterOnWrite() const | |
| 154 | -{ | |
| 155 | - return this->filter_on_write; | |
| 156 | -} | |
| 157 | - | |
| 158 | -void | |
| 159 | 146 | QPDF_Stream::disconnect() |
| 160 | 147 | { |
| 161 | 148 | this->stream_provider = nullptr; |
| ... | ... | @@ -175,8 +162,20 @@ QPDF_Stream::writeJSON(int json_version, JSON::Writer& jw) |
| 175 | 162 | stream_dict.writeJSON(json_version, jw); |
| 176 | 163 | } |
| 177 | 164 | |
| 165 | +QPDF_Stream* | |
| 166 | +Stream::stream() const | |
| 167 | +{ | |
| 168 | + if (obj) { | |
| 169 | + if (auto s = obj->as<QPDF_Stream>()) { | |
| 170 | + return s; | |
| 171 | + } | |
| 172 | + } | |
| 173 | + throw std::runtime_error("operation for stream attempted on object of type dictionary"); | |
| 174 | + return nullptr; // unreachable | |
| 175 | +} | |
| 176 | + | |
| 178 | 177 | JSON |
| 179 | -QPDF_Stream::getStreamJSON( | |
| 178 | +Stream::getStreamJSON( | |
| 180 | 179 | int json_version, |
| 181 | 180 | qpdf_json_stream_data_e json_data, |
| 182 | 181 | qpdf_stream_decode_level_e decode_level, |
| ... | ... | @@ -190,13 +189,13 @@ QPDF_Stream::getStreamJSON( |
| 190 | 189 | pb.finish(); |
| 191 | 190 | auto result = JSON::parse(pb.getString()); |
| 192 | 191 | if (json_data == qpdf_sj_inline) { |
| 193 | - result.addDictionaryMember("data", JSON::makeBlob(StreamBlobProvider(this, decode_level))); | |
| 192 | + result.addDictionaryMember("data", JSON::makeBlob(StreamBlobProvider(*this, decode_level))); | |
| 194 | 193 | } |
| 195 | 194 | return result; |
| 196 | 195 | } |
| 197 | 196 | |
| 198 | 197 | qpdf_stream_decode_level_e |
| 199 | -QPDF_Stream::writeStreamJSON( | |
| 198 | +Stream::writeStreamJSON( | |
| 200 | 199 | int json_version, |
| 201 | 200 | JSON::Writer& jw, |
| 202 | 201 | qpdf_json_stream_data_e json_data, |
| ... | ... | @@ -205,6 +204,7 @@ QPDF_Stream::writeStreamJSON( |
| 205 | 204 | std::string const& data_filename, |
| 206 | 205 | bool no_data_key) |
| 207 | 206 | { |
| 207 | + auto s = stream(); | |
| 208 | 208 | switch (json_data) { |
| 209 | 209 | case qpdf_sj_none: |
| 210 | 210 | case qpdf_sj_inline: |
| ... | ... | @@ -232,7 +232,7 @@ QPDF_Stream::writeStreamJSON( |
| 232 | 232 | if (json_data == qpdf_sj_none) { |
| 233 | 233 | jw.writeNext(); |
| 234 | 234 | jw << R"("dict": )"; |
| 235 | - stream_dict.writeJSON(json_version, jw); | |
| 235 | + s->stream_dict.writeJSON(json_version, jw); | |
| 236 | 236 | jw.writeEnd('}'); |
| 237 | 237 | return decode_level; |
| 238 | 238 | } |
| ... | ... | @@ -264,7 +264,7 @@ QPDF_Stream::writeStreamJSON( |
| 264 | 264 | throw std::logic_error("QPDF_Stream: failed to get stream data"); |
| 265 | 265 | } |
| 266 | 266 | // We can use unsafeShallowCopy because we are only touching top-level keys. |
| 267 | - auto dict = stream_dict.unsafeShallowCopy(); | |
| 267 | + auto dict = s->stream_dict.unsafeShallowCopy(); | |
| 268 | 268 | dict.removeKey("/Length"); |
| 269 | 269 | if (filter && filtered) { |
| 270 | 270 | dict.removeKey("/Filter"); |
| ... | ... | @@ -305,48 +305,19 @@ QPDF_Stream::setDictDescription() |
| 305 | 305 | } |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | -QPDFObjectHandle | |
| 309 | -QPDF_Stream::getDict() const | |
| 310 | -{ | |
| 311 | - return this->stream_dict; | |
| 312 | -} | |
| 313 | - | |
| 314 | -bool | |
| 315 | -QPDF_Stream::isDataModified() const | |
| 316 | -{ | |
| 317 | - return (!this->token_filters.empty()); | |
| 318 | -} | |
| 319 | - | |
| 320 | -size_t | |
| 321 | -QPDF_Stream::getLength() const | |
| 322 | -{ | |
| 323 | - return this->length; | |
| 324 | -} | |
| 325 | - | |
| 326 | -std::shared_ptr<Buffer> | |
| 327 | -QPDF_Stream::getStreamDataBuffer() const | |
| 328 | -{ | |
| 329 | - return this->stream_data; | |
| 330 | -} | |
| 331 | - | |
| 332 | -std::shared_ptr<QPDFObjectHandle::StreamDataProvider> | |
| 333 | -QPDF_Stream::getStreamDataProvider() const | |
| 334 | -{ | |
| 335 | - return this->stream_provider; | |
| 336 | -} | |
| 337 | - | |
| 338 | 308 | std::shared_ptr<Buffer> |
| 339 | -QPDF_Stream::getStreamData(qpdf_stream_decode_level_e decode_level) | |
| 309 | +Stream::getStreamData(qpdf_stream_decode_level_e decode_level) | |
| 340 | 310 | { |
| 311 | + auto s = stream(); | |
| 341 | 312 | Pl_Buffer buf("stream data buffer"); |
| 342 | 313 | bool filtered; |
| 343 | 314 | pipeStreamData(&buf, &filtered, 0, decode_level, false, false); |
| 344 | 315 | if (!filtered) { |
| 345 | 316 | throw QPDFExc( |
| 346 | 317 | qpdf_e_unsupported, |
| 347 | - qpdf->getFilename(), | |
| 318 | + s->qpdf->getFilename(), | |
| 348 | 319 | "", |
| 349 | - this->parsed_offset, | |
| 320 | + s->parsed_offset, | |
| 350 | 321 | "getStreamData called on unfilterable stream"); |
| 351 | 322 | } |
| 352 | 323 | QTC::TC("qpdf", "QPDF_Stream getStreamData"); |
| ... | ... | @@ -354,15 +325,16 @@ QPDF_Stream::getStreamData(qpdf_stream_decode_level_e decode_level) |
| 354 | 325 | } |
| 355 | 326 | |
| 356 | 327 | std::shared_ptr<Buffer> |
| 357 | -QPDF_Stream::getRawStreamData() | |
| 328 | +Stream::getRawStreamData() | |
| 358 | 329 | { |
| 330 | + auto s = stream(); | |
| 359 | 331 | Pl_Buffer buf("stream data buffer"); |
| 360 | 332 | if (!pipeStreamData(&buf, nullptr, 0, qpdf_dl_none, false, false)) { |
| 361 | 333 | throw QPDFExc( |
| 362 | 334 | qpdf_e_unsupported, |
| 363 | - qpdf->getFilename(), | |
| 335 | + s->qpdf->getFilename(), | |
| 364 | 336 | "", |
| 365 | - this->parsed_offset, | |
| 337 | + s->parsed_offset, | |
| 366 | 338 | "error getting raw stream data"); |
| 367 | 339 | } |
| 368 | 340 | QTC::TC("qpdf", "QPDF_Stream getRawStreamData"); |
| ... | ... | @@ -370,14 +342,15 @@ QPDF_Stream::getRawStreamData() |
| 370 | 342 | } |
| 371 | 343 | |
| 372 | 344 | bool |
| 373 | -QPDF_Stream::filterable( | |
| 345 | +Stream::filterable( | |
| 374 | 346 | std::vector<std::shared_ptr<QPDFStreamFilter>>& filters, |
| 375 | 347 | bool& specialized_compression, |
| 376 | 348 | bool& lossy_compression) |
| 377 | 349 | { |
| 350 | + auto s = stream(); | |
| 378 | 351 | // Check filters |
| 379 | 352 | |
| 380 | - QPDFObjectHandle filter_obj = this->stream_dict.getKey("/Filter"); | |
| 353 | + QPDFObjectHandle filter_obj = s->stream_dict.getKey("/Filter"); | |
| 381 | 354 | bool filters_okay = true; |
| 382 | 355 | |
| 383 | 356 | std::vector<std::string> filter_names; |
| ... | ... | @@ -432,7 +405,7 @@ QPDF_Stream::filterable( |
| 432 | 405 | |
| 433 | 406 | // See if we can support any decode parameters that are specified. |
| 434 | 407 | |
| 435 | - QPDFObjectHandle decode_obj = this->stream_dict.getKey("/DecodeParms"); | |
| 408 | + QPDFObjectHandle decode_obj = s->stream_dict.getKey("/DecodeParms"); | |
| 436 | 409 | std::vector<QPDFObjectHandle> decode_parms; |
| 437 | 410 | if (decode_obj.isArray() && (decode_obj.getArrayNItems() == 0)) { |
| 438 | 411 | decode_obj = QPDFObjectHandle::newNull(); |
| ... | ... | @@ -479,7 +452,7 @@ QPDF_Stream::filterable( |
| 479 | 452 | } |
| 480 | 453 | |
| 481 | 454 | bool |
| 482 | -QPDF_Stream::pipeStreamData( | |
| 455 | +Stream::pipeStreamData( | |
| 483 | 456 | Pipeline* pipeline, |
| 484 | 457 | bool* filterp, |
| 485 | 458 | int encode_flags, |
| ... | ... | @@ -487,6 +460,7 @@ QPDF_Stream::pipeStreamData( |
| 487 | 460 | bool suppress_warnings, |
| 488 | 461 | bool will_retry) |
| 489 | 462 | { |
| 463 | + auto s = stream(); | |
| 490 | 464 | std::vector<std::shared_ptr<QPDFStreamFilter>> filters; |
| 491 | 465 | bool specialized_compression = false; |
| 492 | 466 | bool lossy_compression = false; |
| ... | ... | @@ -543,7 +517,7 @@ QPDF_Stream::pipeStreamData( |
| 543 | 517 | pipeline = new_pipeline.get(); |
| 544 | 518 | } |
| 545 | 519 | |
| 546 | - for (auto iter = this->token_filters.rbegin(); iter != this->token_filters.rend(); ++iter) { | |
| 520 | + for (auto iter = s->token_filters.rbegin(); iter != s->token_filters.rend(); ++iter) { | |
| 547 | 521 | new_pipeline = |
| 548 | 522 | std::make_shared<Pl_QPDFTokenizer>("token filter", (*iter).get(), pipeline); |
| 549 | 523 | to_delete.push_back(new_pipeline); |
| ... | ... | @@ -562,25 +536,25 @@ QPDF_Stream::pipeStreamData( |
| 562 | 536 | } |
| 563 | 537 | } |
| 564 | 538 | |
| 565 | - if (this->stream_data.get()) { | |
| 539 | + if (s->stream_data.get()) { | |
| 566 | 540 | QTC::TC("qpdf", "QPDF_Stream pipe replaced stream data"); |
| 567 | - pipeline->write(this->stream_data->getBuffer(), this->stream_data->getSize()); | |
| 541 | + pipeline->write(s->stream_data->getBuffer(), s->stream_data->getSize()); | |
| 568 | 542 | pipeline->finish(); |
| 569 | - } else if (this->stream_provider.get()) { | |
| 543 | + } else if (s->stream_provider.get()) { | |
| 570 | 544 | Pl_Count count("stream provider count", pipeline); |
| 571 | - if (this->stream_provider->supportsRetry()) { | |
| 572 | - if (!this->stream_provider->provideStreamData( | |
| 573 | - og, &count, suppress_warnings, will_retry)) { | |
| 545 | + if (s->stream_provider->supportsRetry()) { | |
| 546 | + if (!s->stream_provider->provideStreamData( | |
| 547 | + s->og, &count, suppress_warnings, will_retry)) { | |
| 574 | 548 | filter = false; |
| 575 | 549 | success = false; |
| 576 | 550 | } |
| 577 | 551 | } else { |
| 578 | - this->stream_provider->provideStreamData(og, &count); | |
| 552 | + s->stream_provider->provideStreamData(s->og, &count); | |
| 579 | 553 | } |
| 580 | 554 | qpdf_offset_t actual_length = count.getCount(); |
| 581 | 555 | qpdf_offset_t desired_length = 0; |
| 582 | - if (success && this->stream_dict.hasKey("/Length")) { | |
| 583 | - desired_length = this->stream_dict.getKey("/Length").getIntValue(); | |
| 556 | + if (success && s->stream_dict.hasKey("/Length")) { | |
| 557 | + desired_length = s->stream_dict.getKey("/Length").getIntValue(); | |
| 584 | 558 | if (actual_length == desired_length) { |
| 585 | 559 | QTC::TC("qpdf", "QPDF_Stream pipe use stream provider"); |
| 586 | 560 | } else { |
| ... | ... | @@ -588,25 +562,25 @@ QPDF_Stream::pipeStreamData( |
| 588 | 562 | // This would be caused by programmer error on the part of a library user, not by |
| 589 | 563 | // invalid input data. |
| 590 | 564 | throw std::runtime_error( |
| 591 | - "stream data provider for " + og.unparse(' ') + " provided " + | |
| 565 | + "stream data provider for " + s->og.unparse(' ') + " provided " + | |
| 592 | 566 | std::to_string(actual_length) + " bytes instead of expected " + |
| 593 | 567 | std::to_string(desired_length) + " bytes"); |
| 594 | 568 | } |
| 595 | 569 | } else if (success) { |
| 596 | 570 | QTC::TC("qpdf", "QPDF_Stream provider length not provided"); |
| 597 | - this->stream_dict.replaceKey("/Length", QPDFObjectHandle::newInteger(actual_length)); | |
| 571 | + s->stream_dict.replaceKey("/Length", QPDFObjectHandle::newInteger(actual_length)); | |
| 598 | 572 | } |
| 599 | - } else if (this->parsed_offset == 0) { | |
| 573 | + } else if (s->parsed_offset == 0) { | |
| 600 | 574 | QTC::TC("qpdf", "QPDF_Stream pipe no stream data"); |
| 601 | 575 | throw std::logic_error("pipeStreamData called for stream with no data"); |
| 602 | 576 | } else { |
| 603 | 577 | QTC::TC("qpdf", "QPDF_Stream pipe original stream data"); |
| 604 | 578 | if (!QPDF::Pipe::pipeStreamData( |
| 605 | - this->qpdf, | |
| 606 | - og, | |
| 607 | - this->parsed_offset, | |
| 608 | - this->length, | |
| 609 | - this->stream_dict, | |
| 579 | + s->qpdf, | |
| 580 | + s->og, | |
| 581 | + s->parsed_offset, | |
| 582 | + s->length, | |
| 583 | + s->stream_dict, | |
| 610 | 584 | pipeline, |
| 611 | 585 | suppress_warnings, |
| 612 | 586 | will_retry)) { |
| ... | ... | @@ -634,60 +608,52 @@ QPDF_Stream::pipeStreamData( |
| 634 | 608 | } |
| 635 | 609 | |
| 636 | 610 | void |
| 637 | -QPDF_Stream::replaceStreamData( | |
| 611 | +Stream::replaceStreamData( | |
| 638 | 612 | std::shared_ptr<Buffer> data, |
| 639 | 613 | QPDFObjectHandle const& filter, |
| 640 | 614 | QPDFObjectHandle const& decode_parms) |
| 641 | 615 | { |
| 642 | - this->stream_data = data; | |
| 643 | - this->stream_provider = nullptr; | |
| 616 | + auto s = stream(); | |
| 617 | + s->stream_data = data; | |
| 618 | + s->stream_provider = nullptr; | |
| 644 | 619 | replaceFilterData(filter, decode_parms, data->getSize()); |
| 645 | 620 | } |
| 646 | 621 | |
| 647 | 622 | void |
| 648 | -QPDF_Stream::replaceStreamData( | |
| 623 | +Stream::replaceStreamData( | |
| 649 | 624 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider, |
| 650 | 625 | QPDFObjectHandle const& filter, |
| 651 | 626 | QPDFObjectHandle const& decode_parms) |
| 652 | 627 | { |
| 653 | - this->stream_provider = provider; | |
| 654 | - this->stream_data = nullptr; | |
| 628 | + auto s = stream(); | |
| 629 | + s->stream_provider = provider; | |
| 630 | + s->stream_data = nullptr; | |
| 655 | 631 | replaceFilterData(filter, decode_parms, 0); |
| 656 | 632 | } |
| 657 | 633 | |
| 658 | 634 | void |
| 659 | -QPDF_Stream::addTokenFilter(std::shared_ptr<QPDFObjectHandle::TokenFilter> token_filter) | |
| 660 | -{ | |
| 661 | - this->token_filters.push_back(token_filter); | |
| 662 | -} | |
| 663 | - | |
| 664 | -void | |
| 665 | -QPDF_Stream::replaceFilterData( | |
| 635 | +Stream::replaceFilterData( | |
| 666 | 636 | QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length) |
| 667 | 637 | { |
| 638 | + auto s = stream(); | |
| 668 | 639 | if (filter) { |
| 669 | - stream_dict.replaceKey("/Filter", filter); | |
| 640 | + s->stream_dict.replaceKey("/Filter", filter); | |
| 670 | 641 | } |
| 671 | 642 | if (decode_parms) { |
| 672 | - stream_dict.replaceKey("/DecodeParms", decode_parms); | |
| 643 | + s->stream_dict.replaceKey("/DecodeParms", decode_parms); | |
| 673 | 644 | } |
| 674 | 645 | if (length == 0) { |
| 675 | 646 | QTC::TC("qpdf", "QPDF_Stream unknown stream length"); |
| 676 | - stream_dict.removeKey("/Length"); | |
| 647 | + s->stream_dict.removeKey("/Length"); | |
| 677 | 648 | } else { |
| 678 | - stream_dict.replaceKey("/Length", QPDFObjectHandle::newInteger(QIntC::to_longlong(length))); | |
| 649 | + s->stream_dict.replaceKey( | |
| 650 | + "/Length", QPDFObjectHandle::newInteger(QIntC::to_longlong(length))); | |
| 679 | 651 | } |
| 680 | 652 | } |
| 681 | 653 | |
| 682 | 654 | void |
| 683 | -QPDF_Stream::replaceDict(QPDFObjectHandle const& new_dict) | |
| 684 | -{ | |
| 685 | - this->stream_dict = new_dict; | |
| 686 | - setDictDescription(); | |
| 687 | -} | |
| 688 | - | |
| 689 | -void | |
| 690 | -QPDF_Stream::warn(std::string const& message) | |
| 655 | +Stream::warn(std::string const& message) | |
| 691 | 656 | { |
| 692 | - this->qpdf->warn(qpdf_e_damaged_pdf, "", this->parsed_offset, message); | |
| 657 | + auto s = stream(); | |
| 658 | + s->qpdf->warn(qpdf_e_damaged_pdf, "", s->parsed_offset, message); | |
| 693 | 659 | } | ... | ... |
libqpdf/QPDF_json.cc
| ... | ... | @@ -5,6 +5,7 @@ |
| 5 | 5 | #include <qpdf/Pl_Base64.hh> |
| 6 | 6 | #include <qpdf/Pl_StdioFile.hh> |
| 7 | 7 | #include <qpdf/QIntC.hh> |
| 8 | +#include <qpdf/QPDFObjectHandle_private.hh> | |
| 8 | 9 | #include <qpdf/QPDFObject_private.hh> |
| 9 | 10 | #include <qpdf/QPDFValue.hh> |
| 10 | 11 | #include <qpdf/QPDF_Null.hh> |
| ... | ... | @@ -821,7 +822,7 @@ void |
| 821 | 822 | writeJSONStreamFile( |
| 822 | 823 | int version, |
| 823 | 824 | JSON::Writer& jw, |
| 824 | - QPDF_Stream& stream, | |
| 825 | + qpdf::Stream& stream, | |
| 825 | 826 | int id, |
| 826 | 827 | qpdf_stream_decode_level_e decode_level, |
| 827 | 828 | std::string const& file_prefix) |
| ... | ... | @@ -894,13 +895,13 @@ QPDF::writeJSON( |
| 894 | 895 | } else { |
| 895 | 896 | jw << "\n },\n \"" << key; |
| 896 | 897 | } |
| 897 | - if (auto* stream = obj.getObjectPtr()->as<QPDF_Stream>()) { | |
| 898 | + if (auto stream = obj.as_stream()) { | |
| 898 | 899 | jw << "\": {\n \"stream\": "; |
| 899 | 900 | if (json_stream_data == qpdf_sj_file) { |
| 900 | 901 | writeJSONStreamFile( |
| 901 | - version, jw, *stream, og.getObj(), decode_level, file_prefix); | |
| 902 | + version, jw, stream, og.getObj(), decode_level, file_prefix); | |
| 902 | 903 | } else { |
| 903 | - stream->writeStreamJSON( | |
| 904 | + stream.writeStreamJSON( | |
| 904 | 905 | version, jw, json_stream_data, decode_level, nullptr, ""); |
| 905 | 906 | } |
| 906 | 907 | } else { | ... | ... |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | #include <qpdf/QPDFObject_private.hh> |
| 7 | 7 | #include <qpdf/QPDF_Array.hh> |
| 8 | 8 | #include <qpdf/QPDF_Dictionary.hh> |
| 9 | +#include <qpdf/QPDF_Stream.hh> | |
| 9 | 10 | |
| 10 | 11 | namespace qpdf |
| 11 | 12 | { |
| ... | ... | @@ -80,6 +81,123 @@ namespace qpdf |
| 80 | 81 | } |
| 81 | 82 | }; |
| 82 | 83 | |
| 84 | + class Stream final: public BaseHandle | |
| 85 | + { | |
| 86 | + public: | |
| 87 | + explicit Stream(std::shared_ptr<QPDFObject> const& obj) : | |
| 88 | + BaseHandle(obj) | |
| 89 | + { | |
| 90 | + } | |
| 91 | + | |
| 92 | + explicit Stream(std::shared_ptr<QPDFObject>&& obj) : | |
| 93 | + BaseHandle(std::move(obj)) | |
| 94 | + { | |
| 95 | + } | |
| 96 | + | |
| 97 | + QPDFObjectHandle | |
| 98 | + getDict() const | |
| 99 | + { | |
| 100 | + return stream()->stream_dict; | |
| 101 | + } | |
| 102 | + bool | |
| 103 | + isDataModified() const | |
| 104 | + { | |
| 105 | + return !stream()->token_filters.empty(); | |
| 106 | + } | |
| 107 | + void | |
| 108 | + setFilterOnWrite(bool val) | |
| 109 | + { | |
| 110 | + stream()->filter_on_write = val; | |
| 111 | + } | |
| 112 | + bool | |
| 113 | + getFilterOnWrite() const | |
| 114 | + { | |
| 115 | + return stream()->filter_on_write; | |
| 116 | + } | |
| 117 | + | |
| 118 | + // Methods to help QPDF copy foreign streams | |
| 119 | + size_t | |
| 120 | + getLength() const | |
| 121 | + { | |
| 122 | + return stream()->length; | |
| 123 | + } | |
| 124 | + std::shared_ptr<Buffer> | |
| 125 | + getStreamDataBuffer() const | |
| 126 | + { | |
| 127 | + return stream()->stream_data; | |
| 128 | + } | |
| 129 | + std::shared_ptr<QPDFObjectHandle::StreamDataProvider> | |
| 130 | + getStreamDataProvider() const | |
| 131 | + { | |
| 132 | + return stream()->stream_provider; | |
| 133 | + } | |
| 134 | + | |
| 135 | + // See comments in QPDFObjectHandle.hh for these methods. | |
| 136 | + bool pipeStreamData( | |
| 137 | + Pipeline* p, | |
| 138 | + bool* tried_filtering, | |
| 139 | + int encode_flags, | |
| 140 | + qpdf_stream_decode_level_e decode_level, | |
| 141 | + bool suppress_warnings, | |
| 142 | + bool will_retry); | |
| 143 | + std::shared_ptr<Buffer> getStreamData(qpdf_stream_decode_level_e level); | |
| 144 | + std::shared_ptr<Buffer> getRawStreamData(); | |
| 145 | + void replaceStreamData( | |
| 146 | + std::shared_ptr<Buffer> data, | |
| 147 | + QPDFObjectHandle const& filter, | |
| 148 | + QPDFObjectHandle const& decode_parms); | |
| 149 | + void replaceStreamData( | |
| 150 | + std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider, | |
| 151 | + QPDFObjectHandle const& filter, | |
| 152 | + QPDFObjectHandle const& decode_parms); | |
| 153 | + void | |
| 154 | + addTokenFilter(std::shared_ptr<QPDFObjectHandle::TokenFilter> token_filter) | |
| 155 | + { | |
| 156 | + stream()->token_filters.emplace_back(token_filter); | |
| 157 | + } | |
| 158 | + JSON getStreamJSON( | |
| 159 | + int json_version, | |
| 160 | + qpdf_json_stream_data_e json_data, | |
| 161 | + qpdf_stream_decode_level_e decode_level, | |
| 162 | + Pipeline* p, | |
| 163 | + std::string const& data_filename); | |
| 164 | + qpdf_stream_decode_level_e writeStreamJSON( | |
| 165 | + int json_version, | |
| 166 | + JSON::Writer& jw, | |
| 167 | + qpdf_json_stream_data_e json_data, | |
| 168 | + qpdf_stream_decode_level_e decode_level, | |
| 169 | + Pipeline* p, | |
| 170 | + std::string const& data_filename, | |
| 171 | + bool no_data_key = false); | |
| 172 | + void | |
| 173 | + replaceDict(QPDFObjectHandle const& new_dict) | |
| 174 | + { | |
| 175 | + auto s = stream(); | |
| 176 | + s->stream_dict = new_dict; | |
| 177 | + s->setDictDescription(); | |
| 178 | + } | |
| 179 | + | |
| 180 | + static void registerStreamFilter( | |
| 181 | + std::string const& filter_name, | |
| 182 | + std::function<std::shared_ptr<QPDFStreamFilter>()> factory); | |
| 183 | + | |
| 184 | + private: | |
| 185 | + QPDF_Stream* stream() const; | |
| 186 | + | |
| 187 | + bool filterable( | |
| 188 | + std::vector<std::shared_ptr<QPDFStreamFilter>>& filters, | |
| 189 | + bool& specialized_compression, | |
| 190 | + bool& lossy_compression); | |
| 191 | + void replaceFilterData( | |
| 192 | + QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length); | |
| 193 | + | |
| 194 | + void warn(std::string const& message); | |
| 195 | + | |
| 196 | + static std::map<std::string, std::string> filter_abbreviations; | |
| 197 | + static std::map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>> | |
| 198 | + filter_factories; | |
| 199 | + }; | |
| 200 | + | |
| 83 | 201 | inline qpdf_object_type_e |
| 84 | 202 | BaseHandle::type_code() const |
| 85 | 203 | { |
| ... | ... | @@ -98,7 +216,7 @@ QPDFObjectHandle::as_array(qpdf::typed options) const |
| 98 | 216 | (options & qpdf::optional && type_code() == ::ot_null)) { |
| 99 | 217 | return qpdf::Array(obj); |
| 100 | 218 | } |
| 101 | - return qpdf::Array({}); | |
| 219 | + return qpdf::Array(std::shared_ptr<QPDFObject>()); | |
| 102 | 220 | } |
| 103 | 221 | |
| 104 | 222 | inline qpdf::Dictionary |
| ... | ... | @@ -114,4 +232,17 @@ QPDFObjectHandle::as_dictionary(qpdf::typed options) const |
| 114 | 232 | return qpdf::Dictionary(std::shared_ptr<QPDFObject>()); |
| 115 | 233 | } |
| 116 | 234 | |
| 235 | +inline qpdf::Stream | |
| 236 | +QPDFObjectHandle::as_stream(qpdf::typed options) const | |
| 237 | +{ | |
| 238 | + if (options & qpdf::any_flag || type_code() == ::ot_stream || | |
| 239 | + (options & qpdf::optional && type_code() == ::ot_null)) { | |
| 240 | + return qpdf::Stream(obj); | |
| 241 | + } | |
| 242 | + if (options & qpdf::error) { | |
| 243 | + assertType("stream", false); | |
| 244 | + } | |
| 245 | + return qpdf::Stream(std::shared_ptr<QPDFObject>()); | |
| 246 | +} | |
| 247 | + | |
| 117 | 248 | #endif // OBJECTHANDLE_PRIVATE_HH | ... | ... |
libqpdf/qpdf/QPDF_Stream.hh
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | #include <qpdf/Types.h> |
| 5 | 5 | |
| 6 | 6 | #include <qpdf/QPDFObjectHandle.hh> |
| 7 | +#include <qpdf/QPDFObject_private.hh> | |
| 7 | 8 | #include <qpdf/QPDFStreamFilter.hh> |
| 8 | 9 | #include <qpdf/QPDFValue.hh> |
| 9 | 10 | |
| ... | ... | @@ -25,69 +26,15 @@ class QPDF_Stream final: public QPDFValue |
| 25 | 26 | void setDescription( |
| 26 | 27 | QPDF*, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset) final; |
| 27 | 28 | void disconnect() final; |
| 28 | - QPDFObjectHandle getDict() const; | |
| 29 | - bool isDataModified() const; | |
| 30 | - void setFilterOnWrite(bool); | |
| 31 | - bool getFilterOnWrite() const; | |
| 32 | - | |
| 33 | - // Methods to help QPDF copy foreign streams | |
| 34 | - size_t getLength() const; | |
| 35 | - std::shared_ptr<Buffer> getStreamDataBuffer() const; | |
| 36 | - std::shared_ptr<QPDFObjectHandle::StreamDataProvider> getStreamDataProvider() const; | |
| 37 | - | |
| 38 | - // See comments in QPDFObjectHandle.hh for these methods. | |
| 39 | - bool pipeStreamData( | |
| 40 | - Pipeline*, | |
| 41 | - bool* tried_filtering, | |
| 42 | - int encode_flags, | |
| 43 | - qpdf_stream_decode_level_e decode_level, | |
| 44 | - bool suppress_warnings, | |
| 45 | - bool will_retry); | |
| 46 | - std::shared_ptr<Buffer> getStreamData(qpdf_stream_decode_level_e); | |
| 47 | - std::shared_ptr<Buffer> getRawStreamData(); | |
| 48 | - void replaceStreamData( | |
| 49 | - std::shared_ptr<Buffer> data, | |
| 50 | - QPDFObjectHandle const& filter, | |
| 51 | - QPDFObjectHandle const& decode_parms); | |
| 52 | - void replaceStreamData( | |
| 53 | - std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider, | |
| 54 | - QPDFObjectHandle const& filter, | |
| 55 | - QPDFObjectHandle const& decode_parms); | |
| 56 | - void addTokenFilter(std::shared_ptr<QPDFObjectHandle::TokenFilter> token_filter); | |
| 57 | - JSON getStreamJSON( | |
| 58 | - int json_version, | |
| 59 | - qpdf_json_stream_data_e json_data, | |
| 60 | - qpdf_stream_decode_level_e decode_level, | |
| 61 | - Pipeline* p, | |
| 62 | - std::string const& data_filename); | |
| 63 | - qpdf_stream_decode_level_e writeStreamJSON( | |
| 64 | - int json_version, | |
| 65 | - JSON::Writer& jw, | |
| 66 | - qpdf_json_stream_data_e json_data, | |
| 67 | - qpdf_stream_decode_level_e decode_level, | |
| 68 | - Pipeline* p, | |
| 69 | - std::string const& data_filename, | |
| 70 | - bool no_data_key = false); | |
| 71 | - | |
| 72 | - void replaceDict(QPDFObjectHandle const& new_dict); | |
| 73 | - | |
| 74 | - static void registerStreamFilter( | |
| 75 | - std::string const& filter_name, std::function<std::shared_ptr<QPDFStreamFilter>()> factory); | |
| 76 | 29 | |
| 77 | 30 | private: |
| 31 | + friend class qpdf::Stream; | |
| 32 | + | |
| 78 | 33 | QPDF_Stream( |
| 79 | 34 | QPDF*, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length); |
| 80 | - static std::map<std::string, std::string> filter_abbreviations; | |
| 81 | - static std::map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>> | |
| 82 | - filter_factories; | |
| 83 | 35 | |
| 84 | 36 | void replaceFilterData( |
| 85 | 37 | QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length); |
| 86 | - bool filterable( | |
| 87 | - std::vector<std::shared_ptr<QPDFStreamFilter>>& filters, | |
| 88 | - bool& specialized_compression, | |
| 89 | - bool& lossy_compression); | |
| 90 | - void warn(std::string const& message); | |
| 91 | 38 | void setDictDescription(); |
| 92 | 39 | |
| 93 | 40 | bool filter_on_write; | ... | ... |