How to Load a PDF Document from Memory in pdf-inspector

pdf-inspector provides dedicated *_mem APIs that accept raw byte slices (&[u8]) to process PDFs entirely in memory without filesystem I/O.

Loading PDFs directly from memory is essential for serverless environments, streaming pipelines, or any application where data arrives over the network. The pdf-inspector crate exposes a complete suite of memory-based functions that mirror its file-based API, all built on a single efficient loading pipeline in src/lib.rs.

The Core Memory Loading Pipeline

All memory-based operations in pdf-inspector follow a standard four-step process:

  1. Validate the byte slice — validate_pdf_bytes verifies the PDF header signature
  2. Load and parse — load_document_from_mem_with_password (lines 66-71 in src/lib.rs) creates a lopdf::Document and handles decryption if needed
  3. Process — the document passes to process_document for type detection, layout analysis, and extraction
  4. Return results — a PdfProcessResult containing detected type, page count, markdown output, and OCR metadata

Because the document parses exactly once, memory-based calls outperform their path-based equivalents by eliminating redundant filesystem operations.

Available Memory-Based Functions in pdf-inspector

Function Purpose Location
process_pdf_mem Full pipeline: detect + extract + markdown src/lib.rs
detect_pdf_mem Fast metadata-only detection src/lib.rs
extract_text_mem Plain text extraction src/extractor/mod.rs
extract_text_with_positions_mem Text with positional metadata src/extractor/mod.rs
extract_pages_markdown_mem Markdown for specific page ranges src/lib.rs
process_pdf_with_ocr_mem OCR-enabled processing src/vision/mod.rs

Each function delegates to load_document_from_mem_with_password, which automatically repairs malformed PDFs and decrypts password-protected files.

Loading a PDF from Memory in Rust

Full Document Processing

The process_pdf_mem function runs the complete analysis pipeline on a byte buffer:

use pdf_inspector::{process_pdf_mem, PdfOptions, ProcessMode};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load PDF from any source: network request, embedded asset, database
    let pdf_bytes = std::fs::read("example.pdf")?;

    // Execute full pipeline with default options
    let result = process_pdf_mem(&pdf_bytes)?;

    println!("PDF type: {:?}\nPages: {}", result.pdf_type, result.page_count);
    
    if let Some(md) = result.markdown {
        println!("Markdown output:\n{md}");
    }
    
    Ok(())
}

Fast Detection Without Extraction

Use detect_pdf_mem when you only need metadata:

use pdf_inspector::detect_pdf_mem;

let pdf_bytes = std::fs::read("sample.pdf")?;
let detection = detect_pdf_mem(&pdf_bytes)?;
println!("Detected type: {:?}", detection.pdf_type);

Text-Only Extraction

For scenarios requiring just the text content:

use pdf_inspector::extract_text_mem;

let pdf_bytes = std::fs::read("my.pdf")?;
let text = extract_text_mem(&pdf_bytes)?;
println!("{text}");

The underlying implementation in src/extractor/mod.rs (lines 62-68) provides both extract_text_mem and extract_text_with_positions_mem for spatial-aware extraction.

Loading a PDF from Memory in Python

The Python bindings expose the same memory capabilities. In src/python.rs (line 700+), Rust functions are wrapped for direct Python access:

import pdf_inspector

# Read PDF into memory from any source

with open("doc.pdf", "rb") as f:
    data = f.read()

# Full processing pipeline

result = pdf_inspector.process_pdf_mem(data)
print(result["markdown"])

# Quick detection without full extraction

info = pdf_inspector.detect_pdf_mem(data)
print(info["pdf_type"])

Source Code Reference Map

File Key Symbols Line Range
src/lib.rs process_pdf_mem, detect_pdf_mem, load_document_from_mem_with_password 66-71, 299-314
src/extractor/mod.rs extract_text_mem, extract_text_with_positions_mem 62-68
src/detector.rs detect_pdf_type_mem 110-115
src/python.rs Python wrappers for memory functions 700-808
src/vision/mod.rs process_pdf_with_ocr_mem 54-56

Performance and Security Considerations

  • Single-pass parsing: The load_document_from_mem_with_password function parses once and reuses the lopdf::Document across all subsequent operations
  • Automatic repair: Malformed PDF structures are handled transparently during load
  • In-memory decryption: Password-protected PDFs decrypt without temporary files
  • Zero filesystem I/O: Eliminates latency from disk operations and temporary file cleanup

Summary

  • pdf-inspector loads PDFs from memory using *_mem suffixed functions that accept &[u8] buffers
  • The central loader load_document_from_mem_with_password in src/lib.rs handles validation, parsing, decryption, and repair in one call
  • Available functions span full processing (process_pdf_mem), fast detection (detect_pdf_mem), text extraction (extract_text_mem), and OCR (process_pdf_with_ocr_mem)
  • Python bindings mirror the Rust API through wrappers in src/python.rs
  • Memory-based operations eliminate filesystem I/O and execute faster than path-based equivalents

Frequently Asked Questions

How does pdf-inspector validate a PDF before loading from memory?

The validate_pdf_bytes function checks for the %PDF- header signature before attempting to parse. This prevents wasted processing on non-PDF data and provides early error feedback when the byte slice contains incorrect or corrupted content.

Can pdf-inspector handle encrypted PDFs loaded from memory?

Yes. load_document_from_mem_with_password accepts an optional password parameter and performs in-memory decryption using the same pipeline as file-based operations. No temporary decrypted files are written to disk.

What is the difference between process_pdf_mem and detect_pdf_mem?

process_pdf_mem executes the full pipeline including text extraction, layout analysis, and markdown generation. detect_pdf_mem stops after type detection and metadata extraction, making it significantly faster when you only need to identify the PDF variant or count pages.

How do I extract text from specific pages using the memory API?

Use extract_pages_markdown_mem(buffer: &[u8], pages: Option<&[u32]>) from src/lib.rs. Pass None for all pages or a slice of page numbers (1-indexed) to limit extraction. For plain text with positional data, extract_text_with_positions_mem in src/extractor/mod.rs returns a Vec<TextItem> containing bounding box coordinates for each text element.

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 →