Commit 962288647aec7a08b619e57b686ec2bb43a1059d
1 parent
1527bf29
Refactor stream filtering to simplify decode-level handling.
Replaced individual compression flags with a unified decode-level parameter for stream filtering. Introduced a helper function to handle filtering conditions, reducing redundancy and improving readability. Removed unused code and updated related tests to reflect these changes.
Showing
3 changed files
with
18 additions
and
41 deletions
libqpdf/QPDF_Stream.cc
| ... | ... | @@ -343,9 +343,8 @@ Stream::isRootMetadata() const |
| 343 | 343 | |
| 344 | 344 | bool |
| 345 | 345 | Stream::filterable( |
| 346 | - std::vector<std::shared_ptr<QPDFStreamFilter>>& filters, | |
| 347 | - bool& specialized_compression, | |
| 348 | - bool& lossy_compression) | |
| 346 | + qpdf_stream_decode_level_e decode_level, | |
| 347 | + std::vector<std::shared_ptr<QPDFStreamFilter>>& filters) | |
| 349 | 348 | { |
| 350 | 349 | auto s = stream(); |
| 351 | 350 | // Check filters |
| ... | ... | @@ -387,6 +386,16 @@ Stream::filterable( |
| 387 | 386 | |
| 388 | 387 | auto decode_obj = s->stream_dict.getKey("/DecodeParms"); |
| 389 | 388 | |
| 389 | + auto can_filter = // linebreak | |
| 390 | + [](auto d_level, auto& filter, auto& d_obj) -> bool { | |
| 391 | + if (!filter.setDecodeParms(d_obj) || | |
| 392 | + (d_level < qpdf_dl_all && filter.isLossyCompression()) || | |
| 393 | + (d_level < qpdf_dl_specialized && filter.isSpecializedCompression())) { | |
| 394 | + return false; | |
| 395 | + } | |
| 396 | + return true; | |
| 397 | + }; | |
| 398 | + | |
| 390 | 399 | auto decode_array = decode_obj.as_array(strict); |
| 391 | 400 | if (!decode_array || decode_array.size() == 0) { |
| 392 | 401 | if (decode_array) { |
| ... | ... | @@ -394,17 +403,9 @@ Stream::filterable( |
| 394 | 403 | } |
| 395 | 404 | |
| 396 | 405 | for (auto& filter: filters) { |
| 397 | - if (!filter->setDecodeParms(decode_obj)) { | |
| 406 | + if (!can_filter(decode_level, *filter, decode_obj)) { | |
| 398 | 407 | return false; |
| 399 | 408 | } |
| 400 | - if (filter->isLossyCompression()) { | |
| 401 | - specialized_compression = true; | |
| 402 | - lossy_compression = true; | |
| 403 | - continue; | |
| 404 | - } | |
| 405 | - if (filter->isSpecializedCompression()) { | |
| 406 | - specialized_compression = true; | |
| 407 | - } | |
| 408 | 409 | } |
| 409 | 410 | } else { |
| 410 | 411 | // Ignore /DecodeParms entirely if /Filters is empty. At least one case of a file whose |
| ... | ... | @@ -416,17 +417,10 @@ Stream::filterable( |
| 416 | 417 | |
| 417 | 418 | int i = -1; |
| 418 | 419 | for (auto& filter: filters) { |
| 419 | - if (!filter->setDecodeParms(decode_array.at(++i).second)) { | |
| 420 | + auto d_obj = decode_array.at(++i).second; | |
| 421 | + if (!can_filter(decode_level, *filter, d_obj)) { | |
| 420 | 422 | return false; |
| 421 | 423 | } |
| 422 | - if (filter->isLossyCompression()) { | |
| 423 | - specialized_compression = true; | |
| 424 | - lossy_compression = true; | |
| 425 | - continue; | |
| 426 | - } | |
| 427 | - if (filter->isSpecializedCompression()) { | |
| 428 | - specialized_compression = true; | |
| 429 | - } | |
| 430 | 424 | } |
| 431 | 425 | } |
| 432 | 426 | |
| ... | ... | @@ -444,8 +438,6 @@ Stream::pipeStreamData( |
| 444 | 438 | { |
| 445 | 439 | auto s = stream(); |
| 446 | 440 | std::vector<std::shared_ptr<QPDFStreamFilter>> filters; |
| 447 | - bool specialized_compression = false; | |
| 448 | - bool lossy_compression = false; | |
| 449 | 441 | bool ignored; |
| 450 | 442 | if (!filterp) { |
| 451 | 443 | filterp = &ignored; |
| ... | ... | @@ -453,20 +445,7 @@ Stream::pipeStreamData( |
| 453 | 445 | bool& filter = *filterp; |
| 454 | 446 | filter = encode_flags || decode_level != qpdf_dl_none; |
| 455 | 447 | if (filter) { |
| 456 | - filter = filterable(filters, specialized_compression, lossy_compression); | |
| 457 | - if ((decode_level < qpdf_dl_all) && lossy_compression) { | |
| 458 | - filter = false; | |
| 459 | - } | |
| 460 | - if (decode_level < qpdf_dl_specialized && specialized_compression) { | |
| 461 | - filter = false; | |
| 462 | - } | |
| 463 | - QTC::TC( | |
| 464 | - "qpdf", | |
| 465 | - "QPDF_Stream special filters", | |
| 466 | - (!filter) ? 0 | |
| 467 | - : lossy_compression ? 1 | |
| 468 | - : specialized_compression ? 2 | |
| 469 | - : 3); | |
| 448 | + filter = filterable(decode_level, filters); | |
| 470 | 449 | } |
| 471 | 450 | |
| 472 | 451 | if (!pipeline) { | ... | ... |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| ... | ... | @@ -312,9 +312,8 @@ namespace qpdf |
| 312 | 312 | return nullptr; // unreachable |
| 313 | 313 | } |
| 314 | 314 | bool filterable( |
| 315 | - std::vector<std::shared_ptr<QPDFStreamFilter>>& filters, | |
| 316 | - bool& specialized_compression, | |
| 317 | - bool& lossy_compression); | |
| 315 | + qpdf_stream_decode_level_e decode_level, | |
| 316 | + std::vector<std::shared_ptr<QPDFStreamFilter>>& filters); | |
| 318 | 317 | void replaceFilterData( |
| 319 | 318 | QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length); |
| 320 | 319 | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -278,7 +278,6 @@ QPDF ignore second extra space in xref entry 0 |
| 278 | 278 | QPDF ignore length error xref entry 0 |
| 279 | 279 | QPDF_encryption pad short parameter 0 |
| 280 | 280 | QPDFObjectHandle found old angle 1 |
| 281 | -QPDF_Stream special filters 3 | |
| 282 | 281 | QPDFTokenizer block long token 0 |
| 283 | 282 | qpdf-c called qpdf_set_decode_level 0 |
| 284 | 283 | qpdf-c called qpdf_set_compress_streams 0 | ... | ... |