Commit 3bdefb4c2df28167fbce6d4bc266f3256454bb98

Authored by Jay Berkenbilt
1 parent 0f0f6010

Update examples to use copyStream()

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
... ...