#jpegxl #image-encoding #codec #api-bindings

jpegxl-rs

Safe Rust wrapper for JPEG XL reference implementation

30 releases

0.11.1+libjxl-0.11.0 Oct 1, 2024
0.10.4+libjxl-0.10.3 Jun 30, 2024
0.10.2+libjxl-0.10.2 Mar 21, 2024
0.8.3+libjxl-0.8.2 Oct 13, 2023
0.1.4 Aug 25, 2020

#33 in Images

Download history 294/week @ 2024-07-17 248/week @ 2024-07-24 223/week @ 2024-07-31 131/week @ 2024-08-07 230/week @ 2024-08-14 171/week @ 2024-08-21 270/week @ 2024-08-28 283/week @ 2024-09-04 461/week @ 2024-09-11 608/week @ 2024-09-18 1244/week @ 2024-09-25 1858/week @ 2024-10-02 2009/week @ 2024-10-09 2736/week @ 2024-10-16 1226/week @ 2024-10-23 1490/week @ 2024-10-30

7,692 downloads per month
Used in simp

GPL-3.0-or-later

330KB
3K SLoC

jpegxl-rs

Documentation Crates.io dependency status CI codecov License: GPL-3.0-or-later

A safe JPEGXL wrapper over libjxl library. Check out the original library and the bindings.

Building

If you wish to specify a custom library path, set the DEP_JXL_LIB environment variable.

Building libjxl and statically linking can be enabled by using the vendored feature.

If you don't want to depend on C++ standard library, disable the feature threads.

Usage

Currently, u8, u16, f16 and f32 are supported as pixel types.

Decoding

use jpegxl_rs::*;
use jpegxl_rs::decode::*;

let mut decoder = decoder_builder().build().unwrap();
let sample = include_bytes!("../../samples/sample.jxl");

let (Metadata { width, height, ..}, pixels) = decoder.decode(sample).unwrap();
match pixels {
    Pixels::Float(data) => { /* do something with Vec<f32> data */ },
    Pixels::Uint8(data) => { /* do something with Vec<u8> data */ },
    Pixels::Uint16(data) => { /* do something with Vec<u16> data */ },
    Pixels::Float16(data) => { /* do something with Vec<f16> data */ },
}

// Multi-threading
use jpegxl_rs::ThreadsRunner;
let runner = ThreadsRunner::default();
let mut decoder = decoder_builder()
                      .parallel_runner(&runner)
                      .build()
                      .unwrap();

// Customize pixel format
let mut decoder = decoder_builder()
                      .pixel_format(PixelFormat {
                          num_channels: 3,
                          endianness: Endianness::Big,
                          align: 8
                      })
                      .build()
                      .unwrap();

decoder.decode_with::<u8>(sample);

// You can change the settings after initialization
decoder.skip_reorientation = Some(true);

// Reconstruct JPEG, fallback to pixels if JPEG reconstruction is not possible
// This operation is finished in on pass
let (metadata, data) = decoder.reconstruct(sample).unwrap();
match data {
    Data::Jpeg(jpeg) => {/* do something with the JPEG data */}
    Data::Pixels(pixels) => {/* do something with the pixels data */}
}

Encoding

use image::ImageReader;
use jpegxl_rs::encoder_builder;
use jpegxl_rs::encode::{EncoderResult, EncoderSpeed};

let sample = ImageReader::open("../samples/sample.png").unwrap().decode().unwrap().to_rgba16();
let mut encoder = encoder_builder().build().unwrap();

let buffer: EncoderResult<f32> = encoder.encode(&sample, sample.width(), sample.height()).unwrap();

// Set encoder options
let mut encoder = encoder_builder()
                    .lossless(true)
                    .speed(EncoderSpeed::Falcon)
                    .build()
                    .unwrap();

// You can change the settings after initialization
encoder.lossless = false;
encoder.quality = 3.0;

image crate integration

The integration is enabled by default. If you don't need it, disable image feature.

use jpegxl_rs::image::ToDynamic;
use jpegxl_rs::decoder_builder;
use image::DynamicImage;

let sample = std::fs::read("../samples/sample.jxl").unwrap();
let mut decoder = decoder_builder().build().unwrap();
let img = decoder.decode_to_image(&sample).unwrap();
let img = decoder.decode_to_image_with::<f32>(&sample).unwrap();

License: GPL-3.0-or-later

Dependencies

~3MB
~64K SLoC