Skip to content

M11: measure every use of an image drawn through deeply nested forms (#1811) - #1933

Merged
echelon merged 2 commits into
storytold:mainfrom
mlkonrad:fix/optimize-deep-form-uses
Oct 15, 2026
Merged

echelon merged 2 commits into
storytold:mainfrom
mlkonrad:fix/optimize-deep-form-uses

Conversation

@mlkonrad

Copy link
Copy Markdown
Contributor

What this changes

Fixes #1811. The findings and reproduction are in the issue comment.

effective_resolutions skipped a form XObject it had already visited once (anywhere in the document) when it was nested more than four deep. A later, larger use of that form was never measured, so Reduce File Size and Optimize PDF resampled the image for its smallest use. On main, a 1200 px image drawn 1 in and 8 in wide through six nested forms is resampled to 150 px, about 19 ppi on the large copy. With the fix it measures 150 ppi and is left at 1200 px.

The walk (crates/optimize/src/images.rs) is now a small Walk struct:

  • Cycles are detected on the current path of forms, not with a document-wide seen-set.
  • Repeats are skipped only when they can't change the result: same form, its own /Resources, same linear part of the CTM (ppi doesn't depend on translation). A form tiled many times at one size is still walked once. That's also cheaper than before, since shallow forms used to be re-walked on every page. A form without /Resources draws its caller's images, so it is always walked.
  • Work is bounded. Each form's first walk is free (bounded by the object count). Repeat walks are capped at 100,000. If that cap or the existing 12-level depth limit leaves a use unmeasured, every image gets INFINITY: recompressed as the settings say, never resampled. Before, those uses were silently ignored.

How you verified it

  • cargo fmt --check, cargo clippy -p pdfcraft-optimize --all-targets -- -D warnings
  • cargo test -p pdfcraft-optimize (17 passed), plus the optimize/reduce tests in pdfcraft-engine and pdfcraft-automation
  • cargo xtask layers, assets, parity, wasm

New tests in crates/optimize/tests/optimize.rs. All four fail on main (fix reverted) and pass with it:

  • a_deeply_nested_form_is_measured_at_its_largest_use: 1, 6 and 12 levels, both uses on one page and on two pages. On main: 1200 ppi instead of 150 at 6 levels.
  • a_form_drawing_itself_is_walked_once_per_use: a self-drawing form. On main it was followed four more levels at 2× each and recorded 75 ppi for draws no renderer makes.
  • a_shared_form_without_resources_draws_each_callers_image: one resource-less form reached through two chains naming different images. On main the second image wasn't measured at all.
  • images_are_not_resampled_when_some_uses_could_not_be_measured: 13 levels (depth limit), and a 12-deep 3-way fan-out of resource-less forms (≈265k walks, budget). On main: measured as 1200 ppi and resampled.

Never-crash

  • No new unwrap/expect/panic!/unreachable!/todo! outside tests
  • No input-derived indexing; recursion bounded by depth (12) and the repeat-walk budget
  • No unsafe

Provenance

  • No assets, fonts or copied code; behaviour from ISO 32000 (form XObjects, CTM) only

Parity and reach

  • optimize.downsample-images notes and evidence updated; crates/optimize/README.md updated
  • No new tool needed: doc_optimize and doc_reduce use the same code

Anything a reviewer should look at first

🤖 Generated with Claude Code

…torytold#1811)

The effective-resolution walk skipped any form XObject already visited
once when it was nested more than four deep, with one seen-set for the
whole document. A later, larger use of the same form was never measured,
so Reduce File Size and Optimize PDF resampled the image for its smallest
use: a 1200 px image drawn 1 in and 8 in wide through six nested forms
came out 150 px wide, about 19 ppi on the large copy.

- Cycles are detected on the current path of forms, not document-wide.
- A form with its own resources drawn again at the same scale (only
  moved) is skipped, as that can't change any image's resolution; forms
  without resources draw their caller's images and are always walked.
- Repeat walks are capped at 100,000. If the cap or the 12-level depth
  limit leaves a use unmeasured, every image gets INFINITY: recompressed
  as the settings say, never resampled.

Fixes storytold#1811

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mlkonrad
mlkonrad force-pushed the fix/optimize-deep-form-uses branch from a9012f3 to 963fcb0 Compare October 14, 2026 16:54
# Conflicts:
#	crates/optimize/tests/optimize.rs
#	parity/acrobat-features.toml
@echelon
echelon merged commit 3f25d55 into storytold:main Oct 15, 2026
3 of 5 checks passed
@echelon

echelon commented Oct 15, 2026

Copy link
Copy Markdown
Member

Thank you @mlkonrad for fixing optimize downsampling images that deeply nested forms draw larger (#1811)! It's merged into main now.

If you haven't already, please come and join us on Discord: https://discord.gg/artcraft

@mlkonrad
mlkonrad deleted the fix/optimize-deep-form-uses branch October 18, 2026 06:53
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.

optimize: deep shared Form deduplication skips larger-scale image invocations

2 participants