Commit de2e46cc333e5ec9dc37a13b713038eacdc6cbd3
1 parent
a9d8b976
Refactor `QPDFWriter` configuration: encapsulate configuration parameters in `Co…
…nfig` struct, update member access to use `cfg`, and streamline related logic across `QPDFWriter`.
Showing
2 changed files
with
174 additions
and
150 deletions
libqpdf/QPDFWriter.cc
| ... | ... | @@ -275,6 +275,8 @@ namespace qpdf::impl |
| 275 | 275 | |
| 276 | 276 | protected: |
| 277 | 277 | Doc::Linearization& lin; |
| 278 | + | |
| 279 | + qpdf::Writer::Config cfg; | |
| 278 | 280 | }; |
| 279 | 281 | } // namespace qpdf::impl |
| 280 | 282 | |
| ... | ... | @@ -437,27 +439,9 @@ class QPDFWriter::Members: impl::Writer |
| 437 | 439 | bool close_file{false}; |
| 438 | 440 | std::unique_ptr<Pl_Buffer> buffer_pipeline{nullptr}; |
| 439 | 441 | Buffer* output_buffer{nullptr}; |
| 440 | - bool normalize_content_set{false}; | |
| 441 | - bool normalize_content{false}; | |
| 442 | - bool compress_streams{true}; | |
| 443 | - bool compress_streams_set{false}; | |
| 444 | - qpdf_stream_decode_level_e stream_decode_level{qpdf_dl_generalized}; | |
| 445 | - bool stream_decode_level_set{false}; | |
| 446 | - bool recompress_flate{false}; | |
| 447 | - bool qdf_mode{false}; | |
| 448 | - bool preserve_unreferenced_objects{false}; | |
| 449 | - bool newline_before_endstream{false}; | |
| 450 | - bool static_id{false}; | |
| 451 | - bool suppress_original_object_ids{false}; | |
| 452 | - bool direct_stream_lengths{true}; | |
| 453 | - bool preserve_encryption{true}; | |
| 454 | - bool linearized{false}; | |
| 455 | - bool pclm{false}; | |
| 456 | - qpdf_object_stream_e object_stream_mode{qpdf_o_preserve}; | |
| 457 | 442 | |
| 458 | 443 | std::unique_ptr<QPDF::Doc::Encryption> encryption; |
| 459 | 444 | std::string encryption_key; |
| 460 | - bool encrypt_use_aes{false}; | |
| 461 | 445 | |
| 462 | 446 | std::string id1; // for /ID key of |
| 463 | 447 | std::string id2; // trailer dictionary |
| ... | ... | @@ -465,9 +449,6 @@ class QPDFWriter::Members: impl::Writer |
| 465 | 449 | int final_extension_level{0}; |
| 466 | 450 | std::string min_pdf_version; |
| 467 | 451 | int min_extension_level{0}; |
| 468 | - std::string forced_pdf_version; | |
| 469 | - int forced_extension_level{0}; | |
| 470 | - std::string extra_header_text; | |
| 471 | 452 | int encryption_dict_objid{0}; |
| 472 | 453 | std::string cur_data_key; |
| 473 | 454 | std::unique_ptr<Pipeline> file_pl; |
| ... | ... | @@ -486,13 +467,9 @@ class QPDFWriter::Members: impl::Writer |
| 486 | 467 | std::map<QPDFObjGen, int> contents_to_page_seq; |
| 487 | 468 | std::map<int, std::vector<QPDFObjGen>> object_stream_to_objects; |
| 488 | 469 | Pl_stack pipeline_stack; |
| 489 | - bool deterministic_id{false}; | |
| 490 | 470 | std::string deterministic_id_data; |
| 491 | 471 | bool did_write_setup{false}; |
| 492 | 472 | |
| 493 | - // For linearization only | |
| 494 | - std::string lin_pass1_filename; | |
| 495 | - | |
| 496 | 473 | // For progress reporting |
| 497 | 474 | std::shared_ptr<QPDFWriter::ProgressReporter> progress_reporter; |
| 498 | 475 | int events_expected{0}; |
| ... | ... | @@ -576,7 +553,7 @@ QPDFWriter::setOutputPipeline(Pipeline* p) |
| 576 | 553 | void |
| 577 | 554 | QPDFWriter::setObjectStreamMode(qpdf_object_stream_e mode) |
| 578 | 555 | { |
| 579 | - m->object_stream_mode = mode; | |
| 556 | + m->cfg.object_stream_mode_ = mode; | |
| 580 | 557 | } |
| 581 | 558 | |
| 582 | 559 | void |
| ... | ... | @@ -584,67 +561,67 @@ QPDFWriter::setStreamDataMode(qpdf_stream_data_e mode) |
| 584 | 561 | { |
| 585 | 562 | switch (mode) { |
| 586 | 563 | case qpdf_s_uncompress: |
| 587 | - m->stream_decode_level = std::max(qpdf_dl_generalized, m->stream_decode_level); | |
| 588 | - m->compress_streams = false; | |
| 564 | + m->cfg.stream_decode_level_ = std::max(qpdf_dl_generalized, m->cfg.stream_decode_level_); | |
| 565 | + m->cfg.compress_streams_ = false; | |
| 589 | 566 | break; |
| 590 | 567 | |
| 591 | 568 | case qpdf_s_preserve: |
| 592 | - m->stream_decode_level = qpdf_dl_none; | |
| 593 | - m->compress_streams = false; | |
| 569 | + m->cfg.stream_decode_level_ = qpdf_dl_none; | |
| 570 | + m->cfg.compress_streams_ = false; | |
| 594 | 571 | break; |
| 595 | 572 | |
| 596 | 573 | case qpdf_s_compress: |
| 597 | - m->stream_decode_level = std::max(qpdf_dl_generalized, m->stream_decode_level); | |
| 598 | - m->compress_streams = true; | |
| 574 | + m->cfg.stream_decode_level_ = std::max(qpdf_dl_generalized, m->cfg.stream_decode_level_); | |
| 575 | + m->cfg.compress_streams_ = true; | |
| 599 | 576 | break; |
| 600 | 577 | } |
| 601 | - m->stream_decode_level_set = true; | |
| 602 | - m->compress_streams_set = true; | |
| 578 | + m->cfg.stream_decode_level_set_ = true; | |
| 579 | + m->cfg.compress_streams_set_ = true; | |
| 603 | 580 | } |
| 604 | 581 | |
| 605 | 582 | void |
| 606 | 583 | QPDFWriter::setCompressStreams(bool val) |
| 607 | 584 | { |
| 608 | - m->compress_streams = val; | |
| 609 | - m->compress_streams_set = true; | |
| 585 | + m->cfg.compress_streams_ = val; | |
| 586 | + m->cfg.compress_streams_set_ = true; | |
| 610 | 587 | } |
| 611 | 588 | |
| 612 | 589 | void |
| 613 | 590 | QPDFWriter::setDecodeLevel(qpdf_stream_decode_level_e val) |
| 614 | 591 | { |
| 615 | - m->stream_decode_level = val; | |
| 616 | - m->stream_decode_level_set = true; | |
| 592 | + m->cfg.stream_decode_level_ = val; | |
| 593 | + m->cfg.stream_decode_level_set_ = true; | |
| 617 | 594 | } |
| 618 | 595 | |
| 619 | 596 | void |
| 620 | 597 | QPDFWriter::setRecompressFlate(bool val) |
| 621 | 598 | { |
| 622 | - m->recompress_flate = val; | |
| 599 | + m->cfg.recompress_flate_ = val; | |
| 623 | 600 | } |
| 624 | 601 | |
| 625 | 602 | void |
| 626 | 603 | QPDFWriter::setContentNormalization(bool val) |
| 627 | 604 | { |
| 628 | - m->normalize_content_set = true; | |
| 629 | - m->normalize_content = val; | |
| 605 | + m->cfg.normalize_content_set_ = true; | |
| 606 | + m->cfg.normalize_content_ = val; | |
| 630 | 607 | } |
| 631 | 608 | |
| 632 | 609 | void |
| 633 | 610 | QPDFWriter::setQDFMode(bool val) |
| 634 | 611 | { |
| 635 | - m->qdf_mode = val; | |
| 612 | + m->cfg.qdf_mode_ = val; | |
| 636 | 613 | } |
| 637 | 614 | |
| 638 | 615 | void |
| 639 | 616 | QPDFWriter::setPreserveUnreferencedObjects(bool val) |
| 640 | 617 | { |
| 641 | - m->preserve_unreferenced_objects = val; | |
| 618 | + m->cfg.preserve_unreferenced_objects_ = val; | |
| 642 | 619 | } |
| 643 | 620 | |
| 644 | 621 | void |
| 645 | 622 | QPDFWriter::setNewlineBeforeEndstream(bool val) |
| 646 | 623 | { |
| 647 | - m->newline_before_endstream = val; | |
| 624 | + m->cfg.newline_before_endstream_ = val; | |
| 648 | 625 | } |
| 649 | 626 | |
| 650 | 627 | void |
| ... | ... | @@ -700,16 +677,16 @@ QPDFWriter::setMinimumPDFVersion(PDFVersion const& v) |
| 700 | 677 | void |
| 701 | 678 | QPDFWriter::forcePDFVersion(std::string const& version, int extension_level) |
| 702 | 679 | { |
| 703 | - m->forced_pdf_version = version; | |
| 704 | - m->forced_extension_level = extension_level; | |
| 680 | + m->cfg.forced_pdf_version_ = version; | |
| 681 | + m->cfg.forced_extension_level_ = extension_level; | |
| 705 | 682 | } |
| 706 | 683 | |
| 707 | 684 | void |
| 708 | 685 | QPDFWriter::setExtraHeaderText(std::string const& text) |
| 709 | 686 | { |
| 710 | - m->extra_header_text = text; | |
| 711 | - if (!m->extra_header_text.empty() && *m->extra_header_text.rbegin() != '\n') { | |
| 712 | - m->extra_header_text += "\n"; | |
| 687 | + m->cfg.extra_header_text_ = text; | |
| 688 | + if (!m->cfg.extra_header_text_.empty() && m->cfg.extra_header_text_.back() != '\n') { | |
| 689 | + m->cfg.extra_header_text_ += "\n"; | |
| 713 | 690 | } else { |
| 714 | 691 | QTC::TC("qpdf", "QPDFWriter extra header text no newline"); |
| 715 | 692 | } |
| ... | ... | @@ -718,13 +695,13 @@ QPDFWriter::setExtraHeaderText(std::string const& text) |
| 718 | 695 | void |
| 719 | 696 | QPDFWriter::setStaticID(bool val) |
| 720 | 697 | { |
| 721 | - m->static_id = val; | |
| 698 | + m->cfg.static_id_ = val; | |
| 722 | 699 | } |
| 723 | 700 | |
| 724 | 701 | void |
| 725 | 702 | QPDFWriter::setDeterministicID(bool val) |
| 726 | 703 | { |
| 727 | - m->deterministic_id = val; | |
| 704 | + m->cfg.deterministic_id_ = val; | |
| 728 | 705 | } |
| 729 | 706 | |
| 730 | 707 | void |
| ... | ... | @@ -738,36 +715,36 @@ QPDFWriter::setStaticAesIV(bool val) |
| 738 | 715 | void |
| 739 | 716 | QPDFWriter::setSuppressOriginalObjectIDs(bool val) |
| 740 | 717 | { |
| 741 | - m->suppress_original_object_ids = val; | |
| 718 | + m->cfg.suppress_original_object_ids_ = val; | |
| 742 | 719 | } |
| 743 | 720 | |
| 744 | 721 | void |
| 745 | 722 | QPDFWriter::setPreserveEncryption(bool val) |
| 746 | 723 | { |
| 747 | - m->preserve_encryption = val; | |
| 724 | + m->cfg.preserve_encryption_ = val; | |
| 748 | 725 | } |
| 749 | 726 | |
| 750 | 727 | void |
| 751 | 728 | QPDFWriter::setLinearization(bool val) |
| 752 | 729 | { |
| 753 | - m->linearized = val; | |
| 730 | + m->cfg.linearized_ = val; | |
| 754 | 731 | if (val) { |
| 755 | - m->pclm = false; | |
| 732 | + m->cfg.pclm_ = false; | |
| 756 | 733 | } |
| 757 | 734 | } |
| 758 | 735 | |
| 759 | 736 | void |
| 760 | 737 | QPDFWriter::setLinearizationPass1Filename(std::string const& filename) |
| 761 | 738 | { |
| 762 | - m->lin_pass1_filename = filename; | |
| 739 | + m->cfg.lin_pass1_filename_ = filename; | |
| 763 | 740 | } |
| 764 | 741 | |
| 765 | 742 | void |
| 766 | 743 | QPDFWriter::setPCLm(bool val) |
| 767 | 744 | { |
| 768 | - m->pclm = val; | |
| 745 | + m->cfg.pclm_ = val; | |
| 769 | 746 | if (val) { |
| 770 | - m->linearized = false; | |
| 747 | + m->cfg.linearized_ = false; | |
| 771 | 748 | } |
| 772 | 749 | } |
| 773 | 750 | |
| ... | ... | @@ -836,7 +813,7 @@ QPDFWriter::setR4EncryptionParametersInsecure( |
| 836 | 813 | bool use_aes) |
| 837 | 814 | { |
| 838 | 815 | m->encryption = std::make_unique<Encryption>(4, 4, 16, encrypt_metadata); |
| 839 | - m->encrypt_use_aes = use_aes; | |
| 816 | + m->cfg.encrypt_use_aes_ = use_aes; | |
| 840 | 817 | m->interpretR3EncryptionParameters( |
| 841 | 818 | allow_accessibility, |
| 842 | 819 | allow_extract, |
| ... | ... | @@ -863,7 +840,7 @@ QPDFWriter::setR5EncryptionParameters( |
| 863 | 840 | bool encrypt_metadata) |
| 864 | 841 | { |
| 865 | 842 | m->encryption = std::make_unique<Encryption>(5, 5, 32, encrypt_metadata); |
| 866 | - m->encrypt_use_aes = true; | |
| 843 | + m->cfg.encrypt_use_aes_ = true; | |
| 867 | 844 | m->interpretR3EncryptionParameters( |
| 868 | 845 | allow_accessibility, |
| 869 | 846 | allow_extract, |
| ... | ... | @@ -899,7 +876,7 @@ QPDFWriter::setR6EncryptionParameters( |
| 899 | 876 | allow_modify_other, |
| 900 | 877 | print, |
| 901 | 878 | qpdf_r3m_all); |
| 902 | - m->encrypt_use_aes = true; | |
| 879 | + m->cfg.encrypt_use_aes_ = true; | |
| 903 | 880 | m->setEncryptionParameters(user_password, owner_password); |
| 904 | 881 | } |
| 905 | 882 | |
| ... | ... | @@ -1020,7 +997,7 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) |
| 1020 | 997 | void |
| 1021 | 998 | QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) |
| 1022 | 999 | { |
| 1023 | - preserve_encryption = false; | |
| 1000 | + cfg.preserve_encryption_ = false; | |
| 1024 | 1001 | QPDFObjectHandle trailer = qpdf.getTrailer(); |
| 1025 | 1002 | if (trailer.hasKey("/Encrypt")) { |
| 1026 | 1003 | generateID(true); |
| ... | ... | @@ -1040,10 +1017,10 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) |
| 1040 | 1017 | // Acrobat doesn't create files with V >= 4 that don't use AES, and the logic of |
| 1041 | 1018 | // figuring out whether AES is used or not is complicated with /StmF, /StrF, and /EFF |
| 1042 | 1019 | // all potentially having different values. |
| 1043 | - encrypt_use_aes = true; | |
| 1020 | + cfg.encrypt_use_aes_ = true; | |
| 1044 | 1021 | } |
| 1045 | 1022 | QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", encrypt_metadata ? 0 : 1); |
| 1046 | - QTC::TC("qpdf", "QPDFWriter copy use_aes", encrypt_use_aes ? 0 : 1); | |
| 1023 | + QTC::TC("qpdf", "QPDFWriter copy use_aes", cfg.encrypt_use_aes_ ? 0 : 1); | |
| 1047 | 1024 | |
| 1048 | 1025 | encryption = std::make_unique<Encryption>( |
| 1049 | 1026 | V, |
| ... | ... | @@ -1084,7 +1061,7 @@ QPDFWriter::Members::disableIncompatibleEncryption(int major, int minor, int ext |
| 1084 | 1061 | encryption = nullptr; |
| 1085 | 1062 | } |
| 1086 | 1063 | } else if (compareVersions(major, minor, 1, 6) < 0) { |
| 1087 | - if (encrypt_use_aes) { | |
| 1064 | + if (cfg.encrypt_use_aes_) { | |
| 1088 | 1065 | encryption = nullptr; |
| 1089 | 1066 | } |
| 1090 | 1067 | } else if ( |
| ... | ... | @@ -1141,7 +1118,7 @@ QPDFWriter::Members::setEncryptionMinimumVersion() |
| 1141 | 1118 | } else if (R == 5) { |
| 1142 | 1119 | w.setMinimumPDFVersion("1.7", 3); |
| 1143 | 1120 | } else if (R == 4) { |
| 1144 | - w.setMinimumPDFVersion(encrypt_use_aes ? "1.6" : "1.5"); | |
| 1121 | + w.setMinimumPDFVersion(cfg.encrypt_use_aes_ ? "1.6" : "1.5"); | |
| 1145 | 1122 | } else if (R == 3) { |
| 1146 | 1123 | w.setMinimumPDFVersion("1.4"); |
| 1147 | 1124 | } else { |
| ... | ... | @@ -1154,7 +1131,7 @@ QPDFWriter::Members::setDataKey(int objid) |
| 1154 | 1131 | { |
| 1155 | 1132 | if (encryption) { |
| 1156 | 1133 | cur_data_key = QPDF::compute_data_key( |
| 1157 | - encryption_key, objid, 0, encrypt_use_aes, encryption->getV(), encryption->getR()); | |
| 1134 | + encryption_key, objid, 0, cfg.encrypt_use_aes_, encryption->getV(), encryption->getR()); | |
| 1158 | 1135 | } |
| 1159 | 1136 | } |
| 1160 | 1137 | |
| ... | ... | @@ -1222,7 +1199,7 @@ template <typename... Args> |
| 1222 | 1199 | QPDFWriter::Members& |
| 1223 | 1200 | QPDFWriter::Members::write_qdf(Args&&... args) |
| 1224 | 1201 | { |
| 1225 | - if (qdf_mode) { | |
| 1202 | + if (cfg.qdf_mode_) { | |
| 1226 | 1203 | pipeline->write(std::forward<Args>(args)...); |
| 1227 | 1204 | } |
| 1228 | 1205 | return *this; |
| ... | ... | @@ -1232,7 +1209,7 @@ template <typename... Args> |
| 1232 | 1209 | QPDFWriter::Members& |
| 1233 | 1210 | QPDFWriter::Members::write_no_qdf(Args&&... args) |
| 1234 | 1211 | { |
| 1235 | - if (!qdf_mode) { | |
| 1212 | + if (!cfg.qdf_mode_) { | |
| 1236 | 1213 | pipeline->write(std::forward<Args>(args)...); |
| 1237 | 1214 | } |
| 1238 | 1215 | return *this; |
| ... | ... | @@ -1241,7 +1218,7 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) |
| 1241 | 1218 | void |
| 1242 | 1219 | QPDFWriter::Members::adjustAESStreamLength(size_t& length) |
| 1243 | 1220 | { |
| 1244 | - if (encryption && !cur_data_key.empty() && encrypt_use_aes) { | |
| 1221 | + if (encryption && !cur_data_key.empty() && cfg.encrypt_use_aes_) { | |
| 1245 | 1222 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will |
| 1246 | 1223 | // also be prepended by 16 bits of random data. |
| 1247 | 1224 | length += 32 - (length & 0xf); |
| ... | ... | @@ -1253,7 +1230,7 @@ QPDFWriter::Members::write_encrypted(std::string_view str) |
| 1253 | 1230 | { |
| 1254 | 1231 | if (!(encryption && !cur_data_key.empty())) { |
| 1255 | 1232 | write(str); |
| 1256 | - } else if (encrypt_use_aes) { | |
| 1233 | + } else if (cfg.encrypt_use_aes_) { | |
| 1257 | 1234 | write(pl::pipe<Pl_AES_PDF>(str, true, cur_data_key)); |
| 1258 | 1235 | } else { |
| 1259 | 1236 | write(pl::pipe<Pl_RC4>(str, cur_data_key)); |
| ... | ... | @@ -1324,7 +1301,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) |
| 1324 | 1301 | "Use QPDF::copyForeignObject to add objects from another file." // |
| 1325 | 1302 | ); |
| 1326 | 1303 | |
| 1327 | - if (qdf_mode && object.isStreamOfType("/XRef")) { | |
| 1304 | + if (cfg.qdf_mode_ && object.isStreamOfType("/XRef")) { | |
| 1328 | 1305 | // As a special case, do not output any extraneous XRef streams in QDF mode. Doing so |
| 1329 | 1306 | // will confuse fix-qdf, which expects to see only one XRef stream at the end of the |
| 1330 | 1307 | // file. This case can occur when creating a QDF from a file with object streams when |
| ... | ... | @@ -1350,10 +1327,10 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) |
| 1350 | 1327 | if (og.getGen() == 0 && object_stream_to_objects.contains(og.getObj())) { |
| 1351 | 1328 | // For linearized files, uncompressed objects go at end, and we take care of |
| 1352 | 1329 | // assigning numbers to them elsewhere. |
| 1353 | - if (!linearized) { | |
| 1330 | + if (!cfg.linearized_) { | |
| 1354 | 1331 | assignCompressedObjectNumbers(og); |
| 1355 | 1332 | } |
| 1356 | - } else if (!direct_stream_lengths && object.isStream()) { | |
| 1333 | + } else if (!cfg.direct_stream_lengths_ && object.isStream()) { | |
| 1357 | 1334 | // reserve next object ID for length |
| 1358 | 1335 | ++next_objid; |
| 1359 | 1336 | } |
| ... | ... | @@ -1362,7 +1339,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) |
| 1362 | 1339 | return; |
| 1363 | 1340 | } |
| 1364 | 1341 | |
| 1365 | - if (linearized) { | |
| 1342 | + if (cfg.linearized_) { | |
| 1366 | 1343 | return; |
| 1367 | 1344 | } |
| 1368 | 1345 | |
| ... | ... | @@ -1383,7 +1360,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) |
| 1383 | 1360 | void |
| 1384 | 1361 | QPDFWriter::Members::unparseChild(QPDFObjectHandle const& child, size_t level, int flags) |
| 1385 | 1362 | { |
| 1386 | - if (!linearized) { | |
| 1363 | + if (!cfg.linearized_) { | |
| 1387 | 1364 | enqueue(child); |
| 1388 | 1365 | } |
| 1389 | 1366 | if (child.indirect()) { |
| ... | ... | @@ -1442,7 +1419,7 @@ QPDFWriter::Members::writeTrailer( |
| 1442 | 1419 | } |
| 1443 | 1420 | write("<00000000000000000000000000000000>"); |
| 1444 | 1421 | } else { |
| 1445 | - if (linearization_pass == 0 && deterministic_id) { | |
| 1422 | + if (linearization_pass == 0 && cfg.deterministic_id_) { | |
| 1446 | 1423 | computeDeterministicIDData(); |
| 1447 | 1424 | } |
| 1448 | 1425 | generateID(encryption.get()); |
| ... | ... | @@ -1473,19 +1450,19 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st |
| 1473 | 1450 | { |
| 1474 | 1451 | const bool is_root_metadata = stream.isRootMetadata(); |
| 1475 | 1452 | bool filter = false; |
| 1476 | - auto decode_level = stream_decode_level; | |
| 1453 | + auto decode_level = cfg.stream_decode_level_; | |
| 1477 | 1454 | int encode_flags = 0; |
| 1478 | 1455 | Dictionary stream_dict = stream.getDict(); |
| 1479 | 1456 | |
| 1480 | 1457 | if (stream.getFilterOnWrite()) { |
| 1481 | - filter = stream.isDataModified() || compress_streams || decode_level != qpdf_dl_none; | |
| 1482 | - if (compress_streams) { | |
| 1458 | + filter = stream.isDataModified() || cfg.compress_streams_ || decode_level != qpdf_dl_none; | |
| 1459 | + if (cfg.compress_streams_) { | |
| 1483 | 1460 | // Don't filter if the stream is already compressed with FlateDecode. This way we don't |
| 1484 | 1461 | // make it worse if the original file used a better Flate algorithm, and we don't spend |
| 1485 | 1462 | // time and CPU cycles uncompressing and recompressing stuff. This can be overridden |
| 1486 | 1463 | // with setRecompressFlate(true). |
| 1487 | 1464 | Name Filter = stream_dict["/Filter"]; |
| 1488 | - if (Filter && !recompress_flate && !stream.isDataModified() && | |
| 1465 | + if (Filter && !cfg.recompress_flate_ && !stream.isDataModified() && | |
| 1489 | 1466 | (Filter == "/FlateDecode" || Filter == "/Fl")) { |
| 1490 | 1467 | filter = false; |
| 1491 | 1468 | } |
| ... | ... | @@ -1493,10 +1470,10 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st |
| 1493 | 1470 | if (is_root_metadata && (!encryption || !encryption->getEncryptMetadata())) { |
| 1494 | 1471 | filter = true; |
| 1495 | 1472 | decode_level = qpdf_dl_all; |
| 1496 | - } else if (normalize_content && normalized_streams.contains(stream)) { | |
| 1473 | + } else if (cfg.normalize_content_ && normalized_streams.contains(stream)) { | |
| 1497 | 1474 | encode_flags = qpdf_ef_normalize; |
| 1498 | 1475 | filter = true; |
| 1499 | - } else if (filter && compress_streams) { | |
| 1476 | + } else if (filter && cfg.compress_streams_) { | |
| 1500 | 1477 | encode_flags = qpdf_ef_compress; |
| 1501 | 1478 | } |
| 1502 | 1479 | } |
| ... | ... | @@ -1550,11 +1527,11 @@ QPDFWriter::Members::unparseObject( |
| 1550 | 1527 | // For non-qdf, "indent" and "indent_large" are a single space between tokens. For qdf, they |
| 1551 | 1528 | // include the preceding newline. |
| 1552 | 1529 | std::string indent_large = " "; |
| 1553 | - if (qdf_mode) { | |
| 1530 | + if (cfg.qdf_mode_) { | |
| 1554 | 1531 | indent_large.append(2 * (level + 1), ' '); |
| 1555 | 1532 | indent_large[0] = '\n'; |
| 1556 | 1533 | } |
| 1557 | - std::string_view indent{indent_large.data(), qdf_mode ? indent_large.size() - 2 : 1}; | |
| 1534 | + std::string_view indent{indent_large.data(), cfg.qdf_mode_ ? indent_large.size() - 2 : 1}; | |
| 1558 | 1535 | |
| 1559 | 1536 | if (auto const tc = object.getTypeCode(); tc == ::ot_array) { |
| 1560 | 1537 | // Note: PDF spec 1.4 implementation note 121 states that Acrobat requires a space after the |
| ... | ... | @@ -1610,7 +1587,7 @@ QPDFWriter::Members::unparseObject( |
| 1610 | 1587 | if (need_extensions_adbe) { |
| 1611 | 1588 | if (!(have_extensions_other || have_extensions_adbe)) { |
| 1612 | 1589 | // We need Extensions and don't have it. Create it here. |
| 1613 | - QTC::TC("qpdf", "QPDFWriter create Extensions", qdf_mode ? 0 : 1); | |
| 1590 | + QTC::TC("qpdf", "QPDFWriter create Extensions", cfg.qdf_mode_ ? 0 : 1); | |
| 1614 | 1591 | extensions = object.replaceKeyAndGetNew( |
| 1615 | 1592 | "/Extensions", QPDFObjectHandle::newDictionary()); |
| 1616 | 1593 | } |
| ... | ... | @@ -1715,7 +1692,7 @@ QPDFWriter::Members::unparseObject( |
| 1715 | 1692 | if (flags & f_stream) { |
| 1716 | 1693 | write(indent_large).write("/Length "); |
| 1717 | 1694 | |
| 1718 | - if (direct_stream_lengths) { | |
| 1695 | + if (cfg.direct_stream_lengths_) { | |
| 1719 | 1696 | write(stream_length); |
| 1720 | 1697 | } else { |
| 1721 | 1698 | write(cur_stream_length_id).write(" 0 R"); |
| ... | ... | @@ -1728,7 +1705,7 @@ QPDFWriter::Members::unparseObject( |
| 1728 | 1705 | write(indent).write(">>"); |
| 1729 | 1706 | } else if (tc == ::ot_stream) { |
| 1730 | 1707 | // Write stream data to a buffer. |
| 1731 | - if (!direct_stream_lengths) { | |
| 1708 | + if (!cfg.direct_stream_lengths_) { | |
| 1732 | 1709 | cur_stream_length_id = obj[old_og].renumber + 1; |
| 1733 | 1710 | } |
| 1734 | 1711 | |
| ... | ... | @@ -1749,14 +1726,14 @@ QPDFWriter::Members::unparseObject( |
| 1749 | 1726 | unparseObject(stream_dict, 0, flags, cur_stream_length, compress_stream); |
| 1750 | 1727 | char last_char = stream_data.empty() ? '\0' : stream_data.back(); |
| 1751 | 1728 | write("\nstream\n").write_encrypted(stream_data); |
| 1752 | - added_newline = newline_before_endstream || (qdf_mode && last_char != '\n'); | |
| 1729 | + added_newline = cfg.newline_before_endstream_ || (cfg.qdf_mode_ && last_char != '\n'); | |
| 1753 | 1730 | write(added_newline ? "\nendstream" : "endstream"); |
| 1754 | 1731 | } else if (tc == ::ot_string) { |
| 1755 | 1732 | std::string val; |
| 1756 | 1733 | if (encryption && !(flags & f_in_ostream) && !(flags & f_no_encryption) && |
| 1757 | 1734 | !cur_data_key.empty()) { |
| 1758 | 1735 | val = object.getStringValue(); |
| 1759 | - if (encrypt_use_aes) { | |
| 1736 | + if (cfg.encrypt_use_aes_) { | |
| 1760 | 1737 | Pl_Buffer bufpl("encrypted string"); |
| 1761 | 1738 | Pl_AES_PDF pl("aes encrypt string", &bufpl, true, cur_data_key); |
| 1762 | 1739 | pl.writeString(val); |
| ... | ... | @@ -1822,7 +1799,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) |
| 1822 | 1799 | std::string stream_buffer_pass1; |
| 1823 | 1800 | std::string stream_buffer_pass2; |
| 1824 | 1801 | int first_obj = -1; |
| 1825 | - const bool compressed = compress_streams && !qdf_mode; | |
| 1802 | + const bool compressed = cfg.compress_streams_ && !cfg.qdf_mode_; | |
| 1826 | 1803 | { |
| 1827 | 1804 | // Pass 1 |
| 1828 | 1805 | auto pp_ostream_pass1 = pipeline_stack.activate(stream_buffer_pass1); |
| ... | ... | @@ -1834,9 +1811,9 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) |
| 1834 | 1811 | if (first_obj == -1) { |
| 1835 | 1812 | first_obj = new_o; |
| 1836 | 1813 | } |
| 1837 | - if (qdf_mode) { | |
| 1814 | + if (cfg.qdf_mode_) { | |
| 1838 | 1815 | write("%% Object stream: object ").write(new_o).write(", index ").write(count); |
| 1839 | - if (!suppress_original_object_ids) { | |
| 1816 | + if (!cfg.suppress_original_object_ids_) { | |
| 1840 | 1817 | write("; original object ID: ").write(og.getObj()); |
| 1841 | 1818 | // For compatibility, only write the generation if non-zero. While object |
| 1842 | 1819 | // streams only allow objects with generation 0, if we are generating object |
| ... | ... | @@ -1915,7 +1892,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) |
| 1915 | 1892 | if (encryption) { |
| 1916 | 1893 | QTC::TC("qpdf", "QPDFWriter encrypt object stream"); |
| 1917 | 1894 | } |
| 1918 | - write(newline_before_endstream ? "\nendstream" : "endstream"); | |
| 1895 | + write(cfg.newline_before_endstream_ ? "\nendstream" : "endstream"); | |
| 1919 | 1896 | cur_data_key.clear(); |
| 1920 | 1897 | closeObject(new_stream_id); |
| 1921 | 1898 | } |
| ... | ... | @@ -1933,7 +1910,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde |
| 1933 | 1910 | |
| 1934 | 1911 | indicateProgress(false, false); |
| 1935 | 1912 | auto new_id = obj[old_og].renumber; |
| 1936 | - if (qdf_mode) { | |
| 1913 | + if (cfg.qdf_mode_) { | |
| 1937 | 1914 | if (page_object_to_seq.contains(old_og)) { |
| 1938 | 1915 | write("%% Page ").write(page_object_to_seq[old_og]).write("\n"); |
| 1939 | 1916 | } |
| ... | ... | @@ -1942,7 +1919,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde |
| 1942 | 1919 | } |
| 1943 | 1920 | } |
| 1944 | 1921 | if (object_stream_index == -1) { |
| 1945 | - if (qdf_mode && !suppress_original_object_ids) { | |
| 1922 | + if (cfg.qdf_mode_ && !cfg.suppress_original_object_ids_) { | |
| 1946 | 1923 | write("%% Original object ID: ").write(object.getObjGen().unparse(' ')).write("\n"); |
| 1947 | 1924 | } |
| 1948 | 1925 | openObject(new_id); |
| ... | ... | @@ -1955,8 +1932,8 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde |
| 1955 | 1932 | write("\n"); |
| 1956 | 1933 | } |
| 1957 | 1934 | |
| 1958 | - if (!direct_stream_lengths && object.isStream()) { | |
| 1959 | - if (qdf_mode) { | |
| 1935 | + if (!cfg.direct_stream_lengths_ && object.isStream()) { | |
| 1936 | + if (cfg.qdf_mode_) { | |
| 1960 | 1937 | if (added_newline) { |
| 1961 | 1938 | write("%QDF: ignore_newline\n"); |
| 1962 | 1939 | } |
| ... | ... | @@ -1992,7 +1969,7 @@ QPDFWriter::Members::generateID(bool encrypted) |
| 1992 | 1969 | |
| 1993 | 1970 | std::string result; |
| 1994 | 1971 | |
| 1995 | - if (static_id) { | |
| 1972 | + if (cfg.static_id_) { | |
| 1996 | 1973 | // For test suite use only... |
| 1997 | 1974 | static unsigned char tmp[] = { |
| 1998 | 1975 | 0x31, |
| ... | ... | @@ -2024,7 +2001,7 @@ QPDFWriter::Members::generateID(bool encrypted) |
| 2024 | 2001 | // that case, would have the same ID regardless of the output file's name. |
| 2025 | 2002 | |
| 2026 | 2003 | std::string seed; |
| 2027 | - if (deterministic_id) { | |
| 2004 | + if (cfg.deterministic_id_) { | |
| 2028 | 2005 | if (encrypted) { |
| 2029 | 2006 | throw std::runtime_error( |
| 2030 | 2007 | "QPDFWriter: unable to generated a deterministic ID because the file to be " |
| ... | ... | @@ -2106,7 +2083,7 @@ QPDFWriter::Members::preserveObjectStreams() |
| 2106 | 2083 | // objects from being included. |
| 2107 | 2084 | auto end = xref.cend(); |
| 2108 | 2085 | obj.streams_empty = true; |
| 2109 | - if (preserve_unreferenced_objects) { | |
| 2086 | + if (cfg.preserve_unreferenced_objects_) { | |
| 2110 | 2087 | for (auto iter = xref.cbegin(); iter != end; ++iter) { |
| 2111 | 2088 | if (iter->second.getType() == 2) { |
| 2112 | 2089 | // Pdf contains object streams. |
| ... | ... | @@ -2248,63 +2225,63 @@ QPDFWriter::Members::doWriteSetup() |
| 2248 | 2225 | |
| 2249 | 2226 | // Do preliminary setup |
| 2250 | 2227 | |
| 2251 | - if (linearized) { | |
| 2252 | - qdf_mode = false; | |
| 2228 | + if (cfg.linearized_) { | |
| 2229 | + cfg.qdf_mode_ = false; | |
| 2253 | 2230 | } |
| 2254 | 2231 | |
| 2255 | - if (pclm) { | |
| 2256 | - stream_decode_level = qpdf_dl_none; | |
| 2257 | - compress_streams = false; | |
| 2232 | + if (cfg.pclm_) { | |
| 2233 | + cfg.stream_decode_level_ = qpdf_dl_none; | |
| 2234 | + cfg.compress_streams_ = false; | |
| 2258 | 2235 | encryption = nullptr; |
| 2259 | 2236 | } |
| 2260 | 2237 | |
| 2261 | - if (qdf_mode) { | |
| 2262 | - if (!normalize_content_set) { | |
| 2263 | - normalize_content = true; | |
| 2238 | + if (cfg.qdf_mode_) { | |
| 2239 | + if (!cfg.normalize_content_set_) { | |
| 2240 | + cfg.normalize_content_ = true; | |
| 2264 | 2241 | } |
| 2265 | - if (!compress_streams_set) { | |
| 2266 | - compress_streams = false; | |
| 2242 | + if (!cfg.compress_streams_set_) { | |
| 2243 | + cfg.compress_streams_ = false; | |
| 2267 | 2244 | } |
| 2268 | - if (!stream_decode_level_set) { | |
| 2269 | - stream_decode_level = qpdf_dl_generalized; | |
| 2245 | + if (!cfg.stream_decode_level_set_) { | |
| 2246 | + cfg.stream_decode_level_ = qpdf_dl_generalized; | |
| 2270 | 2247 | } |
| 2271 | 2248 | } |
| 2272 | 2249 | |
| 2273 | 2250 | if (encryption) { |
| 2274 | 2251 | // Encryption has been explicitly set |
| 2275 | - preserve_encryption = false; | |
| 2276 | - } else if (normalize_content || pclm || qdf_mode) { | |
| 2252 | + cfg.preserve_encryption_ = false; | |
| 2253 | + } else if (cfg.normalize_content_ || cfg.pclm_ || cfg.qdf_mode_) { | |
| 2277 | 2254 | // Encryption makes looking at contents pretty useless. If the user explicitly encrypted |
| 2278 | 2255 | // though, we still obey that. |
| 2279 | - preserve_encryption = false; | |
| 2256 | + cfg.preserve_encryption_ = false; | |
| 2280 | 2257 | } |
| 2281 | 2258 | |
| 2282 | - if (preserve_encryption) { | |
| 2259 | + if (cfg.preserve_encryption_) { | |
| 2283 | 2260 | copyEncryptionParameters(qpdf); |
| 2284 | 2261 | } |
| 2285 | 2262 | |
| 2286 | - if (!forced_pdf_version.empty()) { | |
| 2263 | + if (!cfg.forced_pdf_version_.empty()) { | |
| 2287 | 2264 | int major = 0; |
| 2288 | 2265 | int minor = 0; |
| 2289 | - parseVersion(forced_pdf_version, major, minor); | |
| 2290 | - disableIncompatibleEncryption(major, minor, forced_extension_level); | |
| 2266 | + parseVersion(cfg.forced_pdf_version_, major, minor); | |
| 2267 | + disableIncompatibleEncryption(major, minor, cfg.forced_extension_level_); | |
| 2291 | 2268 | if (compareVersions(major, minor, 1, 5) < 0) { |
| 2292 | - object_stream_mode = qpdf_o_disable; | |
| 2269 | + cfg.object_stream_mode_ = qpdf_o_disable; | |
| 2293 | 2270 | } |
| 2294 | 2271 | } |
| 2295 | 2272 | |
| 2296 | - if (qdf_mode || normalize_content) { | |
| 2273 | + if (cfg.qdf_mode_ || cfg.normalize_content_) { | |
| 2297 | 2274 | initializeSpecialStreams(); |
| 2298 | 2275 | } |
| 2299 | 2276 | |
| 2300 | - if (qdf_mode) { | |
| 2277 | + if (cfg.qdf_mode_) { | |
| 2301 | 2278 | // Generate indirect stream lengths for qdf mode since fix-qdf uses them for storing |
| 2302 | 2279 | // recomputed stream length data. Certain streams such as object streams, xref streams, and |
| 2303 | 2280 | // hint streams always get direct stream lengths. |
| 2304 | - direct_stream_lengths = false; | |
| 2281 | + cfg.direct_stream_lengths_ = false; | |
| 2305 | 2282 | } |
| 2306 | 2283 | |
| 2307 | - switch (object_stream_mode) { | |
| 2284 | + switch (cfg.object_stream_mode_) { | |
| 2308 | 2285 | case qpdf_o_disable: |
| 2309 | 2286 | initializeTables(); |
| 2310 | 2287 | obj.streams_empty = true; |
| ... | ... | @@ -2323,7 +2300,7 @@ QPDFWriter::Members::doWriteSetup() |
| 2323 | 2300 | } |
| 2324 | 2301 | |
| 2325 | 2302 | if (!obj.streams_empty) { |
| 2326 | - if (linearized) { | |
| 2303 | + if (cfg.linearized_) { | |
| 2327 | 2304 | // Page dictionaries are not allowed to be compressed objects. |
| 2328 | 2305 | for (auto& page: pages) { |
| 2329 | 2306 | if (obj[page].object_stream > 0) { |
| ... | ... | @@ -2332,9 +2309,9 @@ QPDFWriter::Members::doWriteSetup() |
| 2332 | 2309 | } |
| 2333 | 2310 | } |
| 2334 | 2311 | |
| 2335 | - if (linearized || encryption) { | |
| 2336 | - // The document catalog is not allowed to be compressed in linearized files either. It | |
| 2337 | - // also appears that Adobe Reader 8.0.0 has a bug that prevents it from being able to | |
| 2312 | + if (cfg.linearized_ || encryption) { | |
| 2313 | + // The document catalog is not allowed to be compressed in cfg.linearized_ files either. | |
| 2314 | + // It also appears that Adobe Reader 8.0.0 has a bug that prevents it from being able to | |
| 2338 | 2315 | // handle encrypted files with compressed document catalogs, so we disable them in that |
| 2339 | 2316 | // case as well. |
| 2340 | 2317 | if (obj[root_og].object_stream > 0) { |
| ... | ... | @@ -2364,9 +2341,9 @@ QPDFWriter::Members::doWriteSetup() |
| 2364 | 2341 | setMinimumPDFVersion(qpdf.getPDFVersion(), qpdf.getExtensionLevel()); |
| 2365 | 2342 | final_pdf_version = min_pdf_version; |
| 2366 | 2343 | final_extension_level = min_extension_level; |
| 2367 | - if (!forced_pdf_version.empty()) { | |
| 2368 | - final_pdf_version = forced_pdf_version; | |
| 2369 | - final_extension_level = forced_extension_level; | |
| 2344 | + if (!cfg.forced_pdf_version_.empty()) { | |
| 2345 | + final_pdf_version = cfg.forced_pdf_version_; | |
| 2346 | + final_extension_level = cfg.forced_extension_level_; | |
| 2370 | 2347 | } |
| 2371 | 2348 | } |
| 2372 | 2349 | |
| ... | ... | @@ -2383,11 +2360,11 @@ QPDFWriter::Members::write() |
| 2383 | 2360 | |
| 2384 | 2361 | // Set up progress reporting. For linearized files, we write two passes. events_expected is an |
| 2385 | 2362 | // approximation, but it's good enough for progress reporting, which is mostly a guess anyway. |
| 2386 | - events_expected = QIntC::to_int(qpdf.getObjectCount() * (linearized ? 2 : 1)); | |
| 2363 | + events_expected = QIntC::to_int(qpdf.getObjectCount() * (cfg.linearized_ ? 2 : 1)); | |
| 2387 | 2364 | |
| 2388 | 2365 | prepareFileForWrite(); |
| 2389 | 2366 | |
| 2390 | - if (linearized) { | |
| 2367 | + if (cfg.linearized_) { | |
| 2391 | 2368 | writeLinearized(); |
| 2392 | 2369 | } else { |
| 2393 | 2370 | writeStandard(); |
| ... | ... | @@ -2449,10 +2426,10 @@ QPDFWriter::Members::writeEncryptionDictionary() |
| 2449 | 2426 | write("<<"); |
| 2450 | 2427 | if (V >= 4) { |
| 2451 | 2428 | write(" /CF << /StdCF << /AuthEvent /DocOpen /CFM "); |
| 2452 | - write(encrypt_use_aes ? (V < 5 ? "/AESV2" : "/AESV3") : "/V2"); | |
| 2429 | + write(cfg.encrypt_use_aes_ ? (V < 5 ? "/AESV2" : "/AESV3") : "/V2"); | |
| 2453 | 2430 | // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of |
| 2454 | 2431 | // MacOS won't open encrypted files without it. |
| 2455 | - write((V < 5) ? " /Length 16 >> >>" : " /Length 32 >> >>"); | |
| 2432 | + write(V < 5 ? " /Length 16 >> >>" : " /Length 32 >> >>"); | |
| 2456 | 2433 | if (!encryption->getEncryptMetadata()) { |
| 2457 | 2434 | write(" /EncryptMetadata false"); |
| 2458 | 2435 | } |
| ... | ... | @@ -2490,7 +2467,7 @@ void |
| 2490 | 2467 | QPDFWriter::Members::writeHeader() |
| 2491 | 2468 | { |
| 2492 | 2469 | write("%PDF-").write(final_pdf_version); |
| 2493 | - if (pclm) { | |
| 2470 | + if (cfg.pclm_) { | |
| 2494 | 2471 | // PCLm version |
| 2495 | 2472 | write("\n%PCLm 1.0\n"); |
| 2496 | 2473 | } else { |
| ... | ... | @@ -2512,7 +2489,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) |
| 2512 | 2489 | std::string hint_buffer; |
| 2513 | 2490 | int S = 0; |
| 2514 | 2491 | int O = 0; |
| 2515 | - bool compressed = compress_streams; | |
| 2492 | + bool compressed = cfg.compress_streams_; | |
| 2516 | 2493 | lin.generateHintStream(new_obj, obj, hint_buffer, S, O, compressed); |
| 2517 | 2494 | |
| 2518 | 2495 | openObject(hint_id); |
| ... | ... | @@ -2625,7 +2602,7 @@ QPDFWriter::Members::writeXRefStream( |
| 2625 | 2602 | new_obj[xref_id].xref = QPDFXRefEntry(pipeline->getCount()); |
| 2626 | 2603 | |
| 2627 | 2604 | std::string xref_data; |
| 2628 | - const bool compressed = compress_streams && !qdf_mode; | |
| 2605 | + const bool compressed = cfg.compress_streams_ && !cfg.qdf_mode_; | |
| 2629 | 2606 | { |
| 2630 | 2607 | auto pp_xref = pipeline_stack.activate(xref_data); |
| 2631 | 2608 | |
| ... | ... | @@ -2815,7 +2792,7 @@ QPDFWriter::Members::writeLinearized() |
| 2815 | 2792 | enqueuePart(part8); |
| 2816 | 2793 | enqueuePart(part9); |
| 2817 | 2794 | if (next_objid != after_second_half) { |
| 2818 | - throw std::runtime_error("error encountered after writing part 9 of linearized data"); | |
| 2795 | + throw std::runtime_error("error encountered after writing part 9 of cfg.linearized_ data"); | |
| 2819 | 2796 | } |
| 2820 | 2797 | |
| 2821 | 2798 | qpdf_offset_t hint_length = 0; |
| ... | ... | @@ -2828,15 +2805,15 @@ QPDFWriter::Members::writeLinearized() |
| 2828 | 2805 | auto pp_md5 = pipeline_stack.popper(); |
| 2829 | 2806 | for (int pass: {1, 2}) { |
| 2830 | 2807 | if (pass == 1) { |
| 2831 | - if (!lin_pass1_filename.empty()) { | |
| 2832 | - lin_pass1_file = QUtil::safe_fopen(lin_pass1_filename.c_str(), "wb"); | |
| 2808 | + if (!cfg.lin_pass1_filename_.empty()) { | |
| 2809 | + lin_pass1_file = QUtil::safe_fopen(cfg.lin_pass1_filename_.data(), "wb"); | |
| 2833 | 2810 | pipeline_stack.activate( |
| 2834 | 2811 | pp_pass1, |
| 2835 | 2812 | std::make_unique<Pl_StdioFile>("linearization pass1", lin_pass1_file)); |
| 2836 | 2813 | } else { |
| 2837 | 2814 | pipeline_stack.activate(pp_pass1, true); |
| 2838 | 2815 | } |
| 2839 | - if (deterministic_id) { | |
| 2816 | + if (cfg.deterministic_id_) { | |
| 2840 | 2817 | pipeline_stack.activate_md5(pp_md5); |
| 2841 | 2818 | } |
| 2842 | 2819 | } |
| ... | ... | @@ -2871,7 +2848,7 @@ QPDFWriter::Members::writeLinearized() |
| 2871 | 2848 | |
| 2872 | 2849 | // If the user supplied any additional header text, write it here after the linearization |
| 2873 | 2850 | // parameter dictionary. |
| 2874 | - write(extra_header_text); | |
| 2851 | + write(cfg.extra_header_text_); | |
| 2875 | 2852 | |
| 2876 | 2853 | // Part 3: first page cross reference table and trailer. |
| 2877 | 2854 | |
| ... | ... | @@ -3006,7 +2983,7 @@ QPDFWriter::Members::writeLinearized() |
| 3006 | 2983 | write("startxref\n").write(first_xref_offset).write("\n%%EOF\n"); |
| 3007 | 2984 | |
| 3008 | 2985 | if (pass == 1) { |
| 3009 | - if (deterministic_id) { | |
| 2986 | + if (cfg.deterministic_id_) { | |
| 3010 | 2987 | QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1); |
| 3011 | 2988 | computeDeterministicIDData(); |
| 3012 | 2989 | pp_md5.pop(); |
| ... | ... | @@ -3051,7 +3028,7 @@ QPDFWriter::Members::writeLinearized() |
| 3051 | 3028 | void |
| 3052 | 3029 | QPDFWriter::Members::enqueueObjectsStandard() |
| 3053 | 3030 | { |
| 3054 | - if (preserve_unreferenced_objects) { | |
| 3031 | + if (cfg.preserve_unreferenced_objects_) { | |
| 3055 | 3032 | for (auto const& oh: qpdf.getAllObjects()) { |
| 3056 | 3033 | enqueue(oh); |
| 3057 | 3034 | } |
| ... | ... | @@ -3132,16 +3109,16 @@ void |
| 3132 | 3109 | QPDFWriter::Members::writeStandard() |
| 3133 | 3110 | { |
| 3134 | 3111 | auto pp_md5 = pipeline_stack.popper(); |
| 3135 | - if (deterministic_id) { | |
| 3112 | + if (cfg.deterministic_id_) { | |
| 3136 | 3113 | pipeline_stack.activate_md5(pp_md5); |
| 3137 | 3114 | } |
| 3138 | 3115 | |
| 3139 | 3116 | // Start writing |
| 3140 | 3117 | |
| 3141 | 3118 | writeHeader(); |
| 3142 | - write(extra_header_text); | |
| 3119 | + write(cfg.extra_header_text_); | |
| 3143 | 3120 | |
| 3144 | - if (pclm) { | |
| 3121 | + if (cfg.pclm_) { | |
| 3145 | 3122 | enqueueObjectsPCLm(); |
| 3146 | 3123 | } else { |
| 3147 | 3124 | enqueueObjectsStandard(); |
| ... | ... | @@ -3171,7 +3148,7 @@ QPDFWriter::Members::writeStandard() |
| 3171 | 3148 | } |
| 3172 | 3149 | write("startxref\n").write(xref_offset).write("\n%%EOF\n"); |
| 3173 | 3150 | |
| 3174 | - if (deterministic_id) { | |
| 3151 | + if (cfg.deterministic_id_) { | |
| 3175 | 3152 | QTC::TC( |
| 3176 | 3153 | "qpdf", |
| 3177 | 3154 | "QPDFWriter standard deterministic ID", | ... | ... |
libqpdf/qpdf/QPDFWriter_private.hh
| ... | ... | @@ -5,6 +5,7 @@ |
| 5 | 5 | |
| 6 | 6 | #include <qpdf/ObjTable.hh> |
| 7 | 7 | #include <qpdf/Pipeline_private.hh> |
| 8 | +#include <qpdf/QPDF.hh> | |
| 8 | 9 | |
| 9 | 10 | // This file is intended for inclusion by QPDFWriter, QPDF, QPDF_optimization and QPDF_linearization |
| 10 | 11 | // only. |
| ... | ... | @@ -43,4 +44,50 @@ class QPDFWriter::NewObjTable: public ::ObjTable<QPDFWriter::NewObject> |
| 43 | 44 | friend class QPDFWriter; |
| 44 | 45 | }; |
| 45 | 46 | |
| 47 | +namespace qpdf | |
| 48 | +{ | |
| 49 | + namespace impl | |
| 50 | + { | |
| 51 | + class Writer; | |
| 52 | + } | |
| 53 | + | |
| 54 | + class Writer | |
| 55 | + { | |
| 56 | + public: | |
| 57 | + class Config | |
| 58 | + { | |
| 59 | + friend class impl::Writer; | |
| 60 | + friend class ::QPDFWriter; | |
| 61 | + | |
| 62 | + std::string forced_pdf_version_; | |
| 63 | + std::string extra_header_text_; | |
| 64 | + // For linearization only | |
| 65 | + std::string lin_pass1_filename_; | |
| 66 | + | |
| 67 | + qpdf_object_stream_e object_stream_mode_{qpdf_o_preserve}; | |
| 68 | + | |
| 69 | + int forced_extension_level_{0}; | |
| 70 | + | |
| 71 | + bool normalize_content_set_{false}; | |
| 72 | + bool normalize_content_{false}; | |
| 73 | + bool compress_streams_{true}; | |
| 74 | + bool compress_streams_set_{false}; | |
| 75 | + qpdf_stream_decode_level_e stream_decode_level_{qpdf_dl_generalized}; | |
| 76 | + bool stream_decode_level_set_{false}; | |
| 77 | + bool recompress_flate_{false}; | |
| 78 | + bool qdf_mode_{false}; | |
| 79 | + bool preserve_unreferenced_objects_{false}; | |
| 80 | + bool newline_before_endstream_{false}; | |
| 81 | + bool deterministic_id_{false}; | |
| 82 | + bool static_id_{false}; | |
| 83 | + bool suppress_original_object_ids_{false}; | |
| 84 | + bool direct_stream_lengths_{true}; | |
| 85 | + bool preserve_encryption_{true}; | |
| 86 | + bool linearized_{false}; | |
| 87 | + bool pclm_{false}; | |
| 88 | + bool encrypt_use_aes_{false}; | |
| 89 | + }; // class Writer::Config | |
| 90 | + }; // class Writer | |
| 91 | +} // namespace qpdf | |
| 92 | + | |
| 46 | 93 | #endif // QPDFWRITER_PRIVATE_HH | ... | ... |