Commit f52b984892bc4908ce14c4aa7ed881991cc38cf3
1 parent
ff09d994
Refactor `QPDFWriter`: move methods `setDataKey`, `indicateProgress`, `adjustAES…
…StreamLength`, `computeDeterministicIDData`, and `calculateXrefStreamPadding` to `QPDFWriter::Members`. Update related logic and remove obsolete declarations.
Showing
2 changed files
with
42 additions
and
50 deletions
include/qpdf/QPDFWriter.hh
| ... | ... | @@ -469,16 +469,6 @@ class QPDFWriter |
| 469 | 469 | qpdf_r3_modify_e modify); |
| 470 | 470 | void setEncryptionParameters(char const* user_password, char const* owner_password); |
| 471 | 471 | void setEncryptionMinimumVersion(); |
| 472 | - void setDataKey(int objid); | |
| 473 | - void indicateProgress(bool decrement, bool finished); | |
| 474 | - size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes); | |
| 475 | - | |
| 476 | - // When filtering subsections, push additional pipelines to the stack. When ready to switch, | |
| 477 | - // activate the pipeline stack. When the passed in PipelinePopper goes out of scope, the stack | |
| 478 | - // is popped. | |
| 479 | - | |
| 480 | - void adjustAESStreamLength(size_t& length); | |
| 481 | - void computeDeterministicIDData(); | |
| 482 | 472 | |
| 483 | 473 | class Members; |
| 484 | 474 | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -380,6 +380,13 @@ class QPDFWriter::Members |
| 380 | 380 | bool skip_compression, |
| 381 | 381 | int linearization_pass); |
| 382 | 382 | |
| 383 | + void setDataKey(int objid); | |
| 384 | + void indicateProgress(bool decrement, bool finished); | |
| 385 | + size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes); | |
| 386 | + | |
| 387 | + void adjustAESStreamLength(size_t& length); | |
| 388 | + void computeDeterministicIDData(); | |
| 389 | + | |
| 383 | 390 | private: |
| 384 | 391 | QPDFWriter& w; |
| 385 | 392 | QPDF& pdf; |
| ... | ... | @@ -1102,16 +1109,11 @@ QPDFWriter::setEncryptionMinimumVersion() |
| 1102 | 1109 | } |
| 1103 | 1110 | |
| 1104 | 1111 | void |
| 1105 | -QPDFWriter::setDataKey(int objid) | |
| 1112 | +QPDFWriter::Members::setDataKey(int objid) | |
| 1106 | 1113 | { |
| 1107 | - if (m->encryption) { | |
| 1108 | - m->cur_data_key = QPDF::compute_data_key( | |
| 1109 | - m->encryption_key, | |
| 1110 | - objid, | |
| 1111 | - 0, | |
| 1112 | - m->encrypt_use_aes, | |
| 1113 | - m->encryption->getV(), | |
| 1114 | - m->encryption->getR()); | |
| 1114 | + if (encryption) { | |
| 1115 | + cur_data_key = QPDF::compute_data_key( | |
| 1116 | + encryption_key, objid, 0, encrypt_use_aes, encryption->getV(), encryption->getR()); | |
| 1115 | 1117 | } |
| 1116 | 1118 | } |
| 1117 | 1119 | |
| ... | ... | @@ -1196,9 +1198,9 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) |
| 1196 | 1198 | } |
| 1197 | 1199 | |
| 1198 | 1200 | void |
| 1199 | -QPDFWriter::adjustAESStreamLength(size_t& length) | |
| 1201 | +QPDFWriter::Members::adjustAESStreamLength(size_t& length) | |
| 1200 | 1202 | { |
| 1201 | - if (m->encryption && !m->cur_data_key.empty() && m->encrypt_use_aes) { | |
| 1203 | + if (encryption && !cur_data_key.empty() && encrypt_use_aes) { | |
| 1202 | 1204 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will |
| 1203 | 1205 | // also be prepended by 16 bits of random data. |
| 1204 | 1206 | length += 32 - (length & 0xf); |
| ... | ... | @@ -1220,15 +1222,15 @@ QPDFWriter::Members::write_encrypted(std::string_view str) |
| 1220 | 1222 | } |
| 1221 | 1223 | |
| 1222 | 1224 | void |
| 1223 | -QPDFWriter::computeDeterministicIDData() | |
| 1225 | +QPDFWriter::Members::computeDeterministicIDData() | |
| 1224 | 1226 | { |
| 1225 | - if (!m->id2.empty()) { | |
| 1227 | + if (!id2.empty()) { | |
| 1226 | 1228 | // Can't happen in the code |
| 1227 | 1229 | throw std::logic_error( |
| 1228 | 1230 | "Deterministic ID computation enabled after ID generation has already occurred."); |
| 1229 | 1231 | } |
| 1230 | - qpdf_assert_debug(m->deterministic_id_data.empty()); | |
| 1231 | - m->deterministic_id_data = m->pipeline_stack.hex_digest(); | |
| 1232 | + qpdf_assert_debug(deterministic_id_data.empty()); | |
| 1233 | + deterministic_id_data = pipeline_stack.hex_digest(); | |
| 1232 | 1234 | } |
| 1233 | 1235 | |
| 1234 | 1236 | int |
| ... | ... | @@ -1399,7 +1401,7 @@ QPDFWriter::Members::writeTrailer( |
| 1399 | 1401 | write("<00000000000000000000000000000000>"); |
| 1400 | 1402 | } else { |
| 1401 | 1403 | if (linearization_pass == 0 && deterministic_id) { |
| 1402 | - w.computeDeterministicIDData(); | |
| 1404 | + computeDeterministicIDData(); | |
| 1403 | 1405 | } |
| 1404 | 1406 | generateID(encryption.get()); |
| 1405 | 1407 | write_string(id1, true).write_string(id2, true); |
| ... | ... | @@ -1715,7 +1717,7 @@ QPDFWriter::Members::unparseObject( |
| 1715 | 1717 | // Don't encrypt stream data for the metadata stream |
| 1716 | 1718 | cur_data_key.clear(); |
| 1717 | 1719 | } |
| 1718 | - w.adjustAESStreamLength(cur_stream_length); | |
| 1720 | + adjustAESStreamLength(cur_stream_length); | |
| 1719 | 1721 | unparseObject(stream_dict, 0, flags, cur_stream_length, compress_stream); |
| 1720 | 1722 | char last_char = stream_data.empty() ? '\0' : stream_data.back(); |
| 1721 | 1723 | write("\nstream\n").write_encrypted(stream_data); |
| ... | ... | @@ -1821,7 +1823,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) |
| 1821 | 1823 | offsets.push_back(pipeline->getCount()); |
| 1822 | 1824 | // To avoid double-counting objects being written in object streams for progress |
| 1823 | 1825 | // reporting, decrement in pass 1. |
| 1824 | - w.indicateProgress(true, false); | |
| 1826 | + indicateProgress(true, false); | |
| 1825 | 1827 | |
| 1826 | 1828 | QPDFObjectHandle obj_to_write = pdf.getObject(og); |
| 1827 | 1829 | if (obj_to_write.isStream()) { |
| ... | ... | @@ -1863,10 +1865,10 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) |
| 1863 | 1865 | |
| 1864 | 1866 | // Write the object |
| 1865 | 1867 | openObject(new_stream_id); |
| 1866 | - w.setDataKey(new_stream_id); | |
| 1868 | + setDataKey(new_stream_id); | |
| 1867 | 1869 | write("<<").write_qdf("\n ").write(" /Type /ObjStm").write_qdf("\n "); |
| 1868 | 1870 | size_t length = stream_buffer_pass2.size(); |
| 1869 | - w.adjustAESStreamLength(length); | |
| 1871 | + adjustAESStreamLength(length); | |
| 1870 | 1872 | write(" /Length ").write(length).write_qdf("\n "); |
| 1871 | 1873 | if (compressed) { |
| 1872 | 1874 | write(" /Filter /FlateDecode"); |
| ... | ... | @@ -1901,7 +1903,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde |
| 1901 | 1903 | return; |
| 1902 | 1904 | } |
| 1903 | 1905 | |
| 1904 | - w.indicateProgress(false, false); | |
| 1906 | + indicateProgress(false, false); | |
| 1905 | 1907 | auto new_id = obj[old_og].renumber; |
| 1906 | 1908 | if (qdf_mode) { |
| 1907 | 1909 | if (page_object_to_seq.contains(old_og)) { |
| ... | ... | @@ -1916,7 +1918,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde |
| 1916 | 1918 | write("%% Original object ID: ").write(object.getObjGen().unparse(' ')).write("\n"); |
| 1917 | 1919 | } |
| 1918 | 1920 | openObject(new_id); |
| 1919 | - w.setDataKey(new_id); | |
| 1921 | + setDataKey(new_id); | |
| 1920 | 1922 | unparseObject(object, 0, 0); |
| 1921 | 1923 | cur_data_key.clear(); |
| 1922 | 1924 | closeObject(new_id); |
| ... | ... | @@ -2367,7 +2369,7 @@ QPDFWriter::write() |
| 2367 | 2369 | m->output_buffer = m->buffer_pipeline->getBuffer(); |
| 2368 | 2370 | m->buffer_pipeline = nullptr; |
| 2369 | 2371 | } |
| 2370 | - indicateProgress(false, true); | |
| 2372 | + m->indicateProgress(false, true); | |
| 2371 | 2373 | } |
| 2372 | 2374 | |
| 2373 | 2375 | QPDFObjGen |
| ... | ... | @@ -2475,7 +2477,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) |
| 2475 | 2477 | QPDF::Writer::generateHintStream(pdf, new_obj, obj, hint_buffer, S, O, compressed); |
| 2476 | 2478 | |
| 2477 | 2479 | openObject(hint_id); |
| 2478 | - w.setDataKey(hint_id); | |
| 2480 | + setDataKey(hint_id); | |
| 2479 | 2481 | |
| 2480 | 2482 | size_t hlen = hint_buffer.size(); |
| 2481 | 2483 | |
| ... | ... | @@ -2487,7 +2489,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) |
| 2487 | 2489 | if (O) { |
| 2488 | 2490 | write(" /O ").write(O); |
| 2489 | 2491 | } |
| 2490 | - w.adjustAESStreamLength(hlen); | |
| 2492 | + adjustAESStreamLength(hlen); | |
| 2491 | 2493 | write(" /Length ").write(hlen); |
| 2492 | 2494 | write(" >>\nstream\n").write_encrypted(hint_buffer); |
| 2493 | 2495 | |
| ... | ... | @@ -2649,7 +2651,7 @@ QPDFWriter::Members::writeXRefStream( |
| 2649 | 2651 | } |
| 2650 | 2652 | |
| 2651 | 2653 | size_t |
| 2652 | -QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | |
| 2654 | +QPDFWriter::Members::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | |
| 2653 | 2655 | { |
| 2654 | 2656 | // This routine is called right after a linearization first pass xref stream has been written |
| 2655 | 2657 | // without compression. Calculate the amount of padding that would be required in the worst |
| ... | ... | @@ -2876,7 +2878,7 @@ QPDFWriter::Members::writeLinearized() |
| 2876 | 2878 | qpdf_offset_t endpos = pipeline->getCount(); |
| 2877 | 2879 | if (pass == 1) { |
| 2878 | 2880 | // Pad so we have enough room for the real xref stream. |
| 2879 | - write(w.calculateXrefStreamPadding(endpos - pos), ' '); | |
| 2881 | + write(calculateXrefStreamPadding(endpos - pos), ' '); | |
| 2880 | 2882 | first_xref_end = pipeline->getCount(); |
| 2881 | 2883 | } else { |
| 2882 | 2884 | // Pad so that the next object starts at the same place as in pass 1. |
| ... | ... | @@ -2953,7 +2955,7 @@ QPDFWriter::Members::writeLinearized() |
| 2953 | 2955 | if (pass == 1) { |
| 2954 | 2956 | // Pad so we have enough room for the real xref stream. See comments for previous |
| 2955 | 2957 | // xref stream on how we calculate the padding. |
| 2956 | - write(w.calculateXrefStreamPadding(endpos - pos), ' ').write("\n"); | |
| 2958 | + write(calculateXrefStreamPadding(endpos - pos), ' ').write("\n"); | |
| 2957 | 2959 | second_xref_end = pipeline->getCount(); |
| 2958 | 2960 | } else { |
| 2959 | 2961 | // Make the file size the same. |
| ... | ... | @@ -2976,7 +2978,7 @@ QPDFWriter::Members::writeLinearized() |
| 2976 | 2978 | if (pass == 1) { |
| 2977 | 2979 | if (deterministic_id) { |
| 2978 | 2980 | QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1); |
| 2979 | - w.computeDeterministicIDData(); | |
| 2981 | + computeDeterministicIDData(); | |
| 2980 | 2982 | pp_md5.pop(); |
| 2981 | 2983 | } |
| 2982 | 2984 | |
| ... | ... | @@ -3070,30 +3072,30 @@ QPDFWriter::Members::enqueueObjectsPCLm() |
| 3070 | 3072 | } |
| 3071 | 3073 | |
| 3072 | 3074 | void |
| 3073 | -QPDFWriter::indicateProgress(bool decrement, bool finished) | |
| 3075 | +QPDFWriter::Members::indicateProgress(bool decrement, bool finished) | |
| 3074 | 3076 | { |
| 3075 | 3077 | if (decrement) { |
| 3076 | - --m->events_seen; | |
| 3078 | + --events_seen; | |
| 3077 | 3079 | return; |
| 3078 | 3080 | } |
| 3079 | 3081 | |
| 3080 | - ++m->events_seen; | |
| 3082 | + ++events_seen; | |
| 3081 | 3083 | |
| 3082 | - if (!m->progress_reporter.get()) { | |
| 3084 | + if (!progress_reporter.get()) { | |
| 3083 | 3085 | return; |
| 3084 | 3086 | } |
| 3085 | 3087 | |
| 3086 | - if (finished || (m->events_seen >= m->next_progress_report)) { | |
| 3088 | + if (finished || events_seen >= next_progress_report) { | |
| 3087 | 3089 | int percentage = |
| 3088 | 3090 | (finished ? 100 |
| 3089 | - : m->next_progress_report == 0 | |
| 3091 | + : next_progress_report == 0 | |
| 3090 | 3092 | ? 0 |
| 3091 | - : std::min(99, 1 + ((100 * m->events_seen) / m->events_expected))); | |
| 3092 | - m->progress_reporter->reportProgress(percentage); | |
| 3093 | + : std::min(99, 1 + ((100 * events_seen) / events_expected))); | |
| 3094 | + progress_reporter->reportProgress(percentage); | |
| 3093 | 3095 | } |
| 3094 | - int increment = std::max(1, (m->events_expected / 100)); | |
| 3095 | - while (m->events_seen >= m->next_progress_report) { | |
| 3096 | - m->next_progress_report += increment; | |
| 3096 | + int increment = std::max(1, (events_expected / 100)); | |
| 3097 | + while (events_seen >= next_progress_report) { | |
| 3098 | + next_progress_report += increment; | |
| 3097 | 3099 | } |
| 3098 | 3100 | } |
| 3099 | 3101 | ... | ... |