diff --git a/include/qpdf/ObjectHandle.hh b/include/qpdf/ObjectHandle.hh index 781cf59..4fd9d8a 100644 --- a/include/qpdf/ObjectHandle.hh +++ b/include/qpdf/ObjectHandle.hh @@ -39,7 +39,7 @@ namespace qpdf class Dictionary; class Stream; - enum typed : std::uint8_t { strict = 0, any_flag = 1, optional = 2, any = 3, error = 4}; + enum typed : std::uint8_t { strict = 0, any_flag = 1, optional = 2, any = 3, error = 4 }; // Basehandle is only used as a base-class for QPDFObjectHandle like classes. Currently the only // methods exposed in public API are operators to convert derived objects to QPDFObjectHandle, diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 2e8ebf2..71ad050 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -957,180 +957,7 @@ QPDFObjectHandle::getUniqueResourceName( // Dictionary mutators are in QPDF_Dictionary.cc -// Stream accessors - -QPDFObjectHandle -QPDFObjectHandle::getDict() const -{ - return as_stream(error).getDict(); -} - -void -QPDFObjectHandle::setFilterOnWrite(bool val) -{ - as_stream(error).setFilterOnWrite(val); -} - -bool -QPDFObjectHandle::getFilterOnWrite() -{ - return as_stream(error).getFilterOnWrite(); -} - -bool -QPDFObjectHandle::isDataModified() -{ - return as_stream(error).isDataModified(); -} - -void -QPDFObjectHandle::replaceDict(QPDFObjectHandle const& new_dict) -{ - as_stream(error).replaceDict(new_dict); -} - -std::shared_ptr -QPDFObjectHandle::getStreamData(qpdf_stream_decode_level_e level) -{ - return as_stream(error).getStreamData(level); -} - -std::shared_ptr -QPDFObjectHandle::getRawStreamData() -{ - return as_stream(error).getRawStreamData(); -} - -bool -QPDFObjectHandle::pipeStreamData( - Pipeline* p, - bool* filtering_attempted, - int encode_flags, - qpdf_stream_decode_level_e decode_level, - bool suppress_warnings, - bool will_retry) -{ - return as_stream(error).pipeStreamData( - p, filtering_attempted, encode_flags, decode_level, suppress_warnings, will_retry); -} - -bool -QPDFObjectHandle::pipeStreamData( - Pipeline* p, - int encode_flags, - qpdf_stream_decode_level_e decode_level, - bool suppress_warnings, - bool will_retry) -{ - bool filtering_attempted; - as_stream(error).pipeStreamData( - p, &filtering_attempted, encode_flags, decode_level, suppress_warnings, will_retry); - return filtering_attempted; -} - -bool -QPDFObjectHandle::pipeStreamData(Pipeline* p, bool filter, bool normalize, bool compress) -{ - int encode_flags = 0; - qpdf_stream_decode_level_e decode_level = qpdf_dl_none; - if (filter) { - decode_level = qpdf_dl_generalized; - if (normalize) { - encode_flags |= qpdf_ef_normalize; - } - if (compress) { - encode_flags |= qpdf_ef_compress; - } - } - return pipeStreamData(p, encode_flags, decode_level, false); -} - -void -QPDFObjectHandle::replaceStreamData( - std::shared_ptr data, - QPDFObjectHandle const& filter, - QPDFObjectHandle const& decode_parms) -{ - as_stream(error).replaceStreamData(data, filter, decode_parms); -} - -void -QPDFObjectHandle::replaceStreamData( - std::string const& data, QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms) -{ - auto b = std::make_shared(data.length()); - unsigned char* bp = b->getBuffer(); - if (bp) { - memcpy(bp, data.c_str(), data.length()); - } - as_stream(error).replaceStreamData(b, filter, decode_parms); -} - -void -QPDFObjectHandle::replaceStreamData( - std::shared_ptr provider, - QPDFObjectHandle const& filter, - QPDFObjectHandle const& decode_parms) -{ - as_stream(error).replaceStreamData(provider, filter, decode_parms); -} - -namespace -{ - class FunctionProvider: public QPDFObjectHandle::StreamDataProvider - { - public: - FunctionProvider(std::function provider) : - StreamDataProvider(false), - p1(provider), - p2(nullptr) - { - } - FunctionProvider(std::function provider) : - StreamDataProvider(true), - p1(nullptr), - p2(provider) - { - } - - void - provideStreamData(QPDFObjGen const&, Pipeline* pipeline) override - { - p1(pipeline); - } - - bool - provideStreamData( - QPDFObjGen const&, Pipeline* pipeline, bool suppress_warnings, bool will_retry) override - { - return p2(pipeline, suppress_warnings, will_retry); - } - - private: - std::function p1; - std::function p2; - }; -} // namespace - -void -QPDFObjectHandle::replaceStreamData( - std::function provider, - QPDFObjectHandle const& filter, - QPDFObjectHandle const& decode_parms) -{ - auto sdp = std::shared_ptr(new FunctionProvider(provider)); - as_stream(error).replaceStreamData(sdp, filter, decode_parms); -} - -void -QPDFObjectHandle::replaceStreamData( - std::function provider, - QPDFObjectHandle const& filter, - QPDFObjectHandle const& decode_parms) -{ - auto sdp = std::shared_ptr(new FunctionProvider(provider)); - as_stream(error).replaceStreamData(sdp, filter, decode_parms); -} +// Stream accessors are in QPDF_Stream.cc std::map QPDFObjectHandle::getPageImages() @@ -1340,17 +1167,6 @@ QPDFObjectHandle::writeJSON( writeJSON(json_version, jw, dereference_indirect); } -JSON -QPDFObjectHandle::getStreamJSON( - int json_version, - qpdf_json_stream_data_e json_data, - qpdf_stream_decode_level_e decode_level, - Pipeline* p, - std::string const& data_filename) -{ - return as_stream(error).getStreamJSON(json_version, json_data, decode_level, p, data_filename); -} - QPDFObjectHandle QPDFObjectHandle::wrapInArray() { diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index d041a65..552d220 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -162,18 +162,6 @@ QPDF_Stream::writeJSON(int json_version, JSON::Writer& jw) stream_dict.writeJSON(json_version, jw); } -QPDF_Stream* -Stream::stream() const -{ - if (obj) { - if (auto s = obj->as()) { - return s; - } - } - throw std::runtime_error("operation for stream attempted on object of type dictionary"); - return nullptr; // unreachable -} - JSON Stream::getStreamJSON( int json_version, @@ -657,3 +645,187 @@ Stream::warn(std::string const& message) auto s = stream(); s->qpdf->warn(qpdf_e_damaged_pdf, "", s->parsed_offset, message); } + +QPDFObjectHandle +QPDFObjectHandle::getDict() const +{ + return as_stream(error).getDict(); +} + +void +QPDFObjectHandle::setFilterOnWrite(bool val) +{ + as_stream(error).setFilterOnWrite(val); +} + +bool +QPDFObjectHandle::getFilterOnWrite() +{ + return as_stream(error).getFilterOnWrite(); +} + +bool +QPDFObjectHandle::isDataModified() +{ + return as_stream(error).isDataModified(); +} + +void +QPDFObjectHandle::replaceDict(QPDFObjectHandle const& new_dict) +{ + as_stream(error).replaceDict(new_dict); +} + +std::shared_ptr +QPDFObjectHandle::getStreamData(qpdf_stream_decode_level_e level) +{ + return as_stream(error).getStreamData(level); +} + +std::shared_ptr +QPDFObjectHandle::getRawStreamData() +{ + return as_stream(error).getRawStreamData(); +} + +bool +QPDFObjectHandle::pipeStreamData( + Pipeline* p, + bool* filtering_attempted, + int encode_flags, + qpdf_stream_decode_level_e decode_level, + bool suppress_warnings, + bool will_retry) +{ + return as_stream(error).pipeStreamData( + p, filtering_attempted, encode_flags, decode_level, suppress_warnings, will_retry); +} + +bool +QPDFObjectHandle::pipeStreamData( + Pipeline* p, + int encode_flags, + qpdf_stream_decode_level_e decode_level, + bool suppress_warnings, + bool will_retry) +{ + bool filtering_attempted; + as_stream(error).pipeStreamData( + p, &filtering_attempted, encode_flags, decode_level, suppress_warnings, will_retry); + return filtering_attempted; +} + +bool +QPDFObjectHandle::pipeStreamData(Pipeline* p, bool filter, bool normalize, bool compress) +{ + int encode_flags = 0; + qpdf_stream_decode_level_e decode_level = qpdf_dl_none; + if (filter) { + decode_level = qpdf_dl_generalized; + if (normalize) { + encode_flags |= qpdf_ef_normalize; + } + if (compress) { + encode_flags |= qpdf_ef_compress; + } + } + return pipeStreamData(p, encode_flags, decode_level, false); +} + +void +QPDFObjectHandle::replaceStreamData( + std::shared_ptr data, + QPDFObjectHandle const& filter, + QPDFObjectHandle const& decode_parms) +{ + as_stream(error).replaceStreamData(data, filter, decode_parms); +} + +void +QPDFObjectHandle::replaceStreamData( + std::string const& data, QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms) +{ + auto b = std::make_shared(data.length()); + unsigned char* bp = b->getBuffer(); + if (bp) { + memcpy(bp, data.c_str(), data.length()); + } + as_stream(error).replaceStreamData(b, filter, decode_parms); +} + +void +QPDFObjectHandle::replaceStreamData( + std::shared_ptr provider, + QPDFObjectHandle const& filter, + QPDFObjectHandle const& decode_parms) +{ + as_stream(error).replaceStreamData(provider, filter, decode_parms); +} + +namespace +{ + class FunctionProvider: public QPDFObjectHandle::StreamDataProvider + { + public: + FunctionProvider(std::function provider) : + StreamDataProvider(false), + p1(provider), + p2(nullptr) + { + } + FunctionProvider(std::function provider) : + StreamDataProvider(true), + p1(nullptr), + p2(provider) + { + } + + void + provideStreamData(QPDFObjGen const&, Pipeline* pipeline) override + { + p1(pipeline); + } + + bool + provideStreamData( + QPDFObjGen const&, Pipeline* pipeline, bool suppress_warnings, bool will_retry) override + { + return p2(pipeline, suppress_warnings, will_retry); + } + + private: + std::function p1; + std::function p2; + }; +} // namespace + +void +QPDFObjectHandle::replaceStreamData( + std::function provider, + QPDFObjectHandle const& filter, + QPDFObjectHandle const& decode_parms) +{ + auto sdp = std::shared_ptr(new FunctionProvider(provider)); + as_stream(error).replaceStreamData(sdp, filter, decode_parms); +} + +void +QPDFObjectHandle::replaceStreamData( + std::function provider, + QPDFObjectHandle const& filter, + QPDFObjectHandle const& decode_parms) +{ + auto sdp = std::shared_ptr(new FunctionProvider(provider)); + as_stream(error).replaceStreamData(sdp, filter, decode_parms); +} + +JSON +QPDFObjectHandle::getStreamJSON( + int json_version, + qpdf_json_stream_data_e json_data, + qpdf_stream_decode_level_e decode_level, + Pipeline* p, + std::string const& data_filename) +{ + return as_stream(error).getStreamJSON(json_version, json_data, decode_level, p, data_filename); +} diff --git a/libqpdf/qpdf/QPDFObjectHandle_private.hh b/libqpdf/qpdf/QPDFObjectHandle_private.hh index afd4118..4554dc1 100644 --- a/libqpdf/qpdf/QPDFObjectHandle_private.hh +++ b/libqpdf/qpdf/QPDFObjectHandle_private.hh @@ -182,8 +182,17 @@ namespace qpdf std::function()> factory); private: - QPDF_Stream* stream() const; - + QPDF_Stream* + stream() const + { + if (obj) { + if (auto s = obj->as()) { + return s; + } + } + throw std::runtime_error("operation for stream attempted on object of type dictionary"); + return nullptr; // unreachable + } bool filterable( std::vector>& filters, bool& specialized_compression,