mirror of https://github.com/qpdf/qpdf.git
Update examples to use copyStream()
This commit is contained in:
parent
0f0f60109b
commit
3bdefb4c2d
|
@ -1,5 +1,10 @@
|
||||||
2021-02-25 Jay Berkenbilt <ejb@ql.org>
|
2021-02-25 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Update StreamDataProvider examples to use copyStream() when they
|
||||||
|
want to get to the original stream data from the provider. Prior
|
||||||
|
to 10.2.0, we had to copy the stream to another QPDF, but now we
|
||||||
|
can just use copyStream().
|
||||||
|
|
||||||
* Bug fix/behavior change: when QPDF::replaceObject or
|
* Bug fix/behavior change: when QPDF::replaceObject or
|
||||||
QPDF::swapObjects is called, existing QPDFObjectHandle instances
|
QPDF::swapObjects is called, existing QPDFObjectHandle instances
|
||||||
will now notice the change. This removes a long-standing source of
|
will now notice the change. This removes a long-standing source of
|
||||||
|
|
|
@ -198,8 +198,7 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider
|
||||||
// original stream data is no longer directly accessible. Trying
|
// original stream data is no longer directly accessible. Trying
|
||||||
// to retrieve the stream data would be an infinite loop because
|
// to retrieve the stream data would be an infinite loop because
|
||||||
// it would just end up calling provideStreamData again. This is
|
// it would just end up calling provideStreamData again. This is
|
||||||
// why maybeReplace uses a stashed copy of the original stream
|
// why maybeReplace uses a stashed copy of the original stream.
|
||||||
// from the "other" QPDF object.
|
|
||||||
|
|
||||||
// Additional explanation can be found in the method
|
// Additional explanation can be found in the method
|
||||||
// implementations.
|
// implementations.
|
||||||
|
@ -223,11 +222,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider
|
||||||
// we are replacing. We need this to create a new stream.
|
// we are replacing. We need this to create a new stream.
|
||||||
QPDF* pdf;
|
QPDF* pdf;
|
||||||
|
|
||||||
// This second QPDF instance gives us a place to copy streams to
|
|
||||||
// so that we can access the original stream data of the streams
|
|
||||||
// whose data we are replacing.
|
|
||||||
QPDF other;
|
|
||||||
|
|
||||||
// Map the object/generation in original file to the copied stream
|
// Map the object/generation in original file to the copied stream
|
||||||
// in "other". We use this to retrieve the original data.
|
// in "other". We use this to retrieve the original data.
|
||||||
std::map<QPDFObjGen, QPDFObjectHandle> copied_streams;
|
std::map<QPDFObjGen, QPDFObjectHandle> copied_streams;
|
||||||
|
@ -241,10 +235,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider
|
||||||
StreamReplacer::StreamReplacer(QPDF* pdf) :
|
StreamReplacer::StreamReplacer(QPDF* pdf) :
|
||||||
pdf(pdf)
|
pdf(pdf)
|
||||||
{
|
{
|
||||||
// Our "other" QPDF is just a place to stash streams. It doesn't
|
|
||||||
// have to be a valid PDF with pages, etc. We are never going to
|
|
||||||
// write this out.
|
|
||||||
this->other.emptyPDF();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -375,9 +365,11 @@ StreamReplacer::registerStream(
|
||||||
|
|
||||||
if (should_replace)
|
if (should_replace)
|
||||||
{
|
{
|
||||||
// Copy the stream to another QPDF object so we can get to the
|
// Copy the stream so we can get to the original data from the
|
||||||
// original data from the stream data provider.
|
// stream data provider. This doesn't actually copy any data,
|
||||||
this->copied_streams[og] = this->other.copyForeignObject(stream);
|
// but the copy retains the original stream data after the
|
||||||
|
// original one is modified.
|
||||||
|
this->copied_streams[og] = stream.copyStream();
|
||||||
// Update the stream dictionary with any changes.
|
// Update the stream dictionary with any changes.
|
||||||
auto dict = stream.getDict();
|
auto dict = stream.getDict();
|
||||||
for (auto const& k: dict_updates.getKeys())
|
for (auto const& k: dict_updates.getKeys())
|
||||||
|
|
|
@ -25,15 +25,13 @@ void usage()
|
||||||
// allocate memory up front for the objects. We want to replace the
|
// allocate memory up front for the objects. We want to replace the
|
||||||
// stream data with a function of the original stream data. In order
|
// stream data with a function of the original stream data. In order
|
||||||
// to do this without actually holding all the images in memory, we
|
// to do this without actually holding all the images in memory, we
|
||||||
// create another QPDF object and copy the streams. Copying the
|
// create copies of the streams. Copying the streams doesn't actually
|
||||||
// streams doesn't actually copy the data. Internally, the qpdf
|
// copy the data. Internally, the qpdf library is holding onto the
|
||||||
// library is holding onto the location of the stream data in the
|
// location of the original stream data, which makes it possible for
|
||||||
// original file, which makes it possible for the StreamDataProvider
|
// the StreamDataProvider to access it when it needs it.
|
||||||
// to access it when it needs it.
|
|
||||||
class ImageInverter: public QPDFObjectHandle::StreamDataProvider
|
class ImageInverter: public QPDFObjectHandle::StreamDataProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageInverter();
|
|
||||||
virtual ~ImageInverter()
|
virtual ~ImageInverter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -45,16 +43,9 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider
|
||||||
PointerHolder<QPDFObjectHandle::StreamDataProvider> self);
|
PointerHolder<QPDFObjectHandle::StreamDataProvider> self);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPDF other;
|
|
||||||
// Map og in original to copied image
|
|
||||||
std::map<QPDFObjGen, QPDFObjectHandle> copied_images;
|
std::map<QPDFObjGen, QPDFObjectHandle> copied_images;
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageInverter::ImageInverter()
|
|
||||||
{
|
|
||||||
this->other.emptyPDF();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImageInverter::registerImage(
|
ImageInverter::registerImage(
|
||||||
QPDFObjectHandle image,
|
QPDFObjectHandle image,
|
||||||
|
@ -77,7 +68,7 @@ ImageInverter::registerImage(
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->copied_images[og] = this->other.copyForeignObject(image);
|
this->copied_images[og] = image.copyStream();
|
||||||
|
|
||||||
// Register our stream data provider for this stream. Future calls
|
// Register our stream data provider for this stream. Future calls
|
||||||
// to getStreamData or pipeStreamData will use the new
|
// to getStreamData or pipeStreamData will use the new
|
||||||
|
|
Loading…
Reference in New Issue