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 rectangles
  • extract_tables_in_regions_mem – detects and extracts Markdown tables from regions
  • extract_text_with_positions_mem – returns text with precise glyph positions

Each function accepts a Vec<(page_number, Vec<[f32;4]>)> parameter where:

  • page_number is 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, &regions)?;
    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, &regions)?;
    // 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:

  1. Low latency – no subprocess overhead for small region extractions
  2. 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 *_mem API functions in src/lib.rs provide memory-only, thread-safe extraction for high-throughput services
  • Each region result includes needs_ocr and ocr_reason to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →