jpegli

Higher-level wrapper for Jpegli library

1 unstable release

0.1.0 Apr 9, 2024

#490 in Images

BSD-3-Clause

13MB
262K SLoC

C++ 125K SLoC // 0.1% comments C 83K SLoC // 0.2% comments Assembly 24K SLoC // 0.2% comments GNU Style Assembly 7K SLoC // 0.1% comments Bazel 6.5K SLoC // 0.1% comments Python 4K SLoC // 0.1% comments Java 3.5K SLoC // 0.4% comments Shell 3K SLoC // 0.2% comments Rust 3K SLoC // 0.0% comments JavaScript 1.5K SLoC // 0.1% comments Bitbake 1.5K SLoC // 0.0% comments Go 577 SLoC // 0.2% comments Forge Config 94 SLoC // 0.3% comments Batch 82 SLoC // 0.4% comments TypeScript 51 SLoC // 0.3% comments Objective-C 31 SLoC Automake 25 SLoC

Rust wrapper for Jpegli library based on mozjpeg-rust

This library adds a safe(r) interface on top of jpegli for reading and writing well-compressed JPEG images.

The interface is still being developed, so it has rough edges and may change.

In particular, error handling is weird due to libjpeg's peculiar design. Error handling can't use Result, but needs to depend on Rust's resume_unwind (a panic, basically) to signal any errors in libjpeg. It's necessary to wrap all uses of this library in catch_unwind.

In crates compiled with panic=abort setting, any JPEG error will abort the process.

Decoding example

std::panic::catch_unwind(|| -> std::io::Result<Vec<rgb::RGB8>> {
    let d = jpegli::Decompress::with_markers(jpegli::ALL_MARKERS)
        .from_path("tests/test.jpg")?;

    d.width(); // FYI
    d.height();
    d.color_space() == jpegli::ColorSpace::JCS_YCbCr;
    for marker in d.markers() { /* read metadata or color profiles */ }

    // rgb() enables conversion
    let mut image = d.rgb()?;
    image.width();
    image.height();
    image.color_space() == jpegli::ColorSpace::JCS_RGB;

    let pixels = image.read_scanlines()?;
    image.finish()?;
    Ok(pixels)
});

Encoding example

# let width = 8; let height = 8;
std::panic::catch_unwind(|| -> std::io::Result<Vec<u8>> {
    let mut comp = jpegli::Compress::new(jpegli::ColorSpace::JCS_RGB);

    comp.set_size(width, height);
    let mut comp = comp.start_compress(Vec::new())?; // any io::Write will work

    // replace with your image data
    let pixels = vec![0u8; width * height * 3];
    comp.write_scanlines(&pixels[..])?;

    let writer = comp.finish()?;
    Ok(writer)
});

Thanks

Huge thanks for the original authors of the mozjpeg-rust library, which this library is based on.

Most of the code is taken from there, with some modifications to work with jpegli instead of mozjpeg.

Dependencies