From 31a1ca6f8bbc6c0dfe32740e6a80ee61f0ee8e4d Mon Sep 17 00:00:00 2001 From: Matteo Paonessa Date: Fri, 11 Oct 2024 15:17:51 +0200 Subject: [PATCH] Example and cleanup --- .idea/caesium.iml | 1 + Cargo.toml | 4 - README.md | 191 +++++-------------------------- src/main.rs => examples/basic.rs | 5 +- examples/convert.rs | 22 ++++ examples/size.rs | 21 ++++ src/lib.rs | 7 -- src/parameters.rs | 7 +- 8 files changed, 76 insertions(+), 182 deletions(-) rename src/main.rs => examples/basic.rs (78%) create mode 100644 examples/convert.rs create mode 100644 examples/size.rs diff --git a/.idea/caesium.iml b/.idea/caesium.iml index d233b62..11c4ee6 100644 --- a/.idea/caesium.iml +++ b/.idea/caesium.iml @@ -4,6 +4,7 @@ + diff --git a/Cargo.toml b/Cargo.toml index df3236a..59a3196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,10 +47,6 @@ kamadak-exif = "0.5" [dev-dependencies] dssim = { version = "3.3", default-features = false, features = ["no-macos-vimage"] } -[[bin]] -name = "main" -path = "src/main.rs" - [lib] name = "caesium" path = "src/lib.rs" diff --git a/README.md b/README.md index f2a4829..780f449 100644 --- a/README.md +++ b/README.md @@ -7,155 +7,35 @@ Rust, with a C interface. > 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 in Rust +## Usage example Libcaesium exposes two functions, auto-detecting the input file type -### Based on quality values - ```Rust -pub fn compress( - input_path: String, - output_path: String, - parameters: &CSParameters -) -> Result<(), Box> +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, ¶meters).is_ok(); ``` -#### Parameters +## Compilation -- `input_path` - input file path (full filename) -- `output_path` - output file path (full filename) -- `parameters` - options struct, containing compression parameters (see below) +Compilation is available for all supported platforms: Windows, macOS and Linux. -### Based on output size +> [!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. +> -```Rust -pub fn compress_to_size( - input_path: String, - output_path: String, - parameters: &CSParameters, - max_output_size: usize, -) -> Result<(), Box> +```bash +cargo build --release ``` -#### 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 - -This function will attempt to compress the given file *below* the desired size. It will never exceed it. The function -will start looping until the best size under the desired is achieved. The function has a 2% tolerance for the output -size. -All quality value set to the parameters will be ignored and overwritten during the compression. - -NOTE: The output folder where the file is compressed **must** exist. - -### Compression options - -Libcaesium supports a few compression parameters for each file it supports. -They are defined into a top level struct containing each supported file parameters, as follows: - -```Rust -pub struct CSParameters { - pub jpeg: jpeg::Parameters, - pub png: png::Parameters, - pub gif: gif::Parameters, - pub webp: webp::Parameters, - pub tiff: tiff::Parameters, - pub keep_metadata: bool, - pub optimize: bool, - pub width: u32, - pub height: u32, -} -``` - -Each file type has its own options, but the last two are generic: - -- `keep_metadata`: will keep metadata information for any supported type. JPEG and PNG supported. Default `false`. -- `optimize`: forces optimization, when available. With this option enabled the compression will be lossless. JPEG, PNG - and WebP supported. Default `false`. -- `width`: Resizes the image to the given width. If this value is `0` and the height value is also `0`, no resizing will - be done. If this is `0` and height is `> 0`, the image will be scaled based on height keeping the aspect ratio. - Default `0`. -- `height`: Resizes the image to the given height. If this value is `0` and the width value is also `0`, no resizing - will be done. If this is `0` and width is `> 0`, the image will be scaled based on width keeping the aspect ratio. - Default `0`. - -#### jpeg - -```Rust -pub struct Parameters { - pub quality: u32, - pub chroma_subsampling: jpeg::ChromaSubsampling, - pub progressive: bool -} -``` - -- `quality`: in a range from 0 to 100, the quality of the resulting image. Default `80`. -- `chroma_subsampling`: [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling) to apply during - compression. Default `Auto`. -- `progressive`: outputs a progressive image (recommended). Set to `false` for baseline. Default `true`. - -#### png - -```Rust -pub struct Parameters { - pub quality: u32, - pub force_zopfli: bool, - pub optimization_level: u32 -} -``` - -- `quality`: in a range from 0 to 100, the quality of the resulting image. Default `80`. -- `force_zopfli`: if `optimization` is `true` and this option is also `true`, will use zopfli algorithm for compression, - resulting in a smaller image, but it may take minutes to finish the process. Default `false`. -- `optimization_level`: if `optimization` is `true` will set the level of oxipng optimization, from 0 to 6. Default `3`. - -#### gif - -GIF support is experimental, has many know issues and does not support optimization. Expect bugs (especially on -Windows). - -```Rust -pub struct Parameters { - pub quality: u32, -} -``` - -- `quality`: in a range from 0 to 100, the quality of the resulting image. If the optimization flag is `true`, the level - is set to `100`. Default: `80`. - -#### webp - -WebP's compression is tricky. The format is already well optimized and using the `optimize` flag will probably result in -a bigger image. - -```Rust -pub struct Parameters { - pub quality: u32, -} -``` - -- `quality`: in a range from 0 to 100, the quality of the resulting image. If the optimization flag is `true`, this - option will be ignored. Default: `60`. - -#### tiff - -Supported TIFF compression is only lossless. The supported algorithms are: Lzw, Deflate, Packbits, Uncompressed. - -```Rust -pub struct Parameters { - pub algorithm: TiffCompression, - pub deflate_level: TiffDeflateLevel, -} -``` - -- `algorithm`: supported algorithms are: Lzw, Deflate, Packbits, Uncompressed. -- `deflate_level`: can be one of `Fast`, `Balanced`, `Best`. - -_________________ +The result will be a dynamic library usable by external applications through its C interface. ## Usage in C @@ -248,39 +128,20 @@ pub struct CCSParameters { } ``` -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` +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. -## Download - -Binaries not available. Please refer to the compilation section below. - -## Compilation and Installation - -Compilation is available for all supported platforms: Windows, macOS and Linux. - -``` -cargo build --release -``` - -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. - -The result will be a dynamic library usable by external applications through its C interface. - ## 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. +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, by setting the _quality_ to 0. This performs a lossless process, resulting in the -same image, -but with a smaller size (10-12% usually). +same 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. diff --git a/src/main.rs b/examples/basic.rs similarity index 78% rename from src/main.rs rename to examples/basic.rs index 8f45edd..d56b156 100644 --- a/src/main.rs +++ b/examples/basic.rs @@ -9,7 +9,10 @@ fn main() -> ExitCode { let input = args[1].clone(); let output = args[2].clone(); - let parameters = CSParameters::new(); + let mut parameters = CSParameters::new(); + parameters.keep_metadata = true; + parameters.jpeg.quality = 60; + match compress(input, output, ¶meters) { Ok(_) => ExitCode::SUCCESS, Err(e) => { diff --git a/examples/convert.rs b/examples/convert.rs new file mode 100644 index 0000000..75bf71a --- /dev/null +++ b/examples/convert.rs @@ -0,0 +1,22 @@ +use caesium::parameters::CSParameters; +use caesium::convert; +use std::env; +use std::process::ExitCode; + +fn main() -> ExitCode { + let args: Vec = env::args().collect(); + + let input = args[1].clone(); + let output = args[2].clone(); + + let mut parameters = CSParameters::new(); + parameters.png.quality = 60; + + match convert(input, output, ¶meters, caesium::SupportedFileTypes::Png) { + Ok(_) => ExitCode::SUCCESS, + Err(e) => { + eprintln!("{}", e); + ExitCode::FAILURE + } + } +} diff --git a/examples/size.rs b/examples/size.rs new file mode 100644 index 0000000..e09ca92 --- /dev/null +++ b/examples/size.rs @@ -0,0 +1,21 @@ +use caesium::compress_to_size; +use caesium::parameters::CSParameters; +use std::env; +use std::process::ExitCode; + +fn main() -> ExitCode { + let args: Vec = env::args().collect(); + + let input = args[1].clone(); + let output = args[2].clone(); + + let mut parameters = CSParameters::new(); + + match compress_to_size(input, output, &mut parameters, 1000000, true) { + Ok(_) => ExitCode::SUCCESS, + Err(e) => { + eprintln!("{}", e); + ExitCode::FAILURE + } + } +} diff --git a/src/lib.rs b/src/lib.rs index af2f0b4..19d8eaf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -381,13 +381,6 @@ fn validate_parameters(parameters: &CSParameters) -> error::Result<()> { }); } - if parameters.optimize && parameters.output_size > 0 { - return Err(CaesiumError { - message: "Cannot compress to desired size with lossless optimization".into(), - code: 10005, - }); - } - Ok(()) } diff --git a/src/parameters.rs b/src/parameters.rs index 4039a43..7589741 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -109,7 +109,6 @@ pub struct TiffParameters { /// - `optimize`: Whether to use lossless compression /// - `width`: Width of the output image /// - `height`: Height of the output image -/// - `output_size`: Desired output size of the compressed image #[derive(Copy, Clone)] pub struct CSParameters { pub jpeg: JpegParameters, @@ -120,8 +119,7 @@ pub struct CSParameters { pub keep_metadata: bool, pub optimize: bool, pub width: u32, - pub height: u32, - pub output_size: u32, + pub height: u32 } impl Default for CSParameters { fn default() -> Self { @@ -162,7 +160,6 @@ fn initialize_parameters() -> CSParameters { keep_metadata: false, optimize: false, width: 0, - height: 0, - output_size: 0, + height: 0 } } \ No newline at end of file