#jpeg #静态 #libjpeg #mozjpeg

sys mozjpeg-sys

FFI绑定MozJPEG v4。MozJPEG将自动构建并静态链接。需要nasm和C编译器。

10个稳定版本

2.2.1 2024年8月2日
2.2.0 2024年5月20日
2.1.0 2024年3月25日
2.0.5 2023年10月19日
0.0.4 2015年1月31日

#967 in 图像

Download history 3513/week @ 2024-05-04 3774/week @ 2024-05-11 3824/week @ 2024-05-18 3218/week @ 2024-05-25 4101/week @ 2024-06-01 3363/week @ 2024-06-08 3269/week @ 2024-06-15 2944/week @ 2024-06-22 4104/week @ 2024-06-29 3198/week @ 2024-07-06 3589/week @ 2024-07-13 3557/week @ 2024-07-20 3901/week @ 2024-07-27 5162/week @ 2024-08-03 3912/week @ 2024-08-10 2406/week @ 2024-08-17

每月16,219次下载
用于 30 个crate(6个直接使用)

IJG AND Zlib AND BSD-3-Clause

4.5MB
84K 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

为Rust提供低级MozJPEG绑定

此crate公开了原始libjpeg API,因此适用libjpeg使用手册。你很可能会想通过更高级的API来使用它 :)

struct中的许多字段默认标记为私有,但如果你需要访问它们,请提交一个标记它们为 pub 的pull request。

需求

  • 构建基本工具(gcc等)
  • nasm 用于Intel CPU,gas 用于ARM。注意:Apple的Xcode提供了一个极其过时的nasm版本,无法使用。

此crate支持x86、x86-64和ARM64。

用法

在Rust/Cargo中,在Cargo.toml中将 "mozjpeg-sys" 添加为依赖项。

如果你需要使用Cargo构建C代码的jpeglib.h头文件,所需的包含路径在Cargo 构建脚本中通过DEP_JPEG_INCLUDE环境变量设置。

对于非Rust项目,你可以使用Cargo构建库。

cargo build --release

它创建了 target/release/libmozjpeg_sys.atarget/release/libmozjpeg_sys.{dll,so,dylib},这些文件可以用C和其他语言进行链接。

默认情况下,nasm_simd 特性被启用,并且这个crate将尝试编译SIMD支持。此外,您还可以设置 TARGET_CPU 环境变量(等同于 -march=$TARGET_CPU)以针对特定CPU型号优化所有C代码。

示例

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);

编写

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);

依赖关系