Commit d7853db8f86613bae02f446b6d3ae9c06bc4d8dc

Authored by m-holger
1 parent 65e7e3db

In QPDFWriter::willFilterStream use Pl_String instead of Pl_Buffer

Also,
- use Pl_Discard when only checking whether stream is filterable
- get last char directly from output string
include/qpdf/QPDFWriter.hh
@@ -493,7 +493,7 @@ class QPDFWriter @@ -493,7 +493,7 @@ class QPDFWriter
493 QPDFObjectHandle stream, 493 QPDFObjectHandle stream,
494 bool& compress_stream, 494 bool& compress_stream,
495 bool& is_metadata, 495 bool& is_metadata,
496 - std::shared_ptr<Buffer>* stream_data); 496 + std::string* stream_data);
497 void unparseObject( 497 void unparseObject(
498 QPDFObjectHandle object, 498 QPDFObjectHandle object,
499 int level, 499 int level,
libqpdf/QPDFWriter.cc
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 #include <qpdf/Pl_PNGFilter.hh> 13 #include <qpdf/Pl_PNGFilter.hh>
14 #include <qpdf/Pl_RC4.hh> 14 #include <qpdf/Pl_RC4.hh>
15 #include <qpdf/Pl_StdioFile.hh> 15 #include <qpdf/Pl_StdioFile.hh>
  16 +#include <qpdf/Pl_String.hh>
16 #include <qpdf/QIntC.hh> 17 #include <qpdf/QIntC.hh>
17 #include <qpdf/QPDFObjectHandle_private.hh> 18 #include <qpdf/QPDFObjectHandle_private.hh>
18 #include <qpdf/QPDFObject_private.hh> 19 #include <qpdf/QPDFObject_private.hh>
@@ -1244,7 +1245,7 @@ QPDFWriter::willFilterStream( @@ -1244,7 +1245,7 @@ QPDFWriter::willFilterStream(
1244 QPDFObjectHandle stream, 1245 QPDFObjectHandle stream,
1245 bool& compress_stream, // out only 1246 bool& compress_stream, // out only
1246 bool& is_metadata, // out only 1247 bool& is_metadata, // out only
1247 - std::shared_ptr<Buffer>* stream_data) 1248 + std::string* stream_data)
1248 { 1249 {
1249 compress_stream = false; 1250 compress_stream = false;
1250 is_metadata = false; 1251 is_metadata = false;
@@ -1290,8 +1291,12 @@ QPDFWriter::willFilterStream( @@ -1290,8 +1291,12 @@ QPDFWriter::willFilterStream(
1290 1291
1291 bool filtered = false; 1292 bool filtered = false;
1292 for (bool first_attempt: {true, false}) { 1293 for (bool first_attempt: {true, false}) {
1293 - pushPipeline(new Pl_Buffer("stream data"));  
1294 - PipelinePopper pp_stream_data(this, stream_data); 1294 + if (stream_data != nullptr) {
  1295 + pushPipeline(new Pl_String("stream data", nullptr, *stream_data));
  1296 + } else {
  1297 + pushPipeline(new Pl_Discard());
  1298 + }
  1299 + PipelinePopper pp_stream_data(this);
1295 activatePipelineStack(pp_stream_data); 1300 activatePipelineStack(pp_stream_data);
1296 try { 1301 try {
1297 filtered = stream.pipeStreamData( 1302 filtered = stream.pipeStreamData(
@@ -1320,6 +1325,9 @@ QPDFWriter::willFilterStream( @@ -1320,6 +1325,9 @@ QPDFWriter::willFilterStream(
1320 throw std::runtime_error( 1325 throw std::runtime_error(
1321 "error while getting stream data for " + stream.unparse() + ": " + e.what()); 1326 "error while getting stream data for " + stream.unparse() + ": " + e.what());
1322 } 1327 }
  1328 + if (stream_data) {
  1329 + stream_data->clear();
  1330 + }
1323 } 1331 }
1324 if (!filtered) { 1332 if (!filtered) {
1325 compress_stream = false; 1333 compress_stream = false;
@@ -1545,29 +1553,28 @@ QPDFWriter::unparseObject( @@ -1545,29 +1553,28 @@ QPDFWriter::unparseObject(
1545 flags |= f_stream; 1553 flags |= f_stream;
1546 bool compress_stream = false; 1554 bool compress_stream = false;
1547 bool is_metadata = false; 1555 bool is_metadata = false;
1548 - std::shared_ptr<Buffer> stream_data; 1556 + std::string stream_data;
1549 if (willFilterStream(object, compress_stream, is_metadata, &stream_data)) { 1557 if (willFilterStream(object, compress_stream, is_metadata, &stream_data)) {
1550 flags |= f_filtered; 1558 flags |= f_filtered;
1551 } 1559 }
1552 QPDFObjectHandle stream_dict = object.getDict(); 1560 QPDFObjectHandle stream_dict = object.getDict();
1553 1561
1554 - m->cur_stream_length = stream_data->getSize(); 1562 + m->cur_stream_length = stream_data.size();
1555 if (is_metadata && m->encrypted && (!m->encrypt_metadata)) { 1563 if (is_metadata && m->encrypted && (!m->encrypt_metadata)) {
1556 // Don't encrypt stream data for the metadata stream 1564 // Don't encrypt stream data for the metadata stream
1557 m->cur_data_key.clear(); 1565 m->cur_data_key.clear();
1558 } 1566 }
1559 adjustAESStreamLength(m->cur_stream_length); 1567 adjustAESStreamLength(m->cur_stream_length);
1560 unparseObject(stream_dict, 0, flags, m->cur_stream_length, compress_stream); 1568 unparseObject(stream_dict, 0, flags, m->cur_stream_length, compress_stream);
1561 - unsigned char last_char = '\0'; 1569 + char last_char = stream_data.empty() ? '\0' : stream_data.back();
1562 writeString("\nstream\n"); 1570 writeString("\nstream\n");
1563 { 1571 {
1564 PipelinePopper pp_enc(this); 1572 PipelinePopper pp_enc(this);
1565 pushEncryptionFilter(pp_enc); 1573 pushEncryptionFilter(pp_enc);
1566 - writeBuffer(stream_data);  
1567 - last_char = m->pipeline->getLastChar(); 1574 + writeString(stream_data);
1568 } 1575 }
1569 1576
1570 - if (m->newline_before_endstream || (m->qdf_mode && (last_char != '\n'))) { 1577 + if (m->newline_before_endstream || (m->qdf_mode && last_char != '\n')) {
1571 writeString("\n"); 1578 writeString("\n");
1572 m->added_newline = true; 1579 m->added_newline = true;
1573 } else { 1580 } else {