Skip to content

The Caesium compression library written in Rust (with a C interface)

License

Notifications You must be signed in to change notification settings

Lymphatus/libcaesium

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

libcaesium Rust

Libcaesium is a simple library performing JPEG, PNG, WebP and GIF (experimental) compression/optimization written in Rust, with a C interface.

Warning

starting from v0.6.0 the library is written in Rust and no longer in C. There's a C interface, but it's not backward compatible with the <0.6.0.

Usage example

Libcaesium exposes two functions, auto-detecting the input file type

use caesium::parameters::CSParameters;
use caesium::compress;

let mut parameters = CSParameters::new();
parameters.keep_metadata = true;
parameters.jpeg.quality = 60;

let success = compress(input, output, &parameters).is_ok();

Compilation

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.

Usage in C

You can find the C header file in the include folder in the project root directory.

Libcaesium exposes there C functions, auto-detecting the input file type:

Based on quality values

pub unsafe extern "C" fn c_compress(
    input_path: *const c_char,
    output_path: *const c_char,
    params: CCSParameters
) -> CCSResult

Parameters

  • input_path - input file path (full filename)
  • output_path - output file path (full filename)
  • parameters - options struct, containing compression parameters (see below)

Return

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.

Based on output size

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

Parameters

  • 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 bytes
  • return_smallest - whether to return the smallest

Return

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.

Based on convert output

pub unsafe extern "C" fn c_convert(
    input_path: *const c_char,
    output_path: *const c_char,
    format: SupportedFileTypes,
    params: CCSParameters,
) -> CCSResult

Parameters

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

Return

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.

Compression options

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 png_quality: u32,
    pub png_optimization_level: u32,
    pub png_force_zopfli: bool,
    pub gif_quality: u32,
    pub webp_quality: u32,
    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 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.

Supported file types

#[repr(C)]
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum SupportedFileTypes {
    Jpeg,
    Png,
    Gif,
    WebP,
    Tiff,
    Unkn,
}

Compression vs Optimization

JPEG is a lossy format: that means you will always lose some information after each compression. So, compressing a file with 100 quality 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.