Skip to content

nimazareian/mini-jpeg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mini-jpeg

A minimal JPEG decoder implementation written in Rust for educational purposes. The goal is to make the code readable and serve as a learning resource for understanding JPEG compression algorithms, rather than focusing on performance optimization.

Input: Baseline DCT JPEG images in JFIF format (.jpg/.jpeg)
Output: Decoded bitmap images (.bmp)

What This Decoder Implements

The decoder implements the full JPEG decoding pipeline:

JFIF File Format Parsing: SOI, APP0, COM, DQT, SOF0 (Baseline DCT), DHT, SOS, and EOI markers

Decoding Pipeline:

  • Huffman Decoding - Constructs Huffman trees and decodes DC/AC coefficients with run-length encoding (RLE)
  • Inverse Quantization - Dequantizes DCT coefficients using quantization tables
  • Inverse Discrete Cosine Transform (IDCT) - Converts frequency domain back to spatial domain
  • Color Space Conversion - YCbCr to RGB transformation
  • Image Reconstruction - Assembles 8×8 MCU blocks into the final image

Current Limitations

This implementation supports:

  • Baseline DCT JPEG images only (no progressive JPEG)
  • 4:4:4 chroma subsampling (no subsampling)
  • 3-component YCbCr color images and 1-component grayscale images

Optimization Opportunities

As this is a learning-focused implementation, there are many low-hanging fruit optimizations that could significantly improve performance:

IDCT Optimizations

  • Integer-based IDCT: Replace floating-point calculations with fixed-point integer arithmetic
  • Separable 1D transforms: Use two 1D IDCT passes (rows then columns) instead of a 2D transform, reducing complexity from O(n⁴) to O(n³)
  • Precomputed cosine tables: Cache cosine calculations instead of computing them for each coefficient
  • SIMD vectorization: Leverage CPU vector instructions for parallel computation

Parallelization

  • RST marker support: Implement restart marker (RST) handling to enable parallel decoding of image segments
  • Multi-threaded block processing: Process multiple MCU blocks concurrently

Other Improvements

  • Chroma subsampling support: Implement 4:2:2 and 4:2:0 subsampling with upsampling
  • Progressive JPEG: Add support for progressive DCT encoding
  • Memory optimization: Reduce memory allocations and improve cache locality

Learning Resources

This implementation was developed with the help of the following excellent resources:

Building and Running

# Build the project
cargo build --release

# Run the decoder (default image: images/lenna.jpg)
cargo run --release

The decoded output will be saved as a BMP file in the same directory as the input JPEG.

Project Structure

src/
├── main.rs           # Entry point
├── jpeg_parser.rs    # Main decoder logic and JFIF parsing
├── huffman_tree.rs   # Huffman tree construction and decoding
├── bit_reader.rs     # Bit-level reading utilities
└── constants.rs      # JFIF markers and zigzag ordering

Dependencies

  • bmp - For saving decoded images
  • byteorder - For reading big-endian data from JPEG files
  • anyhow - For error handling

About

Mini JPEG Decoder written in Rust

Topics

Resources

Stars

Watchers

Forks

Languages