Commit 3bdefb4c2df28167fbce6d4bc266f3256454bb98

Authored by Jay Berkenbilt
1 parent 0f0f6010

Update examples to use copyStream()

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