#jpeg #static #libjpeg #mozjpeg

sys mozjpeg-sys

FFI bindings for MozJPEG v4. MozJPEG is automatically built and linked statically. Requires nasm and a C compiler.

12 stable releases

2.2.4-beta.1 Feb 10, 2025
2.2.1 Aug 2, 2024
2.2.0 May 20, 2024
2.1.0 Mar 25, 2024
0.0.4 Jan 31, 2015

#888 in Images

Download history 2179/week @ 2024-10-30 2214/week @ 2024-11-06 2095/week @ 2024-11-13 2088/week @ 2024-11-20 2416/week @ 2024-11-27 3288/week @ 2024-12-04 3568/week @ 2024-12-11 2665/week @ 2024-12-18 2172/week @ 2024-12-25 2996/week @ 2025-01-01 3178/week @ 2025-01-08 3444/week @ 2025-01-15 3169/week @ 2025-01-22 2784/week @ 2025-01-29 3573/week @ 2025-02-05 3336/week @ 2025-02-12

13,592 downloads per month
Used in 42 crates (10 directly)

IJG AND Zlib AND BSD-3-Clause

4.5MB
85K SLoC

C 51K SLoC // 0.2% comments Assembly 24K SLoC // 0.2% comments GNU Style Assembly 7K SLoC // 0.1% comments Rust 2K SLoC // 0.0% comments Bitbake 742 SLoC

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

  • build-essentials (gcc, etc.)
  • nasm for Intel CPUs, gas for ARM. Note: Apple's Xcode ships an incredibly outdated version of nasm that won't work.

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:

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

let mut err: jpeg_error_mgr = mem::zeroed();
let mut cinfo: jpeg_decompress_struct = mem::zeroed();
cinfo.common.err = jpeg_std_error(&mut err);
jpeg_create_decompress(&mut cinfo);

let file_name = CString::new(file_name.as_bytes()).unwrap();
let mode = CString::new("rb").unwrap();
let fh = libc::fopen(file_name.as_ptr(), mode.as_ptr());
jpeg_stdio_src(&mut cinfo, fh);
jpeg_read_header(&mut cinfo, true as boolean);

// Available only after `jpeg_read_header()`
let width = cinfo.image_width;
let height = cinfo.image_height;

// Output settings be set before calling `jpeg_start_decompress()`
cinfo.out_color_space = J_COLOR_SPACE::JCS_RGB;
jpeg_start_decompress(&mut cinfo);
let row_stride = cinfo.image_width as usize * cinfo.output_components as usize;
let buffer_size = row_stride * cinfo.image_height as usize;
let mut buffer = vec![0u8; buffer_size];

while cinfo.output_scanline < cinfo.output_height {
    let offset = cinfo.output_scanline as usize * row_stride;
    let mut jsamparray = [buffer[offset..].as_mut_ptr()];
    jpeg_read_scanlines(&mut cinfo, jsamparray.as_mut_ptr(), 1);
}

jpeg_finish_decompress(&mut cinfo);
jpeg_destroy_decompress(&mut cinfo);
libc::fclose(fh);

Writing:

let quality = 98;
let file_name = CString::new("example_result.jpg").unwrap();
let mode = CString::new("wb").unwrap();
let fh = libc::fopen(file_name.as_ptr(), mode.as_ptr());

let mut err = mem::zeroed();
let mut cinfo: jpeg_compress_struct = mem::zeroed();
cinfo.common.err = jpeg_std_error(&mut err);
jpeg_create_compress(&mut cinfo);
jpeg_stdio_dest(&mut cinfo, fh);

cinfo.image_width = width;
cinfo.image_height = height;
cinfo.in_color_space = J_COLOR_SPACE::JCS_RGB;
cinfo.input_components = 3;
jpeg_set_defaults(&mut cinfo);

let row_stride = cinfo.image_width as usize * cinfo.input_components as usize;
cinfo.dct_method = J_DCT_METHOD::JDCT_ISLOW;
jpeg_set_quality(&mut cinfo, quality, true as boolean);

jpeg_start_compress(&mut cinfo, true as boolean);

while cinfo.next_scanline < cinfo.image_height {
    let offset = cinfo.next_scanline as usize * row_stride;
    let jsamparray = [buffer[offset..].as_ptr()];
    jpeg_write_scanlines(&mut cinfo, jsamparray.as_ptr(), 1);
}

jpeg_finish_compress(&mut cinfo);
jpeg_destroy_compress(&mut cinfo);
libc::fclose(fh);

Dependencies

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy