From a72bc945fc4da502a9e8164b2c4bff3409ff36e8 Mon Sep 17 00:00:00 2001 From: Kornel Date: Tue, 31 Dec 2024 15:47:18 +0000 Subject: [PATCH] Clippy --- benches/filters.rs | 123 ++++++++++--------------------------- benches/strategies.rs | 20 ++---- src/atomicmin.rs | 5 +- src/colors.rs | 54 ++++++++-------- src/deflate/deflater.rs | 1 + src/error.rs | 8 +-- src/evaluate.rs | 2 +- src/headers.rs | 12 ++-- src/lib.rs | 18 +++--- src/main.rs | 12 ++-- src/options.rs | 31 ++++++---- src/png/mod.rs | 27 +++++--- src/png/scan_lines.rs | 3 + src/reduction/alpha.rs | 5 +- src/reduction/bit_depth.rs | 12 ++-- src/reduction/color.rs | 8 +-- src/reduction/palette.rs | 2 +- tests/flags.rs | 13 ++-- 18 files changed, 148 insertions(+), 208 deletions(-) diff --git a/benches/filters.rs b/benches/filters.rs index 50536b50..b710131a 100644 --- a/benches/filters.rs +++ b/benches/filters.rs @@ -5,7 +5,8 @@ extern crate test; use std::path::PathBuf; -use oxipng::{internal_tests::*, *}; +use oxipng::internal_tests::*; +use oxipng::*; use test::Bencher; #[bench] @@ -13,9 +14,7 @@ fn filters_16_bits_filter_0(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::None, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::None, false)); } #[bench] @@ -23,9 +22,7 @@ fn filters_8_bits_filter_0(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::None, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::None, false)); } #[bench] @@ -35,9 +32,7 @@ fn filters_4_bits_filter_0(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::None, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::None, false)); } #[bench] @@ -47,9 +42,7 @@ fn filters_2_bits_filter_0(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::None, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::None, false)); } #[bench] @@ -59,9 +52,7 @@ fn filters_1_bits_filter_0(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::None, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::None, false)); } #[bench] @@ -69,9 +60,7 @@ fn filters_16_bits_filter_1(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Sub, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Sub, false)); } #[bench] @@ -79,9 +68,7 @@ fn filters_8_bits_filter_1(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Sub, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Sub, false)); } #[bench] @@ -91,9 +78,7 @@ fn filters_4_bits_filter_1(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Sub, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Sub, false)); } #[bench] @@ -103,9 +88,7 @@ fn filters_2_bits_filter_1(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Sub, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Sub, false)); } #[bench] @@ -115,9 +98,7 @@ fn filters_1_bits_filter_1(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Sub, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Sub, false)); } #[bench] @@ -125,9 +106,7 @@ fn filters_16_bits_filter_2(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Up, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Up, false)); } #[bench] @@ -135,9 +114,7 @@ fn filters_8_bits_filter_2(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Up, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Up, false)); } #[bench] @@ -147,9 +124,7 @@ fn filters_4_bits_filter_2(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Up, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Up, false)); } #[bench] @@ -159,9 +134,7 @@ fn filters_2_bits_filter_2(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Up, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Up, false)); } #[bench] @@ -171,9 +144,7 @@ fn filters_1_bits_filter_2(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Up, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Up, false)); } #[bench] @@ -181,9 +152,7 @@ fn filters_16_bits_filter_3(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Average, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Average, false)); } #[bench] @@ -191,9 +160,7 @@ fn filters_8_bits_filter_3(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Average, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Average, false)); } #[bench] @@ -203,9 +170,7 @@ fn filters_4_bits_filter_3(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Average, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Average, false)); } #[bench] @@ -215,9 +180,7 @@ fn filters_2_bits_filter_3(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Average, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Average, false)); } #[bench] @@ -227,9 +190,7 @@ fn filters_1_bits_filter_3(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Average, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Average, false)); } #[bench] @@ -237,9 +198,7 @@ fn filters_16_bits_filter_4(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Paeth, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Paeth, false)); } #[bench] @@ -247,9 +206,7 @@ fn filters_8_bits_filter_4(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Paeth, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Paeth, false)); } #[bench] @@ -259,9 +216,7 @@ fn filters_4_bits_filter_4(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Paeth, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Paeth, false)); } #[bench] @@ -271,9 +226,7 @@ fn filters_2_bits_filter_4(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Paeth, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Paeth, false)); } #[bench] @@ -283,9 +236,7 @@ fn filters_1_bits_filter_4(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Paeth, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Paeth, false)); } #[bench] @@ -293,9 +244,7 @@ fn filters_16_bits_filter_5(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::MinSum, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::MinSum, false)); } #[bench] @@ -303,9 +252,7 @@ fn filters_8_bits_filter_5(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::MinSum, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::MinSum, false)); } #[bench] @@ -315,9 +262,7 @@ fn filters_4_bits_filter_5(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::MinSum, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::MinSum, false)); } #[bench] @@ -327,9 +272,7 @@ fn filters_2_bits_filter_5(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::MinSum, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::MinSum, false)); } #[bench] @@ -339,7 +282,5 @@ fn filters_1_bits_filter_5(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::MinSum, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::MinSum, false)); } diff --git a/benches/strategies.rs b/benches/strategies.rs index ab894b1a..15f546f1 100644 --- a/benches/strategies.rs +++ b/benches/strategies.rs @@ -13,9 +13,7 @@ fn filters_minsum(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::MinSum, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::MinSum, false)); } #[bench] @@ -23,9 +21,7 @@ fn filters_entropy(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Entropy, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Entropy, false)); } #[bench] @@ -33,9 +29,7 @@ fn filters_bigrams(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Bigrams, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Bigrams, false)); } #[bench] @@ -43,9 +37,7 @@ fn filters_bigent(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::BigEnt, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::BigEnt, false)); } #[bench] @@ -53,7 +45,5 @@ fn filters_brute(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| { - png.raw.filter_image(RowFilter::Brute, false); - }); + b.iter(|| png.raw.filter_image(RowFilter::Brute, false)); } diff --git a/src/atomicmin.rs b/src/atomicmin.rs index 4f781c3a..8cbe273e 100644 --- a/src/atomicmin.rs +++ b/src/atomicmin.rs @@ -6,6 +6,7 @@ pub struct AtomicMin { } impl AtomicMin { + #[must_use] pub fn new(init: Option) -> Self { Self { val: AtomicUsize::new(init.unwrap_or(usize::MAX)), @@ -21,8 +22,8 @@ impl AtomicMin { } } - /// Unset value is usize_max - pub fn as_atomic_usize(&self) -> &AtomicUsize { + /// Unset value is `usize_max` + pub const fn as_atomic_usize(&self) -> &AtomicUsize { &self.val } diff --git a/src/colors.rs b/src/colors.rs index 1f33b7e8..3827e247 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -32,13 +32,13 @@ impl Display for ColorType { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - ColorType::Grayscale { .. } => Display::fmt("Grayscale", f), - ColorType::RGB { .. } => Display::fmt("RGB", f), - ColorType::Indexed { palette } => { + Self::Grayscale { .. } => Display::fmt("Grayscale", f), + Self::RGB { .. } => Display::fmt("RGB", f), + Self::Indexed { palette } => { Display::fmt(&format!("Indexed ({} colors)", palette.len()), f) } - ColorType::GrayscaleAlpha => Display::fmt("Grayscale + Alpha", f), - ColorType::RGBA => Display::fmt("RGB + Alpha", f), + Self::GrayscaleAlpha => Display::fmt("Grayscale + Alpha", f), + Self::RGBA => Display::fmt("RGB + Alpha", f), } } } @@ -46,49 +46,47 @@ impl Display for ColorType { impl ColorType { /// Get the code used by the PNG specification to denote this color type #[inline] - pub fn png_header_code(&self) -> u8 { + #[must_use] + pub const fn png_header_code(&self) -> u8 { match self { - ColorType::Grayscale { .. } => 0, - ColorType::RGB { .. } => 2, - ColorType::Indexed { .. } => 3, - ColorType::GrayscaleAlpha => 4, - ColorType::RGBA => 6, + Self::Grayscale { .. } => 0, + Self::RGB { .. } => 2, + Self::Indexed { .. } => 3, + Self::GrayscaleAlpha => 4, + Self::RGBA => 6, } } #[inline] - pub(crate) fn channels_per_pixel(&self) -> u8 { + pub(crate) const fn channels_per_pixel(&self) -> u8 { match self { - ColorType::Grayscale { .. } | ColorType::Indexed { .. } => 1, - ColorType::GrayscaleAlpha => 2, - ColorType::RGB { .. } => 3, - ColorType::RGBA => 4, + Self::Grayscale { .. } | Self::Indexed { .. } => 1, + Self::GrayscaleAlpha => 2, + Self::RGB { .. } => 3, + Self::RGBA => 4, } } #[inline] - pub(crate) fn is_rgb(&self) -> bool { - matches!(self, ColorType::RGB { .. } | ColorType::RGBA) + pub(crate) const fn is_rgb(&self) -> bool { + matches!(self, Self::RGB { .. } | Self::RGBA) } #[inline] - pub(crate) fn is_gray(&self) -> bool { - matches!( - self, - ColorType::Grayscale { .. } | ColorType::GrayscaleAlpha - ) + pub(crate) const fn is_gray(&self) -> bool { + matches!(self, Self::Grayscale { .. } | Self::GrayscaleAlpha) } #[inline] - pub(crate) fn has_alpha(&self) -> bool { - matches!(self, ColorType::GrayscaleAlpha | ColorType::RGBA) + pub(crate) const fn has_alpha(&self) -> bool { + matches!(self, Self::GrayscaleAlpha | Self::RGBA) } #[inline] - pub(crate) fn has_trns(&self) -> bool { + pub(crate) const fn has_trns(&self) -> bool { match self { - ColorType::Grayscale { transparent_shade } => transparent_shade.is_some(), - ColorType::RGB { transparent_color } => transparent_color.is_some(), + Self::Grayscale { transparent_shade } => transparent_shade.is_some(), + Self::RGB { transparent_color } => transparent_color.is_some(), _ => false, } } diff --git a/src/deflate/deflater.rs b/src/deflate/deflater.rs index ac0f98ee..a744cdc7 100644 --- a/src/deflate/deflater.rs +++ b/src/deflate/deflater.rs @@ -30,6 +30,7 @@ pub fn inflate(data: &[u8], out_size: usize) -> PngResult> { Ok(dest) } +#[must_use] pub fn crc32(data: &[u8]) -> u32 { let mut crc = Crc::new(); crc.update(data); diff --git a/src/error.rs b/src/error.rs index 21ce6ab5..b2079d1b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -33,14 +33,13 @@ impl fmt::Display for PngError { f.write_str("Missing data in the file; the file is truncated") } PngError::APNGNotSupported => f.write_str("APNG files are not (yet) supported"), - PngError::ChunkMissing(s) => write!(f, "Chunk {} missing or empty", s), + PngError::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"), PngError::InvalidDepthForType(d, ref c) => { - write!(f, "Invalid bit depth {} for color type {}", d, c) + write!(f, "Invalid bit depth {d} for color type {c}") } PngError::IncorrectDataLength(l1, l2) => write!( f, - "Data length {} does not match the expected length {}", - l1, l2 + "Data length {l1} does not match the expected length {l2}" ), PngError::C2PAMetadataPreventsChanges => f.write_str( "The image contains C2PA manifest that would be invalidated by any file changes", @@ -52,6 +51,7 @@ impl fmt::Display for PngError { impl PngError { #[cold] + #[must_use] pub fn new(description: &str) -> PngError { PngError::Other(description.into()) } diff --git a/src/evaluate.rs b/src/evaluate.rs index e67f14bf..b3801fac 100644 --- a/src/evaluate.rs +++ b/src/evaluate.rs @@ -18,7 +18,7 @@ use rayon::prelude::*; use crate::rayon; use crate::{atomicmin::AtomicMin, deflate, filters::RowFilter, png::PngImage, Deadline, PngError}; -pub struct Candidate { +pub(crate) struct Candidate { pub image: Arc, pub idat_data: Vec, pub filtered: Vec, diff --git a/src/headers.rs b/src/headers.rs index 92c949ac..4cead1d9 100644 --- a/src/headers.rs +++ b/src/headers.rs @@ -30,7 +30,7 @@ impl IhdrData { /// Bits per pixel #[must_use] #[inline] - pub fn bpp(&self) -> usize { + pub const fn bpp(&self) -> usize { self.bit_depth as usize * self.color_type.channels_per_pixel() as usize } @@ -91,11 +91,11 @@ pub enum StripChunks { impl StripChunks { pub(crate) fn keep(&self, name: &[u8; 4]) -> bool { match &self { - StripChunks::None => true, - StripChunks::Keep(names) => names.contains(name), - StripChunks::Strip(names) => !names.contains(name), - StripChunks::Safe => DISPLAY_CHUNKS.contains(name), - StripChunks::All => false, + Self::None => true, + Self::Keep(names) => names.contains(name), + Self::Strip(names) => !names.contains(name), + Self::Safe => DISPLAY_CHUNKS.contains(name), + Self::All => false, } } } diff --git a/src/lib.rs b/src/lib.rs index cf6f0e47..956d5937 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -195,8 +195,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( .map_err(|err| { // Fail if metadata cannot be preserved PngError::new(&format!( - "Unable to read metadata from input file {:?}: {}", - input_path, err + "Unable to read metadata from input file {input_path:?}: {err}" )) }) .map(Some)?; @@ -211,7 +210,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( let mut data = Vec::new(); stdin() .read_to_end(&mut data) - .map_err(|e| PngError::new(&format!("Error reading stdin: {}", e)))?; + .map_err(|e| PngError::new(&format!("Error reading stdin: {e}")))?; data } }; @@ -260,7 +259,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( let mut buffer = BufWriter::new(stdout()); buffer .write_all(&optimized_output) - .map_err(|e| PngError::new(&format!("Unable to write to stdout: {}", e)))?; + .map_err(|e| PngError::new(&format!("Unable to write to stdout: {e}")))?; } (OutFile::Path { path, .. }, _) => { let output_path = path @@ -460,7 +459,7 @@ fn optimize_raw( if eval_result.is_some() { // Some filters have already been evaluated, we don't need to try them again - filters = filters.difference(&eval_filters).cloned().collect(); + filters = filters.difference(&eval_filters).copied().collect(); } if !filters.is_empty() { @@ -609,6 +608,7 @@ pub struct Deadline { } impl Deadline { + #[must_use] pub fn new(timeout: Option) -> Self { Self { imp: timeout.map(|timeout| DeadlineImp { @@ -742,7 +742,7 @@ fn postprocess_chunks( c.data.truncate(4); c.data.append(&mut data); } - }) + }); } } @@ -756,8 +756,7 @@ fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()> .set_permissions(metadata_input.permissions()) .map_err(|err_io| { PngError::new(&format!( - "unable to set permissions for output file: {}", - err_io + "unable to set permissions for output file: {err_io}" )) }) } @@ -778,8 +777,7 @@ fn copy_times(input_path_meta: &Metadata, out_path: &Path) -> PngResult<()> { ); filetime::set_file_times(out_path, atime, mtime).map_err(|err_io| { PngError::new(&format!( - "unable to set file times on {:?}: {}", - out_path, err_io + "unable to set file times on {out_path:?}: {err_io}" )) }) } diff --git a/src/main.rs b/src/main.rs index 1b8d4781..eea4b9ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -228,8 +228,8 @@ fn parse_opts_into_struct( let out_dir = if let Some(path) = matches.get_one::("output_dir") { if !path.exists() { match DirBuilder::new().recursive(true).create(path) { - Ok(_) => (), - Err(x) => return Err(format!("Could not create output directory {}", x)), + Ok(()) => (), + Err(x) => return Err(format!("Could not create output directory {x}")), }; } else if !path.is_dir() { return Err(format!( @@ -305,9 +305,9 @@ fn parse_opts_into_struct( }) .collect::, _>>()?; if keep_display { - names.extend(DISPLAY_CHUNKS.iter().cloned()); + names.extend(DISPLAY_CHUNKS.iter().copied()); } - opts.strip = StripChunks::Keep(names) + opts.strip = StripChunks::Keep(names); } if let Some(strip) = matches.get_one::("strip") { @@ -329,7 +329,7 @@ fn parse_opts_into_struct( } let name = parse_chunk_name(x)?; if FORBIDDEN_CHUNKS.contains(&name) { - return Err(format!("{} chunk is not allowed to be stripped", x)); + return Err(format!("{x} chunk is not allowed to be stripped")); } Ok(name) }) @@ -370,7 +370,7 @@ fn parse_chunk_name(name: &str) -> Result<[u8; 4], String> { name.trim() .as_bytes() .try_into() - .map_err(|_| format!("Invalid chunk name {}", name)) + .map_err(|_| format!("Invalid chunk name {name}")) } fn parse_numeric_range_opts( diff --git a/src/options.rs b/src/options.rs index f2cf7c51..b7ff717e 100644 --- a/src/options.rs +++ b/src/options.rs @@ -31,6 +31,7 @@ impl OutFile { /// Construct a new `OutFile` with the given path. /// /// This is a convenience method for `OutFile::Path { path: Some(path), preserve_attrs: false }`. + #[must_use] pub fn from_path(path: PathBuf) -> Self { OutFile::Path { path: Some(path), @@ -38,9 +39,10 @@ impl OutFile { } } + #[must_use] pub fn path(&self) -> Option<&Path> { match *self { - OutFile::Path { + Self::Path { path: Some(ref p), .. } => Some(p.as_path()), _ => None, @@ -57,10 +59,11 @@ pub enum InFile { } impl InFile { + #[must_use] pub fn path(&self) -> Option<&Path> { match *self { - InFile::Path(ref p) => Some(p.as_path()), - InFile::StdIn => None, + Self::Path(ref p) => Some(p.as_path()), + Self::StdIn => None, } } } @@ -68,15 +71,15 @@ impl InFile { impl fmt::Display for InFile { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - InFile::Path(ref p) => write!(f, "{}", p.display()), - InFile::StdIn => f.write_str("stdin"), + Self::Path(ref p) => write!(f, "{}", p.display()), + Self::StdIn => f.write_str("stdin"), } } } impl> From for InFile { fn from(s: T) -> Self { - InFile::Path(s.into()) + Self::Path(s.into()) } } @@ -91,7 +94,7 @@ pub struct Options { /// /// Default: `false` pub force: bool, - /// Which RowFilters to try on the file + /// Which `RowFilters` to try on the file /// /// Default: `None,Sub,Entropy,Bigrams` pub filter: IndexSet, @@ -156,8 +159,9 @@ pub struct Options { } impl Options { - pub fn from_preset(level: u8) -> Options { - let opts = Options::default(); + #[must_use] + pub fn from_preset(level: u8) -> Self { + let opts = Self::default(); match level { 0 => opts.apply_preset_0(), 1 => opts.apply_preset_1(), @@ -173,8 +177,9 @@ impl Options { } } - pub fn max_compression() -> Options { - Options::from_preset(6) + #[must_use] + pub fn max_compression() -> Self { + Self::from_preset(6) } // The following methods make assumptions that they are operating @@ -237,9 +242,9 @@ impl Options { } impl Default for Options { - fn default() -> Options { + fn default() -> Self { // Default settings based on -o 2 from the CLI interface - Options { + Self { fix_errors: false, force: false, filter: indexset! {RowFilter::None, RowFilter::Sub, RowFilter::Entropy, RowFilter::Bigrams}, diff --git a/src/png/mod.rs b/src/png/mod.rs index 08ef264d..9d98c63a 100644 --- a/src/png/mod.rs +++ b/src/png/mod.rs @@ -105,7 +105,7 @@ impl PngData { aux_chunks.push(Chunk { name: chunk.name, data: Vec::new(), - }) + }); } idat_data.extend_from_slice(chunk.data); } @@ -126,7 +126,7 @@ impl PngData { aux_chunks.push(Chunk { name: chunk.name, data: chunk.data.to_owned(), - }) + }); } else if chunk.name == *b"acTL" { warn!( "Stripping animation data from APNG - image will become standard PNG" @@ -170,11 +170,13 @@ impl PngData { } /// Return an estimate of the output size which can help with evaluation of very small data + #[must_use] pub fn estimated_output_size(&self) -> usize { self.idat_data.len() + self.raw.key_chunks_size() } /// Format the `PngData` struct into a valid PNG bytestream + #[must_use] pub fn output(&self) -> Vec { // PNG header let mut output = vec![0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]; @@ -227,7 +229,7 @@ impl PngData { transparent_color: Some(trns), } => { // Transparency pixel - 6 byte RGB16 - let trns_data: Vec<_> = trns.iter().flat_map(|c| c.to_be_bytes()).collect(); + let trns_data: Vec<_> = trns.iter().flat_map(u16::to_be_bytes).collect(); write_png_block(b"tRNS", &trns_data, &mut output); } _ => {} @@ -261,7 +263,7 @@ impl PngImage { /// Assumes that the data has already been de-filtered #[inline] #[must_use] - pub fn change_interlacing(&self, interlace: Interlacing) -> Option { + pub fn change_interlacing(&self, interlace: Interlacing) -> Option { if interlace == self.ihdr.interlaced { return None; } @@ -277,13 +279,15 @@ impl PngImage { /// Return the number of channels in the image, based on color type #[inline] - pub fn channels_per_pixel(&self) -> usize { + #[must_use] + pub const fn channels_per_pixel(&self) -> usize { self.ihdr.color_type.channels_per_pixel() as usize } /// Return the number of bytes per channel in the image #[inline] - pub fn bytes_per_channel(&self) -> usize { + #[must_use] + pub const fn bytes_per_channel(&self) -> usize { match self.ihdr.bit_depth { BitDepth::Sixteen => 2, // Depths lower than 8 will round up to 1 byte @@ -292,6 +296,7 @@ impl PngImage { } /// Calculate the size of the PLTE and tRNS chunks + #[must_use] pub fn key_chunks_size(&self) -> usize { match &self.ihdr.color_type { ColorType::Indexed { palette } => { @@ -310,6 +315,7 @@ impl PngImage { /// Return an iterator over the scanlines of the image #[inline] + #[must_use] pub fn scan_lines(&self, has_filter: bool) -> ScanLines<'_> { ScanLines::new(self, has_filter) } @@ -337,6 +343,7 @@ impl PngImage { } /// Apply the specified filter type to all rows in the image + #[must_use] pub fn filter_image(&self, filter: RowFilter, optimize_alpha: bool) -> Vec { let mut filtered = Vec::with_capacity(self.data.len()); let bpp = self.bytes_per_channel() * self.channels_per_pixel(); @@ -411,7 +418,7 @@ impl PngImage { for f in try_filters { f.filter_line(bpp, &mut line_data, &prev_line, &mut f_buf, alpha_bytes); let mut counts = vec![0; 0x100]; - for &i in f_buf.iter() { + for &i in &f_buf { counts[i as usize] += 1; } let size = counts.into_iter().fold(0, |acc, x| { @@ -435,7 +442,7 @@ impl PngImage { f.filter_line(bpp, &mut line_data, &prev_line, &mut f_buf, alpha_bytes); let mut set = bitarr![0; 0x10000]; for pair in f_buf.windows(2) { - let bigram = (pair[0] as usize) << 8 | pair[1] as usize; + let bigram = ((pair[0] as usize) << 8) | pair[1] as usize; set.set(bigram, true); } let size = set.count_ones(); @@ -455,7 +462,7 @@ impl PngImage { f.filter_line(bpp, &mut line_data, &prev_line, &mut f_buf, alpha_bytes); counts.clear(); for pair in f_buf.windows(2) { - let bigram = (pair[0] as u16) << 8 | pair[1] as u16; + let bigram = (u16::from(pair[0]) << 8) | u16::from(pair[1]); counts.entry(bigram).and_modify(|e| *e += 1).or_insert(1); } let size = counts.values().fold(0, |acc, &x| acc + ilog2i(x)) as i32; @@ -516,7 +523,7 @@ fn write_png_block(key: &[u8], chunk: &[u8], output: &mut Vec) { } // Integer approximation for i * log2(i) - much faster than float calculations -fn ilog2i(i: u32) -> u32 { +const fn ilog2i(i: u32) -> u32 { let log = 32 - i.leading_zeros() - 1; i * log + ((i - (1 << log)) << 1) } diff --git a/src/png/scan_lines.rs b/src/png/scan_lines.rs index 080c211e..3c039e4f 100644 --- a/src/png/scan_lines.rs +++ b/src/png/scan_lines.rs @@ -11,6 +11,7 @@ pub struct ScanLines<'a> { } impl<'a> ScanLines<'a> { + #[must_use] pub fn new(png: &'a PngImage, has_filter: bool) -> Self { Self { iter: ScanLineRanges::new(png, has_filter), @@ -22,6 +23,7 @@ impl<'a> ScanLines<'a> { impl<'a> Iterator for ScanLines<'a> { type Item = ScanLine<'a>; + #[inline] fn next(&mut self) -> Option { let (len, pass, num_pixels) = self.iter.next()?; @@ -79,6 +81,7 @@ impl ScanLineRanges { impl Iterator for ScanLineRanges { type Item = (usize, Option, usize); + fn next(&mut self) -> Option { if self.left == 0 { return None; diff --git a/src/reduction/alpha.rs b/src/reduction/alpha.rs index f0b408bc..9e17be9e 100644 --- a/src/reduction/alpha.rs +++ b/src/reduction/alpha.rs @@ -7,6 +7,7 @@ use crate::{ }; /// Clean the alpha channel by setting the color of all fully transparent pixels to black +#[must_use] pub fn cleaned_alpha_channel(png: &PngImage) -> Option { if !png.ihdr.color_type.has_alpha() { return None; @@ -85,8 +86,8 @@ pub fn reduced_alpha_channel(png: &PngImage, optimize_alpha: bool) -> Option (trns as u16) << 8 | trns as u16, - _ => trns as u16, + BitDepth::Sixteen => (u16::from(trns) << 8) | u16::from(trns), + _ => u16::from(trns), }); let target_color_type = match png.ihdr.color_type { ColorType::GrayscaleAlpha => ColorType::Grayscale { diff --git a/src/reduction/bit_depth.rs b/src/reduction/bit_depth.rs index 6d5c9702..ee8b6314 100644 --- a/src/reduction/bit_depth.rs +++ b/src/reduction/bit_depth.rs @@ -22,7 +22,7 @@ pub fn reduced_bit_depth_16_to_8(png: &PngImage, force_scale: bool) -> Option Option { } // See: http://www.libpng.org/pub/png/spec/1.2/PNG-Decoders.html#D.Sample-depth-rescaling // This allows values such as 0x00FF to be rounded to 0x01 rather than truncated to 0x00 - let val = u16::from_be_bytes([pair[0], pair[1]]) as f64; - (val * 255.0 / 65535.0).round() as u8 + let val = f32::from(u16::from_be_bytes([pair[0], pair[1]])); + (val * (255.0 / 65535.0)).round() as u8 }) .collect(); @@ -138,7 +138,7 @@ pub fn reduced_bit_depth_8_or_less(png: &PngImage) -> Option { let mut check = reduced_trans; let mut bits = minimum_bits; while bits < 8 { - check = check << bits | check; + check = (check << bits) | check; bits <<= 1; } // If the transparency doesn't fit the new bit depth it is therefore unused - set it to None @@ -188,7 +188,7 @@ pub fn expanded_bit_depth_to_8(png: &PngImage) -> Option { // Expand gray by repeating the bits let mut bits = bit_depth; while bits < 8 { - val = val << bits | val; + val = (val << bits) | val; bits <<= 1; } } @@ -207,7 +207,7 @@ pub fn expanded_bit_depth_to_8(png: &PngImage) -> Option { { let mut bits = bit_depth; while bits < 8 { - trans = trans << bits | trans; + trans = (trans << bits) | trans; bits <<= 1; } ColorType::Grayscale { diff --git a/src/reduction/color.rs b/src/reduction/color.rs index 5797b19b..8992d1c7 100644 --- a/src/reduction/color.rs +++ b/src/reduction/color.rs @@ -49,7 +49,7 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option = match png.ihdr.color_type { ColorType::Grayscale { transparent_shade } => { - let pmap = build_palette(png.data.as_gray().iter().cloned(), &mut raw_data)?; + let pmap = build_palette(png.data.as_gray().iter().copied(), &mut raw_data)?; // Convert the Gray16 transparency to Gray8 let transparency_pixel = transparent_shade.map(|t| Gray::from(t as u8)); pmap.into_iter() @@ -63,7 +63,7 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option { - let pmap = build_palette(png.data.as_rgb().iter().cloned(), &mut raw_data)?; + let pmap = build_palette(png.data.as_rgb().iter().copied(), &mut raw_data)?; // Convert the RGB16 transparency to RGB8 let transparency_pixel = transparent_color.map(|t| t.map(|c| c as u8)); pmap.into_iter() @@ -77,11 +77,11 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option { - let pmap = build_palette(png.data.as_gray_alpha().iter().cloned(), &mut raw_data)?; + let pmap = build_palette(png.data.as_gray_alpha().iter().copied(), &mut raw_data)?; pmap.into_iter().map(RGBA::from).collect() } ColorType::RGBA => { - let pmap = build_palette(png.data.as_rgba().iter().cloned(), &mut raw_data)?; + let pmap = build_palette(png.data.as_rgba().iter().copied(), &mut raw_data)?; pmap.into_iter().collect() } _ => return None, diff --git a/src/reduction/palette.rs b/src/reduction/palette.rs index a87efad1..b80c6995 100644 --- a/src/reduction/palette.rs +++ b/src/reduction/palette.rs @@ -278,7 +278,7 @@ fn co_occurrence_matrix(num_colors: usize, png: &PngImage) -> Vec> { matrix[val][prev_val] += 1; } } - prev = Some(line) + prev = Some(line); } matrix } diff --git a/tests/flags.rs b/tests/flags.rs index 85da071f..8ac73f87 100644 --- a/tests/flags.rs +++ b/tests/flags.rs @@ -2,8 +2,6 @@ use std::cell::RefCell; #[cfg(feature = "zopfli")] use std::num::NonZeroU8; -#[cfg(feature = "filetime")] -use std::ops::Deref; use std::{ fs::remove_file, path::{Path, PathBuf}, @@ -94,7 +92,7 @@ fn test_it_converts( bit_depth_out, |_| {}, |_| {}, - ) + ); } #[test] @@ -194,10 +192,7 @@ fn verbose_mode() { let expected_prefix = expected_prefixes[i]; assert!( log.starts_with(expected_prefix), - "logs[{}] = {:?} doesn't start with {:?}", - i, - log, - expected_prefix + "logs[{i}] = {log:?} doesn't start with {expected_prefix:?}" ); } } @@ -540,8 +535,8 @@ fn preserve_attrs() { let cellref_atime_canon = atime_canon.borrow(); let cellref_mtime_canon = mtime_canon.borrow(); - let ref_atime_canon: &filetime::FileTime = cellref_atime_canon.deref(); - let ref_mtime_canon: &filetime::FileTime = cellref_mtime_canon.deref(); + let ref_atime_canon: &filetime::FileTime = &cellref_atime_canon; + let ref_mtime_canon: &filetime::FileTime = &cellref_mtime_canon; assert_eq!( ref_atime_canon,