Commit 9ad84bae860b2c7974123805727eea218de09720

Authored by m-holger
1 parent 0889eba4

Move `copyStreamData` implementation from `QPDF.cc` to `QPDF_Stream.cc`.

libqpdf/QPDF.cc
@@ -677,49 +677,6 @@ Objects::Foreign::Copier::replace_indirect_object(QPDFObjectHandle const& foreig @@ -677,49 +677,6 @@ Objects::Foreign::Copier::replace_indirect_object(QPDFObjectHandle const& foreig
677 return result; 677 return result;
678 } 678 }
679 679
680 -void  
681 -QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign_oh)  
682 -{  
683 - // This method was originally written for copying foreign streams, but it is used by  
684 - // Stream::copy to copy streams from the same QPDF object as well.  
685 -  
686 - Dictionary dict = result.getDict();  
687 - Dictionary old_dict = foreign_oh.getDict();  
688 - QPDFObjGen local_og(result.getObjGen());  
689 - // Copy information from the foreign stream so we can pipe its data later without keeping the  
690 - // original QPDF object around.  
691 -  
692 - QPDF& foreign_stream_qpdf =  
693 - foreign_oh.getQPDF("unable to retrieve owning qpdf from foreign stream");  
694 -  
695 - Stream foreign = foreign_oh;  
696 - if (!foreign) {  
697 - throw std::logic_error("unable to retrieve underlying stream object from foreign stream");  
698 - }  
699 - std::shared_ptr<Buffer> stream_buffer = foreign.getStreamDataBuffer();  
700 - if (foreign_stream_qpdf.m->immediate_copy_from && !stream_buffer) {  
701 - // Pull the stream data into a buffer before attempting the copy operation. Do it on the  
702 - // source stream so that if the source stream is copied multiple times, we don't have to  
703 - // keep duplicating the memory.  
704 - foreign.replaceStreamData(  
705 - foreign.getRawStreamData(), old_dict["/Filter"], old_dict["/DecodeParms"]);  
706 - stream_buffer = foreign.getStreamDataBuffer();  
707 - }  
708 - auto stream_provider = foreign.getStreamDataProvider();  
709 - if (stream_buffer) {  
710 - result.replaceStreamData(stream_buffer, dict["/Filter"], dict["/DecodeParms"]);  
711 - } else if (stream_provider) {  
712 - // In this case, the remote stream's QPDF must stay in scope.  
713 - m->objects.streams().copier()->register_copy(local_og, foreign_oh);  
714 - result.replaceStreamData(  
715 - m->objects.streams().copier(), dict["/Filter"], dict["/DecodeParms"]);  
716 - } else {  
717 - m->objects.streams().copier()->register_copy(local_og, foreign, foreign_oh.offset(), dict);  
718 - result.replaceStreamData(  
719 - m->objects.streams().copier(), dict["/Filter"], dict["/DecodeParms"]);  
720 - }  
721 -}  
722 -  
723 unsigned long long 680 unsigned long long
724 QPDF::getUniqueId() const 681 QPDF::getUniqueId() const
725 { 682 {
libqpdf/QPDF_Stream.cc
@@ -197,6 +197,49 @@ Stream::copy() const @@ -197,6 +197,49 @@ Stream::copy() const
197 } 197 }
198 198
199 void 199 void
  200 +QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign_oh)
  201 +{
  202 + // This method was originally written for copying foreign streams, but it is used by
  203 + // Stream::copy to copy streams from the same QPDF object as well.
  204 +
  205 + Dictionary dict = result.getDict();
  206 + Dictionary old_dict = foreign_oh.getDict();
  207 + QPDFObjGen local_og(result.getObjGen());
  208 + // Copy information from the foreign stream so we can pipe its data later without keeping the
  209 + // original QPDF object around.
  210 +
  211 + QPDF& foreign_stream_qpdf =
  212 + foreign_oh.getQPDF("unable to retrieve owning qpdf from foreign stream");
  213 +
  214 + Stream foreign = foreign_oh;
  215 + if (!foreign) {
  216 + throw std::logic_error("unable to retrieve underlying stream object from foreign stream");
  217 + }
  218 + std::shared_ptr<Buffer> stream_buffer = foreign.getStreamDataBuffer();
  219 + if (foreign_stream_qpdf.m->immediate_copy_from && !stream_buffer) {
  220 + // Pull the stream data into a buffer before attempting the copy operation. Do it on the
  221 + // source stream so that if the source stream is copied multiple times, we don't have to
  222 + // keep duplicating the memory.
  223 + foreign.replaceStreamData(
  224 + foreign.getRawStreamData(), old_dict["/Filter"], old_dict["/DecodeParms"]);
  225 + stream_buffer = foreign.getStreamDataBuffer();
  226 + }
  227 + auto stream_provider = foreign.getStreamDataProvider();
  228 + if (stream_buffer) {
  229 + result.replaceStreamData(stream_buffer, dict["/Filter"], dict["/DecodeParms"]);
  230 + } else if (stream_provider) {
  231 + // In this case, the remote stream's QPDF must stay in scope.
  232 + m->objects.streams().copier()->register_copy(local_og, foreign_oh);
  233 + result.replaceStreamData(
  234 + m->objects.streams().copier(), dict["/Filter"], dict["/DecodeParms"]);
  235 + } else {
  236 + m->objects.streams().copier()->register_copy(local_og, foreign, foreign_oh.offset(), dict);
  237 + result.replaceStreamData(
  238 + m->objects.streams().copier(), dict["/Filter"], dict["/DecodeParms"]);
  239 + }
  240 +}
  241 +
  242 +void
200 Stream::registerStreamFilter( 243 Stream::registerStreamFilter(
201 std::string const& filter_name, std::function<std::shared_ptr<QPDFStreamFilter>()> factory) 244 std::string const& filter_name, std::function<std::shared_ptr<QPDFStreamFilter>()> factory)
202 { 245 {