Region-Based Extraction for Layout Model Integration in pdf-inspector: A Complete Guide
Region-based extraction in pdf-inspector lets you extract text, tables, and layout data from specific rectangular areas on PDF pages, enabling lightweight integration with external layout models and OCR services.
The firecrawl/pdf-inspector Rust crate provides a modular pipeline for PDF parsing with a powerful region-based extraction API. This feature allows developers to target specific document areas rather than processing entire pages—critical for layout model workflows that need precise, high-performance data extraction.
How Region-Based Extraction Works
The pdf-inspector pipeline follows a three-stage architecture optimized for selective extraction.
Stage 1: PDF Type Detection
Before extraction begins, the library classifies the document using detect_pdf_type_mem in src/detector.rs. This determines whether the document is TextBased, Scanned, or Mixed, and selects the appropriate processing path.
Detection runs automatically during region extraction, so you don't need to call it manually. The classifier uses heuristics for tiled scans and garbage text to avoid unnecessary OCR overhead.
Stage 2: Region Specification and Filtering
The public API in src/lib.rs exposes three primary region-aware functions:
extract_text_in_regions_mem– extracts raw text from specified rectanglesextract_tables_in_regions_mem– detects and extracts Markdown tables from regionsextract_text_with_positions_mem– returns text with precise glyph positions
Each function accepts a Vec<(page_number, Vec<[f32;4]>)> parameter where:
page_numberis 1-indexed- Each inner array encodes
[x0, y0, x1, y1]in PDF user space units
The core logic in src/extractor/mod.rs processes these regions through geometric clipping and overlap detection.
Stage 3: Content Stream Processing and Result Packaging
Inside src/extractor/content_stream.rs, the collect_text_in_region function clips the PDF content stream to your specified rectangles. The extractor preserves partially overlapping glyph runs—a behavior verified by the test_collect_text_in_region_keeps_partial_overlap_items test.
Results return as PageRegionResult structs with three key fields:
| Field | Type | Purpose |
|---|---|---|
text |
String |
Concatenated text for the region (empty if OCR required) |
needs_ocr |
bool |
Flag indicating whether external OCR is needed |
ocr_reason |
constant | One of OCR_REASON_SCANNED, OCR_REASON_VECTOR_TEXT, etc. defined in src/lib.rs |
The src/text_quality.rs module evaluates encoding quality to set needs_ocr appropriately, ensuring you only invoke expensive OCR services when necessary.
Complete Implementation Example
use pdf_inspector::{
extract_text_in_regions_mem, extract_tables_in_regions_mem,
PdfOptions, ProcessMode,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load PDF bytes (e.g., from HTTP request or filesystem)
let pdf_bytes = std::fs::read("report.pdf")?;
// Define regions: page 1 has one region, page 2 has two adjacent regions
let regions = vec![
(1, vec![[100.0, 100.0, 400.0, 500.0]]), // single column on page 1
(2, vec![
[50.0, 600.0, 550.0, 750.0], // left table area on page 2
[560.0, 600.0, 800.0, 750.0], // right table area on page 2
]),
];
// Extract text with OCR intelligence
let text_results = extract_text_in_regions_mem(&pdf_bytes, ®ions)?;
for result in text_results.iter() {
println!("Page {}:", result.page);
for (i, r) in result.regions.iter().enumerate() {
println!(" Region {} needs_ocr: {}", i + 1, r.needs_ocr);
println!(" Text preview: {:.60}...", r.text);
}
}
// Extract tables from the same regions
let table_results = extract_tables_in_regions_mem(&pdf_bytes, ®ions)?;
// Results contain Markdown tables or empty strings if OCR required
Ok(())
}
Performance Characteristics
The *_mem suffix indicates these functions operate entirely in memory without spawning external processes. This design provides two advantages for layout model integration:
- Low latency – no subprocess overhead for small region extractions
- Concurrency safety – multiple extractions can run in parallel threads
Integrating with External Layout Models
Region-based extraction supports three common layout model workflows:
Pre-filtering for vision models
Pass needs_ocr: true regions directly to multimodal APIs, skipping already-extractable text.
Table-only pipelines
Use extract_tables_in_regions_mem to feed Markdown tables into structured data models without noise from body text.
Coordinate preservation
extract_text_with_positions_mem returns glyph-level coordinates in src/extractor/mod.rs, enabling precise bounding box alignment with model predictions.
The table detection in src/tables/detect_rects.rs and Markdown conversion in src/markdown/convert.rs complete the pipeline for document understanding tasks.
Key Source Files Reference
| File | Purpose |
|---|---|
src/lib.rs |
Public API façade, OCR reason constants |
src/detector.rs |
detect_pdf_type_mem PDF classification |
src/extractor/mod.rs |
Region extraction entry points |
src/extractor/content_stream.rs |
Content stream clipping to regions |
src/text_quality.rs |
OCR necessity detection |
src/tables/detect_rects.rs |
Rectangle-based table detection |
src/markdown/convert.rs |
Region results to Markdown conversion |
Summary
- Region-based extraction in pdf-inspector targets specific
(page, [x0, y0, x1, y1])rectangles without full-page processing overhead - The
*_memAPI functions insrc/lib.rsprovide memory-only, thread-safe extraction for high-throughput services - Each region result includes
needs_ocrandocr_reasonto intelligently route content to external layout models or OCR services - Partial overlap detection preserves glyphs that cross region boundaries, ensuring no text loss at edges
- Table detection and Markdown conversion operate seamlessly on region-limited inputs
Frequently Asked Questions
How do I convert pixel coordinates from a UI to PDF user space units?
Multiply pixel coordinates by 72 / DPI where DPI is the rendering resolution of your PDF viewer. PDF user space is always 72 points per inch regardless of display resolution. For scanned documents, check the /CropBox or /MediaBox entries in the PDF catalog to establish the coordinate origin.
Can I extract regions from non-consecutive pages?
Yes—the regions vector accepts any page number combination. Each PageRegionResult in the returned vector maintains the original page number, so you can request pages 1, 50, and 200 in a single call without processing intermediate pages.
What happens if a region contains no extractable content?
The text field returns an empty string and needs_ocr indicates whether the emptiness is due to missing content (false) or unscanned/image content requiring OCR (true). Check ocr_reason in src/lib.rs to distinguish between OCR_REASON_SCANNED, OCR_REASON_VECTOR_TEXT, and other cases.
Is region extraction faster than full-page extraction?
Generally yes—the *_mem functions avoid full document parsing by clipping the content stream in src/extractor/content_stream.rs before text decoding. Performance gains are most significant for large PDFs where you need small footer headers or table areas rather than complete pages.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →