Fix to #82 + added chroma subsampling option #81

This commit is contained in:
Matteo Paonessa 2025-02-21 16:04:18 +01:00
parent 376c76eba8
commit 4b45f33c92
5 changed files with 44 additions and 19 deletions

22
Cargo.lock generated
View File

@ -203,7 +203,7 @@ dependencies = [
"image", "image",
"imagesize", "imagesize",
"indicatif", "indicatif",
"infer 0.19.0", "infer",
"kamadak-exif", "kamadak-exif",
"libcaesium", "libcaesium",
"rayon", "rayon",
@ -620,15 +620,6 @@ dependencies = [
"web-time", "web-time",
] ]
[[package]]
name = "infer"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847"
dependencies = [
"cfb",
]
[[package]] [[package]]
name = "infer" name = "infer"
version = "0.19.0" version = "0.19.0"
@ -712,18 +703,19 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]] [[package]]
name = "libcaesium" name = "libcaesium"
version = "0.17.2" version = "0.17.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01758171300d6c9666e33e9dcac3fe06650884493d221aab06c6a93c671aa800" checksum = "3b0e4c5f85278cfdebc247bd6d09a3637272b79951e7305e69d7707b7b891837"
dependencies = [ dependencies = [
"bytes", "bytes",
"gifsicle", "gifsicle",
"image", "image",
"imagequant", "imagequant",
"img-parts", "img-parts",
"infer 0.16.0", "infer",
"kamadak-exif", "kamadak-exif",
"libc", "libc",
"libwebp-sys",
"lodepng", "lodepng",
"mozjpeg-sys", "mozjpeg-sys",
"oxipng", "oxipng",
@ -772,9 +764,9 @@ dependencies = [
[[package]] [[package]]
name = "libwebp-sys" name = "libwebp-sys"
version = "0.9.6" version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54cd30df7c7165ce74a456e4ca9732c603e8dc5e60784558c1c6dc047f876733" checksum = "829b6b604f31ed6d2bccbac841fe0788de93dbd87e4eb1ba2c4adfe8c012a838"
dependencies = [ dependencies = [
"cc", "cc",
"glob", "glob",

View File

@ -22,7 +22,7 @@ rayon = "1.10"
human_bytes = { version = "0.4", default-features = false } human_bytes = { version = "0.4", default-features = false }
kamadak-exif = "0.6" kamadak-exif = "0.6"
imagesize = "0.13" imagesize = "0.13"
libcaesium = "0.17.2" libcaesium = "0.17.3"
clap = { version = "4.5", features = ["derive"] } clap = { version = "4.5", features = ["derive"] }
[dev-dependencies] [dev-dependencies]

View File

@ -1,6 +1,6 @@
use crate::options::{OutputFormat, OverwritePolicy}; use crate::options::{OutputFormat, OverwritePolicy};
use crate::scan_files::get_file_mime_type; 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 caesium::{compress_in_memory, compress_to_size_in_memory, convert_in_memory, SupportedFileTypes};
use indicatif::ProgressBar; use indicatif::ProgressBar;
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
@ -28,7 +28,6 @@ pub struct CompressionResult {
pub message: String, pub message: String,
} }
#[derive(Debug)]
pub struct CompressionOptions { pub struct CompressionOptions {
pub quality: Option<u32>, pub quality: Option<u32>,
pub max_size: Option<usize>, pub max_size: Option<usize>,
@ -48,6 +47,7 @@ pub struct CompressionOptions {
pub format: OutputFormat, pub format: OutputFormat,
pub keep_dates: bool, pub keep_dates: bool,
pub keep_structure: bool, pub keep_structure: bool,
pub jpeg_chroma_subsampling: ChromaSubsampling,
} }
pub fn start_compression( pub fn start_compression(
@ -251,6 +251,8 @@ fn build_compression_parameters(
parameters.keep_metadata = options.exif; parameters.keep_metadata = options.exif;
parameters.jpeg.chroma_subsampling = options.jpeg_chroma_subsampling;
parameters.png.optimization_level = options.png_opt_level; parameters.png.optimization_level = options.png_opt_level;
parameters.png.force_zopfli = options.zopfli; parameters.png.force_zopfli = options.zopfli;
@ -774,6 +776,7 @@ mod tests {
keep_dates: false, keep_dates: false,
exif: true, exif: true,
png_opt_level: 0, png_opt_level: 0,
jpeg_chroma_subsampling: ChromaSubsampling::Auto,
zopfli: false, zopfli: false,
base_path: PathBuf::new(), base_path: PathBuf::new(),
} }

View File

@ -1,6 +1,7 @@
use crate::compressor::{start_compression, CompressionOptions, CompressionResult, CompressionStatus}; use crate::compressor::{start_compression, CompressionOptions, CompressionResult, CompressionStatus};
use crate::options::CommandLineArgs; use crate::options::{CommandLineArgs, JpegChromaSubsampling};
use crate::scan_files::scan_files; use crate::scan_files::scan_files;
use caesium::parameters::ChromaSubsampling;
use clap::Parser; use clap::Parser;
use human_bytes::human_bytes; use human_bytes::human_bytes;
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
@ -137,11 +138,22 @@ fn build_compression_options(args: &CommandLineArgs, base_path: &Path) -> Compre
keep_dates: args.keep_dates, keep_dates: args.keep_dates,
exif: args.exif, exif: args.exif,
png_opt_level: args.png_opt_level, png_opt_level: args.png_opt_level,
jpeg_chroma_subsampling: parse_jpeg_chroma_subsampling(args.jpeg_chroma_subsampling),
zopfli: args.zopfli, zopfli: args.zopfli,
base_path: PathBuf::from(base_path), 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -19,6 +19,20 @@ pub enum OutputFormat {
Tiff, Tiff,
Original, 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)] #[derive(Parser, Debug)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
pub struct CommandLineArgs { pub struct CommandLineArgs {
@ -39,6 +53,10 @@ pub struct CommandLineArgs {
#[arg(long, default_value = "3")] #[arg(long, default_value = "3")]
pub png_opt_level: u8, 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) /// use zopfli when optimizing PNG files (it may take a very long time to complete)
#[arg(long)] #[arg(long)]
pub zopfli: bool, pub zopfli: bool,