# jpegxl-rs [![Documentation](https://docs.rs/jpegxl-rs/badge.svg)](https://docs.rs/jpegxl-rs/) [![Crates.io](https://img.shields.io/crates/v/jpegxl-rs.svg)](https://crates.io/crates/jpegxl-rs) [![dependency status](https://deps.rs/repo/github/inflation/jpegxl-rs/status.svg)](https://deps.rs/repo/github/inflation/jpegxl-rs) [![CI](https://github.com/inflation/jpegxl-rs/workflows/CI/badge.svg)](https://github.com/inflation/jpegxl-rs/actions?query=workflow%3ACI) [![codecov](https://codecov.io/gh/inflation/jpegxl-rs/branch/master/graph/badge.svg?token=3WMRUQ816H)](https://codecov.io/gh/inflation/jpegxl-rs) [![License: GPL-3.0-or-later](https://img.shields.io/crates/l/jpegxl-rs)](https://github.com/inflation/jpegxl-rs/blob/master/LICENSE) A safe JPEGXL wrapper over `libjxl` library. Check out the original [library](https://github.com/libjxl/libjxl) and the [bindings](https://github.com/inflation/jpegxl-rs/tree/master/jpegxl-sys). ## 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 ```rust 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 data */ }, Pixels::Uint8(data) => { /* do something with Vec data */ }, Pixels::Uint16(data) => { /* do something with Vec data */ }, Pixels::Float16(data) => { /* do something with Vec 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::(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 ```rust 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 = 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`](https://crates.io/crates/image) crate integration The integration is enabled by default. If you don't need it, disable `image` feature. ```rust 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::(&sample).unwrap(); ``` License: GPL-3.0-or-later