From 4b45f33c927aa02d87ca1ca1154d54139e42e46c Mon Sep 17 00:00:00 2001 From: Matteo Paonessa Date: Fri, 21 Feb 2025 16:04:18 +0100 Subject: [PATCH] Fix to #82 + added chroma subsampling option #81 --- Cargo.lock | 22 +++++++--------------- Cargo.toml | 2 +- src/compressor.rs | 7 +++++-- src/main.rs | 14 +++++++++++++- src/options.rs | 18 ++++++++++++++++++ 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a711f5..fa51819 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -203,7 +203,7 @@ dependencies = [ "image", "imagesize", "indicatif", - "infer 0.19.0", + "infer", "kamadak-exif", "libcaesium", "rayon", @@ -620,15 +620,6 @@ dependencies = [ "web-time", ] -[[package]] -name = "infer" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847" -dependencies = [ - "cfb", -] - [[package]] name = "infer" version = "0.19.0" @@ -712,18 +703,19 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libcaesium" -version = "0.17.2" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01758171300d6c9666e33e9dcac3fe06650884493d221aab06c6a93c671aa800" +checksum = "3b0e4c5f85278cfdebc247bd6d09a3637272b79951e7305e69d7707b7b891837" dependencies = [ "bytes", "gifsicle", "image", "imagequant", "img-parts", - "infer 0.16.0", + "infer", "kamadak-exif", "libc", + "libwebp-sys", "lodepng", "mozjpeg-sys", "oxipng", @@ -772,9 +764,9 @@ dependencies = [ [[package]] name = "libwebp-sys" -version = "0.9.6" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54cd30df7c7165ce74a456e4ca9732c603e8dc5e60784558c1c6dc047f876733" +checksum = "829b6b604f31ed6d2bccbac841fe0788de93dbd87e4eb1ba2c4adfe8c012a838" dependencies = [ "cc", "glob", diff --git a/Cargo.toml b/Cargo.toml index 0115fc2..1a6398e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ rayon = "1.10" human_bytes = { version = "0.4", default-features = false } kamadak-exif = "0.6" imagesize = "0.13" -libcaesium = "0.17.2" +libcaesium = "0.17.3" clap = { version = "4.5", features = ["derive"] } [dev-dependencies] diff --git a/src/compressor.rs b/src/compressor.rs index af77ac4..27774c4 100644 --- a/src/compressor.rs +++ b/src/compressor.rs @@ -1,6 +1,6 @@ use crate::options::{OutputFormat, OverwritePolicy}; use crate::scan_files::get_file_mime_type; -use caesium::parameters::CSParameters; +use caesium::parameters::{CSParameters, ChromaSubsampling}; use caesium::{compress_in_memory, compress_to_size_in_memory, convert_in_memory, SupportedFileTypes}; use indicatif::ProgressBar; use rayon::iter::ParallelIterator; @@ -28,7 +28,6 @@ pub struct CompressionResult { pub message: String, } -#[derive(Debug)] pub struct CompressionOptions { pub quality: Option, pub max_size: Option, @@ -48,6 +47,7 @@ pub struct CompressionOptions { pub format: OutputFormat, pub keep_dates: bool, pub keep_structure: bool, + pub jpeg_chroma_subsampling: ChromaSubsampling, } pub fn start_compression( @@ -251,6 +251,8 @@ fn build_compression_parameters( parameters.keep_metadata = options.exif; + parameters.jpeg.chroma_subsampling = options.jpeg_chroma_subsampling; + parameters.png.optimization_level = options.png_opt_level; parameters.png.force_zopfli = options.zopfli; @@ -774,6 +776,7 @@ mod tests { keep_dates: false, exif: true, png_opt_level: 0, + jpeg_chroma_subsampling: ChromaSubsampling::Auto, zopfli: false, base_path: PathBuf::new(), } diff --git a/src/main.rs b/src/main.rs index 67664de..78b74ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use crate::compressor::{start_compression, CompressionOptions, CompressionResult, CompressionStatus}; -use crate::options::CommandLineArgs; +use crate::options::{CommandLineArgs, JpegChromaSubsampling}; use crate::scan_files::scan_files; +use caesium::parameters::ChromaSubsampling; use clap::Parser; use human_bytes::human_bytes; use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; @@ -137,11 +138,22 @@ fn build_compression_options(args: &CommandLineArgs, base_path: &Path) -> Compre keep_dates: args.keep_dates, exif: args.exif, png_opt_level: args.png_opt_level, + jpeg_chroma_subsampling: parse_jpeg_chroma_subsampling(args.jpeg_chroma_subsampling), zopfli: args.zopfli, base_path: PathBuf::from(base_path), } } +fn parse_jpeg_chroma_subsampling(arg: JpegChromaSubsampling) -> ChromaSubsampling { + match arg { + JpegChromaSubsampling::ChromaSubsampling444 => ChromaSubsampling::CS444, + JpegChromaSubsampling::ChromaSubsampling422 => ChromaSubsampling::CS422, + JpegChromaSubsampling::ChromaSubsampling420 => ChromaSubsampling::CS420, + JpegChromaSubsampling::ChromaSubsampling411 => ChromaSubsampling::CS411, + _ => ChromaSubsampling::Auto, + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/options.rs b/src/options.rs index c3389c1..13e320a 100644 --- a/src/options.rs +++ b/src/options.rs @@ -19,6 +19,20 @@ pub enum OutputFormat { Tiff, Original, } + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)] +pub enum JpegChromaSubsampling { + #[value(name = "4:4:4")] + ChromaSubsampling444, + #[value(name = "4:2:2")] + ChromaSubsampling422, + #[value(name = "4:2:0")] + ChromaSubsampling420, + #[value(name = "4:1:1")] + ChromaSubsampling411, + #[value(name = "auto")] + Auto, +} #[derive(Parser, Debug)] #[command(version, about, long_about = None)] pub struct CommandLineArgs { @@ -39,6 +53,10 @@ pub struct CommandLineArgs { #[arg(long, default_value = "3")] pub png_opt_level: u8, + /// select level for PNG optimization, between [0-6] + #[arg(long, value_enum, default_value = "auto")] + pub jpeg_chroma_subsampling: JpegChromaSubsampling, + /// use zopfli when optimizing PNG files (it may take a very long time to complete) #[arg(long)] pub zopfli: bool,