How to Change the PDF Classification Strategy in pdf-inspector: A Complete Guide
You can change the PDF classification strategy in pdf-inspector by creating a custom DetectionConfig with your desired ScanStrategy variant and passing it to detect_pdf_type_with_config().
The pdf-inspector repository by Firecrawl provides Rust-based PDF analysis that classifies documents into four types: TextBased, Scanned, ImageBased, or Mixed. The classification behavior is controlled through configurable scanning strategies that trade speed for accuracy. This article explains how to customize these strategies using the detector API exported from src/detector.rs.
Understanding the Classification Workflow
Before changing strategies, it helps to understand how pdf-inspector analyzes documents. The detection pipeline runs through six distinct phases as implemented in src/detector.rs:
- Document loading –
detect_pdf_type()opens the PDF vialopdf::Document - Page selection – The
ScanStrategyresolves to specific page indices and anallow_early_exitflag - Per-page analysis –
analyze_page_content()extracts text operators, image counts, vector-text flags, and font decodability signals - Signal aggregation – Ratios like
text_ratio(text pages ÷ sampled pages) are computed - Heuristic classification – Rules in
detect_from_document()(lines 101–134) determine the finalPdfType - Optional refinement phases – Newspaper layout detection and per-page OCR recommendations
The ScanStrategy you choose directly affects step 2, controlling which pages contribute to the aggregated signals.
The Four ScanStrategy Variants
The ScanStrategy enum in src/detector.rs defines four approaches for page sampling:
| Variant | Behavior | Best For |
|---|---|---|
EarlyExit |
Scan sequentially, stop at first non-text page | Fast routing of clearly TextBased documents |
Full |
Analyze every page, never exit early | Maximum accuracy for Mixed vs. Scanned discrimination |
Sample(u32) |
Scan N evenly distributed pages (first, last, middle) | Large PDFs where speed outweighs perfection |
Pages(Vec<u32>) |
Scan exact page numbers you specify | Deterministic testing or metadata-driven selection |
The default configuration uses Sample(8) as defined near line 84 in src/detector.rs.
Changing the Strategy in Rust Code
To override the default strategy, construct a DetectionConfig and pass it to detect_pdf_type_with_config().
Example 1: Full Scan for Maximum Accuracy
Use ScanStrategy::Full when you cannot afford misclassification on documents with text-only covers followed by scanned content:
use pdf_inspector::detector::{detect_pdf_type_with_config, DetectionConfig, ScanStrategy};
fn main() -> Result<(), pdf_inspector::PdfError> {
let cfg = DetectionConfig {
strategy: ScanStrategy::Full,
..Default::default()
};
let result = detect_pdf_type_with_config("example.pdf", cfg)?;
println!("PDF type: {:?}, confidence: {}", result.pdf_type, result.confidence);
Ok(())
}
Example 2: Sample 4 Pages for Large Documents
Reduce runtime on hundred-page PDFs by sampling just 4 representative pages:
use pdf_inspector::detector::{detect_pdf_type_with_config, DetectionConfig, ScanStrategy};
fn main() -> Result<(), pdf_inspector::PdfError> {
let cfg = DetectionConfig {
strategy: ScanStrategy::Sample(4),
..Default::default()
};
let result = detect_pdf_type_with_config("big.pdf", cfg)?;
println!("Detected as {:?} ({}% confidence)", result.pdf_type, result.confidence * 100.0);
Ok(())
}
Example 3: Specific Pages Only
Pass exact page numbers when external metadata (like a table of contents) indicates relevant sections:
let cfg = DetectionConfig {
strategy: ScanStrategy::Pages(vec![1, 2, 3, 4, 5]),
..Default::default()
};
let result = detect_pdf_type_with_config("document.pdf", cfg)?;
Adjusting Classification Thresholds
Beyond page selection, DetectionConfig exposes thresholds that affect heuristics in lines 101–134 of src/detector.rs:
| Field | Default Purpose | When to Change |
|---|---|---|
min_text_ops_per_page |
Minimum PDF text operators to count a page as "having text" | Raise for stricter TextBased classification |
text_page_ratio_threshold |
Proportion of text pages required for TextBased result | Raise to reduce false TextBased positives |
Example 4: Strict TextBased Requirements
use pdf_inspector::detector::{detect_pdf_type_with_config, DetectionConfig, ScanStrategy};
fn main() -> Result<(), pdf_inspector::PdfError> {
let cfg = DetectionConfig {
strategy: ScanStrategy::Sample(8),
min_text_ops_per_page: 7, // default is lower; requires more text operators
text_page_ratio_threshold: 0.8, // default is 0.7; demands 80% text pages
..Default::default()
};
let result = detect_pdf_type_with_config("strict.pdf", cfg)?;
println!("Result: {:?}", result);
Ok(())
}
CLI Integration Notes
The detect_pdf binary in src/bin/detect_pdf.rs serves as the command-line interface. It constructs a DetectionConfig from parsed arguments and forwards it to detect_pdf_type_with_config().
To add a new CLI flag like --full-scan, modify src/bin/detect_pdf.rs to:
- Parse the flag from arguments
- Build
DetectionConfig { strategy: ScanStrategy::Full, ..Default::default() } - Pass that config to the detector function
No changes to src/detector.rs are required for basic strategy switching via CLI.
Key Source Files for Customization
| File | Role | Key Locations |
|---|---|---|
src/detector.rs |
Core detection logic, DetectionConfig, ScanStrategy, PdfType enum |
Definitions from line 12; strategy handling at lines 92–110; classification rules at lines 101–134 |
src/bin/detect_pdf.rs |
CLI entry point | Arguments parsed here, config constructed, detect_pdf_type_with_config invoked |
src/lib.rs |
Public API exports | Re-exports detector functions for library consumers |
src/extractor/ |
Content stream analysis | analyze_page_content() feeds signals to the detector |
Summary
- pdf-inspector classifies PDFs via configurable
ScanStrategyvariants insrc/detector.rs - Four strategies exist:
EarlyExit,Full,Sample(N), andPages(Vec<u32>) - Default is
Sample(8)— override viaDetectionConfigpassed todetect_pdf_type_with_config() - Threshold fields (
min_text_ops_per_page,text_page_ratio_threshold) fine-tune heuristics without code changes to classification rules - CLI customization requires modifying
src/bin/detect_pdf.rsto construct and forward custom configs
Frequently Asked Questions
What is the fastest PDF classification strategy in pdf-inspector?
ScanStrategy::EarlyExit is fastest for documents that start with text pages, as it stops at the first non-text page. For documents known to be large and mixed, ScanStrategy::Sample(4) provides predictable, bounded runtime regardless of content distribution.
When should I use Full scanning instead of the default Sample strategy?
Use ScanStrategy::Full when your pipeline cannot tolerate false TextBased classifications on documents with text covers followed by scanned interiors. The default Sample(8) may miss late-occurring scanned pages in very long PDFs.
Can I change classification thresholds without modifying the source code?
Yes, through DetectionConfig fields. Adjust min_text_ops_per_page to require more text operators before counting a page as textual, or raise text_page_ratio_threshold above 0.7 to demand a higher proportion of text pages for TextBased results. These apply regardless of which ScanStrategy you select.
How do I specify exact pages to analyze for classification?
Use ScanStrategy::Pages(Vec<u32>) with 1-indexed page numbers. This bypasses all sampling logic in lines 92–110 of src/detector.rs and analyzes only your specified pages, giving you deterministic, reproducible classification behavior ideal for testing or metadata-driven workflows.
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 →