Commit 60afe4142e4399b12f21aced476df7ef719008b9
1 parent
15269f36
Refactor: separate copyStreamData from replaceForeignIndirectObjects
Showing
2 changed files
with
87 additions
and
77 deletions
include/qpdf/QPDF.hh
| ... | ... | @@ -1005,6 +1005,8 @@ class QPDF |
| 1005 | 1005 | bool top); |
| 1006 | 1006 | QPDFObjectHandle replaceForeignIndirectObjects( |
| 1007 | 1007 | QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top); |
| 1008 | + void copyStreamData( | |
| 1009 | + QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream); | |
| 1008 | 1010 | |
| 1009 | 1011 | // Linearization Hint table structures. |
| 1010 | 1012 | // Naming conventions: | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -2569,88 +2569,14 @@ QPDF::replaceForeignIndirectObjects( |
| 2569 | 2569 | QPDFObjectHandle old_dict = foreign.getDict(); |
| 2570 | 2570 | std::set<std::string> keys = old_dict.getKeys(); |
| 2571 | 2571 | for (std::set<std::string>::iterator iter = keys.begin(); |
| 2572 | - iter != keys.end(); ++iter) | |
| 2573 | - { | |
| 2572 | + iter != keys.end(); ++iter) | |
| 2573 | + { | |
| 2574 | 2574 | dict.replaceKey( |
| 2575 | 2575 | *iter, |
| 2576 | 2576 | replaceForeignIndirectObjects( |
| 2577 | 2577 | old_dict.getKey(*iter), obj_copier, false)); |
| 2578 | - } | |
| 2579 | - if (this->m->copied_stream_data_provider == 0) | |
| 2580 | - { | |
| 2581 | - this->m->copied_stream_data_provider = | |
| 2582 | - new CopiedStreamDataProvider(*this); | |
| 2583 | - this->m->copied_streams = this->m->copied_stream_data_provider; | |
| 2584 | - } | |
| 2585 | - QPDFObjGen local_og(result.getObjGen()); | |
| 2586 | - // Copy information from the foreign stream so we can pipe its | |
| 2587 | - // data later without keeping the original QPDF object around. | |
| 2588 | - QPDF* foreign_stream_qpdf = foreign.getOwningQPDF(); | |
| 2589 | - if (! foreign_stream_qpdf) | |
| 2590 | - { | |
| 2591 | - throw std::logic_error("unable to retrieve owning qpdf" | |
| 2592 | - " from foreign stream"); | |
| 2593 | - } | |
| 2594 | - QPDF_Stream* stream = | |
| 2595 | - dynamic_cast<QPDF_Stream*>( | |
| 2596 | - QPDFObjectHandle::ObjAccessor::getObject( | |
| 2597 | - foreign).getPointer()); | |
| 2598 | - if (! stream) | |
| 2599 | - { | |
| 2600 | - throw std::logic_error("unable to retrieve underlying" | |
| 2601 | - " stream object from foreign stream"); | |
| 2602 | - } | |
| 2603 | - PointerHolder<Buffer> stream_buffer = | |
| 2604 | - stream->getStreamDataBuffer(); | |
| 2605 | - if ((foreign_stream_qpdf->m->immediate_copy_from) && | |
| 2606 | - (stream_buffer.getPointer() == 0)) | |
| 2607 | - { | |
| 2608 | - // Pull the stream data into a buffer before attempting | |
| 2609 | - // the copy operation. Do it on the source stream so that | |
| 2610 | - // if the source stream is copied multiple times, we don't | |
| 2611 | - // have to keep duplicating the memory. | |
| 2612 | - QTC::TC("qpdf", "QPDF immediate copy stream data"); | |
| 2613 | - foreign.replaceStreamData(foreign.getRawStreamData(), | |
| 2614 | - old_dict.getKey("/Filter"), | |
| 2615 | - old_dict.getKey("/DecodeParms")); | |
| 2616 | - stream_buffer = stream->getStreamDataBuffer(); | |
| 2617 | - } | |
| 2618 | - PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider = | |
| 2619 | - stream->getStreamDataProvider(); | |
| 2620 | - if (stream_buffer.getPointer()) | |
| 2621 | - { | |
| 2622 | - QTC::TC("qpdf", "QPDF copy foreign stream with buffer"); | |
| 2623 | - result.replaceStreamData(stream_buffer, | |
| 2624 | - dict.getKey("/Filter"), | |
| 2625 | - dict.getKey("/DecodeParms")); | |
| 2626 | - } | |
| 2627 | - else if (stream_provider.getPointer()) | |
| 2628 | - { | |
| 2629 | - // In this case, the remote stream's QPDF must stay in scope. | |
| 2630 | - QTC::TC("qpdf", "QPDF copy foreign stream with provider"); | |
| 2631 | - this->m->copied_stream_data_provider->registerForeignStream( | |
| 2632 | - local_og, foreign); | |
| 2633 | - result.replaceStreamData(this->m->copied_streams, | |
| 2634 | - dict.getKey("/Filter"), | |
| 2635 | - dict.getKey("/DecodeParms")); | |
| 2636 | - } | |
| 2637 | - else | |
| 2638 | - { | |
| 2639 | - PointerHolder<ForeignStreamData> foreign_stream_data = | |
| 2640 | - new ForeignStreamData( | |
| 2641 | - foreign_stream_qpdf->m->encp, | |
| 2642 | - foreign_stream_qpdf->m->file, | |
| 2643 | - foreign.getObjectID(), | |
| 2644 | - foreign.getGeneration(), | |
| 2645 | - stream->getOffset(), | |
| 2646 | - stream->getLength(), | |
| 2647 | - dict); | |
| 2648 | - this->m->copied_stream_data_provider->registerForeignStream( | |
| 2649 | - local_og, foreign_stream_data); | |
| 2650 | - result.replaceStreamData(this->m->copied_streams, | |
| 2651 | - dict.getKey("/Filter"), | |
| 2652 | - dict.getKey("/DecodeParms")); | |
| 2653 | 2578 | } |
| 2579 | + copyStreamData(result, foreign); | |
| 2654 | 2580 | } |
| 2655 | 2581 | else |
| 2656 | 2582 | { |
| ... | ... | @@ -2668,6 +2594,88 @@ QPDF::replaceForeignIndirectObjects( |
| 2668 | 2594 | } |
| 2669 | 2595 | |
| 2670 | 2596 | void |
| 2597 | +QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) | |
| 2598 | +{ | |
| 2599 | + QPDFObjectHandle dict = result.getDict(); | |
| 2600 | + QPDFObjectHandle old_dict = foreign.getDict(); | |
| 2601 | + if (this->m->copied_stream_data_provider == 0) | |
| 2602 | + { | |
| 2603 | + this->m->copied_stream_data_provider = | |
| 2604 | + new CopiedStreamDataProvider(*this); | |
| 2605 | + this->m->copied_streams = this->m->copied_stream_data_provider; | |
| 2606 | + } | |
| 2607 | + QPDFObjGen local_og(result.getObjGen()); | |
| 2608 | + // Copy information from the foreign stream so we can pipe its | |
| 2609 | + // data later without keeping the original QPDF object around. | |
| 2610 | + QPDF* foreign_stream_qpdf = foreign.getOwningQPDF(); | |
| 2611 | + if (! foreign_stream_qpdf) | |
| 2612 | + { | |
| 2613 | + throw std::logic_error("unable to retrieve owning qpdf" | |
| 2614 | + " from foreign stream"); | |
| 2615 | + } | |
| 2616 | + QPDF_Stream* stream = | |
| 2617 | + dynamic_cast<QPDF_Stream*>( | |
| 2618 | + QPDFObjectHandle::ObjAccessor::getObject( | |
| 2619 | + foreign).getPointer()); | |
| 2620 | + if (! stream) | |
| 2621 | + { | |
| 2622 | + throw std::logic_error("unable to retrieve underlying" | |
| 2623 | + " stream object from foreign stream"); | |
| 2624 | + } | |
| 2625 | + PointerHolder<Buffer> stream_buffer = | |
| 2626 | + stream->getStreamDataBuffer(); | |
| 2627 | + if ((foreign_stream_qpdf->m->immediate_copy_from) && | |
| 2628 | + (stream_buffer.getPointer() == 0)) | |
| 2629 | + { | |
| 2630 | + // Pull the stream data into a buffer before attempting | |
| 2631 | + // the copy operation. Do it on the source stream so that | |
| 2632 | + // if the source stream is copied multiple times, we don't | |
| 2633 | + // have to keep duplicating the memory. | |
| 2634 | + QTC::TC("qpdf", "QPDF immediate copy stream data"); | |
| 2635 | + foreign.replaceStreamData(foreign.getRawStreamData(), | |
| 2636 | + old_dict.getKey("/Filter"), | |
| 2637 | + old_dict.getKey("/DecodeParms")); | |
| 2638 | + stream_buffer = stream->getStreamDataBuffer(); | |
| 2639 | + } | |
| 2640 | + PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider = | |
| 2641 | + stream->getStreamDataProvider(); | |
| 2642 | + if (stream_buffer.getPointer()) | |
| 2643 | + { | |
| 2644 | + QTC::TC("qpdf", "QPDF copy foreign stream with buffer"); | |
| 2645 | + result.replaceStreamData(stream_buffer, | |
| 2646 | + dict.getKey("/Filter"), | |
| 2647 | + dict.getKey("/DecodeParms")); | |
| 2648 | + } | |
| 2649 | + else if (stream_provider.getPointer()) | |
| 2650 | + { | |
| 2651 | + // In this case, the remote stream's QPDF must stay in scope. | |
| 2652 | + QTC::TC("qpdf", "QPDF copy foreign stream with provider"); | |
| 2653 | + this->m->copied_stream_data_provider->registerForeignStream( | |
| 2654 | + local_og, foreign); | |
| 2655 | + result.replaceStreamData(this->m->copied_streams, | |
| 2656 | + dict.getKey("/Filter"), | |
| 2657 | + dict.getKey("/DecodeParms")); | |
| 2658 | + } | |
| 2659 | + else | |
| 2660 | + { | |
| 2661 | + PointerHolder<ForeignStreamData> foreign_stream_data = | |
| 2662 | + new ForeignStreamData( | |
| 2663 | + foreign_stream_qpdf->m->encp, | |
| 2664 | + foreign_stream_qpdf->m->file, | |
| 2665 | + foreign.getObjectID(), | |
| 2666 | + foreign.getGeneration(), | |
| 2667 | + stream->getOffset(), | |
| 2668 | + stream->getLength(), | |
| 2669 | + dict); | |
| 2670 | + this->m->copied_stream_data_provider->registerForeignStream( | |
| 2671 | + local_og, foreign_stream_data); | |
| 2672 | + result.replaceStreamData(this->m->copied_streams, | |
| 2673 | + dict.getKey("/Filter"), | |
| 2674 | + dict.getKey("/DecodeParms")); | |
| 2675 | + } | |
| 2676 | +} | |
| 2677 | + | |
| 2678 | +void | |
| 2671 | 2679 | QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2) |
| 2672 | 2680 | { |
| 2673 | 2681 | swapObjects(og1.getObj(), og1.getGen(), og2.getObj(), og2.getGen()); | ... | ... |