ScanStrategy Detection Modes in pdf-inspector: EarlyExit, Full, Sample, and Pages Explained
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 (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, 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, 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) 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 allows you to instantiate these strategies through DetectionConfig and pass them to detect_pdf_type_with_config:
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, 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.rsand configured throughDetectionConfigbefore callingdetect_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. 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.
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 →