Commit 876c238ea9c6b307b95f838a5d34711a57265c07
1 parent
05f8281f
Add a private API version of Pl_Count
... and use it in QPDFWriter and QPDF::generateHintStream.
Showing
5 changed files
with
75 additions
and
31 deletions
include/qpdf/QPDFWriter.hh
| ... | ... | @@ -597,7 +597,7 @@ class QPDFWriter |
| 597 | 597 | // activate the pipeline stack. When the passed in PipelinePopper goes out of scope, the stack |
| 598 | 598 | // is popped. |
| 599 | 599 | Pipeline* pushPipeline(Pipeline*); |
| 600 | - void activatePipelineStack(PipelinePopper&); | |
| 600 | + void activatePipelineStack(PipelinePopper& pp, bool discard = false); | |
| 601 | 601 | void initializePipelineStack(Pipeline*); |
| 602 | 602 | |
| 603 | 603 | void adjustAESStreamLength(size_t& length); | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -6,8 +6,6 @@ |
| 6 | 6 | |
| 7 | 7 | #include <qpdf/MD5.hh> |
| 8 | 8 | #include <qpdf/Pl_AES_PDF.hh> |
| 9 | -#include <qpdf/Pl_Count.hh> | |
| 10 | -#include <qpdf/Pl_Discard.hh> | |
| 11 | 9 | #include <qpdf/Pl_Flate.hh> |
| 12 | 10 | #include <qpdf/Pl_MD5.hh> |
| 13 | 11 | #include <qpdf/Pl_PNGFilter.hh> |
| ... | ... | @@ -905,26 +903,26 @@ QPDFWriter::writePad(size_t nspaces) |
| 905 | 903 | Pipeline* |
| 906 | 904 | QPDFWriter::pushPipeline(Pipeline* p) |
| 907 | 905 | { |
| 908 | - qpdf_assert_debug(dynamic_cast<Pl_Count*>(p) == nullptr); | |
| 909 | - m->pipeline_stack.push_back(p); | |
| 906 | + qpdf_assert_debug(!dynamic_cast<pl::Count*>(p)); | |
| 907 | + m->pipeline_stack.emplace_back(p); | |
| 910 | 908 | return p; |
| 911 | 909 | } |
| 912 | 910 | |
| 913 | 911 | void |
| 914 | 912 | QPDFWriter::initializePipelineStack(Pipeline* p) |
| 915 | 913 | { |
| 916 | - m->pipeline = new Pl_Count("pipeline stack base", p); | |
| 917 | - m->to_delete.push_back(std::shared_ptr<Pipeline>(m->pipeline)); | |
| 918 | - m->pipeline_stack.push_back(m->pipeline); | |
| 914 | + m->pipeline = new pl::Count("pipeline stack base", p); | |
| 915 | + m->to_delete.emplace_back(std::shared_ptr<Pipeline>(m->pipeline)); | |
| 916 | + m->pipeline_stack.emplace_back(m->pipeline); | |
| 919 | 917 | } |
| 920 | 918 | |
| 921 | 919 | void |
| 922 | -QPDFWriter::activatePipelineStack(PipelinePopper& pp) | |
| 920 | +QPDFWriter::activatePipelineStack(PipelinePopper& pp, bool discard) | |
| 923 | 921 | { |
| 924 | 922 | std::string stack_id("stack " + std::to_string(m->next_stack_id)); |
| 925 | - auto* c = new Pl_Count(stack_id.c_str(), m->pipeline_stack.back()); | |
| 923 | + auto* c = new pl::Count(stack_id.c_str(), discard ? nullptr : m->pipeline_stack.back()); | |
| 926 | 924 | ++m->next_stack_id; |
| 927 | - m->pipeline_stack.push_back(c); | |
| 925 | + m->pipeline_stack.emplace_back(c); | |
| 928 | 926 | m->pipeline = c; |
| 929 | 927 | pp.stack_id = stack_id; |
| 930 | 928 | } |
| ... | ... | @@ -936,7 +934,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper() |
| 936 | 934 | } |
| 937 | 935 | qpdf_assert_debug(qw->m->pipeline_stack.size() >= 2); |
| 938 | 936 | qw->m->pipeline->finish(); |
| 939 | - qpdf_assert_debug(dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == qw->m->pipeline); | |
| 937 | + qpdf_assert_debug(dynamic_cast<pl::Count*>(qw->m->pipeline_stack.back()) == qw->m->pipeline); | |
| 940 | 938 | // It might be possible for this assertion to fail if writeLinearized exits by exception when |
| 941 | 939 | // deterministic ID, but I don't think so. As of this writing, this is the only case in which |
| 942 | 940 | // two dynamically allocated PipelinePopper objects ever exist at the same time, so the |
| ... | ... | @@ -944,7 +942,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper() |
| 944 | 942 | qpdf_assert_debug(qw->m->pipeline->getIdentifier() == stack_id); |
| 945 | 943 | delete qw->m->pipeline_stack.back(); |
| 946 | 944 | qw->m->pipeline_stack.pop_back(); |
| 947 | - while (dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == nullptr) { | |
| 945 | + while (!dynamic_cast<pl::Count*>(qw->m->pipeline_stack.back())) { | |
| 948 | 946 | Pipeline* p = qw->m->pipeline_stack.back(); |
| 949 | 947 | if (dynamic_cast<Pl_MD5*>(p) == qw->m->md5_pipeline) { |
| 950 | 948 | qw->m->md5_pipeline = nullptr; |
| ... | ... | @@ -952,7 +950,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper() |
| 952 | 950 | qw->m->pipeline_stack.pop_back(); |
| 953 | 951 | delete p; |
| 954 | 952 | } |
| 955 | - qw->m->pipeline = dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()); | |
| 953 | + qw->m->pipeline = dynamic_cast<pl::Count*>(qw->m->pipeline_stack.back()); | |
| 956 | 954 | } |
| 957 | 955 | |
| 958 | 956 | void |
| ... | ... | @@ -994,8 +992,7 @@ QPDFWriter::pushEncryptionFilter(PipelinePopper& pp) |
| 994 | 992 | void |
| 995 | 993 | QPDFWriter::pushDiscardFilter(PipelinePopper& pp) |
| 996 | 994 | { |
| 997 | - pushPipeline(new Pl_Discard()); | |
| 998 | - activatePipelineStack(pp); | |
| 995 | + activatePipelineStack(pp, true); | |
| 999 | 996 | } |
| 1000 | 997 | |
| 1001 | 998 | void |
| ... | ... | @@ -1281,13 +1278,13 @@ QPDFWriter::willFilterStream( |
| 1281 | 1278 | |
| 1282 | 1279 | bool filtered = false; |
| 1283 | 1280 | for (bool first_attempt: {true, false}) { |
| 1281 | + PipelinePopper pp_stream_data(this); | |
| 1284 | 1282 | if (stream_data != nullptr) { |
| 1285 | 1283 | pushPipeline(new Pl_String("stream data", nullptr, *stream_data)); |
| 1284 | + activatePipelineStack(pp_stream_data); | |
| 1286 | 1285 | } else { |
| 1287 | - pushPipeline(new Pl_Discard()); | |
| 1286 | + pushDiscardFilter(pp_stream_data); | |
| 1288 | 1287 | } |
| 1289 | - PipelinePopper pp_stream_data(this); | |
| 1290 | - activatePipelineStack(pp_stream_data); | |
| 1291 | 1288 | try { |
| 1292 | 1289 | filtered = stream.pipeStreamData( |
| 1293 | 1290 | m->pipeline, |
| ... | ... | @@ -2678,8 +2675,8 @@ QPDFWriter::writeLinearized() |
| 2678 | 2675 | // Write file in two passes. Part numbers refer to PDF spec 1.4. |
| 2679 | 2676 | |
| 2680 | 2677 | FILE* lin_pass1_file = nullptr; |
| 2681 | - auto pp_pass1 = std::make_shared<PipelinePopper>(this); | |
| 2682 | - auto pp_md5 = std::make_shared<PipelinePopper>(this); | |
| 2678 | + auto pp_pass1 = std::make_unique<PipelinePopper>(this); | |
| 2679 | + auto pp_md5 = std::make_unique<PipelinePopper>(this); | |
| 2683 | 2680 | for (int pass: {1, 2}) { |
| 2684 | 2681 | if (pass == 1) { |
| 2685 | 2682 | if (!m->lin_pass1_filename.empty()) { |
| ... | ... | @@ -3011,9 +3008,9 @@ QPDFWriter::registerProgressReporter(std::shared_ptr<ProgressReporter> pr) |
| 3011 | 3008 | void |
| 3012 | 3009 | QPDFWriter::writeStandard() |
| 3013 | 3010 | { |
| 3014 | - auto pp_md5 = std::make_shared<PipelinePopper>(this); | |
| 3011 | + auto pp_md5 = PipelinePopper(this); | |
| 3015 | 3012 | if (m->deterministic_id) { |
| 3016 | - pushMD5Pipeline(*pp_md5); | |
| 3013 | + pushMD5Pipeline(pp_md5); | |
| 3017 | 3014 | } |
| 3018 | 3015 | |
| 3019 | 3016 | // Start writing |
| ... | ... | @@ -3059,7 +3056,5 @@ QPDFWriter::writeStandard() |
| 3059 | 3056 | "qpdf", |
| 3060 | 3057 | "QPDFWriter standard deterministic ID", |
| 3061 | 3058 | m->object_stream_to_objects.empty() ? 0 : 1); |
| 3062 | - pp_md5 = nullptr; | |
| 3063 | - qpdf_assert_debug(m->md5_pipeline == nullptr); | |
| 3064 | 3059 | } |
| 3065 | 3060 | } | ... | ... |
libqpdf/QPDF_linearization.cc
| ... | ... | @@ -5,8 +5,8 @@ |
| 5 | 5 | #include <qpdf/BitStream.hh> |
| 6 | 6 | #include <qpdf/BitWriter.hh> |
| 7 | 7 | #include <qpdf/InputSource_private.hh> |
| 8 | +#include <qpdf/Pipeline_private.hh> | |
| 8 | 9 | #include <qpdf/Pl_Buffer.hh> |
| 9 | -#include <qpdf/Pl_Count.hh> | |
| 10 | 10 | #include <qpdf/Pl_Flate.hh> |
| 11 | 11 | #include <qpdf/Pl_String.hh> |
| 12 | 12 | #include <qpdf/QPDFExc.hh> |
| ... | ... | @@ -1757,13 +1757,13 @@ QPDF::generateHintStream( |
| 1757 | 1757 | // can get offsets. |
| 1758 | 1758 | Pl_String hint_stream("hint stream", nullptr, hint_buffer); |
| 1759 | 1759 | Pipeline* next = &hint_stream; |
| 1760 | - std::shared_ptr<Pipeline> flate; | |
| 1760 | + std::unique_ptr<Pipeline> flate; | |
| 1761 | 1761 | if (compressed) { |
| 1762 | 1762 | flate = |
| 1763 | - std::make_shared<Pl_Flate>("compress hint stream", &hint_stream, Pl_Flate::a_deflate); | |
| 1763 | + std::make_unique<Pl_Flate>("compress hint stream", &hint_stream, Pl_Flate::a_deflate); | |
| 1764 | 1764 | next = flate.get(); |
| 1765 | 1765 | } |
| 1766 | - Pl_Count c("count", next); | |
| 1766 | + pl::Count c("count", next); | |
| 1767 | 1767 | BitWriter w(&c); |
| 1768 | 1768 | |
| 1769 | 1769 | writeHPageOffset(w); | ... | ... |
libqpdf/qpdf/Pipeline_private.hh
0 → 100644
| 1 | +#ifndef PIPELINE_PRIVATE_HH | |
| 2 | +#define PIPELINE_PRIVATE_HH | |
| 3 | + | |
| 4 | +#include <qpdf/Pipeline.hh> | |
| 5 | + | |
| 6 | +namespace qpdf::pl | |
| 7 | +{ | |
| 8 | + class Count final: public Pipeline | |
| 9 | + { | |
| 10 | + public: | |
| 11 | + Count(char const* identifier, Pipeline* next) : | |
| 12 | + Pipeline(identifier, next) | |
| 13 | + { | |
| 14 | + } | |
| 15 | + | |
| 16 | + ~Count() final = default; | |
| 17 | + | |
| 18 | + void | |
| 19 | + write(unsigned char const* buf, size_t len) final | |
| 20 | + { | |
| 21 | + if (len) { | |
| 22 | + count += static_cast<qpdf_offset_t>(len); | |
| 23 | + if (next()) { | |
| 24 | + next()->write(buf, len); | |
| 25 | + } | |
| 26 | + } | |
| 27 | + } | |
| 28 | + | |
| 29 | + void | |
| 30 | + finish() final | |
| 31 | + { | |
| 32 | + if (next()) { | |
| 33 | + next()->finish(); | |
| 34 | + } | |
| 35 | + } | |
| 36 | + | |
| 37 | + qpdf_offset_t | |
| 38 | + getCount() const | |
| 39 | + { | |
| 40 | + return count; | |
| 41 | + } | |
| 42 | + | |
| 43 | + private: | |
| 44 | + qpdf_offset_t count{0}; | |
| 45 | + }; | |
| 46 | +} // namespace qpdf::pl | |
| 47 | + | |
| 48 | +#endif // PIPELINE_PRIVATE_HH | ... | ... |
libqpdf/qpdf/QPDFWriter_private.hh
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | #include <qpdf/QPDFWriter.hh> |
| 5 | 5 | |
| 6 | 6 | #include <qpdf/ObjTable.hh> |
| 7 | +#include <qpdf/Pipeline_private.hh> | |
| 7 | 8 | |
| 8 | 9 | // This file is intended for inclusion by QPDFWriter, QPDF, QPDF_optimization and QPDF_linearization |
| 9 | 10 | // only. |
| ... | ... | @@ -98,7 +99,7 @@ class QPDFWriter::Members |
| 98 | 99 | int encryption_dict_objid{0}; |
| 99 | 100 | std::string cur_data_key; |
| 100 | 101 | std::list<std::shared_ptr<Pipeline>> to_delete; |
| 101 | - Pl_Count* pipeline{nullptr}; | |
| 102 | + qpdf::pl::Count* pipeline{nullptr}; | |
| 102 | 103 | std::vector<QPDFObjectHandle> object_queue; |
| 103 | 104 | size_t object_queue_front{0}; |
| 104 | 105 | QPDFWriter::ObjTable obj; |
| ... | ... | @@ -112,7 +113,7 @@ class QPDFWriter::Members |
| 112 | 113 | std::map<QPDFObjGen, int> page_object_to_seq; |
| 113 | 114 | std::map<QPDFObjGen, int> contents_to_page_seq; |
| 114 | 115 | std::map<int, std::vector<QPDFObjGen>> object_stream_to_objects; |
| 115 | - std::list<Pipeline*> pipeline_stack; | |
| 116 | + std::vector<Pipeline*> pipeline_stack; | |
| 116 | 117 | unsigned long long next_stack_id{0}; |
| 117 | 118 | bool deterministic_id{false}; |
| 118 | 119 | Pl_MD5* md5_pipeline{nullptr}; | ... | ... |