Skip to main content

Crate oxigdal_jpeg2000

Crate oxigdal_jpeg2000 

Source
Expand description

Pure Rust JPEG2000 (JP2/J2K) driver for OxiGDAL

This crate provides a Pure Rust implementation of JPEG2000 image decoding, supporting both JP2 (JPEG2000 Part 1) and raw J2K codestream formats.

§Features

  • Pure Rust implementation (no C/C++ dependencies)
  • Full JP2 box structure parsing with support for all standard boxes
  • JPEG2000 codestream decoding
  • Wavelet transforms (5/3 reversible and 9/7 irreversible)
  • Multi-component images (RGB, RGBA, grayscale)
  • Tiling support with partial tile decoding
  • Complete metadata extraction (file type, resolution, color spec, XML, UUID)
  • Error resilience modes for handling corrupted files (Basic and Full)
  • Progressive decoding with quality layer support
  • Region of Interest (ROI) decoding for spatial and resolution-level extraction

§Limitations

This is a reference implementation with simplified decoding for common cases. Full JPEG2000 compliance (especially tier-1 EBCOT encoding) requires extensive additional implementation. For production use with complex JPEG2000 files, consider using a more complete decoder.

§Examples

§Basic Usage

use oxigdal_jpeg2000::Jpeg2000Reader;
use std::fs::File;
use std::io::BufReader;

let file = File::open("image.jp2")?;
let reader = BufReader::new(file);

let mut decoder = Jpeg2000Reader::new(reader)?;
decoder.parse_headers()?;

let width = decoder.width()?;
let height = decoder.height()?;
println!("Image size: {}x{}", width, height);

let info = decoder.info()?;
println!("Color space: {:?}", info.color_space);
println!("Decomposition levels: {}", info.num_decomposition_levels);

// Access metadata
if let Some(res) = decoder.capture_resolution_dpi() {
    println!("Resolution: {:.1} x {:.1} DPI", res.0, res.1);
}

// Note: Full decoding not yet implemented
// let rgb_data = decoder.decode_rgb()?;

§Progressive Decoding

use oxigdal_jpeg2000::Jpeg2000Reader;
use std::fs::File;
use std::io::BufReader;

let file = File::open("image.jp2")?;
let reader = BufReader::new(file);
let mut decoder = Jpeg2000Reader::new(reader)?;
decoder.parse_headers()?;

// Decode progressively layer by layer
let mut progressive = decoder.decode_progressive()?;
while let Some(image_data) = progressive.next_layer()? {
    println!("Decoded layer {} of {}",
             progressive.current_layer(),
             progressive.total_layers());
    // Display or process intermediate quality image
}

§Region of Interest Decoding

use oxigdal_jpeg2000::Jpeg2000Reader;
use std::fs::File;
use std::io::BufReader;

let file = File::open("image.jp2")?;
let reader = BufReader::new(file);
let mut decoder = Jpeg2000Reader::new(reader)?;
decoder.parse_headers()?;

// Decode only a specific region (more efficient than full decode)
let region = decoder.decode_region(100, 100, 256, 256)?;

// Decode at lower resolution for thumbnail
let thumbnail = decoder.decode_region_at_resolution(0, 0, 64, 64, 2)?;

§Error Resilience

use oxigdal_jpeg2000::{Jpeg2000Reader, ResilienceMode};
use std::fs::File;
use std::io::BufReader;

let file = File::open("corrupted.jp2")?;
let reader = BufReader::new(file);
let mut decoder = Jpeg2000Reader::new(reader)?;

// Enable error resilience for corrupted files
decoder.enable_full_error_resilience();

// Parser will attempt to recover from errors
decoder.parse_headers()?;

§Architecture

The decoder is organized into several layers:

  • Box Reader (box_reader): Parses JP2 box structure
  • Codestream (codestream): Parses JPEG2000 codestream markers
  • Tier-2 (tier2): Packet decoding and layer management
  • Tier-1 (tier1): Code-block decoding (EBCOT)
  • Wavelet (wavelet): Inverse wavelet transforms
  • Color (color): Color space conversions
  • Metadata (metadata): JP2 metadata boxes
  • Reader (reader): High-level decoding interface

§JPEG2000 Standard

JPEG2000 is defined in ISO/IEC 15444-1:2019. This implementation follows the standard for basic decoding functionality.

§Performance Considerations

  • Wavelet transforms are implemented with minimal optimizations
  • SIMD optimizations are not yet implemented
  • Memory usage is not optimized for large images
  • For high-performance applications, consider using native implementations

§TODO

  • Complete tier-1 EBCOT decoder implementation (currently placeholder)
  • Add writing/encoding support for JP2/J2K files
  • SIMD optimization for wavelet transforms
  • Parallel tile decoding with multi-threading support
  • JPX (JPEG2000 Part 2) extended features
  • Memory-mapped file support for large images

§Recently Implemented

  • ✅ Full JP2 format support (all standard boxes, complete metadata parsing)
  • ✅ Error resilience modes (None, Basic, Full) with packet-level error handling
  • ✅ Progressive decoding with quality layer support
  • ✅ ROI decoding support (spatial regions and resolution levels)

Re-exports§

pub use error::Jpeg2000Error;
pub use error::ResilienceMode;
pub use error::Result;
pub use jp2_boxes::BoxType as Jp2BoxType;
pub use jp2_boxes::ColorSpace;
pub use jp2_boxes::Jp2Box;
pub use jp2_boxes::Jp2Parser;
pub use reader::ImageInfo;
pub use reader::Jpeg2000Reader;
pub use reader::ProgressiveDecoder;
pub use tier2::progression::CodeBlockAddress;
pub use tier2::progression::ProgressionIterator;
pub use tier2::rate_control::QualityLayer;
pub use tier2::rate_control::RateController;
pub use tier2::rate_control::SlopeEntry;
pub use tier2::roi::RoiMap;
pub use tier2::roi::RoiShift;

Modules§

box_reader
JP2 box structure parsing
codestream
JPEG2000 codestream parsing
color
Color space conversions
error
Error types for JPEG2000 driver
jp2_boxes
JP2 (JPEG2000 Part 1) file-format box parser
metadata
JP2 metadata boxes
reader
High-level JP2/J2K reader
tier1
Tier-1 decoder (EBCOT - Embedded Block Coding with Optimized Truncation)
tier2
Tier-2 decoder — packet decoding, progression orders, rate control, and ROI
wavelet
Wavelet transform implementation

Constants§

VERSION
Version information

Functions§

is_j2k
Check if a file is likely a J2K codestream based on SOC marker
is_jp2
Check if a file is likely a JP2 file based on magic bytes