# Region-Based Extraction for Layout Model Integration in pdf-inspector: A Complete Guide

> Master region-based extraction in pdf-inspector for precise text, table, and layout data extraction. Seamlessly integrate external layout models and OCR services with this complete guide.

- Repository: [Firecrawl/pdf-inspector](https://github.com/firecrawl/pdf-inspector)
- Tags: how-to-guide
- Published: 2026-08-10

---

**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`](https://github.com/firecrawl/pdf-inspector/blob/main/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`](https://github.com/firecrawl/pdf-inspector/blob/main/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`](https://github.com/firecrawl/pdf-inspector/blob/main/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`](https://github.com/firecrawl/pdf-inspector/blob/main/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`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs)** |

The **[`src/text_quality.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/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

```rust
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`](https://github.com/firecrawl/pdf-inspector/blob/main/src/extractor/mod.rs)**, enabling precise bounding box alignment with model predictions.

The table detection in **[`src/tables/detect_rects.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/detect_rects.rs)** and Markdown conversion in **[`src/markdown/convert.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/markdown/convert.rs)** complete the pipeline for document understanding tasks.

## Key Source Files Reference

| File | Purpose |
|------|---------|
| [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs) | Public API façade, OCR reason constants |
| [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) | `detect_pdf_type_mem` PDF classification |
| [`src/extractor/mod.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/extractor/mod.rs) | Region extraction entry points |
| [`src/extractor/content_stream.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/extractor/content_stream.rs) | Content stream clipping to regions |
| [`src/text_quality.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/text_quality.rs) | OCR necessity detection |
| [`src/tables/detect_rects.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/tables/detect_rects.rs) | Rectangle-based table detection |
| [`src/markdown/convert.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/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`](https://github.com/firecrawl/pdf-inspector/blob/main/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`](https://github.com/firecrawl/pdf-inspector/blob/main/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`](https://github.com/firecrawl/pdf-inspector/blob/main/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.