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,6 +275,8 @@ namespace qpdf::impl | ||
| 275 | 275 | ||
| 276 | protected: | 276 | protected: |
| 277 | Doc::Linearization& lin; | 277 | Doc::Linearization& lin; |
| 278 | + | ||
| 279 | + qpdf::Writer::Config cfg; | ||
| 278 | }; | 280 | }; |
| 279 | } // namespace qpdf::impl | 281 | } // namespace qpdf::impl |
| 280 | 282 | ||
| @@ -437,27 +439,9 @@ class QPDFWriter::Members: impl::Writer | @@ -437,27 +439,9 @@ class QPDFWriter::Members: impl::Writer | ||
| 437 | bool close_file{false}; | 439 | bool close_file{false}; |
| 438 | std::unique_ptr<Pl_Buffer> buffer_pipeline{nullptr}; | 440 | std::unique_ptr<Pl_Buffer> buffer_pipeline{nullptr}; |
| 439 | Buffer* output_buffer{nullptr}; | 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 | std::unique_ptr<QPDF::Doc::Encryption> encryption; | 443 | std::unique_ptr<QPDF::Doc::Encryption> encryption; |
| 459 | std::string encryption_key; | 444 | std::string encryption_key; |
| 460 | - bool encrypt_use_aes{false}; | ||
| 461 | 445 | ||
| 462 | std::string id1; // for /ID key of | 446 | std::string id1; // for /ID key of |
| 463 | std::string id2; // trailer dictionary | 447 | std::string id2; // trailer dictionary |
| @@ -465,9 +449,6 @@ class QPDFWriter::Members: impl::Writer | @@ -465,9 +449,6 @@ class QPDFWriter::Members: impl::Writer | ||
| 465 | int final_extension_level{0}; | 449 | int final_extension_level{0}; |
| 466 | std::string min_pdf_version; | 450 | std::string min_pdf_version; |
| 467 | int min_extension_level{0}; | 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 | int encryption_dict_objid{0}; | 452 | int encryption_dict_objid{0}; |
| 472 | std::string cur_data_key; | 453 | std::string cur_data_key; |
| 473 | std::unique_ptr<Pipeline> file_pl; | 454 | std::unique_ptr<Pipeline> file_pl; |
| @@ -486,13 +467,9 @@ class QPDFWriter::Members: impl::Writer | @@ -486,13 +467,9 @@ class QPDFWriter::Members: impl::Writer | ||
| 486 | std::map<QPDFObjGen, int> contents_to_page_seq; | 467 | std::map<QPDFObjGen, int> contents_to_page_seq; |
| 487 | std::map<int, std::vector<QPDFObjGen>> object_stream_to_objects; | 468 | std::map<int, std::vector<QPDFObjGen>> object_stream_to_objects; |
| 488 | Pl_stack pipeline_stack; | 469 | Pl_stack pipeline_stack; |
| 489 | - bool deterministic_id{false}; | ||
| 490 | std::string deterministic_id_data; | 470 | std::string deterministic_id_data; |
| 491 | bool did_write_setup{false}; | 471 | bool did_write_setup{false}; |
| 492 | 472 | ||
| 493 | - // For linearization only | ||
| 494 | - std::string lin_pass1_filename; | ||
| 495 | - | ||
| 496 | // For progress reporting | 473 | // For progress reporting |
| 497 | std::shared_ptr<QPDFWriter::ProgressReporter> progress_reporter; | 474 | std::shared_ptr<QPDFWriter::ProgressReporter> progress_reporter; |
| 498 | int events_expected{0}; | 475 | int events_expected{0}; |
| @@ -576,7 +553,7 @@ QPDFWriter::setOutputPipeline(Pipeline* p) | @@ -576,7 +553,7 @@ QPDFWriter::setOutputPipeline(Pipeline* p) | ||
| 576 | void | 553 | void |
| 577 | QPDFWriter::setObjectStreamMode(qpdf_object_stream_e mode) | 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 | void | 559 | void |
| @@ -584,67 +561,67 @@ QPDFWriter::setStreamDataMode(qpdf_stream_data_e mode) | @@ -584,67 +561,67 @@ QPDFWriter::setStreamDataMode(qpdf_stream_data_e mode) | ||
| 584 | { | 561 | { |
| 585 | switch (mode) { | 562 | switch (mode) { |
| 586 | case qpdf_s_uncompress: | 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 | break; | 566 | break; |
| 590 | 567 | ||
| 591 | case qpdf_s_preserve: | 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 | break; | 571 | break; |
| 595 | 572 | ||
| 596 | case qpdf_s_compress: | 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 | break; | 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 | void | 582 | void |
| 606 | QPDFWriter::setCompressStreams(bool val) | 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 | void | 589 | void |
| 613 | QPDFWriter::setDecodeLevel(qpdf_stream_decode_level_e val) | 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 | void | 596 | void |
| 620 | QPDFWriter::setRecompressFlate(bool val) | 597 | QPDFWriter::setRecompressFlate(bool val) |
| 621 | { | 598 | { |
| 622 | - m->recompress_flate = val; | 599 | + m->cfg.recompress_flate_ = val; |
| 623 | } | 600 | } |
| 624 | 601 | ||
| 625 | void | 602 | void |
| 626 | QPDFWriter::setContentNormalization(bool val) | 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 | void | 609 | void |
| 633 | QPDFWriter::setQDFMode(bool val) | 610 | QPDFWriter::setQDFMode(bool val) |
| 634 | { | 611 | { |
| 635 | - m->qdf_mode = val; | 612 | + m->cfg.qdf_mode_ = val; |
| 636 | } | 613 | } |
| 637 | 614 | ||
| 638 | void | 615 | void |
| 639 | QPDFWriter::setPreserveUnreferencedObjects(bool val) | 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 | void | 621 | void |
| 645 | QPDFWriter::setNewlineBeforeEndstream(bool val) | 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 | void | 627 | void |
| @@ -700,16 +677,16 @@ QPDFWriter::setMinimumPDFVersion(PDFVersion const& v) | @@ -700,16 +677,16 @@ QPDFWriter::setMinimumPDFVersion(PDFVersion const& v) | ||
| 700 | void | 677 | void |
| 701 | QPDFWriter::forcePDFVersion(std::string const& version, int extension_level) | 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 | void | 684 | void |
| 708 | QPDFWriter::setExtraHeaderText(std::string const& text) | 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 | } else { | 690 | } else { |
| 714 | QTC::TC("qpdf", "QPDFWriter extra header text no newline"); | 691 | QTC::TC("qpdf", "QPDFWriter extra header text no newline"); |
| 715 | } | 692 | } |
| @@ -718,13 +695,13 @@ QPDFWriter::setExtraHeaderText(std::string const& text) | @@ -718,13 +695,13 @@ QPDFWriter::setExtraHeaderText(std::string const& text) | ||
| 718 | void | 695 | void |
| 719 | QPDFWriter::setStaticID(bool val) | 696 | QPDFWriter::setStaticID(bool val) |
| 720 | { | 697 | { |
| 721 | - m->static_id = val; | 698 | + m->cfg.static_id_ = val; |
| 722 | } | 699 | } |
| 723 | 700 | ||
| 724 | void | 701 | void |
| 725 | QPDFWriter::setDeterministicID(bool val) | 702 | QPDFWriter::setDeterministicID(bool val) |
| 726 | { | 703 | { |
| 727 | - m->deterministic_id = val; | 704 | + m->cfg.deterministic_id_ = val; |
| 728 | } | 705 | } |
| 729 | 706 | ||
| 730 | void | 707 | void |
| @@ -738,36 +715,36 @@ QPDFWriter::setStaticAesIV(bool val) | @@ -738,36 +715,36 @@ QPDFWriter::setStaticAesIV(bool val) | ||
| 738 | void | 715 | void |
| 739 | QPDFWriter::setSuppressOriginalObjectIDs(bool val) | 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 | void | 721 | void |
| 745 | QPDFWriter::setPreserveEncryption(bool val) | 722 | QPDFWriter::setPreserveEncryption(bool val) |
| 746 | { | 723 | { |
| 747 | - m->preserve_encryption = val; | 724 | + m->cfg.preserve_encryption_ = val; |
| 748 | } | 725 | } |
| 749 | 726 | ||
| 750 | void | 727 | void |
| 751 | QPDFWriter::setLinearization(bool val) | 728 | QPDFWriter::setLinearization(bool val) |
| 752 | { | 729 | { |
| 753 | - m->linearized = val; | 730 | + m->cfg.linearized_ = val; |
| 754 | if (val) { | 731 | if (val) { |
| 755 | - m->pclm = false; | 732 | + m->cfg.pclm_ = false; |
| 756 | } | 733 | } |
| 757 | } | 734 | } |
| 758 | 735 | ||
| 759 | void | 736 | void |
| 760 | QPDFWriter::setLinearizationPass1Filename(std::string const& filename) | 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 | void | 742 | void |
| 766 | QPDFWriter::setPCLm(bool val) | 743 | QPDFWriter::setPCLm(bool val) |
| 767 | { | 744 | { |
| 768 | - m->pclm = val; | 745 | + m->cfg.pclm_ = val; |
| 769 | if (val) { | 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,7 +813,7 @@ QPDFWriter::setR4EncryptionParametersInsecure( | ||
| 836 | bool use_aes) | 813 | bool use_aes) |
| 837 | { | 814 | { |
| 838 | m->encryption = std::make_unique<Encryption>(4, 4, 16, encrypt_metadata); | 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 | m->interpretR3EncryptionParameters( | 817 | m->interpretR3EncryptionParameters( |
| 841 | allow_accessibility, | 818 | allow_accessibility, |
| 842 | allow_extract, | 819 | allow_extract, |
| @@ -863,7 +840,7 @@ QPDFWriter::setR5EncryptionParameters( | @@ -863,7 +840,7 @@ QPDFWriter::setR5EncryptionParameters( | ||
| 863 | bool encrypt_metadata) | 840 | bool encrypt_metadata) |
| 864 | { | 841 | { |
| 865 | m->encryption = std::make_unique<Encryption>(5, 5, 32, encrypt_metadata); | 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 | m->interpretR3EncryptionParameters( | 844 | m->interpretR3EncryptionParameters( |
| 868 | allow_accessibility, | 845 | allow_accessibility, |
| 869 | allow_extract, | 846 | allow_extract, |
| @@ -899,7 +876,7 @@ QPDFWriter::setR6EncryptionParameters( | @@ -899,7 +876,7 @@ QPDFWriter::setR6EncryptionParameters( | ||
| 899 | allow_modify_other, | 876 | allow_modify_other, |
| 900 | print, | 877 | print, |
| 901 | qpdf_r3m_all); | 878 | qpdf_r3m_all); |
| 902 | - m->encrypt_use_aes = true; | 879 | + m->cfg.encrypt_use_aes_ = true; |
| 903 | m->setEncryptionParameters(user_password, owner_password); | 880 | m->setEncryptionParameters(user_password, owner_password); |
| 904 | } | 881 | } |
| 905 | 882 | ||
| @@ -1020,7 +997,7 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) | @@ -1020,7 +997,7 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) | ||
| 1020 | void | 997 | void |
| 1021 | QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) | 998 | QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) |
| 1022 | { | 999 | { |
| 1023 | - preserve_encryption = false; | 1000 | + cfg.preserve_encryption_ = false; |
| 1024 | QPDFObjectHandle trailer = qpdf.getTrailer(); | 1001 | QPDFObjectHandle trailer = qpdf.getTrailer(); |
| 1025 | if (trailer.hasKey("/Encrypt")) { | 1002 | if (trailer.hasKey("/Encrypt")) { |
| 1026 | generateID(true); | 1003 | generateID(true); |
| @@ -1040,10 +1017,10 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) | @@ -1040,10 +1017,10 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) | ||
| 1040 | // Acrobat doesn't create files with V >= 4 that don't use AES, and the logic of | 1017 | // Acrobat doesn't create files with V >= 4 that don't use AES, and the logic of |
| 1041 | // figuring out whether AES is used or not is complicated with /StmF, /StrF, and /EFF | 1018 | // figuring out whether AES is used or not is complicated with /StmF, /StrF, and /EFF |
| 1042 | // all potentially having different values. | 1019 | // all potentially having different values. |
| 1043 | - encrypt_use_aes = true; | 1020 | + cfg.encrypt_use_aes_ = true; |
| 1044 | } | 1021 | } |
| 1045 | QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", encrypt_metadata ? 0 : 1); | 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 | encryption = std::make_unique<Encryption>( | 1025 | encryption = std::make_unique<Encryption>( |
| 1049 | V, | 1026 | V, |
| @@ -1084,7 +1061,7 @@ QPDFWriter::Members::disableIncompatibleEncryption(int major, int minor, int ext | @@ -1084,7 +1061,7 @@ QPDFWriter::Members::disableIncompatibleEncryption(int major, int minor, int ext | ||
| 1084 | encryption = nullptr; | 1061 | encryption = nullptr; |
| 1085 | } | 1062 | } |
| 1086 | } else if (compareVersions(major, minor, 1, 6) < 0) { | 1063 | } else if (compareVersions(major, minor, 1, 6) < 0) { |
| 1087 | - if (encrypt_use_aes) { | 1064 | + if (cfg.encrypt_use_aes_) { |
| 1088 | encryption = nullptr; | 1065 | encryption = nullptr; |
| 1089 | } | 1066 | } |
| 1090 | } else if ( | 1067 | } else if ( |
| @@ -1141,7 +1118,7 @@ QPDFWriter::Members::setEncryptionMinimumVersion() | @@ -1141,7 +1118,7 @@ QPDFWriter::Members::setEncryptionMinimumVersion() | ||
| 1141 | } else if (R == 5) { | 1118 | } else if (R == 5) { |
| 1142 | w.setMinimumPDFVersion("1.7", 3); | 1119 | w.setMinimumPDFVersion("1.7", 3); |
| 1143 | } else if (R == 4) { | 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 | } else if (R == 3) { | 1122 | } else if (R == 3) { |
| 1146 | w.setMinimumPDFVersion("1.4"); | 1123 | w.setMinimumPDFVersion("1.4"); |
| 1147 | } else { | 1124 | } else { |
| @@ -1154,7 +1131,7 @@ QPDFWriter::Members::setDataKey(int objid) | @@ -1154,7 +1131,7 @@ QPDFWriter::Members::setDataKey(int objid) | ||
| 1154 | { | 1131 | { |
| 1155 | if (encryption) { | 1132 | if (encryption) { |
| 1156 | cur_data_key = QPDF::compute_data_key( | 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,7 +1199,7 @@ template <typename... Args> | ||
| 1222 | QPDFWriter::Members& | 1199 | QPDFWriter::Members& |
| 1223 | QPDFWriter::Members::write_qdf(Args&&... args) | 1200 | QPDFWriter::Members::write_qdf(Args&&... args) |
| 1224 | { | 1201 | { |
| 1225 | - if (qdf_mode) { | 1202 | + if (cfg.qdf_mode_) { |
| 1226 | pipeline->write(std::forward<Args>(args)...); | 1203 | pipeline->write(std::forward<Args>(args)...); |
| 1227 | } | 1204 | } |
| 1228 | return *this; | 1205 | return *this; |
| @@ -1232,7 +1209,7 @@ template <typename... Args> | @@ -1232,7 +1209,7 @@ template <typename... Args> | ||
| 1232 | QPDFWriter::Members& | 1209 | QPDFWriter::Members& |
| 1233 | QPDFWriter::Members::write_no_qdf(Args&&... args) | 1210 | QPDFWriter::Members::write_no_qdf(Args&&... args) |
| 1234 | { | 1211 | { |
| 1235 | - if (!qdf_mode) { | 1212 | + if (!cfg.qdf_mode_) { |
| 1236 | pipeline->write(std::forward<Args>(args)...); | 1213 | pipeline->write(std::forward<Args>(args)...); |
| 1237 | } | 1214 | } |
| 1238 | return *this; | 1215 | return *this; |
| @@ -1241,7 +1218,7 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) | @@ -1241,7 +1218,7 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) | ||
| 1241 | void | 1218 | void |
| 1242 | QPDFWriter::Members::adjustAESStreamLength(size_t& length) | 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 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will | 1222 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will |
| 1246 | // also be prepended by 16 bits of random data. | 1223 | // also be prepended by 16 bits of random data. |
| 1247 | length += 32 - (length & 0xf); | 1224 | length += 32 - (length & 0xf); |
| @@ -1253,7 +1230,7 @@ QPDFWriter::Members::write_encrypted(std::string_view str) | @@ -1253,7 +1230,7 @@ QPDFWriter::Members::write_encrypted(std::string_view str) | ||
| 1253 | { | 1230 | { |
| 1254 | if (!(encryption && !cur_data_key.empty())) { | 1231 | if (!(encryption && !cur_data_key.empty())) { |
| 1255 | write(str); | 1232 | write(str); |
| 1256 | - } else if (encrypt_use_aes) { | 1233 | + } else if (cfg.encrypt_use_aes_) { |
| 1257 | write(pl::pipe<Pl_AES_PDF>(str, true, cur_data_key)); | 1234 | write(pl::pipe<Pl_AES_PDF>(str, true, cur_data_key)); |
| 1258 | } else { | 1235 | } else { |
| 1259 | write(pl::pipe<Pl_RC4>(str, cur_data_key)); | 1236 | write(pl::pipe<Pl_RC4>(str, cur_data_key)); |
| @@ -1324,7 +1301,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | @@ -1324,7 +1301,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | ||
| 1324 | "Use QPDF::copyForeignObject to add objects from another file." // | 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 | // As a special case, do not output any extraneous XRef streams in QDF mode. Doing so | 1305 | // As a special case, do not output any extraneous XRef streams in QDF mode. Doing so |
| 1329 | // will confuse fix-qdf, which expects to see only one XRef stream at the end of the | 1306 | // will confuse fix-qdf, which expects to see only one XRef stream at the end of the |
| 1330 | // file. This case can occur when creating a QDF from a file with object streams when | 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,10 +1327,10 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | ||
| 1350 | if (og.getGen() == 0 && object_stream_to_objects.contains(og.getObj())) { | 1327 | if (og.getGen() == 0 && object_stream_to_objects.contains(og.getObj())) { |
| 1351 | // For linearized files, uncompressed objects go at end, and we take care of | 1328 | // For linearized files, uncompressed objects go at end, and we take care of |
| 1352 | // assigning numbers to them elsewhere. | 1329 | // assigning numbers to them elsewhere. |
| 1353 | - if (!linearized) { | 1330 | + if (!cfg.linearized_) { |
| 1354 | assignCompressedObjectNumbers(og); | 1331 | assignCompressedObjectNumbers(og); |
| 1355 | } | 1332 | } |
| 1356 | - } else if (!direct_stream_lengths && object.isStream()) { | 1333 | + } else if (!cfg.direct_stream_lengths_ && object.isStream()) { |
| 1357 | // reserve next object ID for length | 1334 | // reserve next object ID for length |
| 1358 | ++next_objid; | 1335 | ++next_objid; |
| 1359 | } | 1336 | } |
| @@ -1362,7 +1339,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | @@ -1362,7 +1339,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | ||
| 1362 | return; | 1339 | return; |
| 1363 | } | 1340 | } |
| 1364 | 1341 | ||
| 1365 | - if (linearized) { | 1342 | + if (cfg.linearized_) { |
| 1366 | return; | 1343 | return; |
| 1367 | } | 1344 | } |
| 1368 | 1345 | ||
| @@ -1383,7 +1360,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | @@ -1383,7 +1360,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | ||
| 1383 | void | 1360 | void |
| 1384 | QPDFWriter::Members::unparseChild(QPDFObjectHandle const& child, size_t level, int flags) | 1361 | QPDFWriter::Members::unparseChild(QPDFObjectHandle const& child, size_t level, int flags) |
| 1385 | { | 1362 | { |
| 1386 | - if (!linearized) { | 1363 | + if (!cfg.linearized_) { |
| 1387 | enqueue(child); | 1364 | enqueue(child); |
| 1388 | } | 1365 | } |
| 1389 | if (child.indirect()) { | 1366 | if (child.indirect()) { |
| @@ -1442,7 +1419,7 @@ QPDFWriter::Members::writeTrailer( | @@ -1442,7 +1419,7 @@ QPDFWriter::Members::writeTrailer( | ||
| 1442 | } | 1419 | } |
| 1443 | write("<00000000000000000000000000000000>"); | 1420 | write("<00000000000000000000000000000000>"); |
| 1444 | } else { | 1421 | } else { |
| 1445 | - if (linearization_pass == 0 && deterministic_id) { | 1422 | + if (linearization_pass == 0 && cfg.deterministic_id_) { |
| 1446 | computeDeterministicIDData(); | 1423 | computeDeterministicIDData(); |
| 1447 | } | 1424 | } |
| 1448 | generateID(encryption.get()); | 1425 | generateID(encryption.get()); |
| @@ -1473,19 +1450,19 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st | @@ -1473,19 +1450,19 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st | ||
| 1473 | { | 1450 | { |
| 1474 | const bool is_root_metadata = stream.isRootMetadata(); | 1451 | const bool is_root_metadata = stream.isRootMetadata(); |
| 1475 | bool filter = false; | 1452 | bool filter = false; |
| 1476 | - auto decode_level = stream_decode_level; | 1453 | + auto decode_level = cfg.stream_decode_level_; |
| 1477 | int encode_flags = 0; | 1454 | int encode_flags = 0; |
| 1478 | Dictionary stream_dict = stream.getDict(); | 1455 | Dictionary stream_dict = stream.getDict(); |
| 1479 | 1456 | ||
| 1480 | if (stream.getFilterOnWrite()) { | 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 | // Don't filter if the stream is already compressed with FlateDecode. This way we don't | 1460 | // Don't filter if the stream is already compressed with FlateDecode. This way we don't |
| 1484 | // make it worse if the original file used a better Flate algorithm, and we don't spend | 1461 | // make it worse if the original file used a better Flate algorithm, and we don't spend |
| 1485 | // time and CPU cycles uncompressing and recompressing stuff. This can be overridden | 1462 | // time and CPU cycles uncompressing and recompressing stuff. This can be overridden |
| 1486 | // with setRecompressFlate(true). | 1463 | // with setRecompressFlate(true). |
| 1487 | Name Filter = stream_dict["/Filter"]; | 1464 | Name Filter = stream_dict["/Filter"]; |
| 1488 | - if (Filter && !recompress_flate && !stream.isDataModified() && | 1465 | + if (Filter && !cfg.recompress_flate_ && !stream.isDataModified() && |
| 1489 | (Filter == "/FlateDecode" || Filter == "/Fl")) { | 1466 | (Filter == "/FlateDecode" || Filter == "/Fl")) { |
| 1490 | filter = false; | 1467 | filter = false; |
| 1491 | } | 1468 | } |
| @@ -1493,10 +1470,10 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st | @@ -1493,10 +1470,10 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st | ||
| 1493 | if (is_root_metadata && (!encryption || !encryption->getEncryptMetadata())) { | 1470 | if (is_root_metadata && (!encryption || !encryption->getEncryptMetadata())) { |
| 1494 | filter = true; | 1471 | filter = true; |
| 1495 | decode_level = qpdf_dl_all; | 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 | encode_flags = qpdf_ef_normalize; | 1474 | encode_flags = qpdf_ef_normalize; |
| 1498 | filter = true; | 1475 | filter = true; |
| 1499 | - } else if (filter && compress_streams) { | 1476 | + } else if (filter && cfg.compress_streams_) { |
| 1500 | encode_flags = qpdf_ef_compress; | 1477 | encode_flags = qpdf_ef_compress; |
| 1501 | } | 1478 | } |
| 1502 | } | 1479 | } |
| @@ -1550,11 +1527,11 @@ QPDFWriter::Members::unparseObject( | @@ -1550,11 +1527,11 @@ QPDFWriter::Members::unparseObject( | ||
| 1550 | // For non-qdf, "indent" and "indent_large" are a single space between tokens. For qdf, they | 1527 | // For non-qdf, "indent" and "indent_large" are a single space between tokens. For qdf, they |
| 1551 | // include the preceding newline. | 1528 | // include the preceding newline. |
| 1552 | std::string indent_large = " "; | 1529 | std::string indent_large = " "; |
| 1553 | - if (qdf_mode) { | 1530 | + if (cfg.qdf_mode_) { |
| 1554 | indent_large.append(2 * (level + 1), ' '); | 1531 | indent_large.append(2 * (level + 1), ' '); |
| 1555 | indent_large[0] = '\n'; | 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 | if (auto const tc = object.getTypeCode(); tc == ::ot_array) { | 1536 | if (auto const tc = object.getTypeCode(); tc == ::ot_array) { |
| 1560 | // Note: PDF spec 1.4 implementation note 121 states that Acrobat requires a space after the | 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,7 +1587,7 @@ QPDFWriter::Members::unparseObject( | ||
| 1610 | if (need_extensions_adbe) { | 1587 | if (need_extensions_adbe) { |
| 1611 | if (!(have_extensions_other || have_extensions_adbe)) { | 1588 | if (!(have_extensions_other || have_extensions_adbe)) { |
| 1612 | // We need Extensions and don't have it. Create it here. | 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 | extensions = object.replaceKeyAndGetNew( | 1591 | extensions = object.replaceKeyAndGetNew( |
| 1615 | "/Extensions", QPDFObjectHandle::newDictionary()); | 1592 | "/Extensions", QPDFObjectHandle::newDictionary()); |
| 1616 | } | 1593 | } |
| @@ -1715,7 +1692,7 @@ QPDFWriter::Members::unparseObject( | @@ -1715,7 +1692,7 @@ QPDFWriter::Members::unparseObject( | ||
| 1715 | if (flags & f_stream) { | 1692 | if (flags & f_stream) { |
| 1716 | write(indent_large).write("/Length "); | 1693 | write(indent_large).write("/Length "); |
| 1717 | 1694 | ||
| 1718 | - if (direct_stream_lengths) { | 1695 | + if (cfg.direct_stream_lengths_) { |
| 1719 | write(stream_length); | 1696 | write(stream_length); |
| 1720 | } else { | 1697 | } else { |
| 1721 | write(cur_stream_length_id).write(" 0 R"); | 1698 | write(cur_stream_length_id).write(" 0 R"); |
| @@ -1728,7 +1705,7 @@ QPDFWriter::Members::unparseObject( | @@ -1728,7 +1705,7 @@ QPDFWriter::Members::unparseObject( | ||
| 1728 | write(indent).write(">>"); | 1705 | write(indent).write(">>"); |
| 1729 | } else if (tc == ::ot_stream) { | 1706 | } else if (tc == ::ot_stream) { |
| 1730 | // Write stream data to a buffer. | 1707 | // Write stream data to a buffer. |
| 1731 | - if (!direct_stream_lengths) { | 1708 | + if (!cfg.direct_stream_lengths_) { |
| 1732 | cur_stream_length_id = obj[old_og].renumber + 1; | 1709 | cur_stream_length_id = obj[old_og].renumber + 1; |
| 1733 | } | 1710 | } |
| 1734 | 1711 | ||
| @@ -1749,14 +1726,14 @@ QPDFWriter::Members::unparseObject( | @@ -1749,14 +1726,14 @@ QPDFWriter::Members::unparseObject( | ||
| 1749 | unparseObject(stream_dict, 0, flags, cur_stream_length, compress_stream); | 1726 | unparseObject(stream_dict, 0, flags, cur_stream_length, compress_stream); |
| 1750 | char last_char = stream_data.empty() ? '\0' : stream_data.back(); | 1727 | char last_char = stream_data.empty() ? '\0' : stream_data.back(); |
| 1751 | write("\nstream\n").write_encrypted(stream_data); | 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 | write(added_newline ? "\nendstream" : "endstream"); | 1730 | write(added_newline ? "\nendstream" : "endstream"); |
| 1754 | } else if (tc == ::ot_string) { | 1731 | } else if (tc == ::ot_string) { |
| 1755 | std::string val; | 1732 | std::string val; |
| 1756 | if (encryption && !(flags & f_in_ostream) && !(flags & f_no_encryption) && | 1733 | if (encryption && !(flags & f_in_ostream) && !(flags & f_no_encryption) && |
| 1757 | !cur_data_key.empty()) { | 1734 | !cur_data_key.empty()) { |
| 1758 | val = object.getStringValue(); | 1735 | val = object.getStringValue(); |
| 1759 | - if (encrypt_use_aes) { | 1736 | + if (cfg.encrypt_use_aes_) { |
| 1760 | Pl_Buffer bufpl("encrypted string"); | 1737 | Pl_Buffer bufpl("encrypted string"); |
| 1761 | Pl_AES_PDF pl("aes encrypt string", &bufpl, true, cur_data_key); | 1738 | Pl_AES_PDF pl("aes encrypt string", &bufpl, true, cur_data_key); |
| 1762 | pl.writeString(val); | 1739 | pl.writeString(val); |
| @@ -1822,7 +1799,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | @@ -1822,7 +1799,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | ||
| 1822 | std::string stream_buffer_pass1; | 1799 | std::string stream_buffer_pass1; |
| 1823 | std::string stream_buffer_pass2; | 1800 | std::string stream_buffer_pass2; |
| 1824 | int first_obj = -1; | 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 | // Pass 1 | 1804 | // Pass 1 |
| 1828 | auto pp_ostream_pass1 = pipeline_stack.activate(stream_buffer_pass1); | 1805 | auto pp_ostream_pass1 = pipeline_stack.activate(stream_buffer_pass1); |
| @@ -1834,9 +1811,9 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | @@ -1834,9 +1811,9 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | ||
| 1834 | if (first_obj == -1) { | 1811 | if (first_obj == -1) { |
| 1835 | first_obj = new_o; | 1812 | first_obj = new_o; |
| 1836 | } | 1813 | } |
| 1837 | - if (qdf_mode) { | 1814 | + if (cfg.qdf_mode_) { |
| 1838 | write("%% Object stream: object ").write(new_o).write(", index ").write(count); | 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 | write("; original object ID: ").write(og.getObj()); | 1817 | write("; original object ID: ").write(og.getObj()); |
| 1841 | // For compatibility, only write the generation if non-zero. While object | 1818 | // For compatibility, only write the generation if non-zero. While object |
| 1842 | // streams only allow objects with generation 0, if we are generating object | 1819 | // streams only allow objects with generation 0, if we are generating object |
| @@ -1915,7 +1892,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | @@ -1915,7 +1892,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | ||
| 1915 | if (encryption) { | 1892 | if (encryption) { |
| 1916 | QTC::TC("qpdf", "QPDFWriter encrypt object stream"); | 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 | cur_data_key.clear(); | 1896 | cur_data_key.clear(); |
| 1920 | closeObject(new_stream_id); | 1897 | closeObject(new_stream_id); |
| 1921 | } | 1898 | } |
| @@ -1933,7 +1910,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | @@ -1933,7 +1910,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | ||
| 1933 | 1910 | ||
| 1934 | indicateProgress(false, false); | 1911 | indicateProgress(false, false); |
| 1935 | auto new_id = obj[old_og].renumber; | 1912 | auto new_id = obj[old_og].renumber; |
| 1936 | - if (qdf_mode) { | 1913 | + if (cfg.qdf_mode_) { |
| 1937 | if (page_object_to_seq.contains(old_og)) { | 1914 | if (page_object_to_seq.contains(old_og)) { |
| 1938 | write("%% Page ").write(page_object_to_seq[old_og]).write("\n"); | 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,7 +1919,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | ||
| 1942 | } | 1919 | } |
| 1943 | } | 1920 | } |
| 1944 | if (object_stream_index == -1) { | 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 | write("%% Original object ID: ").write(object.getObjGen().unparse(' ')).write("\n"); | 1923 | write("%% Original object ID: ").write(object.getObjGen().unparse(' ')).write("\n"); |
| 1947 | } | 1924 | } |
| 1948 | openObject(new_id); | 1925 | openObject(new_id); |
| @@ -1955,8 +1932,8 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | @@ -1955,8 +1932,8 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | ||
| 1955 | write("\n"); | 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 | if (added_newline) { | 1937 | if (added_newline) { |
| 1961 | write("%QDF: ignore_newline\n"); | 1938 | write("%QDF: ignore_newline\n"); |
| 1962 | } | 1939 | } |
| @@ -1992,7 +1969,7 @@ QPDFWriter::Members::generateID(bool encrypted) | @@ -1992,7 +1969,7 @@ QPDFWriter::Members::generateID(bool encrypted) | ||
| 1992 | 1969 | ||
| 1993 | std::string result; | 1970 | std::string result; |
| 1994 | 1971 | ||
| 1995 | - if (static_id) { | 1972 | + if (cfg.static_id_) { |
| 1996 | // For test suite use only... | 1973 | // For test suite use only... |
| 1997 | static unsigned char tmp[] = { | 1974 | static unsigned char tmp[] = { |
| 1998 | 0x31, | 1975 | 0x31, |
| @@ -2024,7 +2001,7 @@ QPDFWriter::Members::generateID(bool encrypted) | @@ -2024,7 +2001,7 @@ QPDFWriter::Members::generateID(bool encrypted) | ||
| 2024 | // that case, would have the same ID regardless of the output file's name. | 2001 | // that case, would have the same ID regardless of the output file's name. |
| 2025 | 2002 | ||
| 2026 | std::string seed; | 2003 | std::string seed; |
| 2027 | - if (deterministic_id) { | 2004 | + if (cfg.deterministic_id_) { |
| 2028 | if (encrypted) { | 2005 | if (encrypted) { |
| 2029 | throw std::runtime_error( | 2006 | throw std::runtime_error( |
| 2030 | "QPDFWriter: unable to generated a deterministic ID because the file to be " | 2007 | "QPDFWriter: unable to generated a deterministic ID because the file to be " |
| @@ -2106,7 +2083,7 @@ QPDFWriter::Members::preserveObjectStreams() | @@ -2106,7 +2083,7 @@ QPDFWriter::Members::preserveObjectStreams() | ||
| 2106 | // objects from being included. | 2083 | // objects from being included. |
| 2107 | auto end = xref.cend(); | 2084 | auto end = xref.cend(); |
| 2108 | obj.streams_empty = true; | 2085 | obj.streams_empty = true; |
| 2109 | - if (preserve_unreferenced_objects) { | 2086 | + if (cfg.preserve_unreferenced_objects_) { |
| 2110 | for (auto iter = xref.cbegin(); iter != end; ++iter) { | 2087 | for (auto iter = xref.cbegin(); iter != end; ++iter) { |
| 2111 | if (iter->second.getType() == 2) { | 2088 | if (iter->second.getType() == 2) { |
| 2112 | // Pdf contains object streams. | 2089 | // Pdf contains object streams. |
| @@ -2248,63 +2225,63 @@ QPDFWriter::Members::doWriteSetup() | @@ -2248,63 +2225,63 @@ QPDFWriter::Members::doWriteSetup() | ||
| 2248 | 2225 | ||
| 2249 | // Do preliminary setup | 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 | encryption = nullptr; | 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 | if (encryption) { | 2250 | if (encryption) { |
| 2274 | // Encryption has been explicitly set | 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 | // Encryption makes looking at contents pretty useless. If the user explicitly encrypted | 2254 | // Encryption makes looking at contents pretty useless. If the user explicitly encrypted |
| 2278 | // though, we still obey that. | 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 | copyEncryptionParameters(qpdf); | 2260 | copyEncryptionParameters(qpdf); |
| 2284 | } | 2261 | } |
| 2285 | 2262 | ||
| 2286 | - if (!forced_pdf_version.empty()) { | 2263 | + if (!cfg.forced_pdf_version_.empty()) { |
| 2287 | int major = 0; | 2264 | int major = 0; |
| 2288 | int minor = 0; | 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 | if (compareVersions(major, minor, 1, 5) < 0) { | 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 | initializeSpecialStreams(); | 2274 | initializeSpecialStreams(); |
| 2298 | } | 2275 | } |
| 2299 | 2276 | ||
| 2300 | - if (qdf_mode) { | 2277 | + if (cfg.qdf_mode_) { |
| 2301 | // Generate indirect stream lengths for qdf mode since fix-qdf uses them for storing | 2278 | // Generate indirect stream lengths for qdf mode since fix-qdf uses them for storing |
| 2302 | // recomputed stream length data. Certain streams such as object streams, xref streams, and | 2279 | // recomputed stream length data. Certain streams such as object streams, xref streams, and |
| 2303 | // hint streams always get direct stream lengths. | 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 | case qpdf_o_disable: | 2285 | case qpdf_o_disable: |
| 2309 | initializeTables(); | 2286 | initializeTables(); |
| 2310 | obj.streams_empty = true; | 2287 | obj.streams_empty = true; |
| @@ -2323,7 +2300,7 @@ QPDFWriter::Members::doWriteSetup() | @@ -2323,7 +2300,7 @@ QPDFWriter::Members::doWriteSetup() | ||
| 2323 | } | 2300 | } |
| 2324 | 2301 | ||
| 2325 | if (!obj.streams_empty) { | 2302 | if (!obj.streams_empty) { |
| 2326 | - if (linearized) { | 2303 | + if (cfg.linearized_) { |
| 2327 | // Page dictionaries are not allowed to be compressed objects. | 2304 | // Page dictionaries are not allowed to be compressed objects. |
| 2328 | for (auto& page: pages) { | 2305 | for (auto& page: pages) { |
| 2329 | if (obj[page].object_stream > 0) { | 2306 | if (obj[page].object_stream > 0) { |
| @@ -2332,9 +2309,9 @@ QPDFWriter::Members::doWriteSetup() | @@ -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 | // handle encrypted files with compressed document catalogs, so we disable them in that | 2315 | // handle encrypted files with compressed document catalogs, so we disable them in that |
| 2339 | // case as well. | 2316 | // case as well. |
| 2340 | if (obj[root_og].object_stream > 0) { | 2317 | if (obj[root_og].object_stream > 0) { |
| @@ -2364,9 +2341,9 @@ QPDFWriter::Members::doWriteSetup() | @@ -2364,9 +2341,9 @@ QPDFWriter::Members::doWriteSetup() | ||
| 2364 | setMinimumPDFVersion(qpdf.getPDFVersion(), qpdf.getExtensionLevel()); | 2341 | setMinimumPDFVersion(qpdf.getPDFVersion(), qpdf.getExtensionLevel()); |
| 2365 | final_pdf_version = min_pdf_version; | 2342 | final_pdf_version = min_pdf_version; |
| 2366 | final_extension_level = min_extension_level; | 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,11 +2360,11 @@ QPDFWriter::Members::write() | ||
| 2383 | 2360 | ||
| 2384 | // Set up progress reporting. For linearized files, we write two passes. events_expected is an | 2361 | // Set up progress reporting. For linearized files, we write two passes. events_expected is an |
| 2385 | // approximation, but it's good enough for progress reporting, which is mostly a guess anyway. | 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 | prepareFileForWrite(); | 2365 | prepareFileForWrite(); |
| 2389 | 2366 | ||
| 2390 | - if (linearized) { | 2367 | + if (cfg.linearized_) { |
| 2391 | writeLinearized(); | 2368 | writeLinearized(); |
| 2392 | } else { | 2369 | } else { |
| 2393 | writeStandard(); | 2370 | writeStandard(); |
| @@ -2449,10 +2426,10 @@ QPDFWriter::Members::writeEncryptionDictionary() | @@ -2449,10 +2426,10 @@ QPDFWriter::Members::writeEncryptionDictionary() | ||
| 2449 | write("<<"); | 2426 | write("<<"); |
| 2450 | if (V >= 4) { | 2427 | if (V >= 4) { |
| 2451 | write(" /CF << /StdCF << /AuthEvent /DocOpen /CFM "); | 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 | // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of | 2430 | // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of |
| 2454 | // MacOS won't open encrypted files without it. | 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 | if (!encryption->getEncryptMetadata()) { | 2433 | if (!encryption->getEncryptMetadata()) { |
| 2457 | write(" /EncryptMetadata false"); | 2434 | write(" /EncryptMetadata false"); |
| 2458 | } | 2435 | } |
| @@ -2490,7 +2467,7 @@ void | @@ -2490,7 +2467,7 @@ void | ||
| 2490 | QPDFWriter::Members::writeHeader() | 2467 | QPDFWriter::Members::writeHeader() |
| 2491 | { | 2468 | { |
| 2492 | write("%PDF-").write(final_pdf_version); | 2469 | write("%PDF-").write(final_pdf_version); |
| 2493 | - if (pclm) { | 2470 | + if (cfg.pclm_) { |
| 2494 | // PCLm version | 2471 | // PCLm version |
| 2495 | write("\n%PCLm 1.0\n"); | 2472 | write("\n%PCLm 1.0\n"); |
| 2496 | } else { | 2473 | } else { |
| @@ -2512,7 +2489,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | @@ -2512,7 +2489,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | ||
| 2512 | std::string hint_buffer; | 2489 | std::string hint_buffer; |
| 2513 | int S = 0; | 2490 | int S = 0; |
| 2514 | int O = 0; | 2491 | int O = 0; |
| 2515 | - bool compressed = compress_streams; | 2492 | + bool compressed = cfg.compress_streams_; |
| 2516 | lin.generateHintStream(new_obj, obj, hint_buffer, S, O, compressed); | 2493 | lin.generateHintStream(new_obj, obj, hint_buffer, S, O, compressed); |
| 2517 | 2494 | ||
| 2518 | openObject(hint_id); | 2495 | openObject(hint_id); |
| @@ -2625,7 +2602,7 @@ QPDFWriter::Members::writeXRefStream( | @@ -2625,7 +2602,7 @@ QPDFWriter::Members::writeXRefStream( | ||
| 2625 | new_obj[xref_id].xref = QPDFXRefEntry(pipeline->getCount()); | 2602 | new_obj[xref_id].xref = QPDFXRefEntry(pipeline->getCount()); |
| 2626 | 2603 | ||
| 2627 | std::string xref_data; | 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 | auto pp_xref = pipeline_stack.activate(xref_data); | 2607 | auto pp_xref = pipeline_stack.activate(xref_data); |
| 2631 | 2608 | ||
| @@ -2815,7 +2792,7 @@ QPDFWriter::Members::writeLinearized() | @@ -2815,7 +2792,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 2815 | enqueuePart(part8); | 2792 | enqueuePart(part8); |
| 2816 | enqueuePart(part9); | 2793 | enqueuePart(part9); |
| 2817 | if (next_objid != after_second_half) { | 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 | qpdf_offset_t hint_length = 0; | 2798 | qpdf_offset_t hint_length = 0; |
| @@ -2828,15 +2805,15 @@ QPDFWriter::Members::writeLinearized() | @@ -2828,15 +2805,15 @@ QPDFWriter::Members::writeLinearized() | ||
| 2828 | auto pp_md5 = pipeline_stack.popper(); | 2805 | auto pp_md5 = pipeline_stack.popper(); |
| 2829 | for (int pass: {1, 2}) { | 2806 | for (int pass: {1, 2}) { |
| 2830 | if (pass == 1) { | 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 | pipeline_stack.activate( | 2810 | pipeline_stack.activate( |
| 2834 | pp_pass1, | 2811 | pp_pass1, |
| 2835 | std::make_unique<Pl_StdioFile>("linearization pass1", lin_pass1_file)); | 2812 | std::make_unique<Pl_StdioFile>("linearization pass1", lin_pass1_file)); |
| 2836 | } else { | 2813 | } else { |
| 2837 | pipeline_stack.activate(pp_pass1, true); | 2814 | pipeline_stack.activate(pp_pass1, true); |
| 2838 | } | 2815 | } |
| 2839 | - if (deterministic_id) { | 2816 | + if (cfg.deterministic_id_) { |
| 2840 | pipeline_stack.activate_md5(pp_md5); | 2817 | pipeline_stack.activate_md5(pp_md5); |
| 2841 | } | 2818 | } |
| 2842 | } | 2819 | } |
| @@ -2871,7 +2848,7 @@ QPDFWriter::Members::writeLinearized() | @@ -2871,7 +2848,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 2871 | 2848 | ||
| 2872 | // If the user supplied any additional header text, write it here after the linearization | 2849 | // If the user supplied any additional header text, write it here after the linearization |
| 2873 | // parameter dictionary. | 2850 | // parameter dictionary. |
| 2874 | - write(extra_header_text); | 2851 | + write(cfg.extra_header_text_); |
| 2875 | 2852 | ||
| 2876 | // Part 3: first page cross reference table and trailer. | 2853 | // Part 3: first page cross reference table and trailer. |
| 2877 | 2854 | ||
| @@ -3006,7 +2983,7 @@ QPDFWriter::Members::writeLinearized() | @@ -3006,7 +2983,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 3006 | write("startxref\n").write(first_xref_offset).write("\n%%EOF\n"); | 2983 | write("startxref\n").write(first_xref_offset).write("\n%%EOF\n"); |
| 3007 | 2984 | ||
| 3008 | if (pass == 1) { | 2985 | if (pass == 1) { |
| 3009 | - if (deterministic_id) { | 2986 | + if (cfg.deterministic_id_) { |
| 3010 | QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1); | 2987 | QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1); |
| 3011 | computeDeterministicIDData(); | 2988 | computeDeterministicIDData(); |
| 3012 | pp_md5.pop(); | 2989 | pp_md5.pop(); |
| @@ -3051,7 +3028,7 @@ QPDFWriter::Members::writeLinearized() | @@ -3051,7 +3028,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 3051 | void | 3028 | void |
| 3052 | QPDFWriter::Members::enqueueObjectsStandard() | 3029 | QPDFWriter::Members::enqueueObjectsStandard() |
| 3053 | { | 3030 | { |
| 3054 | - if (preserve_unreferenced_objects) { | 3031 | + if (cfg.preserve_unreferenced_objects_) { |
| 3055 | for (auto const& oh: qpdf.getAllObjects()) { | 3032 | for (auto const& oh: qpdf.getAllObjects()) { |
| 3056 | enqueue(oh); | 3033 | enqueue(oh); |
| 3057 | } | 3034 | } |
| @@ -3132,16 +3109,16 @@ void | @@ -3132,16 +3109,16 @@ void | ||
| 3132 | QPDFWriter::Members::writeStandard() | 3109 | QPDFWriter::Members::writeStandard() |
| 3133 | { | 3110 | { |
| 3134 | auto pp_md5 = pipeline_stack.popper(); | 3111 | auto pp_md5 = pipeline_stack.popper(); |
| 3135 | - if (deterministic_id) { | 3112 | + if (cfg.deterministic_id_) { |
| 3136 | pipeline_stack.activate_md5(pp_md5); | 3113 | pipeline_stack.activate_md5(pp_md5); |
| 3137 | } | 3114 | } |
| 3138 | 3115 | ||
| 3139 | // Start writing | 3116 | // Start writing |
| 3140 | 3117 | ||
| 3141 | writeHeader(); | 3118 | writeHeader(); |
| 3142 | - write(extra_header_text); | 3119 | + write(cfg.extra_header_text_); |
| 3143 | 3120 | ||
| 3144 | - if (pclm) { | 3121 | + if (cfg.pclm_) { |
| 3145 | enqueueObjectsPCLm(); | 3122 | enqueueObjectsPCLm(); |
| 3146 | } else { | 3123 | } else { |
| 3147 | enqueueObjectsStandard(); | 3124 | enqueueObjectsStandard(); |
| @@ -3171,7 +3148,7 @@ QPDFWriter::Members::writeStandard() | @@ -3171,7 +3148,7 @@ QPDFWriter::Members::writeStandard() | ||
| 3171 | } | 3148 | } |
| 3172 | write("startxref\n").write(xref_offset).write("\n%%EOF\n"); | 3149 | write("startxref\n").write(xref_offset).write("\n%%EOF\n"); |
| 3173 | 3150 | ||
| 3174 | - if (deterministic_id) { | 3151 | + if (cfg.deterministic_id_) { |
| 3175 | QTC::TC( | 3152 | QTC::TC( |
| 3176 | "qpdf", | 3153 | "qpdf", |
| 3177 | "QPDFWriter standard deterministic ID", | 3154 | "QPDFWriter standard deterministic ID", |
libqpdf/qpdf/QPDFWriter_private.hh
| @@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
| 5 | 5 | ||
| 6 | #include <qpdf/ObjTable.hh> | 6 | #include <qpdf/ObjTable.hh> |
| 7 | #include <qpdf/Pipeline_private.hh> | 7 | #include <qpdf/Pipeline_private.hh> |
| 8 | +#include <qpdf/QPDF.hh> | ||
| 8 | 9 | ||
| 9 | // This file is intended for inclusion by QPDFWriter, QPDF, QPDF_optimization and QPDF_linearization | 10 | // This file is intended for inclusion by QPDFWriter, QPDF, QPDF_optimization and QPDF_linearization |
| 10 | // only. | 11 | // only. |
| @@ -43,4 +44,50 @@ class QPDFWriter::NewObjTable: public ::ObjTable<QPDFWriter::NewObject> | @@ -43,4 +44,50 @@ class QPDFWriter::NewObjTable: public ::ObjTable<QPDFWriter::NewObject> | ||
| 43 | friend class QPDFWriter; | 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 | #endif // QPDFWRITER_PRIVATE_HH | 93 | #endif // QPDFWRITER_PRIVATE_HH |