Apply some Clippy lints (#744)

Let me know if I should add these to the `Cargo.toml`.

All `cargo test` tests pass on the latest x86_64-unknown-linux-gnu
nightly.

---------

Co-authored-by: Alejandro González <me@alegon.dev>
This commit is contained in:
Luracasmus 2025-12-06 16:06:35 +01:00 committed by GitHub
parent 285b0aae10
commit 33cea5603e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 120 additions and 108 deletions

View file

@ -112,3 +112,19 @@ assets = [
["README.md", "usr/share/doc/oxipng/", "644"], ["README.md", "usr/share/doc/oxipng/", "644"],
["CHANGELOG.md", "usr/share/doc/oxipng/", "644"], ["CHANGELOG.md", "usr/share/doc/oxipng/", "644"],
] ]
[lints.clippy]
unnecessary_semicolon = "warn"
use_self = "warn"
ignored_unit_patterns = "warn"
unseparated_literal_suffix = "warn"
missing_const_for_fn = "warn"
redundant_closure_for_method_calls = "warn"
option_if_let_else = "warn"
redundant_clone = "warn"
semicolon_if_nothing_returned = "warn"
cloned_instead_of_copied = "warn"
if_not_else = "warn"
useless_let_if_seq = "warn"
manual_let_else = "warn"
map_unwrap_or = "warn"

View file

