Commit 962288647aec7a08b619e57b686ec2bb43a1059d

Authored by m-holger
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.
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
... ...