Commit 3bdefb4c2df28167fbce6d4bc266f3256454bb98
1 parent
0f0f6010
Update examples to use copyStream()
Showing
3 changed files
with
16 additions
and
28 deletions
ChangeLog
| 1 | 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 | 8 | * Bug fix/behavior change: when QPDF::replaceObject or |
| 4 | 9 | QPDF::swapObjects is called, existing QPDFObjectHandle instances |
| 5 | 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 | 198 | // original stream data is no longer directly accessible. Trying |
| 199 | 199 | // to retrieve the stream data would be an infinite loop because |
| 200 | 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 | 203 | // Additional explanation can be found in the method |
| 205 | 204 | // implementations. |
| ... | ... | @@ -223,11 +222,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider |
| 223 | 222 | // we are replacing. We need this to create a new stream. |
| 224 | 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 | 225 | // Map the object/generation in original file to the copied stream |
| 232 | 226 | // in "other". We use this to retrieve the original data. |
| 233 | 227 | std::map<QPDFObjGen, QPDFObjectHandle> copied_streams; |
| ... | ... | @@ -241,10 +235,6 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider |
| 241 | 235 | StreamReplacer::StreamReplacer(QPDF* pdf) : |
| 242 | 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 | 240 | bool |
| ... | ... | @@ -375,9 +365,11 @@ StreamReplacer::registerStream( |
| 375 | 365 | |
| 376 | 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 | 373 | // Update the stream dictionary with any changes. |
| 382 | 374 | auto dict = stream.getDict(); |
| 383 | 375 | for (auto const& k: dict_updates.getKeys()) | ... | ... |
examples/pdf-invert-images.cc
| ... | ... | @@ -25,15 +25,13 @@ void usage() |
| 25 | 25 | // allocate memory up front for the objects. We want to replace the |
| 26 | 26 | // stream data with a function of the original stream data. In order |
| 27 | 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 | 32 | class ImageInverter: public QPDFObjectHandle::StreamDataProvider |
| 34 | 33 | { |
| 35 | 34 | public: |
| 36 | - ImageInverter(); | |
| 37 | 35 | virtual ~ImageInverter() |
| 38 | 36 | { |
| 39 | 37 | } |
| ... | ... | @@ -45,16 +43,9 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider |
| 45 | 43 | PointerHolder<QPDFObjectHandle::StreamDataProvider> self); |
| 46 | 44 | |
| 47 | 45 | private: |
| 48 | - QPDF other; | |
| 49 | - // Map og in original to copied image | |
| 50 | 46 | std::map<QPDFObjGen, QPDFObjectHandle> copied_images; |
| 51 | 47 | }; |
| 52 | 48 | |
| 53 | -ImageInverter::ImageInverter() | |
| 54 | -{ | |
| 55 | - this->other.emptyPDF(); | |
| 56 | -} | |
| 57 | - | |
| 58 | 49 | void |
| 59 | 50 | ImageInverter::registerImage( |
| 60 | 51 | QPDFObjectHandle image, |
| ... | ... | @@ -77,7 +68,7 @@ ImageInverter::registerImage( |
| 77 | 68 | { |
| 78 | 69 | return; |
| 79 | 70 | } |
| 80 | - this->copied_images[og] = this->other.copyForeignObject(image); | |
| 71 | + this->copied_images[og] = image.copyStream(); | |
| 81 | 72 | |
| 82 | 73 | // Register our stream data provider for this stream. Future calls |
| 83 | 74 | // to getStreamData or pipeStreamData will use the new | ... | ... |