diff --git a/src/cli/common.rs b/src/cli/common.rs index e1c7420f..ee400720 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use clap::{arg, value_parser, Command}; +use clap::{arg, value_parser, ArgAction, Command}; use indoc::indoc; use super::{preprocessors::Preprocessors, utils::threads}; @@ -51,6 +51,10 @@ impl CommonArgs for Command { By default, the number of available threads is utilized."#}) .value_parser(value_parser!(u8).range(1..=threads::num_threads() as i64)), ) + .arg( + arg!(-x --strip "Strip metadata when encoding images (where supported)") + .action(ArgAction::SetTrue) + ) .arg( arg!(--"no-progress" "Disables progress bar.") .long_help(indoc! {r#"Disables progress bar. diff --git a/src/codecs/mozjpeg/encoder/mod.rs b/src/codecs/mozjpeg/encoder/mod.rs index aef6de85..e7094eb9 100644 --- a/src/codecs/mozjpeg/encoder/mod.rs +++ b/src/codecs/mozjpeg/encoder/mod.rs @@ -177,6 +177,7 @@ impl EncoderTrait for MozJpegEncoder { { use exif::experimental::Writer; + // write exif data if let Some(metadata) = &image.metadata().exif() { let mut writer = Writer::new(); // write first tags for exif @@ -195,6 +196,11 @@ impl EncoderTrait for MozJpegEncoder { log::warn!("Writing exif failed {:?}", result); } } + + // write icc data + if let Some(metadata) = &image.metadata().icc_chunk() { + comp.write_icc_profile(metadata); + } } comp.write_scanlines(data)?; diff --git a/src/codecs/oxipng/encoder/mod.rs b/src/codecs/oxipng/encoder/mod.rs index 354bbfc6..89426420 100644 --- a/src/codecs/oxipng/encoder/mod.rs +++ b/src/codecs/oxipng/encoder/mod.rs @@ -99,6 +99,7 @@ impl EncoderTrait for OxiPngEncoder { let mut buf = std::io::Cursor::new(vec![]); + // write exif data if let Some(fields) = &image.metadata().exif() { let mut writer = Writer::new(); @@ -112,6 +113,11 @@ impl EncoderTrait for OxiPngEncoder { log::warn!("Writing exif failed {:?}", result); } } + + // write icc data + if let Some(icc) = &image.metadata().icc_chunk() { + img.add_icc_profile(icc); + } } let mut writer = ZWriter::new(sink); diff --git a/src/main.rs b/src/main.rs index e3e54657..f5d284ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,6 +42,9 @@ macro_rules! handle_error { }; } +const SUPPORTS_EXIF: &[&str] = &["mozjpeg", "oxipng"]; +const SUPPORTS_ICC: &[&str] = &["mozjpeg", "oxipng"]; + struct Result { output: PathBuf, input_size: u64, @@ -105,6 +108,7 @@ fn main() { let recursive = matches.get_flag("recursive"); let backup = matches.get_flag("backup"); + let strip_metadata = matches.get_flag("strip"); let quiet = matches.get_flag("quiet"); let no_progress = matches.get_flag("no-progress"); @@ -151,8 +155,13 @@ fn main() { pipeline.chain_operations(Box::new(Depth::new(BitDepth::Eight))); pipeline.chain_operations(Box::new(ColorspaceConv::new(ColorSpace::RGBA))); - pipeline.chain_operations(Box::new(AutoOrient)); - pipeline.chain_operations(Box::new(ApplySRGB)); + if strip_metadata || !SUPPORTS_EXIF.contains(&subcommand) { + pipeline.chain_operations(Box::new(AutoOrient)); + } + + if strip_metadata || !SUPPORTS_ICC.contains(&subcommand) { + pipeline.chain_operations(Box::new(ApplySRGB)); + } operations(matches, &img) .into_iter() diff --git a/src/operations/icc/mod.rs b/src/operations/icc/mod.rs index ac8200f9..180e29b2 100644 --- a/src/operations/icc/mod.rs +++ b/src/operations/icc/mod.rs @@ -121,7 +121,9 @@ impl OperationsTrait for ApplySRGB { return Ok(()); } - ApplyICC::new(Profile::new_srgb_context(ThreadContext::new())).execute_impl(image) + ApplyICC::new(Profile::new_srgb_context(ThreadContext::new())).execute_impl(image)?; + + Ok(()) } fn supported_types(&self) -> &'static [BitType] {