Commit ba1ded84d7c13da5ce0423daf2ad51f70f651f4c
1 parent
c71035c7
Refactor `QPDFWriter`: move `willFilterStream` to `QPDFWriter::Members`, update …
…related logic, and remove obsolete test coverage entries.
Showing
3 changed files
with
19 additions
and
27 deletions
include/qpdf/QPDFWriter.hh
| ... | ... | @@ -476,11 +476,6 @@ class QPDFWriter |
| 476 | 476 | void writeObject(QPDFObjectHandle object, int object_stream_index = -1); |
| 477 | 477 | void writeTrailer( |
| 478 | 478 | trailer_e which, int size, bool xref_stream, qpdf_offset_t prev, int linearization_pass); |
| 479 | - bool willFilterStream( | |
| 480 | - QPDFObjectHandle stream, | |
| 481 | - bool& compress_stream, | |
| 482 | - bool& is_metadata, | |
| 483 | - std::string* stream_data); | |
| 484 | 479 | void unparseObject( |
| 485 | 480 | QPDFObjectHandle object, |
| 486 | 481 | size_t level, | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -305,6 +305,12 @@ class QPDFWriter::Members |
| 305 | 305 | void assignCompressedObjectNumbers(QPDFObjGen og); |
| 306 | 306 | QPDFObjectHandle getTrimmedTrailer(); |
| 307 | 307 | |
| 308 | + bool willFilterStream( | |
| 309 | + QPDFObjectHandle stream, | |
| 310 | + bool& compress_stream, | |
| 311 | + bool& is_metadata, | |
| 312 | + std::string* stream_data); | |
| 313 | + | |
| 308 | 314 | private: |
| 309 | 315 | QPDFWriter& w; |
| 310 | 316 | QPDF& pdf; |
| ... | ... | @@ -1342,7 +1348,7 @@ QPDFWriter::writeTrailer( |
| 1342 | 1348 | } |
| 1343 | 1349 | |
| 1344 | 1350 | bool |
| 1345 | -QPDFWriter::willFilterStream( | |
| 1351 | +QPDFWriter::Members::willFilterStream( | |
| 1346 | 1352 | QPDFObjectHandle stream, |
| 1347 | 1353 | bool& compress_stream, // out only |
| 1348 | 1354 | bool& is_root_metadata, // out only |
| ... | ... | @@ -1357,38 +1363,33 @@ QPDFWriter::willFilterStream( |
| 1357 | 1363 | if (stream.isRootMetadata()) { |
| 1358 | 1364 | is_root_metadata = true; |
| 1359 | 1365 | } |
| 1360 | - bool filter = stream.isDataModified() || m->compress_streams || m->stream_decode_level; | |
| 1366 | + bool filter = stream.isDataModified() || compress_streams || stream_decode_level; | |
| 1361 | 1367 | bool filter_on_write = stream.getFilterOnWrite(); |
| 1362 | 1368 | if (!filter_on_write) { |
| 1363 | - QTC::TC("qpdf", "QPDFWriter getFilterOnWrite false"); | |
| 1364 | 1369 | filter = false; |
| 1365 | 1370 | } |
| 1366 | - if (filter_on_write && m->compress_streams) { | |
| 1371 | + if (filter_on_write && compress_streams) { | |
| 1367 | 1372 | // Don't filter if the stream is already compressed with FlateDecode. This way we don't make |
| 1368 | 1373 | // it worse if the original file used a better Flate algorithm, and we don't spend time and |
| 1369 | 1374 | // CPU cycles uncompressing and recompressing stuff. This can be overridden with |
| 1370 | 1375 | // setRecompressFlate(true). |
| 1371 | 1376 | QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter"); |
| 1372 | - if (!m->recompress_flate && !stream.isDataModified() && filter_obj.isName() && | |
| 1377 | + if (!recompress_flate && !stream.isDataModified() && filter_obj.isName() && | |
| 1373 | 1378 | (filter_obj.getName() == "/FlateDecode" || filter_obj.getName() == "/Fl")) { |
| 1374 | - QTC::TC("qpdf", "QPDFWriter not recompressing /FlateDecode"); | |
| 1375 | 1379 | filter = false; |
| 1376 | 1380 | } |
| 1377 | 1381 | } |
| 1378 | 1382 | bool normalize = false; |
| 1379 | 1383 | bool uncompress = false; |
| 1380 | - if (filter_on_write && is_root_metadata && | |
| 1381 | - (!m->encryption || !m->encryption->getEncryptMetadata())) { | |
| 1382 | - QTC::TC("qpdf", "QPDFWriter not compressing metadata"); | |
| 1384 | + if (filter_on_write && is_root_metadata && (!encryption || !encryption->getEncryptMetadata())) { | |
| 1383 | 1385 | filter = true; |
| 1384 | 1386 | compress_stream = false; |
| 1385 | 1387 | uncompress = true; |
| 1386 | - } else if (filter_on_write && m->normalize_content && m->normalized_streams.contains(old_og)) { | |
| 1388 | + } else if (filter_on_write && normalize_content && normalized_streams.contains(old_og)) { | |
| 1387 | 1389 | normalize = true; |
| 1388 | 1390 | filter = true; |
| 1389 | - } else if (filter_on_write && filter && m->compress_streams) { | |
| 1391 | + } else if (filter_on_write && filter && compress_streams) { | |
| 1390 | 1392 | compress_stream = true; |
| 1391 | - QTC::TC("qpdf", "QPDFWriter compressing uncompressed stream"); | |
| 1392 | 1393 | } |
| 1393 | 1394 | |
| 1394 | 1395 | // Disable compression for empty streams to improve compatibility |
| ... | ... | @@ -1400,16 +1401,16 @@ QPDFWriter::willFilterStream( |
| 1400 | 1401 | |
| 1401 | 1402 | bool filtered = false; |
| 1402 | 1403 | for (bool first_attempt: {true, false}) { |
| 1403 | - auto pp_stream_data = stream_data ? m->pipeline_stack.activate(*stream_data) | |
| 1404 | - : m->pipeline_stack.activate(true); | |
| 1404 | + auto pp_stream_data = | |
| 1405 | + stream_data ? pipeline_stack.activate(*stream_data) : pipeline_stack.activate(true); | |
| 1405 | 1406 | |
| 1406 | 1407 | try { |
| 1407 | 1408 | filtered = stream.pipeStreamData( |
| 1408 | - m->pipeline, | |
| 1409 | + pipeline, | |
| 1409 | 1410 | !filter ? 0 |
| 1410 | 1411 | : ((normalize ? qpdf_ef_normalize : 0) | |
| 1411 | 1412 | (compress_stream ? qpdf_ef_compress : 0)), |
| 1412 | - !filter ? qpdf_dl_none : (uncompress ? qpdf_dl_all : m->stream_decode_level), | |
| 1413 | + !filter ? qpdf_dl_none : (uncompress ? qpdf_dl_all : stream_decode_level), | |
| 1413 | 1414 | false, |
| 1414 | 1415 | first_attempt); |
| 1415 | 1416 | if (filter && !filtered) { |
| ... | ... | @@ -1639,7 +1640,7 @@ QPDFWriter::unparseObject( |
| 1639 | 1640 | bool compress_stream = false; |
| 1640 | 1641 | bool is_metadata = false; |
| 1641 | 1642 | std::string stream_data; |
| 1642 | - if (willFilterStream(object, compress_stream, is_metadata, &stream_data)) { | |
| 1643 | + if (m->willFilterStream(object, compress_stream, is_metadata, &stream_data)) { | |
| 1643 | 1644 | flags |= f_filtered; |
| 1644 | 1645 | } |
| 1645 | 1646 | QPDFObjectHandle stream_dict = object.getDict(); |
| ... | ... | @@ -2607,7 +2608,7 @@ QPDFWriter::writeLinearized() |
| 2607 | 2608 | if (result == 0) { |
| 2608 | 2609 | bool compress_stream; |
| 2609 | 2610 | bool is_metadata; |
| 2610 | - if (willFilterStream(stream, compress_stream, is_metadata, nullptr)) { | |
| 2611 | + if (m->willFilterStream(stream, compress_stream, is_metadata, nullptr)) { | |
| 2611 | 2612 | result = 2; |
| 2612 | 2613 | } else { |
| 2613 | 2614 | result = 1; | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -81,7 +81,6 @@ QPDF xref deleted object 0 |
| 81 | 81 | SF_FlateLzwDecode PNG filter 0 |
| 82 | 82 | QPDF xref /Index is array 1 |
| 83 | 83 | QPDFWriter encrypt object stream 0 |
| 84 | -QPDFWriter compressing uncompressed stream 0 | |
| 85 | 84 | QPDF exclude indirect length 0 |
| 86 | 85 | QPDF exclude encryption dictionary 0 |
| 87 | 86 | QPDF loop detected traversing objects 0 |
| ... | ... | @@ -90,7 +89,6 @@ QPDF recovered in readObjectAtOffset 0 |
| 90 | 89 | QPDF recovered stream length 0 |
| 91 | 90 | QPDF found wrong endstream in recovery 0 |
| 92 | 91 | QPDF_Stream pipeStreamData with null pipeline 0 |
| 93 | -QPDFWriter not recompressing /FlateDecode 0 | |
| 94 | 92 | QPDFJob unable to filter 0 |
| 95 | 93 | QUtil non-trivial UTF-16 0 |
| 96 | 94 | QPDF xref overwrite invalid objgen 0 |
| ... | ... | @@ -134,7 +132,6 @@ qpdf-c called qpdf_set_minimum_pdf_version 0 |
| 134 | 132 | qpdf-c called qpdf_force_pdf_version 0 |
| 135 | 133 | qpdf-c called qpdf_init_write multiple times 0 |
| 136 | 134 | QPDF_encryption rc4 decode string 0 |
| 137 | -QPDFWriter not compressing metadata 0 | |
| 138 | 135 | QPDF_encryption aes decode string 0 |
| 139 | 136 | QPDFWriter forced version disabled encryption 0 |
| 140 | 137 | qpdf-c called qpdf_set_r4_encryption_parameters_insecure 0 |
| ... | ... | @@ -451,7 +448,6 @@ qpdf-c called qpdf_oh_get_generation 0 |
| 451 | 448 | qpdf-c called qpdf_oh_unparse 0 |
| 452 | 449 | qpdf-c called qpdf_oh_unparse_resolved 0 |
| 453 | 450 | qpdf-c called qpdf_oh_unparse_binary 0 |
| 454 | -QPDFWriter getFilterOnWrite false 0 | |
| 455 | 451 | QPDFPageObjectHelper::forEachXObject 3 |
| 456 | 452 | NNTree erased last kid/item in tree 1 |
| 457 | 453 | QPDFPageObjectHelper unresolved names 0 | ... | ... |