Low-level MozJPEG bindings for Rust

This crate exposes the raw libjpeg API, so the libjpeg usage manual applies. You'll most likely want to use it via a higher-level API instead :)

Many fields in structs are marked as private by default, but if you need to access them, make a pull request marking them pub.

Requirements

This crate supports x86, x86-64 and ARM64.

Usage

In Rust/Cargo, add "mozjpeg-sys" as a dependency in Cargo.toml.

In case you need the jpeglib.h header for C code built with Cargo, the required include paths (use env::split_paths()) are set for Cargo build scripts in the DEP_JPEG_INCLUDE env var.

For non-Rust projects you can build the library using Cargo:

sh cargo build --release

It creates target/release/libmozjpeg_sys.a and target/release/libmozjpeg_sys.{dll,so,dylib}, which can be linked with C and other languages.

By default nasm_simd feature is enabled, and this crate will try to compile SIMD support. Additionally, you can set TARGET_CPU environmental variable (equivalent to -march=$TARGET_CPU) to optimize all of C code for a specific CPU model.

Example

```rust let mut err: jpegerrormgr = mem::zeroed(); let mut cinfo: jpegdecompressstruct = mem::zeroed(); cinfo.common.err = jpegstderror(&mut err); jpegcreatedecompress(&mut cinfo);

let filename = CString::new(filename.asbytes()).unwrap(); let mode = CString::new("rb").unwrap(); let fh = libc::fopen(filename.asptr(), mode.asptr()); jpegstdiosrc(&mut cinfo, fh); jpegreadheader(&mut cinfo, true as boolean);

// Available only after jpeg_read_header() let width = cinfo.imagewidth; let height = cinfo.imageheight;

// Output settings be set before calling jpeg_start_decompress() cinfo.outcolorspace = JCOLORSPACE::JCSRGB; jpegstartdecompress(&mut cinfo); let rowstride = cinfo.imagewidth as usize * cinfo.outputcomponents as usize; let buffersize = rowstride * cinfo.imageheight as usize; let mut buffer = vec![0u8; buffersize];

while cinfo.outputscanline < cinfo.outputheight { let offset = cinfo.outputscanline as usize * rowstride; let mut jsamparray = [buffer[offset..].asmutptr()]; jpegreadscanlines(&mut cinfo, jsamparray.asmutptr(), 1); }

jpegfinishdecompress(&mut cinfo); jpegdestroydecompress(&mut cinfo); libc::fclose(fh); ```

Writing:

```rust let quality = 98; let filename = CString::new("exampleresult.jpg").unwrap(); let mode = CString::new("wb").unwrap(); let fh = libc::fopen(filename.asptr(), mode.as_ptr());

let mut err = mem::zeroed(); let mut cinfo: jpegcompressstruct = mem::zeroed(); cinfo.common.err = jpegstderror(&mut err); jpegcreatecompress(&mut cinfo); jpegstdiodest(&mut cinfo, fh);

cinfo.imagewidth = width; cinfo.imageheight = height; cinfo.incolorspace = JCOLORSPACE::JCSRGB; cinfo.inputcomponents = 3; jpegsetdefaults(&mut cinfo);

let rowstride = cinfo.imagewidth as usize * cinfo.inputcomponents as usize; cinfo.dctmethod = JDCTMETHOD::JDCTISLOW; jpegset_quality(&mut cinfo, quality, true as boolean);

jpegstartcompress(&mut cinfo, true as boolean);

while cinfo.nextscanline < cinfo.imageheight { let offset = cinfo.nextscanline as usize * rowstride; let jsamparray = [buffer[offset..].asptr()]; jpegwritescanlines(&mut cinfo, jsamparray.asptr(), 1); }

jpegfinishcompress(&mut cinfo); jpegdestroycompress(&mut cinfo); libc::fclose(fh); ```