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