Commit 95a45263878f33a84afba7cd7826c8dc1ea5a5b5

Authored by m-holger
Committed by GitHub
2 parents b40533ad 6cadafda

Merge pull request #1404 from m-holger/writer

Refactor writing of object streams
libqpdf/QPDFWriter.cc
... ... @@ -1646,36 +1646,12 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1646 1646 std::shared_ptr<Buffer> stream_buffer;
1647 1647 int first_obj = -1;
1648 1648 bool compressed = false;
1649   - for (int pass = 1; pass <= 2; ++pass) {
1650   - // stream_buffer will be initialized only for pass 2
1651   - PipelinePopper pp_ostream(this, &stream_buffer);
1652   - if (pass == 1) {
1653   - pushDiscardFilter(pp_ostream);
1654   - } else {
1655   - // Adjust offsets to skip over comment before first object
1656   - first = offsets.at(0);
1657   - for (auto& iter: offsets) {
1658   - iter -= first;
1659   - }
1660   -
1661   - // Take one pass at writing pairs of numbers so we can get their size information
1662   - {
1663   - PipelinePopper pp_discard(this);
1664   - pushDiscardFilter(pp_discard);
1665   - writeObjectStreamOffsets(offsets, first_obj);
1666   - first += m->pipeline->getCount();
1667   - }
  1649 + {
  1650 + // Pass 1
  1651 + PipelinePopper pp_ostream_pass1(this, &stream_buffer);
1668 1652  
1669   - // Set up a stream to write the stream data into a buffer.
1670   - Pipeline* next = pushPipeline(new Pl_Buffer("object stream"));
1671   - if (m->compress_streams && !m->qdf_mode) {
1672   - compressed = true;
1673   - next =
1674   - pushPipeline(new Pl_Flate("compress object stream", next, Pl_Flate::a_deflate));
1675   - }
1676   - activatePipelineStack(pp_ostream);
1677   - writeObjectStreamOffsets(offsets, first_obj);
1678   - }
  1653 + pushPipeline(new Pl_Buffer("object stream"));
  1654 + activatePipelineStack(pp_ostream_pass1);
1679 1655  
1680 1656 int count = -1;
1681 1657 for (auto const& obj: m->object_stream_to_objects[old_id]) {
... ... @@ -1700,12 +1676,12 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1700 1676 }
1701 1677 writeString("\n");
1702 1678 }
1703   - if (pass == 1) {
1704   - offsets.push_back(m->pipeline->getCount());
1705   - // To avoid double-counting objects being written in object streams for progress
1706   - // reporting, decrement in pass 1.
1707   - indicateProgress(true, false);
1708   - }
  1679 +
  1680 + offsets.push_back(m->pipeline->getCount());
  1681 + // To avoid double-counting objects being written in object streams for progress
  1682 + // reporting, decrement in pass 1.
  1683 + indicateProgress(true, false);
  1684 +
1709 1685 QPDFObjectHandle obj_to_write = m->pdf.getObject(obj);
1710 1686 if (obj_to_write.isStream()) {
1711 1687 // This condition occurred in a fuzz input. Ideally we should block it at parse
... ... @@ -1718,6 +1694,32 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1718 1694 m->new_obj[new_obj].xref = QPDFXRefEntry(new_stream_id, count);
1719 1695 }
1720 1696 }
  1697 + {
  1698 + PipelinePopper pp_ostream(this, &stream_buffer);
  1699 + // Adjust offsets to skip over comment before first object
  1700 + first = offsets.at(0);
  1701 + for (auto& iter: offsets) {
  1702 + iter -= first;
  1703 + }
  1704 +
  1705 + // Take one pass at writing pairs of numbers so we can get their size information
  1706 + {
  1707 + PipelinePopper pp_discard(this);
  1708 + pushDiscardFilter(pp_discard);
  1709 + writeObjectStreamOffsets(offsets, first_obj);
  1710 + first += m->pipeline->getCount();
  1711 + }
  1712 +
  1713 + // Set up a stream to write the stream data into a buffer.
  1714 + Pipeline* next = pushPipeline(new Pl_Buffer("object stream"));
  1715 + if (m->compress_streams && !m->qdf_mode) {
  1716 + compressed = true;
  1717 + next = pushPipeline(new Pl_Flate("compress object stream", next, Pl_Flate::a_deflate));
  1718 + }
  1719 + activatePipelineStack(pp_ostream);
  1720 + writeObjectStreamOffsets(offsets, first_obj);
  1721 + writeBuffer(stream_buffer);
  1722 + }
1721 1723  
1722 1724 // Write the object
1723 1725 openObject(new_stream_id);
... ...
manual/release-notes.rst
... ... @@ -26,6 +26,9 @@ more detail.
26 26 - There have been further enhancements to how files with damaged xref
27 27 tables are recovered.
28 28  
  29 + - There has been some refactoring of how object streams are written with
  30 + some performance improvement.
  31 +
29 32 .. cSpell:ignore substract
30 33  
31 34 .. _r12-0-0:
... ...