@ -31,11 +31,11 @@ pub struct Frame {
impl Frame { impl Frame {
/// Construct a new Frame from the data in a fcTL chunk /// Construct a new Frame from the data in a fcTL chunk
pub fn from_fctl_data(byte_data: &[u8]) -> PngResult<Frame> { pub fn from_fctl_data(byte_data: &[u8]) -> PngResult<Self> {
if byte_data.len() < 26 { if byte_data.len() < 26 {
return Err(PngError::TruncatedData); return Err(PngError::TruncatedData);
} }
Ok(Frame { Ok(Self {
width: read_be_u32(&byte_data[4..8]), width: read_be_u32(&byte_data[4..8]),
height: read_be_u32(&byte_data[8..12]), height: read_be_u32(&byte_data[8..12]),
x_offset: read_be_u32(&byte_data[12..16]), x_offset: read_be_u32(&byte_data[12..16]),

View file

@ -1,8 +1,9 @@
mod deflater; mod deflater;
use std::{fmt, fmt::Display};
pub use deflater::{crc32, deflate, inflate}; pub use deflater::{crc32, deflate, inflate};
use crate::{PngError, PngResult}; use crate::{PngError, PngResult};
use std::{fmt, fmt::Display};
#[cfg(feature = "zopfli")] #[cfg(feature = "zopfli")]
mod zopfli_oxipng; mod zopfli_oxipng;

View file

@ -5,9 +5,9 @@ pub fn deflate(data: &[u8], options: zopfli::Options) -> PngResult<Vec<u8>> {
// Since Rust v1.74, passing &[u8] directly into zopfli causes a regression in compressed size // Since Rust v1.74, passing &[u8] directly into zopfli causes a regression in compressed size
// for some files. Wrapping the slice in another Read implementer such as Box fixes it for now. // for some files. Wrapping the slice in another Read implementer such as Box fixes it for now.
match zopfli::compress(options, zopfli::Format::Zlib, Box::new(data), &mut output) { match zopfli::compress(options, zopfli::Format::Zlib, Box::new(data), &mut output) {
Ok(_) => (), Ok(()) => (),
Err(_) => return Err(PngError::new("Failed to compress in zopfli")), Err(_) => return Err(PngError::new("Failed to compress in zopfli")),
}; }
output.shrink_to_fit(); output.shrink_to_fit();
Ok(output) Ok(output)
} }

View file

@ -28,36 +28,34 @@ impl fmt::Display for PngError {
#[cold] #[cold]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self { match *self {
PngError::APNGOutOfOrder => f.write_str("APNG chunks are out of order"), Self::APNGOutOfOrder => f.write_str("APNG chunks are out of order"),
PngError::C2PAMetadataPreventsChanges => f.write_str( Self::C2PAMetadataPreventsChanges => f.write_str(
"The image contains C2PA manifest that would be invalidated by any file changes", "The image contains C2PA manifest that would be invalidated by any file changes",
), ),
PngError::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"), Self::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"),
PngError::CRCMismatch(ref c) => write!( Self::CRCMismatch(ref c) => write!(
f, f,
"CRC mismatch in {} chunk; May be recoverable by using --fix", "CRC mismatch in {} chunk; May be recoverable by using --fix",
String::from_utf8_lossy(c) String::from_utf8_lossy(c)
), ),
PngError::DeflatedDataTooLong(_) => f.write_str("Deflated data too long"), Self::DeflatedDataTooLong(_) => f.write_str("Deflated data too long"),
PngError::IncorrectDataLength(l1, l2) => write!( Self::IncorrectDataLength(l1, l2) => write!(
f, f,
"Data length {l1} does not match the expected length {l2}" "Data length {l1} does not match the expected length {l2}"
), ),
PngError::InflatedDataTooLong(max) => write!( Self::InflatedDataTooLong(max) => write!(
f, f,
"Inflated data would exceed the maximum size ({max} bytes)" "Inflated data would exceed the maximum size ({max} bytes)"
), ),
PngError::InvalidData => f.write_str("Invalid data found; unable to read PNG file"), Self::InvalidData => f.write_str("Invalid data found; unable to read PNG file"),
PngError::InvalidDepthForType(d, ref c) => { Self::InvalidDepthForType(d, ref c) => {
write!(f, "Invalid bit depth {d} for color type {c}") write!(f, "Invalid bit depth {d} for color type {c}")
} }
PngError::NotPNG => f.write_str("Invalid header detected; Not a PNG file"), Self::NotPNG => f.write_str("Invalid header detected; Not a PNG file"),
PngError::ReadFailed(ref s, ref e) => write!(f, "Failed to read from {s}: {e}"), Self::ReadFailed(ref s, ref e) => write!(f, "Failed to read from {s}: {e}"),
PngError::TruncatedData => { Self::TruncatedData => f.write_str("Missing data in the file; the file is truncated"),
f.write_str("Missing data in the file; the file is truncated") Self::WriteFailed(ref s, ref e) => write!(f, "Failed to write to {s}: {e}"),
} Self::Other(ref s) => f.write_str(s),
PngError::WriteFailed(ref s, ref e) => write!(f, "Failed to write to {s}: {e}"),
PngError::Other(ref s) => f.write_str(s),
} }
} }
} }
@ -65,7 +63,7 @@ impl fmt::Display for PngError {
impl PngError { impl PngError {
#[cold] #[cold]
#[must_use] #[must_use]
pub fn new(description: &str) -> PngError { pub fn new(description: &str) -> Self {
PngError::Other(description.into()) Self::Other(description.into())
} }
} }

View file

@ -127,22 +127,18 @@ impl RowFilter {
} }
Self::Average => { Self::Average => {
for (i, byte) in data.iter().enumerate() { for (i, byte) in data.iter().enumerate() {
buf.push(match i.checked_sub(bpp) { buf.push(byte.wrapping_sub(i.checked_sub(bpp).map_or_else(
Some(x) => byte.wrapping_sub( || prev_line[i] >> 1,
((u16::from(data[x]) + u16::from(prev_line[i])) >> 1) as u8, |x| ((u16::from(data[x]) + u16::from(prev_line[i])) >> 1) as u8,
), )));
None => byte.wrapping_sub(prev_line[i] >> 1),
});
} }
} }
Self::Paeth => { Self::Paeth => {
for (i, byte) in data.iter().enumerate() { for (i, byte) in data.iter().enumerate() {
buf.push(match i.checked_sub(bpp) { buf.push(byte.wrapping_sub(i.checked_sub(bpp).map_or_else(
Some(x) => { || prev_line[i],
byte.wrapping_sub(paeth_predictor(data[x], prev_line[i], prev_line[x])) |x| paeth_predictor(data[x], prev_line[i], prev_line[x]),
} )));
None => byte.wrapping_sub(prev_line[i]),
});
} }
} }
} }
@ -241,10 +237,7 @@ impl RowFilter {
Self::Sub => { Self::Sub => {
for (i, &cur) in data.iter().enumerate() { for (i, &cur) in data.iter().enumerate() {
let prev_byte = i.checked_sub(bpp).and_then(|x| buf.get(x).copied()); let prev_byte = i.checked_sub(bpp).and_then(|x| buf.get(x).copied());
buf.push(match prev_byte { buf.push(prev_byte.map_or(cur, |b| cur.wrapping_add(b)));
Some(b) => cur.wrapping_add(b),
None => cur,
});
} }
} }
Self::Up => { Self::Up => {
@ -257,10 +250,10 @@ impl RowFilter {
Self::Average => { Self::Average => {
for (i, (&cur, &last)) in data.iter().zip(prev_line).enumerate() { for (i, (&cur, &last)) in data.iter().zip(prev_line).enumerate() {
let prev_byte = i.checked_sub(bpp).and_then(|x| buf.get(x).copied()); let prev_byte = i.checked_sub(bpp).and_then(|x| buf.get(x).copied());
buf.push(match prev_byte { buf.push(cur.wrapping_add(prev_byte.map_or_else(
Some(b) => cur.wrapping_add(((u16::from(b) + u16::from(last)) >> 1) as u8), || last >> 1,
None => cur.wrapping_add(last >> 1), |b| ((u16::from(b) + u16::from(last)) >> 1) as u8,
}); )));
} }
} }
Self::Paeth => { Self::Paeth => {

View file

@ -35,18 +35,16 @@ impl IhdrData {
/// Byte length of IDAT that is correct for this IHDR /// Byte length of IDAT that is correct for this IHDR
#[must_use] #[must_use]
pub fn raw_data_size(&self) -> usize { pub const fn raw_data_size(&self) -> usize {
let w = self.width as usize; let w = self.width as usize;
let h = self.height as usize; let h = self.height as usize;
let bpp = self.bpp(); let bpp = self.bpp();
fn bitmap_size(bpp: usize, w: usize, h: usize) -> usize { const fn bitmap_size(bpp: usize, w: usize, h: usize) -> usize {
(w * bpp).div_ceil(8) * h (w * bpp).div_ceil(8) * h
} }
if !self.interlaced { if self.interlaced {
bitmap_size(bpp, w, h) + h
} else {
let mut size = bitmap_size(bpp, (w + 7) >> 3, (h + 7) >> 3) + ((h + 7) >> 3); let mut size = bitmap_size(bpp, (w + 7) >> 3, (h + 7) >> 3) + ((h + 7) >> 3);
if w > 4 { if w > 4 {
size += bitmap_size(bpp, (w + 3) >> 3, (h + 7) >> 3) + ((h + 7) >> 3); size += bitmap_size(bpp, (w + 3) >> 3, (h + 7) >> 3) + ((h + 7) >> 3);
@ -60,6 +58,8 @@ impl IhdrData {
size += bitmap_size(bpp, w >> 1, (h + 1) >> 1) + ((h + 1) >> 1); size += bitmap_size(bpp, w >> 1, (h + 1) >> 1) + ((h + 1) >> 1);
} }
size + bitmap_size(bpp, w, h >> 1) + (h >> 1) size + bitmap_size(bpp, w, h >> 1) + (h >> 1)
} else {
bitmap_size(bpp, w, h) + h
} }
} }
} }

View file

@ -149,7 +149,7 @@ fn deinterlace_bytes(png: &PngImage) -> Vec<u8> {
lines.concat() lines.concat()
} }
fn increment_pass(current_pass: &mut u8, ihdr: &IhdrData) -> bool { const fn increment_pass(current_pass: &mut u8, ihdr: &IhdrData) -> bool {
if *current_pass == 7 { if *current_pass == 7 {
return false; return false;
} }

View file

@ -28,7 +28,7 @@ mod rayon;
use std::{ use std::{
fs::{File, Metadata}, fs::{File, Metadata},
io::{BufWriter, Read, Write, stdin, stdout}, io::{BufWriter, Read, Write, stdin, stdout},
path::Path, path::{Path, PathBuf},
sync::{ sync::{
Arc, Arc,
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
@ -275,8 +275,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
(OutFile::Path { path, .. }, _) => { (OutFile::Path { path, .. }, _) => {
let output_path = path let output_path = path
.as_ref() .as_ref()
.map(|p| p.as_path()) .map_or_else(|| input.path().unwrap(), PathBuf::as_path);
.unwrap_or_else(|| input.path().unwrap());
let out_file = File::create(output_path) let out_file = File::create(output_path)
.map_err(|err| PngError::WriteFailed(output_path.display().to_string(), err))?; .map_err(|err| PngError::WriteFailed(output_path.display().to_string(), err))?;
if let Some(metadata_input) = &opt_metadata_preserved { if let Some(metadata_input) = &opt_metadata_preserved {
@ -449,9 +448,9 @@ fn optimize_raw(
let (result, deflater) = if opts.idat_recoding || reduction_occurred { let (result, deflater) = if opts.idat_recoding || reduction_occurred {
let result = perform_trials( let result = perform_trials(
new_image.clone(), new_image,
opts, opts,
deadline.clone(), deadline,
max_size, max_size,
eval_result, eval_result,
eval_filters, eval_filters,
@ -497,7 +496,7 @@ fn perform_trials(
if !filters.is_empty() { if !filters.is_empty() {
trace!("Evaluating {} filters", filters.len()); trace!("Evaluating {} filters", filters.len());
let eval = Evaluator::new( let eval = Evaluator::new(
deadline.clone(), deadline,
filters, filters,
eval_deflater, eval_deflater,
opts.optimize_alpha, opts.optimize_alpha,
@ -529,7 +528,7 @@ fn perform_trials(
trace!(">{bytes} bytes"); trace!(">{bytes} bytes");
} }
Err(_) => (), Err(_) => (),
}; }
} }
return Some(result); return Some(result);
} }
@ -659,7 +658,7 @@ fn recompress_frames(
} }
/// Check if an image was already optimized prior to oxipng's operations /// Check if an image was already optimized prior to oxipng's operations
fn is_fully_optimized(original_size: usize, optimized_size: usize, opts: &Options) -> bool { const fn is_fully_optimized(original_size: usize, optimized_size: usize, opts: &Options) -> bool {
original_size <= optimized_size && !opts.force original_size <= optimized_size && !opts.force
} }
@ -674,7 +673,7 @@ fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()>
} }
#[cfg(not(feature = "filetime"))] #[cfg(not(feature = "filetime"))]
fn copy_times(_: &Metadata, _: &Path) -> PngResult<()> { const fn copy_times(_: &Metadata, _: &Path) -> PngResult<()> {
Ok(()) Ok(())
} }

View file

@ -19,7 +19,12 @@ mod rayon;
#[cfg(feature = "zopfli")] #[cfg(feature = "zopfli")]
use std::num::NonZeroU64; use std::num::NonZeroU64;
use std::{ use std::{
ffi::OsString, fs::DirBuilder, io::Write, path::PathBuf, process::ExitCode, time::Duration, ffi::{OsStr, OsString},
fs::DirBuilder,
io::Write,
path::PathBuf,
process::ExitCode,
time::Duration,
}; };
use clap::ArgMatches; use clap::ArgMatches;
@ -127,7 +132,7 @@ fn collect_files(
warn!("{} is a directory, skipping", input.display()); warn!("{} is a directory, skipping", input.display());
} }
continue; continue;
}; }
let out_file = let out_file =
if let (Some(out_dir), &OutFile::Path { preserve_attrs, .. }) = (out_dir, out_file) { if let (Some(out_dir), &OutFile::Path { preserve_attrs, .. }) = (out_dir, out_file) {
let path = Some(out_dir.join(input.file_name().unwrap())); let path = Some(out_dir.join(input.file_name().unwrap()));
@ -143,7 +148,7 @@ fn collect_files(
} else { } else {
// Skip non png files if not given on top level // Skip non png files if not given on top level
if !top_level && { if !top_level && {
let extension = input.extension().map(|f| f.to_ascii_lowercase()); let extension = input.extension().map(OsStr::to_ascii_lowercase);
extension != Some(OsString::from("png")) extension != Some(OsString::from("png"))
&& extension != Some(OsString::from("apng")) && extension != Some(OsString::from("apng"))
} { } {
@ -200,7 +205,7 @@ fn parse_opts_into_struct(
}; };
// Get custom brute settings and rebuild the filter set to apply them // Get custom brute settings and rebuild the filter set to apply them
let mut brute_lines = matches.get_one::<usize>("brute-lines").cloned(); let mut brute_lines = matches.get_one::<usize>("brute-lines").copied();
let mut brute_level = matches.get_one::<i64>("brute-level").map(|x| *x as u8); let mut brute_level = matches.get_one::<i64>("brute-level").map(|x| *x as u8);
let mut new_filters = IndexSet::new(); let mut new_filters = IndexSet::new();
for mut f in opts.filters.drain(..) { for mut f in opts.filters.drain(..) {
@ -243,7 +248,7 @@ fn parse_opts_into_struct(
match DirBuilder::new().recursive(true).create(path) { match DirBuilder::new().recursive(true).create(path) {
Ok(()) => (), Ok(()) => (),
Err(x) => return Err(format!("Could not create output directory {x}")), Err(x) => return Err(format!("Could not create output directory {x}")),
}; }
} else if !path.is_dir() { } else if !path.is_dir() {
return Err(format!( return Err(format!(
"{} is an existing file (not a directory), cannot create directory", "{} is an existing file (not a directory), cannot create directory",

View file

@ -32,8 +32,8 @@ impl OutFile {
/// ///
/// This is a convenience method for `OutFile::Path { path: Some(path), preserve_attrs: false }`. /// This is a convenience method for `OutFile::Path { path: Some(path), preserve_attrs: false }`.
#[must_use] #[must_use]
pub fn from_path(path: PathBuf) -> Self { pub const fn from_path(path: PathBuf) -> Self {
OutFile::Path { Self::Path {
path: Some(path), path: Some(path),
preserve_attrs: false, preserve_attrs: false,
} }
@ -199,7 +199,7 @@ impl Options {
self self
} }
fn apply_preset_2(self) -> Self { const fn apply_preset_2(self) -> Self {
self self
} }

View file

@ -123,7 +123,7 @@ impl PngData {
}); });
} }
b"acTL" => { b"acTL" => {
warn!("Stripping animation data from APNG - image will become standard PNG") warn!("Stripping animation data from APNG - image will become standard PNG");
} }
_ => (), _ => (),
} }
@ -133,9 +133,8 @@ impl PngData {
if idat_data.is_empty() { if idat_data.is_empty() {
return Err(PngError::ChunkMissing("IDAT")); return Err(PngError::ChunkMissing("IDAT"));
} }
let ihdr_chunk = match key_chunks.remove(b"IHDR") { let Some(ihdr_chunk) = key_chunks.remove(b"IHDR") else {
Some(ihdr) => ihdr, return Err(PngError::ChunkMissing("IHDR"));
None => return Err(PngError::ChunkMissing("IHDR")),
}; };
let ihdr = parse_ihdr_chunk( let ihdr = parse_ihdr_chunk(
&ihdr_chunk, &ihdr_chunk,
@ -310,11 +309,10 @@ impl PngImage {
match &self.ihdr.color_type { match &self.ihdr.color_type {
ColorType::Indexed { palette } => { ColorType::Indexed { palette } => {
let plte = 12 + palette.len() * 3; let plte = 12 + palette.len() * 3;
if let Some(trns) = palette.iter().rposition(|p| p.a != 255) { palette
plte + 12 + trns + 1 .iter()
} else { .rposition(|p| p.a != 255)
plte .map_or(plte, |trns| plte + 12 + trns + 1)
}
} }
ColorType::Grayscale { transparent_shade } if transparent_shade.is_some() => 12 + 2, ColorType::Grayscale { transparent_shade } if transparent_shade.is_some() => 12 + 2,
ColorType::RGB { transparent_color } if transparent_color.is_some() => 12 + 6, ColorType::RGB { transparent_color } if transparent_color.is_some() => 12 + 6,
@ -348,7 +346,7 @@ impl PngImage {
last_pass = line.pass; last_pass = line.pass;
} }
last_line.resize(line.data.len(), 0); last_line.resize(line.data.len(), 0);
let filter = RowFilter::try_from(line.filter).map_err(|_| PngError::InvalidData)?; let filter = RowFilter::try_from(line.filter).map_err(|()| PngError::InvalidData)?;
filter.unfilter_line(bpp, line.data, &last_line, &mut unfiltered_buf); filter.unfilter_line(bpp, line.data, &last_line, &mut unfiltered_buf);
unfiltered.extend_from_slice(&unfiltered_buf); unfiltered.extend_from_slice(&unfiltered_buf);
std::mem::swap(&mut last_line, &mut unfiltered_buf); std::mem::swap(&mut last_line, &mut unfiltered_buf);

View file

@ -138,7 +138,7 @@ impl Iterator for ScanLineRanges {
pixels_per_line += 1; pixels_per_line += 1;
} }
_ => (), _ => (),
}; }
let current_pass = Some(pass.0); let current_pass = Some(pass.0);
if pass.1 + y_steps >= self.height { if pass.1 + y_steps >= self.height {
pass.0 += 1; pass.0 += 1;

View file

@ -81,7 +81,7 @@ pub fn reduced_alpha_channel(png: &PngImage, optimize_alpha: bool) -> Option<Png
raw_data.resize(raw_data.len() + colored_bytes, trns); raw_data.resize(raw_data.len() + colored_bytes, trns);
} }
_ => raw_data.extend_from_slice(&pixel[0..colored_bytes]), _ => raw_data.extend_from_slice(&pixel[0..colored_bytes]),
}; }
} }
// Construct the color type with appropriate transparency data // Construct the color type with appropriate transparency data

View file

@ -70,17 +70,17 @@ pub fn reduced_bit_depth_8_or_less(png: &PngImage) -> Option<PngImage> {
return None; return None;
} }
let mut minimum_bits = 1; let minimum_bits = if let ColorType::Indexed { palette } = &png.ihdr.color_type {
if let ColorType::Indexed { palette } = &png.ihdr.color_type {
// We can easily determine minimum depth by the palette size // We can easily determine minimum depth by the palette size
minimum_bits = match palette.len() { match palette.len() {
0..=2 => 1, 0..=2 => 1,
3..=4 => 2, 3..=4 => 2,
5..=16 => 4, 5..=16 => 4,
_ => return None, _ => return None,
}; }
} else { } else {
let mut minimum_bits = 1;
// Finding minimum depth for grayscale is much more complicated // Finding minimum depth for grayscale is much more complicated
let mut mask = 1; let mut mask = 1;
let mut divisions = 1..8; let mut divisions = 1..8;
@ -110,7 +110,9 @@ pub fn reduced_bit_depth_8_or_less(png: &PngImage) -> Option<PngImage> {
break; break;
} }
} }
}
minimum_bits
};
let mut reduced = Vec::with_capacity(png.data.len()); let mut reduced = Vec::with_capacity(png.data.len());
let mask = (1 << minimum_bits) - 1; let mask = (1 << minimum_bits) - 1;

View file

@ -54,10 +54,10 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option<PngIm
let transparency_pixel = transparent_shade.map(|t| Gray::from(t as u8)); let transparency_pixel = transparent_shade.map(|t| Gray::from(t as u8));
pmap.into_iter() pmap.into_iter()
.map(|px| { .map(|px| {
RGB::from(px).with_alpha(if Some(px) != transparency_pixel { RGB::from(px).with_alpha(if Some(px) == transparency_pixel {
255
} else {
0 0
} else {
255
}) })
}) })
.collect() .collect()
@ -68,10 +68,10 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option<PngIm
let transparency_pixel = transparent_color.map(|t| t.map(|c| c as u8)); let transparency_pixel = transparent_color.map(|t| t.map(|c| c as u8));
pmap.into_iter() pmap.into_iter()
.map(|px| { .map(|px| {
px.with_alpha(if Some(px) != transparency_pixel { px.with_alpha(if Some(px) == transparency_pixel {
255
} else {
0 0
} else {
255
}) })
}) })
.collect() .collect()

View file

@ -206,7 +206,7 @@ fn apply_palette_reorder(png: &PngImage, remapping: &[usize]) -> Option<PngImage
// Find the most popular color on the image edges (the pixels neighboring the filter bytes) // Find the most popular color on the image edges (the pixels neighboring the filter bytes)
fn most_popular_edge_color(num_colors: usize, png: &PngImage) -> Option<usize> { fn most_popular_edge_color(num_colors: usize, png: &PngImage) -> Option<usize> {
let mut counts = [0u32; 256]; let mut counts = [0_u32; 256];
for line in png.scan_lines(false) { for line in png.scan_lines(false) {
if let &[first, .., last] = line.data { if let &[first, .., last] = line.data {
counts[first as usize] += 1; counts[first as usize] += 1;
@ -229,7 +229,7 @@ fn most_popular_edge_color(num_colors: usize, png: &PngImage) -> Option<usize> {
// Find the most popular color in the image, along with its count // Find the most popular color in the image, along with its count
fn most_popular_color(num_colors: usize, png: &PngImage) -> (usize, u32) { fn most_popular_color(num_colors: usize, png: &PngImage) -> (usize, u32) {
let mut counts = [0u32; 256]; let mut counts = [0_u32; 256];
for &val in &png.data { for &val in &png.data {
counts[val as usize] += 1; counts[val as usize] += 1;
} }
@ -261,7 +261,7 @@ fn apply_most_popular_color(png: &PngImage, remapping: &mut [usize]) {
// Calculate co-occurences matrix // Calculate co-occurences matrix
fn co_occurrence_matrix(num_colors: usize, png: &PngImage) -> Vec<Vec<u32>> { fn co_occurrence_matrix(num_colors: usize, png: &PngImage) -> Vec<Vec<u32>> {
let mut matrix = vec![vec![0u32; num_colors]; num_colors]; let mut matrix = vec![vec![0_u32; num_colors]; num_colors];
let mut prev: Option<ScanLine> = None; let mut prev: Option<ScanLine> = None;
let mut prev_val = None; let mut prev_val = None;
for line in png.scan_lines(false) { for line in png.scan_lines(false) {

View file

@ -44,7 +44,7 @@ fn load_png_image_from_memory(png_data: &[u8]) -> Result<Vec<RgbaImage>, image::
decoder decoder
.apng()? .apng()?
.into_frames() .into_frames()
.map(|f| f.map(|f| f.into_buffer())) .map(|f| f.map(image::Frame::into_buffer))
.collect() .collect()
} else { } else {
DynamicImage::from_decoder(decoder).map(|i| vec![i.into_rgba8()]) DynamicImage::from_decoder(decoder).map(|i| vec![i.into_rgba8()])

View file

@ -36,7 +36,7 @@ fn test_it_converts(
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());

View file

@ -38,7 +38,7 @@ fn test_it_converts(
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());

View file

@ -50,7 +50,7 @@ fn test_it_converts_callbacks<CBPRE, CBPOST>(
match oxipng::optimize(&InFile::Path(input), output, opts) { match oxipng::optimize(&InFile::Path(input), output, opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());
@ -445,7 +445,7 @@ fn preserve_attrs() {
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());

View file

@ -40,7 +40,7 @@ fn test_it_converts(
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());

View file

@ -36,7 +36,7 @@ fn test_it_converts(
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());

View file

@ -41,7 +41,7 @@ fn test_it_converts(
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());
@ -999,7 +999,7 @@ fn palette_should_be_reduced_with_dupes() {
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());
@ -1036,7 +1036,7 @@ fn palette_should_be_reduced_with_unused() {
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());
@ -1074,7 +1074,7 @@ fn palette_should_be_reduced_with_bkgd() {
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());
@ -1112,7 +1112,7 @@ fn palette_should_be_reduced_with_both() {
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());
@ -1149,7 +1149,7 @@ fn palette_should_be_reduced_with_missing() {
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());

View file

@ -42,7 +42,7 @@ fn test_it_converts(
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());

View file

@ -37,7 +37,7 @@ fn test_it_converts(
match oxipng::optimize(&InFile::Path(input), &output, &opts) { match oxipng::optimize(&InFile::Path(input), &output, &opts) {
Ok(_) => (), Ok(_) => (),
Err(x) => panic!("{}", x), Err(x) => panic!("{}", x),
}; }
let output = output.path().unwrap(); let output = output.path().unwrap();
assert!(output.exists()); assert!(output.exists());