M11: only Group 4 is limited to rows of 32,767 samples (README, parity)

The optimizer README's and optimize.mono-compression's "not yet" lists
said rows wider than 32,767 samples aren't stored. That is Group 4's
limit (MAX_G4_COLUMNS); JBIG2 takes rows of up to 1,048,576
(MAX_JBIG2_COLUMNS). Found by CodeRabbit on #4805.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
This commit is contained in:
Grzegorz MartensandClaude Opus 5.5 committed 2026-10-29 20:47:53 +01:00
1 parent b2922056f4
commit e6e34bfa8d
2 files changed
+7 -6

No files matched your search

+6 -5
View File
@@ -42,11 +42,12 @@ let report = optimize_with_progress(&mut doc, &settings, &mut |stage| keep_going
than Group 4. It is lossless: the samples decode to the same bits, so the colour
space, decode array and masks stay. Group 4 wins on scans, whose ragged edges defeat Flate;
on clean computer-drawn 1-bit art Flate can be smaller, and the image then stays. Not yet:
JBIG2 symbol coding (lossy or lossless), monochrome downsampling, inline images, soft masks and `/Mask` images, and rows wider
than 32,767 samples. Redaction doesn't decode Group 4 yet: a mark over part of an image stored
this way removes the whole image (nothing leaks). Nor does anything that exports an image:
Export ▸ Images and Save Image As refuse it, Copy Image fails, and Word, PowerPoint and HTML
export leave the picture out.
JBIG2 symbol coding (lossy or lossless), monochrome downsampling, inline images, soft masks and
`/Mask` images, and Group 4 for rows wider than 32,767 samples (JBIG2 takes rows of up to
1,048,576). Redaction doesn't decode Group 4 yet: a mark over part of an image stored this way
removes the whole image (nothing leaks). Nor does anything that exports an image: Export ▸
Images and Save Image As refuse it, Copy Image fails, and Word, PowerPoint and HTML export leave
the picture out.
- **Discard objects:** thumbnails, alternate images, document tags, print settings.
- **Clean up:** Flate for streams with no filter; for streams with an outer ASCII85 or ASCIIHex
layer, that layer is removed when the result is smaller (the inner filters keep their encoded
+1 -1
View File
@@ -7385,7 +7385,7 @@ status = "partial"
commands = ["optimize.advanced", "optimize.reduce"]
tools = ["doc_optimize", "doc_reduce"]
evidence = ["crates/filters/src/ccitt.rs::bitmaps_round_trip", "crates/filters/src/ccitt.rs::a_page_of_text_like_marks_round_trips_and_shrinks", "crates/filters/src/ccitt.rs::what_it_cannot_encode_is_an_error", "crates/filters/src/mq.rs::the_annex_h_test_sequence_encodes_to_its_bytes", "crates/filters/src/jbig2.rs::bitmaps_round_trip", "crates/filters/src/jbig2.rs::a_page_of_text_like_marks_round_trips_and_shrinks", "crates/optimize/tests/optimize.rs::black_and_white_images_become_jbig2", "crates/automation/tests/it/automation.rs::doc_optimize_stores_black_and_white_images_as_jbig2", "crates/optimize/tests/optimize.rs::black_and_white_images_become_ccitt_group_4", "crates/automation/tests/it/automation.rs::doc_optimize_stores_black_and_white_images_as_ccitt_group_4", "crates/ui-egui/tests/it/create.rs::the_pdf_optimizer_dialog_saves_an_optimized_copy"]
notes = "CCITT Group 4 (the default, so Reduce File Size does it too) or JBIG2, both lossless: PDF Optimizer ▸ Images ▸ Monochrome Images (doc_optimize mono) stores a 1-bit image of one colour component (grey, indexed, a separation) or an image mask, kept with no filter or general-purpose ones, as Group 4 when that is smaller as stored; the samples decode to the same bits, so colour space, decode array and masks stay. Group 4 wins on scans; on clean computer-drawn 1-bit art Flate can be smaller, and the image then stays. JBIG2 is a generic region (template 0, typical prediction), about a third smaller than Group 4 on 300 dpi text; a document below PDF 1.4 gets /Version 1.4. Not yet: JBIG2 symbol coding (text regions with symbol dictionaries, where JBIG2's larger gains on text come from, and its lossy mode), JBIG2Globals, monochrome downsampling, inline images, soft masks and /Mask images, rows wider than 32,767 samples. Redaction doesn't decode Group 4 yet (a mark over part of such an image removes it whole; nothing leaks), nor does anything that exports an image: Export ▸ Images and Save Image As refuse it, Copy Image fails, and Word, PowerPoint and HTML export leave the picture out."
notes = "CCITT Group 4 (the default, so Reduce File Size does it too) or JBIG2, both lossless: PDF Optimizer ▸ Images ▸ Monochrome Images (doc_optimize mono) stores a 1-bit image of one colour component (grey, indexed, a separation) or an image mask, kept with no filter or general-purpose ones, as Group 4 when that is smaller as stored; the samples decode to the same bits, so colour space, decode array and masks stay. Group 4 wins on scans; on clean computer-drawn 1-bit art Flate can be smaller, and the image then stays. JBIG2 is a generic region (template 0, typical prediction), about a third smaller than Group 4 on 300 dpi text; a document below PDF 1.4 gets /Version 1.4. Not yet: JBIG2 symbol coding (text regions with symbol dictionaries, where JBIG2's larger gains on text come from, and its lossy mode), JBIG2Globals, monochrome downsampling, inline images, soft masks and /Mask images, Group 4 for rows wider than 32,767 samples (JBIG2 takes rows of up to 1,048,576). Redaction doesn't decode Group 4 yet (a mark over part of such an image removes it whole; nothing leaks), nor does anything that exports an image: Export ▸ Images and Save Image As refuse it, Copy Image fails, and Word, PowerPoint and HTML export leave the picture out."
[[feature]]
id = "optimize.only-if-smaller"