Commit graph

4 commits

Author SHA1 Message Date
jedarden
9a3e4ce514 feat(pdftract-axcri): record inline images as ImageXObject entries
Add structures and functions to record inline images (BI/ID/EI sequences)
as ImageXObject entries in a page's image list. This enables Phase 4.4
figure detection to correctly classify blocks containing only images.

Changes:
- Add InlineImageHeader struct for inline image metadata
- Add ImageBytesRef enum for image byte references
- Add ImageXObject struct unifying XObject and inline images
- Add collect_image_xobjects() to collect all images with bboxes
- Add parse_inline_image() to parse BI/ID/EI sequences
- Add compute_unit_square_bbox() for bbox computation from CTM
- Add comprehensive unit tests for all acceptance criteria

Acceptance criteria:
- Inline image with no CTM: bbox == [0,0,1,1] 
- Inline image with CTM 100 0 0 50 200 300: bbox == [200,300,300,350] 
- Page with 3 images: page_image_list has 3 entries with correct bboxes 
- Image mask: recorded with is_mask flag 
- Rotation normalization: handled via CTM 

Closes: pdftract-axcri
2026-05-24 07:41:50 -04:00
jedarden
730eeffcee feat(pdftract-p7yll): implement cm operator diagnostics
Added CM_ARG_COUNT and CM_DEGENERATE diagnostic codes for the cm
operator. The cm operator was already implemented in render.rs and
type3_rasterizer.rs; this change adds proper error handling for:

- Wrong argument count (must be exactly 6 numbers)
- Degenerate matrices (NaN values or determinant == 0)

When errors occur, diagnostics are emitted and the CTM is not modified
(clamped to identity).

Closes: pdftract-p7yll

Files modified:
- crates/pdftract-core/src/diagnostics.rs: Added CmArgCount, CmDegenerate
- crates/pdftract-core/src/render.rs: Added diagnostic emission
- crates/pdftract-core/src/font/type3_rasterizer.rs: Added diagnostic emission
- crates/pdftract-cli/src/main.rs: Added CLI output for new diagnostics

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 04:13:16 -04:00
jedarden
367a0f129e feat(pdftract-4my): implement pdfium-render path behind full-render feature
Implements Phase 5.2.2: pdfium-render rendering path gated behind the
full-render Cargo feature, providing accurate rendering for complex PDFs
with overlapping images, image masks, soft masks, blend modes, and other
geometry the direct-compositing path cannot handle.

Changes:
- Add pdfium-render dependency gated under full-render feature
- Implement pdfium_path.rs module with thread-local PDFium instance
- Add render_page_via_pdfium() function for high-fidelity page rendering
- Add has_full_render() runtime detection helper
- Add ExtractionOptions.full_render field for runtime selection
- Re-export has_full_render from pdftract-core lib

Acceptance Criteria:
-  cargo build --features ocr,serve,full-render produces binary
-  cargo build --features ocr,serve does NOT pull in pdfium
-  Runtime fallback: full_render=true without feature -> direct compositing
- ⚠️ Soft-mask fixtures: no fixtures added (testing infrastructure)
- ⚠️ Binary size CI gate: no CI infrastructure (infra task)

Refs:
- Plan section: Phase 5.2 full-render feature (line 1854)
- Bead: pdftract-4my
2026-05-23 16:28:08 -04:00
jedarden
e2d2eded65 feat(pdftract-byq): implement direct image compositing path (Phase 5.2.1)
Implements the default-feature image rendering path for scanned PDFs:
- Walk content stream operators and collect image XObjects with CTMs
- Decode image XObjects (JPEG, RGB, grayscale, CMYK) via Phase 1.5
- Composite images onto canvas using CTM-based pixel placement
- Support page rotation (0, 90, 180, 270 degrees)
- Handle Y-flip CTMs (common in PDFs)
- Emit IMG_SOFTMASK_UNSUPPORTED diagnostic for soft-masked images

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 15:46:38 -04:00