11 releases

0.10.7 Mar 5, 2024
0.10.5 Oct 3, 2023
0.9.6 Jun 17, 2023
0.9.4 Aug 18, 2022
0.8.5 May 9, 2018

#193 in Images

Download history 2368/week @ 2024-02-26 2512/week @ 2024-03-04 2786/week @ 2024-03-11 3053/week @ 2024-03-18 3528/week @ 2024-03-25 3693/week @ 2024-04-01 3224/week @ 2024-04-08 3077/week @ 2024-04-15 2820/week @ 2024-04-22 2872/week @ 2024-04-29 2620/week @ 2024-05-06 2785/week @ 2024-05-13 2794/week @ 2024-05-20 2941/week @ 2024-05-27 2822/week @ 2024-06-03 2857/week @ 2024-06-10

11,592 downloads per month
Used in 16 crates (12 directly)

IJG license

81KB
1.5K SLoC

Rust wrapper for MozJPEG library

This library adds a safe(r) interface on top of libjpeg-turbo and MozJPEG 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 = mozjpeg::Decompress::with_markers(mozjpeg::ALL_MARKERS)
        .from_path("tests/test.jpg")?;

    d.width(); // FYI
    d.height();
    d.color_space() == mozjpeg::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() == mozjpeg::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 = mozjpeg::Compress::new(mozjpeg::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)
});

Dependencies

~4.5MB
~92K SLoC