justbig2 0.2.0

Pure Rust JBIG2 image decoder with no_std support
Documentation
# justbig2

Pure Rust JBIG2 image decoder with `no_std` support.

Decodes JBIG2 (ITU T.88) compressed bi-level images used in PDF documents, fax transmissions, and document archival systems.

## Features

- **Full JBIG2 decoding** — Generic, Text, Halftone, Refinement regions
- **Arithmetic & MMR coding** — QM arithmetic decoder + CCITT Group 4
- **Symbol dictionaries** — Glyph reuse across pages
- **Streaming API** — Feed data incrementally or all at once
- **`no_std` compatible** — Uses `alloc` only, no OS dependencies
- **Zero unsafe code** — Pure safe Rust

## Quick Start

Add to your `Cargo.toml`:

```toml
[dependencies]
justbig2 = "0.1"
```

Decode a JBIG2 file:

```rust
use justbig2::{decode, Page};

let data = std::fs::read("input.jb2").unwrap();
let pages = decode(&data).unwrap();

for page in &pages {
    println!("{}x{} pixels, {} bytes", page.width, page.height, page.data.len());
    // page.data is 1BPP, MSB-first, stride-aligned
    // page.get_pixel(x, y) returns 0 or 1
}
```

## API

### One-shot decoding

```rust
// Full JBIG2 file (with file header)
let pages = justbig2::decode(&data)?;

// Embedded stream (no file header, used in PDF)
let pages = justbig2::decode_embedded(&data)?;
```

### PDF with global segments

```rust
// One-shot with globals
let pages = justbig2::decode_embedded_with_globals(&stream, &globals)?;

// Or cache globals for reuse across many images
let cached = justbig2::Decoder::parse_globals(&globals)?;

let mut decoder = justbig2::Decoder::new_embedded();
decoder.set_global_segments(cached);
decoder.write(&stream)?;
```

### Streaming decoder

```rust
use justbig2::Decoder;

let mut decoder = Decoder::new();

// Feed data in chunks
decoder.write(&chunk1)?;
decoder.write(&chunk2)?;

// Retrieve completed pages
while let Some(page) = decoder.page() {
    // process page
}
```

### Page struct

```rust
pub struct Page {
    pub width: u32,     // Image width in pixels
    pub height: u32,    // Image height in pixels
    pub stride: u32,    // Row stride in bytes (= ceil(width / 8))
    pub data: Vec<u8>,  // 1BPP pixel data, MSB-first
}

// Get individual pixel (0 = white, 1 = black)
let pixel = page.get_pixel(x, y);
```

## Supported Segment Types

| Type | Segment | Status |
|------|---------|--------|
| 0 | Symbol Dictionary | Supported |
| 4, 6, 7 | Text Region | Supported (arithmetic) |
| 16 | Pattern Dictionary | Supported |
| 20, 22, 23 | Halftone Region | Supported |
| 38, 39 | Generic Region | Supported |
| 40, 42, 43 | Refinement Region | Supported |
| 48 | Page Information | Supported |
| 49, 50, 51 | End of Page/Stripe/File | Supported |
| 52 | Profile | Parsed (informational) |
| 53 | Code Table | Supported |
| 62 | Extension | Parsed (comments) |

## Limitations

- **Huffman-coded text regions** — Only arithmetic coding path is implemented. Arithmetic coding is used by the vast majority of real-world JBIG2 files.
- **Color Palette segments (type 54)** — Not implemented. Defined in the spec but rarely used in practice.
- **Intermediate Generic Region (type 36)** — Not implemented. Not seen in real-world files.
- **12 adaptive template pixels (T.88 amendment 2)** — Not supported.
- **Colored region segments (T.88 amendment 3)** — Not supported.

## Minimum Supported Rust Version

The MSRV is **1.56.0** (Rust edition 2021).

## `no_std` Usage

Disable the default `std` feature:

```toml
[dependencies]
justbig2 = { version = "0.1", default-features = false }
```

The library uses `alloc` for `Vec` and `String`. The `std::error::Error` impl is only available with the `std` feature.

## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.