From efd5aced350f36d267a247288462b68cd6a8c492 Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 22 Oct 2025 14:53:14 +0100 Subject: [PATCH] Refactor `QPDFJob` configuration: consolidate options into `w_cfg`, update method calls, and streamline related logic for improved encapsulation and maintainability. --- libqpdf/QPDFJob.cc | 50 ++++---------------------------------------------- libqpdf/QPDFJob_config.cc | 56 ++++++++++++++++++++++++-------------------------------- libqpdf/QPDFWriter.cc | 36 ++++++++++++++++++------------------ libqpdf/qpdf/QPDFJob_private.hh | 20 -------------------- libqpdf/qpdf/QPDFWriter_private.hh | 39 ++++++++++++++++++++++++--------------- 5 files changed, 70 insertions(+), 131 deletions(-) diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 4e6ffb6..30c0bf2 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -804,7 +804,7 @@ QPDFJob::doShowObj(QPDF& pdf) m->log->saveToStandardOutput(true); obj.pipeStreamData( m->log->getSave().get(), - (filter && m->normalize) ? qpdf_ef_normalize : 0, + filter && m->w_cfg.normalize_content() ? qpdf_ef_normalize : 0, filter ? qpdf_dl_all : qpdf_dl_none); } } else { @@ -974,7 +974,7 @@ QPDFJob::doJSONObjects(Pipeline* p, bool& first, QPDF& pdf) p, false, first, - m->decode_level, + m->w_cfg.decode_level(), m->json_stream_data, m->json_stream_prefix, json_objects); @@ -1052,7 +1052,7 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) j_image.addDictionaryMember("decodeparms", dp_array.getJSON(m->json_version)); j_image.addDictionaryMember( "filterable", - JSON::makeBool(image.pipeStreamData(nullptr, 0, m->decode_level, true))); + JSON::makeBool(image.pipeStreamData(nullptr, 0, m->w_cfg.decode_level(), true))); } j_page.addDictionaryMember("images", j_images); JSON j_contents = j_page.addDictionaryMember("contents", JSON::makeArray()); @@ -1569,7 +1569,7 @@ QPDFJob::doJSON(QPDF& pdf, Pipeline* p) JSON::writeDictionaryItem(p, first, "version", JSON::makeInt(m->json_version), 1); JSON j_params = JSON::makeDictionary(); std::string decode_level_str; - switch (m->decode_level) { + switch (m->w_cfg.decode_level()) { case qpdf_dl_none: decode_level_str = "none"; break; @@ -2884,45 +2884,12 @@ QPDFJob::setWriterOptions(Writer& w) if (m->compression_level >= 0) { Pl_Flate::setCompressionLevel(m->compression_level); } - if (m->qdf_mode) { - w.setQDFMode(true); - } - if (m->preserve_unreferenced_objects) { - w.setPreserveUnreferencedObjects(true); - } - if (m->newline_before_endstream) { - w.setNewlineBeforeEndstream(true); - } - if (m->normalize_set) { - w.setContentNormalization(m->normalize); - } - if (m->stream_data_set) { - w.setStreamDataMode(m->stream_data_mode); - } - if (m->compress_streams_set) { - w.setCompressStreams(m->compress_streams); - } - if (m->recompress_flate_set) { - w.setRecompressFlate(m->recompress_flate); - } - if (m->decode_level_set) { - w.setDecodeLevel(m->decode_level); - } if (m->decrypt) { w.setPreserveEncryption(false); } - if (m->deterministic_id) { - w.setDeterministicID(true); - } - if (m->static_id) { - w.setStaticID(true); - } if (m->static_aes_iv) { w.setStaticAesIV(true); } - if (m->suppress_original_object_id) { - w.setSuppressOriginalObjectIDs(true); - } if (m->copy_encryption) { std::unique_ptr encryption_pdf; processFile( @@ -2936,15 +2903,6 @@ QPDFJob::setWriterOptions(Writer& w) if (m->encrypt) { setEncryptionOptions(w); } - if (m->linearize) { - w.setLinearization(true); - } - if (!m->linearize_pass1.empty()) { - w.setLinearizationPass1Filename(m->linearize_pass1); - } - if (m->object_stream_set) { - w.setObjectStreamMode(m->object_stream_mode); - } w.setMinimumPDFVersion(m->max_input_version); if (!m->min_version.empty()) { std::string version; diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index 1f2e99a..5dd8e29 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -124,8 +124,7 @@ QPDFJob::Config::collate(std::string const& parameter) QPDFJob::Config* QPDFJob::Config::compressStreams(std::string const& parameter) { - o.m->compress_streams_set = true; - o.m->compress_streams = (parameter == "y"); + o.m->w_cfg.compress_streams(parameter == "y"); return this; } @@ -146,7 +145,7 @@ QPDFJob::Config::jpegQuality(std::string const& parameter) QPDFJob::Config* QPDFJob::Config::copyEncryption(std::string const& parameter) { - if (o.m->deterministic_id) { + if (o.m->w_cfg.deterministic_id()) { usage("the deterministic-id option is incompatible with encrypted output files"); } o.m->inputs.encryption_file = parameter; @@ -171,7 +170,7 @@ QPDFJob::Config::deterministicId() if (o.m->encrypt || o.m->copy_encryption) { usage("the deterministic-id option is incompatible with encrypted output files"); } - o.m->deterministic_id = true; + o.m->w_cfg.deterministic_id(true); return this; } @@ -327,9 +326,7 @@ QPDFJob::Config::jsonOutput(std::string const& parameter) // No need to set json_stream_data_set -- that indicates explicit use of --json-stream-data. o.m->json_stream_data = qpdf_sj_inline; } - if (!o.m->decode_level_set) { - o.m->decode_level = qpdf_dl_none; - } + o.m->w_cfg.default_decode_level(qpdf_dl_none); o.m->json_keys.insert("qpdf"); return this; } @@ -373,14 +370,14 @@ QPDFJob::Config::keepInlineImages() QPDFJob::Config* QPDFJob::Config::linearize() { - o.m->linearize = true; + o.m->w_cfg.linearize(true); return this; } QPDFJob::Config* QPDFJob::Config::linearizePass1(std::string const& parameter) { - o.m->linearize_pass1 = parameter; + o.m->w_cfg.linearize_pass1(parameter); return this; } @@ -402,14 +399,14 @@ QPDFJob::Config::minVersion(std::string const& parameter) QPDFJob::Config* QPDFJob::Config::newlineBeforeEndstream() { - o.m->newline_before_endstream = true; + o.m->w_cfg.newline_before_endstream(true); return this; } QPDFJob::Config* QPDFJob::Config::noOriginalObjectIds() { - o.m->suppress_original_object_id = true; + o.m->w_cfg.no_original_object_ids(true); return this; } @@ -423,8 +420,7 @@ QPDFJob::Config::noWarn() QPDFJob::Config* QPDFJob::Config::normalizeContent(std::string const& parameter) { - o.m->normalize_set = true; - o.m->normalize = (parameter == "y"); + o.m->w_cfg.normalize_content(parameter == "y"); return this; } @@ -473,7 +469,7 @@ QPDFJob::Config::passwordIsHexKey() QPDFJob::Config* QPDFJob::Config::preserveUnreferenced() { - o.m->preserve_unreferenced_objects = true; + o.m->w_cfg.preserve_unreferenced(true); return this; } @@ -494,7 +490,7 @@ QPDFJob::Config::progress() QPDFJob::Config* QPDFJob::Config::qdf() { - o.m->qdf_mode = true; + o.m->w_cfg.qdf(true); return this; } @@ -508,8 +504,7 @@ QPDFJob::Config::rawStreamData() QPDFJob::Config* QPDFJob::Config::recompressFlate() { - o.m->recompress_flate_set = true; - o.m->recompress_flate = true; + o.m->w_cfg.recompress_flate(true); return this; } @@ -649,7 +644,7 @@ QPDFJob::Config::staticAesIv() QPDFJob::Config* QPDFJob::Config::staticId() { - o.m->static_id = true; + o.m->w_cfg.static_id(true); return this; } @@ -731,13 +726,12 @@ QPDFJob::Config::passwordMode(std::string const& parameter) QPDFJob::Config* QPDFJob::Config::streamData(std::string const& parameter) { - o.m->stream_data_set = true; if (parameter == "compress") { - o.m->stream_data_mode = qpdf_s_compress; + o.m->w_cfg.stream_data(qpdf_s_compress); } else if (parameter == "preserve") { - o.m->stream_data_mode = qpdf_s_preserve; + o.m->w_cfg.stream_data(qpdf_s_preserve); } else if (parameter == "uncompress") { - o.m->stream_data_mode = qpdf_s_uncompress; + o.m->w_cfg.stream_data(qpdf_s_uncompress); } else { usage("invalid stream-data option"); } @@ -747,15 +741,14 @@ QPDFJob::Config::streamData(std::string const& parameter) QPDFJob::Config* QPDFJob::Config::decodeLevel(std::string const& parameter) { - o.m->decode_level_set = true; if (parameter == "none") { - o.m->decode_level = qpdf_dl_none; + o.m->w_cfg.decode_level(qpdf_dl_none); } else if (parameter == "generalized") { - o.m->decode_level = qpdf_dl_generalized; + o.m->w_cfg.decode_level(qpdf_dl_generalized); } else if (parameter == "specialized") { - o.m->decode_level = qpdf_dl_specialized; + o.m->w_cfg.decode_level(qpdf_dl_specialized); } else if (parameter == "all") { - o.m->decode_level = qpdf_dl_all; + o.m->w_cfg.decode_level(qpdf_dl_all); } else { usage("invalid option"); } @@ -765,13 +758,12 @@ QPDFJob::Config::decodeLevel(std::string const& parameter) QPDFJob::Config* QPDFJob::Config::objectStreams(std::string const& parameter) { - o.m->object_stream_set = true; if (parameter == "disable") { - o.m->object_stream_mode = qpdf_o_disable; + o.m->w_cfg.object_streams(qpdf_o_disable); } else if (parameter == "preserve") { - o.m->object_stream_mode = qpdf_o_preserve; + o.m->w_cfg.object_streams(qpdf_o_preserve); } else if (parameter == "generate") { - o.m->object_stream_mode = qpdf_o_generate; + o.m->w_cfg.object_streams(qpdf_o_generate); } else { usage("invalid object stream mode"); } @@ -1111,7 +1103,7 @@ std::shared_ptr QPDFJob::Config::encrypt( int keylen, std::string const& user_password, std::string const& owner_password) { - if (o.m->deterministic_id) { + if (o.m->w_cfg.deterministic_id()) { usage("the deterministic-id option is incompatible with encrypted output files"); } o.m->keylen = keylen; diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index e399994..65571b8 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -577,17 +577,17 @@ Config::stream_data(qpdf_stream_data_e mode) { switch (mode) { case qpdf_s_uncompress: - stream_decode_level(std::max(qpdf_dl_generalized, stream_decode_level_)); + decode_level(std::max(qpdf_dl_generalized, decode_level_)); compress_streams(false); return *this; case qpdf_s_preserve: - stream_decode_level(qpdf_dl_none); + decode_level(qpdf_dl_none); compress_streams(false); return *this; case qpdf_s_compress: - stream_decode_level(std::max(qpdf_dl_generalized, stream_decode_level_)); + decode_level(std::max(qpdf_dl_generalized, decode_level_)); compress_streams(true); } return *this; @@ -614,18 +614,18 @@ Config::compress_streams(bool val) void QPDFWriter::setDecodeLevel(qpdf_stream_decode_level_e val) { - m->cfg.stream_decode_level(val); + m->cfg.decode_level(val); } Config& -Config::stream_decode_level(qpdf_stream_decode_level_e val) +Config::decode_level(qpdf_stream_decode_level_e val) { if (pclm_) { usage("stream_decode_level cannot be set when pclm is set"); return *this; } - stream_decode_level_set_ = true; - stream_decode_level_ = val; + decode_level_set_ = true; + decode_level_ = val; return *this; } @@ -664,8 +664,8 @@ Config::qdf(bool val) if (!compress_streams_set_) { compress_streams(false); } - if (!stream_decode_level_set_) { - stream_decode_level(qpdf_dl_generalized); + if (!decode_level_set_) { + decode_level(qpdf_dl_generalized); } preserve_encryption_ = false; // Generate indirect stream lengths for qdf mode since fix-qdf uses them for storing @@ -785,7 +785,7 @@ QPDFWriter::setStaticAesIV(bool val) void QPDFWriter::setSuppressOriginalObjectIDs(bool val) { - m->cfg.suppress_original_object_ids(val); + m->cfg.no_original_object_ids(val); } void @@ -814,7 +814,7 @@ Config::linearize(bool val) void QPDFWriter::setLinearizationPass1Filename(std::string const& filename) { - m->cfg.lin_pass1_filename(filename); + m->cfg.linearize_pass1(filename); } void @@ -826,7 +826,7 @@ QPDFWriter::setPCLm(bool val) Config& Config::pclm(bool val) { - if (stream_decode_level_set_ || compress_streams_set_ || linearize_) { + if (decode_level_set_ || compress_streams_set_ || linearize_) { usage( "pclm cannot be set when stream_decode_level, compress_streams, linearize or qdf are " "set"); @@ -834,7 +834,7 @@ Config::pclm(bool val) } pclm_ = val; if (val) { - stream_decode_level_ = qpdf_dl_none; + decode_level_ = qpdf_dl_none; compress_streams_ = false; linearize_ = false; } @@ -1549,7 +1549,7 @@ impl::Writer::will_filter_stream(QPDFObjectHandle stream, std::string* stream_da { const bool is_root_metadata = stream.isRootMetadata(); bool filter = false; - auto decode_level = cfg.stream_decode_level(); + auto decode_level = cfg.decode_level(); int encode_flags = 0; Dictionary stream_dict = stream.getDict(); @@ -1912,7 +1912,7 @@ impl::Writer::writeObjectStream(QPDFObjectHandle object) } if (cfg.qdf()) { write("%% Object stream: object ").write(new_o).write(", index ").write(count); - if (!cfg.suppress_original_object_ids()) { + if (!cfg.no_original_object_ids()) { write("; original object ID: ").write(og.getObj()); // For compatibility, only write the generation if non-zero. While object // streams only allow objects with generation 0, if we are generating object @@ -2017,7 +2017,7 @@ impl::Writer::writeObject(QPDFObjectHandle object, int object_stream_index) } } if (object_stream_index == -1) { - if (cfg.qdf() && !cfg.suppress_original_object_ids()) { + if (cfg.qdf() && !cfg.no_original_object_ids()) { write("%% Original object ID: ").write(object.getObjGen().unparse(' ')).write("\n"); } openObject(new_id); @@ -2880,8 +2880,8 @@ impl::Writer::writeLinearized() auto pp_md5 = pipeline_stack.popper(); for (int pass: {1, 2}) { if (pass == 1) { - if (!cfg.lin_pass1_filename().empty()) { - lin_pass1_file = QUtil::safe_fopen(cfg.lin_pass1_filename().data(), "wb"); + if (!cfg.linearize_pass1().empty()) { + lin_pass1_file = QUtil::safe_fopen(cfg.linearize_pass1().data(), "wb"); pipeline_stack.activate( pp_pass1, std::make_unique("linearization pass1", lin_pass1_file)); diff --git a/libqpdf/qpdf/QPDFJob_private.hh b/libqpdf/qpdf/QPDFJob_private.hh index 3f8ec59..adbcfb5 100644 --- a/libqpdf/qpdf/QPDFJob_private.hh +++ b/libqpdf/qpdf/QPDFJob_private.hh @@ -177,7 +177,6 @@ class QPDFJob::Members unsigned long encryption_status{0}; bool verbose{false}; std::string password; - bool linearize{false}; bool decrypt{false}; bool remove_restrictions{false}; int split_pages{0}; @@ -208,25 +207,9 @@ class QPDFJob::Members bool force_R5{false}; bool cleartext_metadata{false}; bool use_aes{false}; - bool stream_data_set{false}; - qpdf_stream_data_e stream_data_mode{qpdf_s_compress}; - bool compress_streams{true}; - bool compress_streams_set{false}; - bool recompress_flate{false}; - bool recompress_flate_set{false}; int compression_level{-1}; int jpeg_quality{-1}; - qpdf_stream_decode_level_e decode_level{qpdf_dl_generalized}; - bool decode_level_set{false}; - bool normalize_set{false}; - bool normalize{false}; - bool object_stream_set{false}; - qpdf_object_stream_e object_stream_mode{qpdf_o_preserve}; - bool qdf_mode{false}; - bool preserve_unreferenced_objects{false}; remove_unref_e remove_unreferenced_page_resources{re_auto}; - bool newline_before_endstream{false}; - std::string linearize_pass1; bool coalesce_contents{false}; bool flatten_annotations{false}; int flatten_annotations_required{0}; @@ -236,10 +219,7 @@ class QPDFJob::Members std::string min_version; std::string force_version; bool show_npages{false}; - bool deterministic_id{false}; - bool static_id{false}; bool static_aes_iv{false}; - bool suppress_original_object_id{false}; bool show_encryption{false}; bool show_encryption_key{false}; bool check_linearization{false}; diff --git a/libqpdf/qpdf/QPDFWriter_private.hh b/libqpdf/qpdf/QPDFWriter_private.hh index cd5e1ee..f3a9587 100644 --- a/libqpdf/qpdf/QPDFWriter_private.hh +++ b/libqpdf/qpdf/QPDFWriter_private.hh @@ -45,15 +45,15 @@ namespace qpdf Config& linearize(bool val); std::string const& - lin_pass1_filename() const + linearize_pass1() const { - return lin_pass1_filename_; + return linearize_pass1_; } Config& - lin_pass1_filename(std::string const& val) + linearize_pass1(std::string const& val) { - lin_pass1_filename_ = val; + linearize_pass1_ = val; return *this; } @@ -83,13 +83,22 @@ namespace qpdf return *this; } + Config& + default_decode_level(qpdf_stream_decode_level_e val) + { + if (!decode_level_set_) { + decode_level_ = val; + } + return *this; + } + qpdf_stream_decode_level_e - stream_decode_level() const + decode_level() const { - return stream_decode_level_; + return decode_level_; } - Config& stream_decode_level(qpdf_stream_decode_level_e val); + Config& decode_level(qpdf_stream_decode_level_e val); qpdf_object_stream_e object_streams() const @@ -202,15 +211,15 @@ namespace qpdf } bool - suppress_original_object_ids() const + no_original_object_ids() const { - return suppress_original_object_ids_; + return no_original_object_ids_; } Config& - suppress_original_object_ids(bool val) + no_original_object_ids(bool val) { - suppress_original_object_ids_ = val; + no_original_object_ids_ = val; return *this; } @@ -282,10 +291,10 @@ namespace qpdf std::string forced_pdf_version_; std::string extra_header_text_; // For linearization only - std::string lin_pass1_filename_; + std::string linearize_pass1_; qpdf_object_stream_e object_streams_{qpdf_o_preserve}; - qpdf_stream_decode_level_e stream_decode_level_{qpdf_dl_generalized}; + qpdf_stream_decode_level_e decode_level_{qpdf_dl_generalized}; int forced_extension_level_{0}; @@ -293,14 +302,14 @@ namespace qpdf bool normalize_content_{false}; bool compress_streams_{true}; bool compress_streams_set_{false}; - bool stream_decode_level_set_{false}; + bool decode_level_set_{false}; bool recompress_flate_{false}; bool qdf_{false}; bool preserve_unreferenced_{false}; bool newline_before_endstream_{false}; bool deterministic_id_{false}; bool static_id_{false}; - bool suppress_original_object_ids_{false}; + bool no_original_object_ids_{false}; bool direct_stream_lengths_{true}; bool preserve_encryption_{true}; bool linearize_{false}; -- libgit2 0.21.4