# ScanStrategy Detection Modes in pdf-inspector: EarlyExit, Full, Sample, and Pages Explained

> Explore ScanStrategy detection modes EarlyExit, Full, Sample, and Pages in pdf-inspector. Choose the best strategy for your PDF analysis needs, balancing speed and accuracy.

- Repository: [Firecrawl/pdf-inspector](https://github.com/firecrawl/pdf-inspector)
- Tags: deep-dive
- Published: 2026-08-11

---

**The `ScanStrategy` enum in firecrawl/pdf-inspector provides four detection modes—EarlyExit, Full, Sample, and Pages—that control which pages are examined when classifying PDF types, allowing trade-offs between speed and accuracy.**

The **ScanStrategy** detection modes determine how the pdf-inspector Rust library analyzes PDF documents to distinguish between text-based and scanned content. Defined in [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) (lines 25-40), these strategies integrate with `DetectionConfig` to customize the classification pipeline without loading unnecessary pages into memory.

## How ScanStrategy Controls PDF Detection

The detection algorithm relies on `ScanStrategy` to build a subset of pages for analysis. According to the source code in [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs), the strategy is stored within `DetectionConfig` (lines 71-73) and consumed by the `detect_pdf_type_with_config` function (lines 93-101). This configuration dictates whether the scanner can exit early upon finding specific content, sample evenly across the document, or examine exact page indices.

## The Four ScanStrategy Detection Modes

### EarlyExit Mode

**EarlyExit** scans pages sequentially starting from page one and aborts immediately upon encountering the first non-text (scanned) page. This mode enables the fastest processing for documents that begin with text content but may contain scanned images later.

In [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs), this variant triggers the early-exit logic during the detection loop, returning results as soon as the classification changes from pure text to mixed or scanned.

### Full Mode

**Full** examines every single page in the document without early termination. This mode provides the most accurate classification—distinguishing between *Mixed* and *Scanned* PDFs—at the cost of processing time.

Use this when you require exact certainty about the document composition and cannot tolerate sampling errors.

### Sample Mode

**Sample(u32)** scans up to *N* evenly-distributed pages across the document, including the first page, last page, and intermediate spreads. The implementation uses a `distribute_pages` helper function to calculate the specific indices.

The default `DetectionConfig::default()` uses `Sample(8)`, making it the standard for large PDFs where speed outweighs the need for pinpoint accuracy. Pass a custom number like `Sample(5)` to adjust the sampling density.

### Pages Mode

**Pages(Vec<u32>)** inspects exactly the page numbers you specify, using 1-based indexing. The constructor validates and deduplicates the provided list before processing.

This mode suits targeted analysis when you already know which pages determine the document type—such as checking only a cover page that might be scanned while the remainder is text.

## Configuring ScanStrategy in Your Code

The public API exposed in [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs) allows you to instantiate these strategies through `DetectionConfig` and pass them to `detect_pdf_type_with_config`:

```rust
use pdf_inspector::detector::{
    detect_pdf_type_with_config, DetectionConfig, ScanStrategy, PdfType,
};

fn main() -> Result<(), pdf_inspector::PdfError> {
    // EarlyExit: Stop at first non-text page
    let cfg_early = DetectionConfig {
        strategy: ScanStrategy::EarlyExit,
        ..Default::default()
    };
    let res_early = detect_pdf_type_with_config("document.pdf", cfg_early)?;
    println!("EarlyExit result: {:?}", res_early.pdf_type);

    // Full: Scan every page
    let cfg_full = DetectionConfig {
        strategy: ScanStrategy::Full,
        ..Default::default()
    };
    let res_full = detect_pdf_type_with_config("document.pdf", cfg_full)?;

    // Sample: Scan up to 5 evenly-spaced pages
    let cfg_sample = DetectionConfig {
        strategy: ScanStrategy::Sample(5),
        ..Default::default()
    };
    let res_sample = detect_pdf_type_with_config("document.pdf", cfg_sample)?;

    // Pages: Scan only specific 1-indexed pages
    let cfg_pages = DetectionConfig {
        strategy: ScanStrategy::Pages(vec![1, 3, 7]),
        ..Default::default()
    };
    let res_pages = detect_pdf_type_with_config("document.pdf", cfg_pages)?;

    Ok(())
}

```

The resulting `PdfType` classification determines downstream processing in components like [`src/markdown/convert.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/markdown/convert.rs), which uses the output to decide whether OCR is required.

## Summary

- **EarlyExit** provides the fastest results by stopping at the first scanned page, ideal for routing pure-text documents quickly.
- **Full** guarantees complete accuracy by examining every page, necessary when distinguishing between mixed and fully scanned documents.
- **Sample(N)** balances speed and accuracy by testing up to N evenly distributed pages, with the default configuration using 8 samples.
- **Pages(Vec)** enables precise targeting of specific 1-indexed page numbers when you know exactly where to look.
- All strategies are defined in [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) and configured through `DetectionConfig` before calling `detect_pdf_type_with_config`.

## Frequently Asked Questions

### What is the default ScanStrategy in pdf-inspector?

The default strategy is `Sample(8)`, configured in `DetectionConfig::default()` according to the source code in [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs). This samples up to eight evenly distributed pages unless you explicitly override the configuration.

### How does EarlyExit differ from Full scan mode?

**EarlyExit** stops processing as soon as it encounters the first non-text page, while **Full** continues scanning every remaining page regardless of findings. EarlyExit optimizes for speed when you only need to know if a document contains *any* scanned content, whereas Full provides complete classification statistics.

### Can I specify exact page numbers with ScanStrategy?

Yes. Use the `Pages(Vec<u32>)` variant to provide a list of specific 1-indexed page numbers. The implementation validates and deduplicates your input before scanning only those pages, making it efficient for targeted analysis of known sections like cover pages or appendices.

### When should I use Sample mode over Full mode?

Use **Sample** mode when processing large PDFs where approximate classification is sufficient, such as batch processing pipelines or when memory constraints prevent loading page metadata for the entire document. Reserve **Full** mode for forensic analysis or when you must distinguish between documents containing *some* scanned pages versus *only* scanned pages.