Libcaesium is a simple library performing JPEG, PNG, WebP, TIFF and GIF (partial) compression/optimization written in Rust, with a C interface.
Libcaesium exposes several functions for compressing and converting images, both from files and in-memory buffers.
use caesium::parameters::CSParameters;
use caesium::compress;
let mut parameters = CSParameters::new();
parameters.keep_metadata = true;
parameters.jpeg.quality = 60;
let input_file_path = "input.jpg".to_string();
let output_file_path = "output.jpg".to_string();
let result = compress(input_file_path, output_file_path, ¶meters);
assert!(result.is_ok());
use caesium::parameters::CSParameters;
use caesium::compress_in_memory;
use std::fs;
let parameters = CSParameters::new();
let image_bytes = fs::read("input.png").unwrap();
let compressed_bytes = compress_in_memory(image_bytes, ¶meters).unwrap();
// You can now write `compressed_bytes` to a file or use it as needed
use caesium::parameters::CSParameters;
use caesium::compress_to_size;
let mut parameters = CSParameters::new();
let input_file_path = "input.webp".to_string();
let output_file_path = "output.webp".to_string();
let max_output_size = 100_000; // 100 KB
let result = compress_to_size(input_file_path, output_file_path, &mut parameters, max_output_size, true);
assert!(result.is_ok());
use caesium::{parameters::CSParameters, convert, SupportedFileTypes};
let parameters = CSParameters::new();
let input_file_path = "input.png".to_string();
let output_file_path = "output.jpg".to_string();
let result = convert(input_file_path, output_file_path, ¶meters, SupportedFileTypes::Jpeg);
assert!(result.is_ok());
use caesium::{parameters::CSParameters, convert_in_memory, SupportedFileTypes};
use std::fs;
let parameters = CSParameters::new();
let image_bytes = fs::read("input.tiff").unwrap();
let converted_bytes = convert_in_memory(image_bytes, ¶meters, SupportedFileTypes::Png).unwrap();
// Use `converted_bytes` as needed
You can find more real-world usage in the examples folder.
To run an example, use:
cargo run --example <example_name>
Compilation is available for all supported platforms: Windows, macOS and Linux.
Note
if you don't use the --release
flag, the PNG optimizations can take a very long time to complete, especially
using the zopfli algorithm.
cargo build --release
The result will be a dynamic library usable by external applications through its C interface.
You can find the C header file in the include folder in the project root directory.
Libcaesium exposes C functions, auto-detecting the input file type:
pub unsafe extern "C" fn c_compress(
input_path: *const c_char,
output_path: *const c_char,
params: CCSParameters
) -> CCSResult
input_path
- input file path (full filename)output_path
- output file path (full filename)parameters
- options struct, containing compression parameters (see below)
A CCSResult
struct
#[repr(C)]
pub struct CCSResult {
pub success: bool,
pub code: u32,
pub error_message: *const c_char,
}
If success
is true
the compression process ended successfully and error_message
will be empty.
On failure, the error_message
will be filled with a string containing a brief explanation of the error.
pub unsafe extern "C" fn c_compress_to_size(
input_path: *const c_char,
output_path: *const c_char,
params: CCSParameters,
max_output_size: usize,
return_smallest: bool,
) -> CCSResult
input_path
- input file path (full filename)output_path
- output file path (full filename)parameters
- options struct, containing compression parameters (see below)max_output_size
- the maximum output size, in bytesreturn_smallest
- whether to return the smallest
A CCSResult
struct
#[repr(C)]
pub struct CCSResult {
pub success: bool,
pub code: u32,
pub error_message: *const c_char,
}
If success
is true
the compression process ended successfully and error_message
will be empty.
On failure, the error_message
will be filled with a string containing a brief explanation of the error.
pub unsafe extern "C" fn c_convert(
input_path: *const c_char,
output_path: *const c_char,
format: SupportedFileTypes,
params: CCSParameters,
) -> CCSResult
input_path
- input file path (full filename)output_path
- output file path (full filename)format
- target image format (see below)parameters
- options struct, containing compression parameters (see below)
A CCSResult
struct
#[repr(C)]
pub struct CCSResult {
pub success: bool,
pub code: u32,
pub error_message: *const c_char,
}
If success
is true
the compression process ended successfully and error_message
will be empty.
On failure, the error_message
will be filled with a string containing a brief explanation of the error.
The C options struct is slightly different from the Rust one:
#[repr(C)]
pub struct CCSParameters {
pub keep_metadata: bool,
pub jpeg_quality: u32,
pub jpeg_chroma_subsampling: u32,
pub jpeg_progressive: bool,
pub jpeg_optimize: bool,
pub png_quality: u32,
pub png_optimization_level: u32,
pub png_force_zopfli: bool,
pub png_optimize: bool,
pub gif_quality: u32,
pub webp_quality: u32,
pub webp_lossless: bool,
pub tiff_compression: u32,
pub tiff_deflate_level: u32,
pub optimize: bool,
pub width: u32,
pub height: u32,
}
The option description is the same as the Rust counterpart.
Valid values for jpeg_chroma_subsampling
are [444, 422, 420, 411]
. Any other value will be ignored and will be used
as
the default option.
Valid values for tiff_compression
are [0 (Uncompressed), 1 (Lzw), 2 (Deflate), 3 (Packbits)]
. Any other value will
be ignored and 0
will be used.
Valid values for tiff_deflate_level
are [1 (Fast), 6 (Balanced), 9 (Best)]
. Any other value will be ignored and
Best
will be used.
#[repr(C)]
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum SupportedFileTypes {
Jpeg,
Png,
Gif,
WebP,
Tiff,
Unkn,
}
JPEG is a lossy format: that means you will always lose some information after each compression. So, compressing a file
with quality 100 for 10 times will result in an always different image, even though you can't really see the difference.
Libcaesium also supports optimization. This performs a lossless process, resulting in the
same exact image, but with a smaller size (10–12% usually).
GIF optimization is possible but currently not supported.
WebP's optimization is also possible, but it will probably result in a bigger output file as it's well suited to
losslessly convert from PNG or JPEG.