Added use_cropbox parameter to rasterize_pdf_page hook to allow
choosing between MediaBox and CropBox rendering:
- Default is use_cropbox=False (MediaBox) for consistency with
Ghostscript's existing behavior
- Ghostscript: passes -dUseCropBox when use_cropbox=True
- pypdfium: calculates crop values to expand from CropBox to MediaBox
when use_cropbox=False
This aligns both rasterizers to produce the same output dimensions
by default, making the rasterizer choice transparent for page
geometry.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
pypdfium2/PDFium is not thread-safe - concurrent calls from different
threads can crash or corrupt the process. Added a module-level lock to
serialize all pdfium operations.
PIL image processing and file I/O are done outside the lock since they
are thread-safe, minimizing lock contention.
For maximum parallelism, users can use process-based parallelism
(use_threads=False) where each process has its own pdfium instance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add test_rasterizer.py with tests covering:
- Basic rasterizer option validation ('auto', 'ghostscript', 'pypdfium')
- Rasterizer + --rotate-pages interaction
- PDFs with nonstandard MediaBox/TrimBox/CropBox
- Direct hook tests verifying plugins respect the option
Also fix pluggy parameter passing: make 'options' a required parameter
(no default) in the hookspec so pluggy forwards it to implementations.
Update test plugins and test_rotation.py to pass the new parameter.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add user control over which rasterizer is used for PDF page rendering:
- 'auto' (default): prefers pypdfium when available, falls back to Ghostscript
- 'pypdfium': force pypdfium2 (errors if not installed)
- 'ghostscript': force traditional Ghostscript rasterizer
Changes:
- Add rasterizer field with validation to OCROptions model
- Add --rasterizer CLI argument in the Advanced options group
- Update rasterize_pdf_page hookspec to pass options to plugins
- Update pypdfium plugin with check_options hook for availability check
- Update both plugins to respect the rasterizer option
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove check_options hook from pypdfium that raised error when
pypdfium2 wasn't installed
- Return None from pypdfium's rasterize_pdf_page when pypdfium2 is
unavailable, allowing the hook to fall through
- Restore Ghostscript's rasterize_pdf_page hook as fallback
This allows OCRmyPDF to work without pypdfium2 installed, using
Ghostscript for rasterization as before.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Completes Phase 5 of the CLI refactoring plan by enabling nested
plugin option access (e.g., options.tesseract.timeout) alongside
the legacy flat access (options.tesseract_timeout).
Changes:
- Add module-level plugin option model registry in _options.py
- Add __getattr__ to OCROptions for dynamic namespace access
- Register plugin models in setup_plugin_infrastructure()
- Add test for nested plugin option access
Plugin option instances are lazily created from flat field values
and cached for subsequent access.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit introduces Pydantic models for plugin-specific options in OCRmyPDF, focusing on:
- Creating TesseractOptions, OptimizeOptions, and GhostscriptOptions
- Adding backward compatibility properties
- Maintaining existing CLI and API functionality
- Preparing for future plugin option registration system
The changes include:
- Added type-annotated option models with validation
- Updated OCROptions to include legacy fields
- Added backward compatibility properties for jbig2 options
- Prepared groundwork for dynamic plugin option handling
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
The commit message captures the essence of the changes: we fixed how the output folder is handled in the hOCR pipeline by making it a proper field in OCROptions and updating the API functions accordingly.
Would you like me to generate a full commit message or is this sufficient?
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit updates `_pdf_to_hocr` and `_hocr_to_ocr_pdf` to use direct OCROptions construction, eliminating the last vestiges of CLI-parser dependency in the experimental APIs.
Key changes:
- Removed `parser = get_parser()` calls
- Added plugin validation similar to main `ocr()` function
- Simplified plugin manager hook calls
- Added None value filtering to use OCROptions defaults
- Maintained error handling and extra_attrs logic
The refactoring makes these experimental APIs truly API-first and simplifies the code by removing unnecessary CLI-related complexity.
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
fix: set default optimize value to 1 to prevent NoneType comparison
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This change ensures that `fast_web_view` always has a default value of 1.0, preventing the TypeError that was occurring in multiple test cases when trying to multiply `None` with an integer.
The modifications include:
1. Changing the type hint for `fast_web_view` from `float | None` to `float`
2. Setting a default value of 1.0
3. Adding a validation step in the `model_validator` to set the default value if not provided
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit addresses several test failures by:
- Adding a compatibility property for `jpeg_quality`
- Changing default color conversion strategy from 'auto' to 'RGB'
- Ensuring `tesseract_config` is always a list
- Improving validation for color conversion and image compression strategies
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>