Skip to content

pdftopdf: recover from PDFio warnings and preserve error-sheet settings - #254

Open
tevinch wants to merge 1 commit into
OpenPrinting:masterfrom
tevinch:pdfio-warning-recovery
Open

tevinch wants to merge 1 commit into
OpenPrinting:masterfrom
tevinch:pdfio-warning-recovery

Conversation

@tevinch

@tevinch tevinch commented Sep 21, 2026

Copy link
Copy Markdown

When a PDF resource dictionary repeats a name pointing to the same image, the PDFio callback currently returns false for its recoverable warning. The tested cairo document then loses pages, or keeps the page count while dropping images in the fit/two-up paths.

Return true for PDFio's WARNING: messages, forward warnings and errors to the caller's logger/context, and track actual errors separately so warning-only jobs do not trigger job-error-sheet-when=on-error. The always setting still adds its requested report page.

Addresses #230. Thanks to @jbtheou and @jasonvanwyk for the reports and fixtures, and @michaelrsweet for identifying the callback behavior.

Validation against c5dc208 on macOS arm64 with CUPS 2.3.4 and PDFio 1.6.5 used a targeted native build of the actual pdftopdf.c and ipp-options.c. The runnable regression checks cover direct copy, page selection, A4 fit, two-up, rendered pixels, logger delivery, both error-sheet settings, and invalid-header rejection. All passed. From that check directory, after the documented dependency setup:

sh build-driver.sh /path/to/libcupsfilters ./filter-check
python3 verify.py --driver ./filter-check

These checks are separate from upstream CI. I have not run the full make check, a Linux distribution build, or a physical printer test. @jasonvanwyk has offered to test a PR build on the original Arch/Canon MF230 setup.

Compatibility limit: PDFio 1.6.5 keeps the first duplicate value; QPDF keeps the last. This preserves the repeated-reference cairo case, but deliberately does not claim QPDF-equivalent output when duplicate names point to different objects. The warning remains visible through the supplied logger.

@jasonvanwyk

Copy link
Copy Markdown

Tested on the setup from the original #230 report: Arch Linux, cups 2.4.19, cups-filters 2.0.1, pdfio 1.6.5, ghostscript 10.07.1, Canon MF230 (UFR II LT PPD). Built master at c5dc208 and this PR (ae2f1f4) from source with --disable-mutool, then ran the system pdftopdf filter against each build's libcupsfilters.so.2 via LD_LIBRARY_PATH (no install), with the Canon PPD in PPD=, on the cairo fixture from #230 (2 pages, 5 image paints, /x7 repeated 3× and 2×). Installed libcupsfilters 2.1.1 (QPDF) is the reference.

build plain print-scaling=fit number-up=2
2.1.1 (QPDF, reference) 2 pages, 5 images 2 pages, 5 images 1 page, 5 images
master c5dc208 2 pages, 0 images, no warning 2 pages, 0 images 1 page, 0 images
PR #254 ae2f1f4 2 pages, 5 images 2 pages, 5 images 1 page, 5 images
  • Image counts from pdfimages -list; rendered pages (pdftoppm) of the PR build match 2.1.1 in content. The only pixel difference is a small horizontal offset of the fit-scaled page, which master shows identically, so it comes from the existing media-box handling, not this PR.
  • The PR build logs WARN: cfFilterPDFToPDF: WARNING: Discarding value for duplicate dictionary key 'x7'. once per duplicate (3 on the fixture), where master is silent — good, that makes the cairo problem visible in the CUPS error log.
  • gstoraster with the Canon PPD then consumed the PR's PDF cleanly (Ghostscript exited with no errors, same raster size as the 2.1.1 path).
  • Note for anyone repeating this: cupsfilter scrubs LD_LIBRARY_PATH, so it silently tests the installed library — call the filter binaries directly.

Not yet done: a physical print through cupsd (that needs the library installed, which I'm holding off on until this is in a release). Happy to do that too if useful.

@jasonvanwyk

Copy link
Copy Markdown

Physical print done as well. Temporarily installed this PR's libcupsfilters.so.2 over the pinned 2.1.1 and sent the #230 fixture through cupsd to the Canon MF230 twice: once plain, once with print-scaling=fit. Both jobs completed (job-completed-successfully, no hang in "processing", which is what the unpatched 2.2.1 did on this printer), and all four pages came out right: three red squares on page 1, two on page 2, for each job. Original library restored afterwards.

So on this setup the PR fixes the reported regression end to end: pdftopdf output, gstoraster, the Canon UFR II driver and paper.

@tevinch

tevinch commented Sep 22, 2026

Copy link
Copy Markdown
Author

Your plain and fit print results establish the missing end-to-end check on the original Arch/Canon setup, alongside the filter and raster comparisons. I have recorded them separately from the local macOS regression checks, including that physical two-up printing was not tested.

The cupsfilter / LD_LIBRARY_PATH detail is useful for avoiding a comparison against the wrong library. The patch remains limited to warning recovery, logging and error-sheet handling; the existing fit offset and PDFio's first-value policy for conflicting duplicate keys are unchanged. This is ready for maintainer review with your results attached.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants