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,16 +469,6 @@ class QPDFWriter | ||
| 469 | qpdf_r3_modify_e modify); | 469 | qpdf_r3_modify_e modify); |
| 470 | void setEncryptionParameters(char const* user_password, char const* owner_password); | 470 | void setEncryptionParameters(char const* user_password, char const* owner_password); |
| 471 | void setEncryptionMinimumVersion(); | 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 | class Members; | 473 | class Members; |
| 484 | 474 |
libqpdf/QPDFWriter.cc
| @@ -380,6 +380,13 @@ class QPDFWriter::Members | @@ -380,6 +380,13 @@ class QPDFWriter::Members | ||
| 380 | bool skip_compression, | 380 | bool skip_compression, |
| 381 | int linearization_pass); | 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 | private: | 390 | private: |
| 384 | QPDFWriter& w; | 391 | QPDFWriter& w; |
| 385 | QPDF& pdf; | 392 | QPDF& pdf; |
| @@ -1102,16 +1109,11 @@ QPDFWriter::setEncryptionMinimumVersion() | @@ -1102,16 +1109,11 @@ QPDFWriter::setEncryptionMinimumVersion() | ||
| 1102 | } | 1109 | } |
| 1103 | 1110 | ||
| 1104 | void | 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,9 +1198,9 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) | ||
| 1196 | } | 1198 | } |
| 1197 | 1199 | ||
| 1198 | void | 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 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will | 1204 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will |
| 1203 | // also be prepended by 16 bits of random data. | 1205 | // also be prepended by 16 bits of random data. |
| 1204 | length += 32 - (length & 0xf); | 1206 | length += 32 - (length & 0xf); |
| @@ -1220,15 +1222,15 @@ QPDFWriter::Members::write_encrypted(std::string_view str) | @@ -1220,15 +1222,15 @@ QPDFWriter::Members::write_encrypted(std::string_view str) | ||
| 1220 | } | 1222 | } |
| 1221 | 1223 | ||
| 1222 | void | 1224 | void |
| 1223 | -QPDFWriter::computeDeterministicIDData() | 1225 | +QPDFWriter::Members::computeDeterministicIDData() |
| 1224 | { | 1226 | { |
| 1225 | - if (!m->id2.empty()) { | 1227 | + if (!id2.empty()) { |
| 1226 | // Can't happen in the code | 1228 | // Can't happen in the code |
| 1227 | throw std::logic_error( | 1229 | throw std::logic_error( |
| 1228 | "Deterministic ID computation enabled after ID generation has already occurred."); | 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 | int | 1236 | int |
| @@ -1399,7 +1401,7 @@ QPDFWriter::Members::writeTrailer( | @@ -1399,7 +1401,7 @@ QPDFWriter::Members::writeTrailer( | ||
| 1399 | write("<00000000000000000000000000000000>"); | 1401 | write("<00000000000000000000000000000000>"); |
| 1400 | } else { | 1402 | } else { |
| 1401 | if (linearization_pass == 0 && deterministic_id) { | 1403 | if (linearization_pass == 0 && deterministic_id) { |
| 1402 | - w.computeDeterministicIDData(); | 1404 | + computeDeterministicIDData(); |
| 1403 | } | 1405 | } |
| 1404 | generateID(encryption.get()); | 1406 | generateID(encryption.get()); |
| 1405 | write_string(id1, true).write_string(id2, true); | 1407 | write_string(id1, true).write_string(id2, true); |
| @@ -1715,7 +1717,7 @@ QPDFWriter::Members::unparseObject( | @@ -1715,7 +1717,7 @@ QPDFWriter::Members::unparseObject( | ||
| 1715 | // Don't encrypt stream data for the metadata stream | 1717 | // Don't encrypt stream data for the metadata stream |
| 1716 | cur_data_key.clear(); | 1718 | cur_data_key.clear(); |
| 1717 | } | 1719 | } |
| 1718 | - w.adjustAESStreamLength(cur_stream_length); | 1720 | + adjustAESStreamLength(cur_stream_length); |
| 1719 | unparseObject(stream_dict, 0, flags, cur_stream_length, compress_stream); | 1721 | unparseObject(stream_dict, 0, flags, cur_stream_length, compress_stream); |
| 1720 | char last_char = stream_data.empty() ? '\0' : stream_data.back(); | 1722 | char last_char = stream_data.empty() ? '\0' : stream_data.back(); |
| 1721 | write("\nstream\n").write_encrypted(stream_data); | 1723 | write("\nstream\n").write_encrypted(stream_data); |
| @@ -1821,7 +1823,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | @@ -1821,7 +1823,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | ||
| 1821 | offsets.push_back(pipeline->getCount()); | 1823 | offsets.push_back(pipeline->getCount()); |
| 1822 | // To avoid double-counting objects being written in object streams for progress | 1824 | // To avoid double-counting objects being written in object streams for progress |
| 1823 | // reporting, decrement in pass 1. | 1825 | // reporting, decrement in pass 1. |
| 1824 | - w.indicateProgress(true, false); | 1826 | + indicateProgress(true, false); |
| 1825 | 1827 | ||
| 1826 | QPDFObjectHandle obj_to_write = pdf.getObject(og); | 1828 | QPDFObjectHandle obj_to_write = pdf.getObject(og); |
| 1827 | if (obj_to_write.isStream()) { | 1829 | if (obj_to_write.isStream()) { |
| @@ -1863,10 +1865,10 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | @@ -1863,10 +1865,10 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | ||
| 1863 | 1865 | ||
| 1864 | // Write the object | 1866 | // Write the object |
| 1865 | openObject(new_stream_id); | 1867 | openObject(new_stream_id); |
| 1866 | - w.setDataKey(new_stream_id); | 1868 | + setDataKey(new_stream_id); |
| 1867 | write("<<").write_qdf("\n ").write(" /Type /ObjStm").write_qdf("\n "); | 1869 | write("<<").write_qdf("\n ").write(" /Type /ObjStm").write_qdf("\n "); |
| 1868 | size_t length = stream_buffer_pass2.size(); | 1870 | size_t length = stream_buffer_pass2.size(); |
| 1869 | - w.adjustAESStreamLength(length); | 1871 | + adjustAESStreamLength(length); |
| 1870 | write(" /Length ").write(length).write_qdf("\n "); | 1872 | write(" /Length ").write(length).write_qdf("\n "); |
| 1871 | if (compressed) { | 1873 | if (compressed) { |
| 1872 | write(" /Filter /FlateDecode"); | 1874 | write(" /Filter /FlateDecode"); |
| @@ -1901,7 +1903,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | @@ -1901,7 +1903,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | ||
| 1901 | return; | 1903 | return; |
| 1902 | } | 1904 | } |
| 1903 | 1905 | ||
| 1904 | - w.indicateProgress(false, false); | 1906 | + indicateProgress(false, false); |
| 1905 | auto new_id = obj[old_og].renumber; | 1907 | auto new_id = obj[old_og].renumber; |
| 1906 | if (qdf_mode) { | 1908 | if (qdf_mode) { |
| 1907 | if (page_object_to_seq.contains(old_og)) { | 1909 | if (page_object_to_seq.contains(old_og)) { |
| @@ -1916,7 +1918,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | @@ -1916,7 +1918,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | ||
| 1916 | write("%% Original object ID: ").write(object.getObjGen().unparse(' ')).write("\n"); | 1918 | write("%% Original object ID: ").write(object.getObjGen().unparse(' ')).write("\n"); |
| 1917 | } | 1919 | } |
| 1918 | openObject(new_id); | 1920 | openObject(new_id); |
| 1919 | - w.setDataKey(new_id); | 1921 | + setDataKey(new_id); |
| 1920 | unparseObject(object, 0, 0); | 1922 | unparseObject(object, 0, 0); |
| 1921 | cur_data_key.clear(); | 1923 | cur_data_key.clear(); |
| 1922 | closeObject(new_id); | 1924 | closeObject(new_id); |
| @@ -2367,7 +2369,7 @@ QPDFWriter::write() | @@ -2367,7 +2369,7 @@ QPDFWriter::write() | ||
| 2367 | m->output_buffer = m->buffer_pipeline->getBuffer(); | 2369 | m->output_buffer = m->buffer_pipeline->getBuffer(); |
| 2368 | m->buffer_pipeline = nullptr; | 2370 | m->buffer_pipeline = nullptr; |
| 2369 | } | 2371 | } |
| 2370 | - indicateProgress(false, true); | 2372 | + m->indicateProgress(false, true); |
| 2371 | } | 2373 | } |
| 2372 | 2374 | ||
| 2373 | QPDFObjGen | 2375 | QPDFObjGen |
| @@ -2475,7 +2477,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | @@ -2475,7 +2477,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | ||
| 2475 | QPDF::Writer::generateHintStream(pdf, new_obj, obj, hint_buffer, S, O, compressed); | 2477 | QPDF::Writer::generateHintStream(pdf, new_obj, obj, hint_buffer, S, O, compressed); |
| 2476 | 2478 | ||
| 2477 | openObject(hint_id); | 2479 | openObject(hint_id); |
| 2478 | - w.setDataKey(hint_id); | 2480 | + setDataKey(hint_id); |
| 2479 | 2481 | ||
| 2480 | size_t hlen = hint_buffer.size(); | 2482 | size_t hlen = hint_buffer.size(); |
| 2481 | 2483 | ||
| @@ -2487,7 +2489,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | @@ -2487,7 +2489,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | ||
| 2487 | if (O) { | 2489 | if (O) { |
| 2488 | write(" /O ").write(O); | 2490 | write(" /O ").write(O); |
| 2489 | } | 2491 | } |
| 2490 | - w.adjustAESStreamLength(hlen); | 2492 | + adjustAESStreamLength(hlen); |
| 2491 | write(" /Length ").write(hlen); | 2493 | write(" /Length ").write(hlen); |
| 2492 | write(" >>\nstream\n").write_encrypted(hint_buffer); | 2494 | write(" >>\nstream\n").write_encrypted(hint_buffer); |
| 2493 | 2495 | ||
| @@ -2649,7 +2651,7 @@ QPDFWriter::Members::writeXRefStream( | @@ -2649,7 +2651,7 @@ QPDFWriter::Members::writeXRefStream( | ||
| 2649 | } | 2651 | } |
| 2650 | 2652 | ||
| 2651 | size_t | 2653 | size_t |
| 2652 | -QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | 2654 | +QPDFWriter::Members::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) |
| 2653 | { | 2655 | { |
| 2654 | // This routine is called right after a linearization first pass xref stream has been written | 2656 | // This routine is called right after a linearization first pass xref stream has been written |
| 2655 | // without compression. Calculate the amount of padding that would be required in the worst | 2657 | // without compression. Calculate the amount of padding that would be required in the worst |
| @@ -2876,7 +2878,7 @@ QPDFWriter::Members::writeLinearized() | @@ -2876,7 +2878,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 2876 | qpdf_offset_t endpos = pipeline->getCount(); | 2878 | qpdf_offset_t endpos = pipeline->getCount(); |
| 2877 | if (pass == 1) { | 2879 | if (pass == 1) { |
| 2878 | // Pad so we have enough room for the real xref stream. | 2880 | // Pad so we have enough room for the real xref stream. |
| 2879 | - write(w.calculateXrefStreamPadding(endpos - pos), ' '); | 2881 | + write(calculateXrefStreamPadding(endpos - pos), ' '); |
| 2880 | first_xref_end = pipeline->getCount(); | 2882 | first_xref_end = pipeline->getCount(); |
| 2881 | } else { | 2883 | } else { |
| 2882 | // Pad so that the next object starts at the same place as in pass 1. | 2884 | // Pad so that the next object starts at the same place as in pass 1. |
| @@ -2953,7 +2955,7 @@ QPDFWriter::Members::writeLinearized() | @@ -2953,7 +2955,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 2953 | if (pass == 1) { | 2955 | if (pass == 1) { |
| 2954 | // Pad so we have enough room for the real xref stream. See comments for previous | 2956 | // Pad so we have enough room for the real xref stream. See comments for previous |
| 2955 | // xref stream on how we calculate the padding. | 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 | second_xref_end = pipeline->getCount(); | 2959 | second_xref_end = pipeline->getCount(); |
| 2958 | } else { | 2960 | } else { |
| 2959 | // Make the file size the same. | 2961 | // Make the file size the same. |
| @@ -2976,7 +2978,7 @@ QPDFWriter::Members::writeLinearized() | @@ -2976,7 +2978,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 2976 | if (pass == 1) { | 2978 | if (pass == 1) { |
| 2977 | if (deterministic_id) { | 2979 | if (deterministic_id) { |
| 2978 | QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1); | 2980 | QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1); |
| 2979 | - w.computeDeterministicIDData(); | 2981 | + computeDeterministicIDData(); |
| 2980 | pp_md5.pop(); | 2982 | pp_md5.pop(); |
| 2981 | } | 2983 | } |
| 2982 | 2984 | ||
| @@ -3070,30 +3072,30 @@ QPDFWriter::Members::enqueueObjectsPCLm() | @@ -3070,30 +3072,30 @@ QPDFWriter::Members::enqueueObjectsPCLm() | ||
| 3070 | } | 3072 | } |
| 3071 | 3073 | ||
| 3072 | void | 3074 | void |
| 3073 | -QPDFWriter::indicateProgress(bool decrement, bool finished) | 3075 | +QPDFWriter::Members::indicateProgress(bool decrement, bool finished) |
| 3074 | { | 3076 | { |
| 3075 | if (decrement) { | 3077 | if (decrement) { |
| 3076 | - --m->events_seen; | 3078 | + --events_seen; |
| 3077 | return; | 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 | return; | 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 | int percentage = | 3089 | int percentage = |
| 3088 | (finished ? 100 | 3090 | (finished ? 100 |
| 3089 | - : m->next_progress_report == 0 | 3091 | + : next_progress_report == 0 |
| 3090 | ? 0 | 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 |