M2: shrink masked images a row at a time; keep near-1:1 scans sharp

Review of #3858 (aiongg):

- An area-shrunk image with a soft mask, a stencil's ink included,
  built its full-resolution RGBA before shrinking. A 10718 x 13701
  stencil at page size peaked at 1.16 GB (587 MB of RGBA). It is now
  premultiplied a source row at a time as it is averaged, and the
  shrink works a target row at a time, so it peaks at 1.03 GB, as the
  nearest-neighbour path did. Same bytes; about 5% slower per shrink.
- An image whose f32 scale passed 1 only by rounding was smoothed
  bilinearly and blurred by half a pixel at a half-pixel offset. It is
  now smoothed only above 1.01.
- A shrunk /ImageMask stencil keeping its thin strokes (#4800) is now
  tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kronbiiandClaude Opus 5.5 committed 2026-11-04 11:32:52 +02:00
1 parent 5ed2f4ba4f
commit c5065554a1
4 files changed
+267 -47

No files matched your search

+2 -2
View File
@@ -734,8 +734,8 @@ milestone = "M2"
status = "partial"
commands = []
tools = ["page_render"]
evidence = ["crates/render/src/raster/tests.rs::renders_a_blue_rectangle", "crates/automation/tests/it/automation.rs::open_inspect_render_and_find", "crates/render/src/raster/tests.rs::user_unit_scales_the_page_and_everything_on_it", "crates/render/src/raster/tests.rs::non_interpolated_minification_keeps_thin_strokes", "crates/render/src/raster/tests.rs::minified_image_edges_snap_to_whole_pixels", "crates/render/src/raster/tests.rs::large_non_interpolated_images_are_smoothed_when_enlarged", "crates/render/src/raster/tests.rs::small_non_interpolated_images_keep_hard_pixels_when_enlarged"]
notes = "hayro bootstrap renderer; own DisplayList devices in M2.6. Pages with /UserUnit are shown at their size in points, as Acrobat reads the value. An image drawn below its resolution is shrunk once to whole device pixels: by area averaging unless it asks for /Interpolate (then Catmull-Rom), so the text of a 300 dpi scan at 100% keeps its strokes (it was nearest-neighbour, which dropped them). Enlarged, an image of page-scan size (512 samples or more on its shorter side) is smoothed bilinearly whatever its /Interpolate, so a zoomed scan has no staircases; smaller images keep their hard pixels. Not measured against Acrobat"
evidence = ["crates/render/src/raster/tests.rs::renders_a_blue_rectangle", "crates/automation/tests/it/automation.rs::open_inspect_render_and_find", "crates/render/src/raster/tests.rs::user_unit_scales_the_page_and_everything_on_it", "crates/render/src/raster/tests.rs::non_interpolated_minification_keeps_thin_strokes", "crates/render/src/raster/tests.rs::a_shrunk_stencil_mask_keeps_thin_strokes", "crates/render/src/raster/tests.rs::minified_image_edges_snap_to_whole_pixels", "crates/render/src/raster/tests.rs::large_non_interpolated_images_are_smoothed_when_enlarged", "crates/render/src/raster/tests.rs::small_non_interpolated_images_keep_hard_pixels_when_enlarged"]
notes = "hayro bootstrap renderer; own DisplayList devices in M2.6. Pages with /UserUnit are shown at their size in points, as Acrobat reads the value. An image drawn below its resolution is shrunk once to whole device pixels: by area averaging unless it asks for /Interpolate (then Catmull-Rom), so the text of a 300 dpi scan at 100% keeps its strokes, a 1-bit /ImageMask text layer included (it was nearest-neighbour, which dropped them). Enlarged by more than 1%, an image of page-scan size (512 samples or more on its shorter side) is smoothed bilinearly whatever its /Interpolate, so a zoomed scan has no staircases; smaller images keep their hard pixels. Not measured against Acrobat"
[[feature]]
id = "view.render-shadings-patterns"