Metadata-Version: 2.4
Name: oxpdf-python
Version: 1.4.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Text Processing :: General
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Summary: Next-generation, blazing fast, layout-aware PDF parser and Markdown extractor in pure Rust
Keywords: pdf,markdown,parser,rust,tables,extraction,pyo3
Home-Page: https://github.com/isaim0011/oxpdf
Author-email: isaim0011 <isaim0011@users.noreply.github.com>
License: MIT OR Apache-2.0
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Documentation, https://docs.rs/oxpdf
Project-URL: Homepage, https://github.com/isaim0011/oxpdf
Project-URL: Repository, https://github.com/isaim0011/oxpdf

# oxpdf

> High-performance, streaming PDF engine for Python — powered by Rust 🦀

[![PyPI version](https://img.shields.io/pypi/v/oxpdf.svg)](https://pypi.org/project/oxpdf/)
[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE-MIT)

`oxpdf` provides blazing-fast, memory-bounded, layout-aware PDF processing for Python. Built from the ground up in Rust with zero heavy C/C++ dependencies, `oxpdf` delivers orders-of-magnitude faster parsing and Markdown conversion than legacy Python libraries (`pypdf`, `pdfplumber`, `pdfminer.six`).

---

## Key Features

- ⚡ **Blazing Fast**: SIMD/SWAR-accelerated tokenization, streaming parser.
- 📐 **Layout-Aware Markdown**: Recursive XY-Cut algorithm for accurate multi-column reading order.
- 📊 **Table Reconstruction**: Geometric table recovery into clean GitHub-Flavored Markdown tables.
- 🖼️ **Zero-Copy Image Extraction**: Direct JPEG stream dumps from DCTDecode and PNG synthesis from Flate streams.
- 🛡️ **Memory-Bounded & Safe**: Protected against cyclic references, decompression bombs, and OOM.
- 🔒 **PDF Security**: Support for standard PDF encryption (RC4, AES-128, AES-256).

---

## Installation

```bash
pip install oxpdf
```

Or build from source using [maturin](https://github.com/PyO3/maturin):

```bash
cd oxpdf-python
maturin develop --release
```

---

## Quickstart

### 1. Document Loading & Inspection

```python
import oxpdf

# Load from file
doc = oxpdf.Document.from_file("annual_report.pdf")

# Or load from bytes
with open("annual_report.pdf", "rb") as f:
    doc = oxpdf.Document.from_bytes(f.read())

print(f"Total pages: {doc.page_count()}")
print(f"Total objects: {doc.object_count()}")
print(f"Page IDs: {doc.get_page_ids()}")
```

### 2. Layout-Aware Markdown Extraction

Convert complex documents into structured GitHub-Flavored Markdown with preserved headers and reconstructed tables:

```python
import oxpdf

doc = oxpdf.Document.from_file("financial_statement.pdf")

# Extract entire document as Markdown
markdown = doc.to_markdown_all()
print(markdown)

# Or convert a specific page by ID
page_ids = doc.get_page_ids()
first_page_md = doc.to_markdown(page_ids[0])
print(first_page_md)
```

### 3. Extracting Plaintext

```python
import oxpdf

doc = oxpdf.Document.from_file("document.pdf")

# Extract all pages
pages = doc.extract_text_all()
for idx, page_text in enumerate(pages, 1):
    print(f"--- Page {idx} ---")
    print(page_text)

# Or extract a specific page
page_ids = doc.get_page_ids()
text = doc.extract_text(page_ids[0])
```

### 4. Zero-Copy Image Extraction

Extract embedded images directly as JPEG or PNG without transcoding:

```python
import oxpdf

doc = oxpdf.Document.from_file("presentation.pdf")

# Extract all images from the document
images = doc.extract_images_all()
print(f"Found {len(images)} images")

for img in images:
    print(f"Name: {img.name}, Format: {img.format}, Size: {img.width}x{img.height}")
    # Write image bytes directly to disk
    with open(f"{img.name}.{img.format}", "wb") as f:
### 5. High-Fidelity Pure-Rust Rendering

Render pages directly to PNG image files or in-memory PNG bytes using the pure-Rust `#![forbid(unsafe_code)]` rasterization engine (zero C/C++ dependencies):

```python
import oxpdf

doc = oxpdf.Document.from_file("annual_report.pdf")

# Render page 1 directly to a PNG file at 150 DPI
doc.render_page_to_png(1, "page_1.png", dpi=150.0)

# Or render to in-memory PNG bytes (e.g. for GUI display or web APIs)
png_bytes = doc.render_page_to_bytes(1, dpi=300.0)
print(f"Rendered PNG size: {len(png_bytes)} bytes")
```

### 6. In-Memory Text Replacement & Document Mutation

```python
import oxpdf

doc = oxpdf.Document.from_file("contract.pdf")

# Replace text on page 1
doc.replace_text(1, "Draft Agreement", "Executed Agreement")

# Save updated document
doc.save("contract_executed.pdf")
```

---

## API Reference

### `oxpdf.Document`

- `Document(data: bytes)`: Constructor from byte buffer.
- `Document.from_bytes(data: bytes) -> Document`: Load from bytes.
- `Document.from_file(path: str) -> Document`: Load from a file path.
- `page_count() -> int`: Returns the total number of pages.
- `get_page_ids() -> list[int]`: Returns indirect object IDs of all pages.
- `extract_text(page_id: int) -> str`: Extracts plaintext from a page.
- `extract_text_all() -> list[str]`: Extracts plaintext from all pages.
- `to_markdown(page_id: int) -> str`: Converts a page to layout-aware Markdown.
- `to_markdown_all() -> str`: Converts all pages to unified Markdown.
- `extract_images(page_id: int) -> list[PyExtractedImage]`: Extracts images from a page.
- `extract_images_all() -> list[PyExtractedImage]`: Extracts all images.
- `render_page_to_png(page_index_or_id: int, path: str, dpi: float = 150.0)`: Renders a page directly to a PNG file.
- `render_page_to_bytes(page_index_or_id: int, dpi: float = 150.0) -> bytes`: Renders a page and returns PNG bytes.
- `replace_text(page_index_or_id: int, target: str, replacement: str)`: Replaces text strings in page content streams.
- `save(path: str) -> int`: Saves the modified document to a filesystem path.
- `save_bytes() -> bytes`: Returns serialized PDF document bytes.
- `object_count() -> int`: Returns the total object count in the xref table.

### `oxpdf.PyExtractedImage`

- `name: str`: Image resource identifier (e.g. `/Im1`).
- `format: str`: Image format (`jpeg`, `png`, `rgb`, `gray`).
- `width: int`: Image pixel width.
- `height: int`: Image pixel height.
- `data: list[int]`: Raw byte data.
- `to_bytes() -> bytes`: Direct Python `bytes` representation.

---

## License

Dual-licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
- MIT license ([LICENSE-MIT](LICENSE-MIT))

