mirror of
https://github.com/qpdf/qpdf.git
synced 2025-02-08 22:58:25 +00:00
Refactor: separate copyStreamData from replaceForeignIndirectObjects
This commit is contained in:
parent
15269f36d8
commit
60afe4142e
@ -1005,6 +1005,8 @@ class QPDF
|
|||||||
bool top);
|
bool top);
|
||||||
QPDFObjectHandle replaceForeignIndirectObjects(
|
QPDFObjectHandle replaceForeignIndirectObjects(
|
||||||
QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top);
|
QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top);
|
||||||
|
void copyStreamData(
|
||||||
|
QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream);
|
||||||
|
|
||||||
// Linearization Hint table structures.
|
// Linearization Hint table structures.
|
||||||
// Naming conventions:
|
// Naming conventions:
|
||||||
|
162
libqpdf/QPDF.cc
162
libqpdf/QPDF.cc
@ -2569,88 +2569,14 @@ QPDF::replaceForeignIndirectObjects(
|
|||||||
QPDFObjectHandle old_dict = foreign.getDict();
|
QPDFObjectHandle old_dict = foreign.getDict();
|
||||||
std::set<std::string> keys = old_dict.getKeys();
|
std::set<std::string> keys = old_dict.getKeys();
|
||||||
for (std::set<std::string>::iterator iter = keys.begin();
|
for (std::set<std::string>::iterator iter = keys.begin();
|
||||||
iter != keys.end(); ++iter)
|
iter != keys.end(); ++iter)
|
||||||
{
|
{
|
||||||
dict.replaceKey(
|
dict.replaceKey(
|
||||||
*iter,
|
*iter,
|
||||||
replaceForeignIndirectObjects(
|
replaceForeignIndirectObjects(
|
||||||
old_dict.getKey(*iter), obj_copier, false));
|
old_dict.getKey(*iter), obj_copier, false));
|
||||||
}
|
|
||||||
if (this->m->copied_stream_data_provider == 0)
|
|
||||||
{
|
|
||||||
this->m->copied_stream_data_provider =
|
|
||||||
new CopiedStreamDataProvider(*this);
|
|
||||||
this->m->copied_streams = this->m->copied_stream_data_provider;
|
|
||||||
}
|
|
||||||
QPDFObjGen local_og(result.getObjGen());
|
|
||||||
// Copy information from the foreign stream so we can pipe its
|
|
||||||
// data later without keeping the original QPDF object around.
|
|
||||||
QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();
|
|
||||||
if (! foreign_stream_qpdf)
|
|
||||||
{
|
|
||||||
throw std::logic_error("unable to retrieve owning qpdf"
|
|
||||||
" from foreign stream");
|
|
||||||
}
|
|
||||||
QPDF_Stream* stream =
|
|
||||||
dynamic_cast<QPDF_Stream*>(
|
|
||||||
QPDFObjectHandle::ObjAccessor::getObject(
|
|
||||||
foreign).getPointer());
|
|
||||||
if (! stream)
|
|
||||||
{
|
|
||||||
throw std::logic_error("unable to retrieve underlying"
|
|
||||||
" stream object from foreign stream");
|
|
||||||
}
|
|
||||||
PointerHolder<Buffer> stream_buffer =
|
|
||||||
stream->getStreamDataBuffer();
|
|
||||||
if ((foreign_stream_qpdf->m->immediate_copy_from) &&
|
|
||||||
(stream_buffer.getPointer() == 0))
|
|
||||||
{
|
|
||||||
// Pull the stream data into a buffer before attempting
|
|
||||||
// the copy operation. Do it on the source stream so that
|
|
||||||
// if the source stream is copied multiple times, we don't
|
|
||||||
// have to keep duplicating the memory.
|
|
||||||
QTC::TC("qpdf", "QPDF immediate copy stream data");
|
|
||||||
foreign.replaceStreamData(foreign.getRawStreamData(),
|
|
||||||
old_dict.getKey("/Filter"),
|
|
||||||
old_dict.getKey("/DecodeParms"));
|
|
||||||
stream_buffer = stream->getStreamDataBuffer();
|
|
||||||
}
|
|
||||||
PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider =
|
|
||||||
stream->getStreamDataProvider();
|
|
||||||
if (stream_buffer.getPointer())
|
|
||||||
{
|
|
||||||
QTC::TC("qpdf", "QPDF copy foreign stream with buffer");
|
|
||||||
result.replaceStreamData(stream_buffer,
|
|
||||||
dict.getKey("/Filter"),
|
|
||||||
dict.getKey("/DecodeParms"));
|
|
||||||
}
|
|
||||||
else if (stream_provider.getPointer())
|
|
||||||
{
|
|
||||||
// In this case, the remote stream's QPDF must stay in scope.
|
|
||||||
QTC::TC("qpdf", "QPDF copy foreign stream with provider");
|
|
||||||
this->m->copied_stream_data_provider->registerForeignStream(
|
|
||||||
local_og, foreign);
|
|
||||||
result.replaceStreamData(this->m->copied_streams,
|
|
||||||
dict.getKey("/Filter"),
|
|
||||||
dict.getKey("/DecodeParms"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PointerHolder<ForeignStreamData> foreign_stream_data =
|
|
||||||
new ForeignStreamData(
|
|
||||||
foreign_stream_qpdf->m->encp,
|
|
||||||
foreign_stream_qpdf->m->file,
|
|
||||||
foreign.getObjectID(),
|
|
||||||
foreign.getGeneration(),
|
|
||||||
stream->getOffset(),
|
|
||||||
stream->getLength(),
|
|
||||||
dict);
|
|
||||||
this->m->copied_stream_data_provider->registerForeignStream(
|
|
||||||
local_og, foreign_stream_data);
|
|
||||||
result.replaceStreamData(this->m->copied_streams,
|
|
||||||
dict.getKey("/Filter"),
|
|
||||||
dict.getKey("/DecodeParms"));
|
|
||||||
}
|
}
|
||||||
|
copyStreamData(result, foreign);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2667,6 +2593,88 @@ QPDF::replaceForeignIndirectObjects(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
|
||||||
|
{
|
||||||
|
QPDFObjectHandle dict = result.getDict();
|
||||||
|
QPDFObjectHandle old_dict = foreign.getDict();
|
||||||
|
if (this->m->copied_stream_data_provider == 0)
|
||||||
|
{
|
||||||
|
this->m->copied_stream_data_provider =
|
||||||
|
new CopiedStreamDataProvider(*this);
|
||||||
|
this->m->copied_streams = this->m->copied_stream_data_provider;
|
||||||
|
}
|
||||||
|
QPDFObjGen local_og(result.getObjGen());
|
||||||
|
// Copy information from the foreign stream so we can pipe its
|
||||||
|
// data later without keeping the original QPDF object around.
|
||||||
|
QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();
|
||||||
|
if (! foreign_stream_qpdf)
|
||||||
|
{
|
||||||
|
throw std::logic_error("unable to retrieve owning qpdf"
|
||||||
|
" from foreign stream");
|
||||||
|
}
|
||||||
|
QPDF_Stream* stream =
|
||||||
|
dynamic_cast<QPDF_Stream*>(
|
||||||
|
QPDFObjectHandle::ObjAccessor::getObject(
|
||||||
|
foreign).getPointer());
|
||||||
|
if (! stream)
|
||||||
|
{
|
||||||
|
throw std::logic_error("unable to retrieve underlying"
|
||||||
|
" stream object from foreign stream");
|
||||||
|
}
|
||||||
|
PointerHolder<Buffer> stream_buffer =
|
||||||
|
stream->getStreamDataBuffer();
|
||||||
|
if ((foreign_stream_qpdf->m->immediate_copy_from) &&
|
||||||
|
(stream_buffer.getPointer() == 0))
|
||||||
|
{
|
||||||
|
// Pull the stream data into a buffer before attempting
|
||||||
|
// the copy operation. Do it on the source stream so that
|
||||||
|
// if the source stream is copied multiple times, we don't
|
||||||
|
// have to keep duplicating the memory.
|
||||||
|
QTC::TC("qpdf", "QPDF immediate copy stream data");
|
||||||
|
foreign.replaceStreamData(foreign.getRawStreamData(),
|
||||||
|
old_dict.getKey("/Filter"),
|
||||||
|
old_dict.getKey("/DecodeParms"));
|
||||||
|
stream_buffer = stream->getStreamDataBuffer();
|
||||||
|
}
|
||||||
|
PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider =
|
||||||
|
stream->getStreamDataProvider();
|
||||||
|
if (stream_buffer.getPointer())
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "QPDF copy foreign stream with buffer");
|
||||||
|
result.replaceStreamData(stream_buffer,
|
||||||
|
dict.getKey("/Filter"),
|
||||||
|
dict.getKey("/DecodeParms"));
|
||||||
|
}
|
||||||
|
else if (stream_provider.getPointer())
|
||||||
|
{
|
||||||
|
// In this case, the remote stream's QPDF must stay in scope.
|
||||||
|
QTC::TC("qpdf", "QPDF copy foreign stream with provider");
|
||||||
|
this->m->copied_stream_data_provider->registerForeignStream(
|
||||||
|
local_og, foreign);
|
||||||
|
result.replaceStreamData(this->m->copied_streams,
|
||||||
|
dict.getKey("/Filter"),
|
||||||
|
dict.getKey("/DecodeParms"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PointerHolder<ForeignStreamData> foreign_stream_data =
|
||||||
|
new ForeignStreamData(
|
||||||
|
foreign_stream_qpdf->m->encp,
|
||||||
|
foreign_stream_qpdf->m->file,
|
||||||
|
foreign.getObjectID(),
|
||||||
|
foreign.getGeneration(),
|
||||||
|
stream->getOffset(),
|
||||||
|
stream->getLength(),
|
||||||
|
dict);
|
||||||
|
this->m->copied_stream_data_provider->registerForeignStream(
|
||||||
|
local_og, foreign_stream_data);
|
||||||
|
result.replaceStreamData(this->m->copied_streams,
|
||||||
|
dict.getKey("/Filter"),
|
||||||
|
dict.getKey("/DecodeParms"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2)
|
QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user