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 |
|
#967 in 图像
每月16,219次下载
用于 30 个crate(6个直接使用)
4.5MB
84K 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.a
和 target/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);