Commit 3bdefb4c2df28167fbce6d4bc266f3256454bb98
1 parent
0f0f6010
Update examples to use copyStream()
Showing
3 changed files
with
16 additions
and
28 deletions
ChangeLog
| 1 | 2021-02-25 Jay Berkenbilt <ejb@ql.org> | 1 | 2021-02-25 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | ||
| 3 | + * Update StreamDataProvider examples to use copyStream() when they | ||
| 4 | + want to get to the original stream data from the provider. Prior | ||
| 5 | + to 10.2.0, we had to copy the stream to another QPDF, but now we | ||
| 6 | + can just use copyStream(). | ||
| 7 | + | ||
| 3 | * Bug fix/behavior change: when QPDF::replaceObject or | 8 | * Bug fix/behavior change: when QPDF::replaceObject or |
| 4 | QPDF::swapObjects is called, existing QPDFObjectHandle instances | 9 | QPDF::swapObjects is called, existing QPDFObjectHandle instances |
| 5 | will now notice the change. This removes a long-standing source of | 10 | will now notice the change. This removes a long-standing source of |
examples/pdf-custom-filter.cc
| @@ -198,8 +198,7 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | @@ -198,8 +198,7 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | ||
| 198 | // original stream data is no longer directly accessible. Trying | 198 | // original stream data is no longer directly accessible. Trying |
| 199 | // to retrieve the stream data would be an infinite loop because | 199 | // to retrieve the stream data would be an infinite loop because |
| 200 | // it would just end up calling provideStreamData again. This is | 200 | // it would just end up calling provideStreamData again. This is |
| 201 | - // why maybeReplace uses a stashed copy of the original stream | ||
| 202 | - // from the "other" QPDF object. | 201 | + // why maybeReplace uses a stashed copy of the original stream. |
| 203 | 202 | ||
| 204 | // Additional explanation can be found in the method | 203 | // Additional explanation can be found in the method |
| 205 | // implementations. | 204 | // implementations. |
| @@ -223,11 +222,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | @@ -223,11 +222,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | ||
| 223 | // we are replacing. We need this to create a new stream. | 222 | // we are replacing. We need this to create a new stream. |
| 224 | QPDF* pdf; | 223 | QPDF* pdf; |
| 225 | 224 | ||
| 226 | - // This second QPDF instance gives us a place to copy streams to | ||
| 227 | - // so that we can access the original stream data of the streams | ||
| 228 | - // whose data we are replacing. | ||
| 229 | - QPDF other; | ||
| 230 | - | ||
| 231 | // Map the object/generation in original file to the copied stream | 225 | // Map the object/generation in original file to the copied stream |
| 232 | // in "other". We use this to retrieve the original data. | 226 | // in "other". We use this to retrieve the original data. |
| 233 | std::map<QPDFObjGen, QPDFObjectHandle> copied_streams; | 227 | std::map<QPDFObjGen, QPDFObjectHandle> copied_streams; |
| @@ -241,10 +235,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | @@ -241,10 +235,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | ||
| 241 | StreamReplacer::StreamReplacer(QPDF* pdf) : | 235 | StreamReplacer::StreamReplacer(QPDF* pdf) : |
| 242 | pdf(pdf) | 236 | pdf(pdf) |
| 243 | { | 237 | { |
| 244 | - // Our "other" QPDF is just a place to stash streams. It doesn't | ||
| 245 | - // have to be a valid PDF with pages, etc. We are never going to | ||
| 246 | - // write this out. | ||
| 247 | - this->other.emptyPDF(); | ||
| 248 | } | 238 | } |
| 249 | 239 | ||
| 250 | bool | 240 | bool |
| @@ -375,9 +365,11 @@ StreamReplacer::registerStream( | @@ -375,9 +365,11 @@ StreamReplacer::registerStream( | ||
| 375 | 365 | ||
| 376 | if (should_replace) | 366 | if (should_replace) |
| 377 | { | 367 | { |
| 378 | - // Copy the stream to another QPDF object so we can get to the | ||
| 379 | - // original data from the stream data provider. | ||
| 380 | - this->copied_streams[og] = this->other.copyForeignObject(stream); | 368 | + // Copy the stream so we can get to the original data from the |
| 369 | + // stream data provider. This doesn't actually copy any data, | ||
| 370 | + // but the copy retains the original stream data after the | ||
| 371 | + // original one is modified. | ||
| 372 | + this->copied_streams[og] = stream.copyStream(); | ||
| 381 | // Update the stream dictionary with any changes. | 373 | // Update the stream dictionary with any changes. |
| 382 | auto dict = stream.getDict(); | 374 | auto dict = stream.getDict(); |
| 383 | for (auto const& k: dict_updates.getKeys()) | 375 | for (auto const& k: dict_updates.getKeys()) |
examples/pdf-invert-images.cc
| @@ -25,15 +25,13 @@ void usage() | @@ -25,15 +25,13 @@ void usage() | ||
| 25 | // allocate memory up front for the objects. We want to replace the | 25 | // allocate memory up front for the objects. We want to replace the |
| 26 | // stream data with a function of the original stream data. In order | 26 | // stream data with a function of the original stream data. In order |
| 27 | // to do this without actually holding all the images in memory, we | 27 | // to do this without actually holding all the images in memory, we |
| 28 | -// create another QPDF object and copy the streams. Copying the | ||
| 29 | -// streams doesn't actually copy the data. Internally, the qpdf | ||
| 30 | -// library is holding onto the location of the stream data in the | ||
| 31 | -// original file, which makes it possible for the StreamDataProvider | ||
| 32 | -// to access it when it needs it. | 28 | +// create copies of the streams. Copying the streams doesn't actually |
| 29 | +// copy the data. Internally, the qpdf library is holding onto the | ||
| 30 | +// location of the original stream data, which makes it possible for | ||
| 31 | +// the StreamDataProvider to access it when it needs it. | ||
| 33 | class ImageInverter: public QPDFObjectHandle::StreamDataProvider | 32 | class ImageInverter: public QPDFObjectHandle::StreamDataProvider |
| 34 | { | 33 | { |
| 35 | public: | 34 | public: |
| 36 | - ImageInverter(); | ||
| 37 | virtual ~ImageInverter() | 35 | virtual ~ImageInverter() |
| 38 | { | 36 | { |
| 39 | } | 37 | } |
| @@ -45,16 +43,9 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider | @@ -45,16 +43,9 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider | ||
| 45 | PointerHolder<QPDFObjectHandle::StreamDataProvider> self); | 43 | PointerHolder<QPDFObjectHandle::StreamDataProvider> self); |
| 46 | 44 | ||
| 47 | private: | 45 | private: |
| 48 | - QPDF other; | ||
| 49 | - // Map og in original to copied image | ||
| 50 | std::map<QPDFObjGen, QPDFObjectHandle> copied_images; | 46 | std::map<QPDFObjGen, QPDFObjectHandle> copied_images; |
| 51 | }; | 47 | }; |
| 52 | 48 | ||
| 53 | -ImageInverter::ImageInverter() | ||
| 54 | -{ | ||
| 55 | - this->other.emptyPDF(); | ||
| 56 | -} | ||
| 57 | - | ||
| 58 | void | 49 | void |
| 59 | ImageInverter::registerImage( | 50 | ImageInverter::registerImage( |
| 60 | QPDFObjectHandle image, | 51 | QPDFObjectHandle image, |
| @@ -77,7 +68,7 @@ ImageInverter::registerImage( | @@ -77,7 +68,7 @@ ImageInverter::registerImage( | ||
| 77 | { | 68 | { |
| 78 | return; | 69 | return; |
| 79 | } | 70 | } |
| 80 | - this->copied_images[og] = this->other.copyForeignObject(image); | 71 | + this->copied_images[og] = image.copyStream(); |
| 81 | 72 | ||
| 82 | // Register our stream data provider for this stream. Future calls | 73 | // Register our stream data provider for this stream. Future calls |
| 83 | // to getStreamData or pipeStreamData will use the new | 74 | // to getStreamData or pipeStreamData will use the new |