pdfcraft/crates/optimize
mlkonrad 2a35a1a76f
M11: Optimize PDF and Reduce File Size run in the background with a progress bar (#370)
* M11: Optimize PDF and Reduce File Size run in the background with a progress bar

Advanced optimization and Reduce File Size did all their work on the UI
thread, so on a large file the window stopped repainting until they were
done and looked as if it had crashed.

- pdfcraft-optimize: optimize_with_progress reports each image and the
  clean-up; returning false stops with OptimizeError::Cancelled.
- engine: Session::optimize_job captures a copy of the document and the
  choices; OptimizeJob::run reports each OptimizeStage (removing user data,
  images, cleaning up, merging, writing), stops on request with
  EditError::Cancelled and turns a panic into an error so a worker always
  reports back. optimized_bytes is the job run in place.
- ui: both commands run the job on a worker thread (inline in tests and on
  the web), like OCR and Export. A card at the bottom centre shows the
  stage ("Optimizing... image 14 of 40"), a bar that eases towards the
  fraction with a light sweeping across it, the percentage and Cancel;
  notices stack above it. A second run is refused while one is going. The
  control channel's state includes the progress.

The headless doc_optimize and doc_reduce tools stay synchronous. New
strings are translated for es, fr, ja, zh-hans, zh-hant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Clippy: as_chunks in the signature image background test (follow-up to #355)

#360 switched the image test to as_chunks; #355 added another chunks_exact(4)
in the background test, which clippy's chunks_exact_to_as_chunks rejects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Optimize: report a failed worker spawn instead of waiting forever

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-08 18:46:34 -04:00
..
src M11: Optimize PDF and Reduce File Size run in the background with a progress bar (#370) 2026-10-08 18:46:34 -04:00
tests M11: Optimize PDF and Reduce File Size run in the background with a progress bar (#370) 2026-10-08 18:46:34 -04:00
Cargo.toml Rename PrintCraft to PdfCraft (#174) 2026-10-07 16:03:57 -04:00
README.md M11: Optimize PDF and Reduce File Size run in the background with a progress bar (#370) 2026-10-08 18:46:34 -04:00

README.md

pdfcraft-optimize

Layer L4: the PDF Optimizer (execution plan M11.1; Acrobat's Reduce File Size and Optimize PDF ▸ Advanced optimization).

let report = optimize(&mut doc, &Settings::default())?;   // Reduce File Size's choices
// Or with progress: called before each image and the clean-up; `false` cancels.
let report = optimize_with_progress(&mut doc, &settings, &mut |stage| keep_going)?;
  • Images: the effective resolution of each image is measured where pages draw it (the CTM through form XObjects; the smallest over all uses). Colour and grayscale images above a threshold are resampled with a bicubic (Catmull-Rom) filter to a target resolution and stored as JPEG (Acrobat's quality steps) or ZIP; soft masks are resampled with their image. An image is replaced only if the result is smaller. Left alone: CMYK and other colour spaces, image masks, decode arrays, more than 8 bits, JPEG 2000, JBIG2 and CCITT.
  • Discard objects: thumbnails, alternate images, document tags, print settings.
  • Clean up: Flate for streams with no filter.

The engine runs Remove Hidden Information (pdfcraft-redact) for the user-data categories, then this, then merges identical objects and writes a full, compressed save (pdfcraft_engine::optimizer::OptimizeJob, which the UI runs on a worker thread with a progress bar). JPEG decoding and encoding and resampling come from the image crate.