diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index f3160bf9..06afc44f 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -382,6 +382,36 @@ class QPDF QPDF_DLL std::map getXRefTable(); + // Public factory methods + + // Create a new stream. A subsequent call must be made to + // replaceStreamData() to provide data for the stream. The stream's + // dictionary may be retrieved by calling getDict(), and the resulting + // dictionary may be modified. Alternatively, you can create a new + // dictionary and call replaceDict to install it. + QPDF_DLL + QPDFObjectHandle newStream(); + + // Create a new stream. Use the given buffer as the stream data. The + // stream dictionary's /Length key will automatically be set to the size of + // the data buffer. If additional keys are required, the stream's + // dictionary may be retrieved by calling getDict(), and the resulting + // dictionary may be modified. This method is just a convenient wrapper + // around the newStream() and replaceStreamData(). It is a convenience + // methods for streams that require no parameters beyond the stream length. + // Note that you don't have to deal with compression yourself if you use + // QPDFWriter. By default, QPDFWriter will automatically compress + // uncompressed stream data. Example programs are provided that + // illustrate this. + QPDF_DLL + QPDFObjectHandle newStream(std::shared_ptr data); + + // Create new stream with data from string. This method will + // create a copy of the data rather than using the user-provided + // buffer as in the std::shared_ptr version of newStream. + QPDF_DLL + QPDFObjectHandle newStream(std::string const& data); + // Install this object handle as an indirect object and return an // indirect reference to it. QPDF_DLL diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 50e08804..fde819a5 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -2001,6 +2001,31 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh) return makeIndirectObject(QPDFObjectHandle::ObjAccessor::getObject(oh)); } +QPDFObjectHandle +QPDF::newStream() +{ + return makeIndirectObject(QPDF_Stream::create( + this, nextObjGen(), QPDFObjectHandle::newDictionary(), 0, 0)); +} + +QPDFObjectHandle +QPDF::newStream(std::shared_ptr data) +{ + auto result = newStream(); + result.replaceStreamData( + data, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull()); + return result; +} + +QPDFObjectHandle +QPDF::newStream(std::string const& data) +{ + auto result = newStream(); + result.replaceStreamData( + data, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull()); + return result; +} + QPDFObjectHandle QPDF::reserveObjectIfNotExists(QPDFObjGen const& og) { diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 6aca51f0..931960ed 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -2165,30 +2165,29 @@ QPDFObjectHandle::newStream(QPDF* qpdf) "attempt to create stream in null qpdf object"); } QTC::TC("qpdf", "QPDFObjectHandle newStream"); - QPDFObjectHandle stream_dict = newDictionary(); - QPDFObjectHandle result = qpdf->makeIndirectObject(QPDFObjectHandle( - QPDF_Stream::create(qpdf, QPDFObjGen(), stream_dict, 0, 0))); - auto stream = result.asStream(); - stream->setObjGen(result.getObjGen()); - return result; + return qpdf->newStream(); } QPDFObjectHandle QPDFObjectHandle::newStream(QPDF* qpdf, std::shared_ptr data) { + if (qpdf == nullptr) { + throw std::runtime_error( + "attempt to create stream in null qpdf object"); + } QTC::TC("qpdf", "QPDFObjectHandle newStream with data"); - QPDFObjectHandle result = newStream(qpdf); - result.replaceStreamData(data, newNull(), newNull()); - return result; + return qpdf->newStream(data); } QPDFObjectHandle QPDFObjectHandle::newStream(QPDF* qpdf, std::string const& data) { + if (qpdf == nullptr) { + throw std::runtime_error( + "attempt to create stream in null qpdf object"); + } QTC::TC("qpdf", "QPDFObjectHandle newStream with string"); - QPDFObjectHandle result = newStream(qpdf); - result.replaceStreamData(data, newNull(), newNull()); - return result; + return qpdf->newStream(data); } QPDFObjectHandle