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:
parent
285b0aae10
commit
33cea5603e
26 changed files with 120 additions and 108 deletions
16
Cargo.toml
16
Cargo.toml
|
|
@ -112,3 +112,19 @@ assets = [
|
|||
["README.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"
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ pub struct Frame {
|
|||
|
||||
impl Frame {
|
||||
/// 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 {
|
||||
return Err(PngError::TruncatedData);
|
||||
}
|
||||
Ok(Frame {
|
||||
Ok(Self {
|
||||
width: read_be_u32(&byte_data[4..8]),
|
||||
height: read_be_u32(&byte_data[8..12]),
|
||||
x_offset: read_be_u32(&byte_data[12..16]),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
mod deflater;
|
||||
use std::{fmt, fmt::Display};
|
||||
|
||||
pub use deflater::{crc32, deflate, inflate};
|
||||
|
||||
use crate::{PngError, PngResult};
|
||||
use std::{fmt, fmt::Display};
|
||||
|
||||
#[cfg(feature = "zopfli")]
|
||||
mod zopfli_oxipng;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// 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) {
|
||||
Ok(_) => (),
|
||||
Ok(()) => (),
|
||||
Err(_) => return Err(PngError::new("Failed to compress in zopfli")),
|
||||
};
|
||||
}
|
||||
output.shrink_to_fit();
|
||||
Ok(output)
|
||||
}
|
||||
|
|
|
|||
34
src/error.rs
34
src/error.rs
|
|
@ -28,36 +28,34 @@ impl fmt::Display for PngError {
|
|||
#[cold]
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
PngError::APNGOutOfOrder => f.write_str("APNG chunks are out of order"),
|
||||
PngError::C2PAMetadataPreventsChanges => f.write_str(
|
||||
Self::APNGOutOfOrder => f.write_str("APNG chunks are out of order"),
|
||||
Self::C2PAMetadataPreventsChanges => f.write_str(
|
||||
"The image contains C2PA manifest that would be invalidated by any file changes",
|
||||
),
|
||||
PngError::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"),
|
||||
PngError::CRCMismatch(ref c) => write!(
|
||||
Self::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"),
|
||||
Self::CRCMismatch(ref c) => write!(
|
||||
f,
|
||||
"CRC mismatch in {} chunk; May be recoverable by using --fix",
|
||||
String::from_utf8_lossy(c)
|
||||
),
|
||||
PngError::DeflatedDataTooLong(_) => f.write_str("Deflated data too long"),
|
||||
PngError::IncorrectDataLength(l1, l2) => write!(
|
||||
Self::DeflatedDataTooLong(_) => f.write_str("Deflated data too long"),
|
||||
Self::IncorrectDataLength(l1, l2) => write!(
|
||||
f,
|
||||
"Data length {l1} does not match the expected length {l2}"
|
||||
),
|
||||
PngError::InflatedDataTooLong(max) => write!(
|
||||
Self::InflatedDataTooLong(max) => write!(
|
||||
f,
|
||||
"Inflated data would exceed the maximum size ({max} bytes)"
|
||||
),
|
||||
PngError::InvalidData => f.write_str("Invalid data found; unable to read PNG file"),
|
||||
PngError::InvalidDepthForType(d, ref c) => {
|
||||
Self::InvalidData => f.write_str("Invalid data found; unable to read PNG file"),
|
||||
Self::InvalidDepthForType(d, ref c) => {
|
||||
write!(f, "Invalid bit depth {d} for color type {c}")
|
||||
}
|
||||
PngError::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}"),
|
||||
PngError::TruncatedData => {
|
||||
f.write_str("Missing data in the file; the file is truncated")
|
||||
}
|
||||
PngError::WriteFailed(ref s, ref e) => write!(f, "Failed to write to {s}: {e}"),
|
||||
PngError::Other(ref s) => f.write_str(s),
|
||||
Self::NotPNG => f.write_str("Invalid header detected; Not a PNG file"),
|
||||
Self::ReadFailed(ref s, ref e) => write!(f, "Failed to read from {s}: {e}"),
|
||||
Self::TruncatedData => 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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +63,7 @@ impl fmt::Display for PngError {
|
|||
impl PngError {
|
||||
#[cold]
|
||||
#[must_use]
|
||||
pub fn new(description: &str) -> PngError {
|
||||
PngError::Other(description.into())
|
||||
pub fn new(description: &str) -> Self {
|
||||
Self::Other(description.into())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,22 +127,18 @@ impl RowFilter {
|
|||
}
|
||||
Self::Average => {
|
||||
for (i, byte) in data.iter().enumerate() {
|
||||
buf.push(match i.checked_sub(bpp) {
|
||||
Some(x) => byte.wrapping_sub(
|
||||
((u16::from(data[x]) + u16::from(prev_line[i])) >> 1) as u8,
|
||||
),
|
||||
None => byte.wrapping_sub(prev_line[i] >> 1),
|
||||
});
|
||||
buf.push(byte.wrapping_sub(i.checked_sub(bpp).map_or_else(
|
||||
|| prev_line[i] >> 1,
|
||||
|x| ((u16::from(data[x]) + u16::from(prev_line[i])) >> 1) as u8,
|
||||
)));
|
||||
}
|
||||
}
|
||||
Self::Paeth => {
|
||||
for (i, byte) in data.iter().enumerate() {
|
||||
buf.push(match i.checked_sub(bpp) {
|
||||
Some(x) => {
|
||||
byte.wrapping_sub(paeth_predictor(data[x], prev_line[i], prev_line[x]))
|
||||
}
|
||||
None => byte.wrapping_sub(prev_line[i]),
|
||||
});
|
||||
buf.push(byte.wrapping_sub(i.checked_sub(bpp).map_or_else(
|
||||
|| prev_line[i],
|
||||
|x| paeth_predictor(data[x], prev_line[i], prev_line[x]),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -241,10 +237,7 @@ impl RowFilter {
|
|||
Self::Sub => {
|
||||
for (i, &cur) in data.iter().enumerate() {
|
||||
let prev_byte = i.checked_sub(bpp).and_then(|x| buf.get(x).copied());
|
||||
buf.push(match prev_byte {
|
||||
Some(b) => cur.wrapping_add(b),
|
||||
None => cur,
|
||||
});
|
||||
buf.push(prev_byte.map_or(cur, |b| cur.wrapping_add(b)));
|
||||
}
|
||||
}
|
||||
Self::Up => {
|
||||
|
|
@ -257,10 +250,10 @@ impl RowFilter {
|
|||
Self::Average => {
|
||||
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());
|
||||
buf.push(match prev_byte {
|
||||
Some(b) => cur.wrapping_add(((u16::from(b) + u16::from(last)) >> 1) as u8),
|
||||
None => cur.wrapping_add(last >> 1),
|
||||
});
|
||||
buf.push(cur.wrapping_add(prev_byte.map_or_else(
|
||||
|| last >> 1,
|
||||
|b| ((u16::from(b) + u16::from(last)) >> 1) as u8,
|
||||
)));
|
||||
}
|
||||
}
|
||||
Self::Paeth => {
|
||||
|
|
|
|||
|
|
@ -35,18 +35,16 @@ impl IhdrData {
|
|||
|
||||
/// Byte length of IDAT that is correct for this IHDR
|
||||
#[must_use]
|
||||
pub fn raw_data_size(&self) -> usize {
|
||||
pub const fn raw_data_size(&self) -> usize {
|
||||
let w = self.width as usize;
|
||||
let h = self.height as usize;
|
||||
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
|
||||
}
|
||||
|
||||
if !self.interlaced {
|
||||
bitmap_size(bpp, w, h) + h
|
||||
} else {
|
||||
if self.interlaced {
|
||||
let mut size = bitmap_size(bpp, (w + 7) >> 3, (h + 7) >> 3) + ((h + 7) >> 3);
|
||||
if w > 4 {
|
||||
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, h >> 1) + (h >> 1)
|
||||
} else {
|
||||
bitmap_size(bpp, w, h) + h
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ fn deinterlace_bytes(png: &PngImage) -> Vec<u8> {
|
|||
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 {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
17
src/lib.rs
17
src/lib.rs
|
|
@ -28,7 +28,7 @@ mod rayon;
|
|||
use std::{
|
||||
fs::{File, Metadata},
|
||||
io::{BufWriter, Read, Write, stdin, stdout},
|
||||
path::Path,
|
||||
path::{Path, PathBuf},
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
|
|
@ -275,8 +275,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
|||
(OutFile::Path { path, .. }, _) => {
|
||||
let output_path = path
|
||||
.as_ref()
|
||||
.map(|p| p.as_path())
|
||||
.unwrap_or_else(|| input.path().unwrap());
|
||||
.map_or_else(|| input.path().unwrap(), PathBuf::as_path);
|
||||
let out_file = File::create(output_path)
|
||||
.map_err(|err| PngError::WriteFailed(output_path.display().to_string(), err))?;
|
||||
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 = perform_trials(
|
||||
new_image.clone(),
|
||||
new_image,
|
||||
opts,
|
||||
deadline.clone(),
|
||||
deadline,
|
||||
max_size,
|
||||
eval_result,
|
||||
eval_filters,
|
||||
|
|
@ -497,7 +496,7 @@ fn perform_trials(
|
|||
if !filters.is_empty() {
|
||||
trace!("Evaluating {} filters", filters.len());
|
||||
let eval = Evaluator::new(
|
||||
deadline.clone(),
|
||||
deadline,
|
||||
filters,
|
||||
eval_deflater,
|
||||
opts.optimize_alpha,
|
||||
|
|
@ -529,7 +528,7 @@ fn perform_trials(
|
|||
trace!(">{bytes} bytes");
|
||||
}
|
||||
Err(_) => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
return Some(result);
|
||||
}
|
||||
|
|
@ -659,7 +658,7 @@ fn recompress_frames(
|
|||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
||||
|
|
@ -674,7 +673,7 @@ fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()>
|
|||
}
|
||||
|
||||
#[cfg(not(feature = "filetime"))]
|
||||
fn copy_times(_: &Metadata, _: &Path) -> PngResult<()> {
|
||||
const fn copy_times(_: &Metadata, _: &Path) -> PngResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
15
src/main.rs
15
src/main.rs
|
|
@ -19,7 +19,12 @@ mod rayon;
|
|||
#[cfg(feature = "zopfli")]
|
||||
use std::num::NonZeroU64;
|
||||
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;
|
||||
|
|
@ -127,7 +132,7 @@ fn collect_files(
|
|||
warn!("{} is a directory, skipping", input.display());
|
||||
}
|
||||
continue;
|
||||
};
|
||||
}
|
||||
let 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()));
|
||||
|
|
@ -143,7 +148,7 @@ fn collect_files(
|
|||
} else {
|
||||
// Skip non png files if not given on 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("apng"))
|
||||
} {
|
||||
|
|
@ -200,7 +205,7 @@ fn parse_opts_into_struct(
|
|||
};
|
||||
|
||||
// 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 new_filters = IndexSet::new();
|
||||
for mut f in opts.filters.drain(..) {
|
||||
|
|
@ -243,7 +248,7 @@ fn parse_opts_into_struct(
|
|||
match DirBuilder::new().recursive(true).create(path) {
|
||||
Ok(()) => (),
|
||||
Err(x) => return Err(format!("Could not create output directory {x}")),
|
||||
};
|
||||
}
|
||||
} else if !path.is_dir() {
|
||||
return Err(format!(
|
||||
"{} is an existing file (not a directory), cannot create directory",
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ impl OutFile {
|
|||
///
|
||||
/// 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 {
|
||||
pub const fn from_path(path: PathBuf) -> Self {
|
||||
Self::Path {
|
||||
path: Some(path),
|
||||
preserve_attrs: false,
|
||||
}
|
||||
|
|
@ -199,7 +199,7 @@ impl Options {
|
|||
self
|
||||
}
|
||||
|
||||
fn apply_preset_2(self) -> Self {
|
||||
const fn apply_preset_2(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ impl PngData {
|
|||
});
|
||||
}
|
||||
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() {
|
||||
return Err(PngError::ChunkMissing("IDAT"));
|
||||
}
|
||||
let ihdr_chunk = match key_chunks.remove(b"IHDR") {
|
||||
Some(ihdr) => ihdr,
|
||||
None => return Err(PngError::ChunkMissing("IHDR")),
|
||||
let Some(ihdr_chunk) = key_chunks.remove(b"IHDR") else {
|
||||
return Err(PngError::ChunkMissing("IHDR"));
|
||||
};
|
||||
let ihdr = parse_ihdr_chunk(
|
||||
&ihdr_chunk,
|
||||
|
|
@ -310,11 +309,10 @@ impl PngImage {
|
|||
match &self.ihdr.color_type {
|
||||
ColorType::Indexed { palette } => {
|
||||
let plte = 12 + palette.len() * 3;
|
||||
if let Some(trns) = palette.iter().rposition(|p| p.a != 255) {
|
||||
plte + 12 + trns + 1
|
||||
} else {
|
||||
plte
|
||||
}
|
||||
palette
|
||||
.iter()
|
||||
.rposition(|p| p.a != 255)
|
||||
.map_or(plte, |trns| plte + 12 + trns + 1)
|
||||
}
|
||||
ColorType::Grayscale { transparent_shade } if transparent_shade.is_some() => 12 + 2,
|
||||
ColorType::RGB { transparent_color } if transparent_color.is_some() => 12 + 6,
|
||||
|
|
@ -348,7 +346,7 @@ impl PngImage {
|
|||
last_pass = line.pass;
|
||||
}
|
||||
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);
|
||||
unfiltered.extend_from_slice(&unfiltered_buf);
|
||||
std::mem::swap(&mut last_line, &mut unfiltered_buf);
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ impl Iterator for ScanLineRanges {
|
|||
pixels_per_line += 1;
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
let current_pass = Some(pass.0);
|
||||
if pass.1 + y_steps >= self.height {
|
||||
pass.0 += 1;
|
||||
|
|
|
|||
|
|
@ -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.extend_from_slice(&pixel[0..colored_bytes]),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the color type with appropriate transparency data
|
||||
|
|
|
|||
|
|
@ -70,17 +70,17 @@ pub fn reduced_bit_depth_8_or_less(png: &PngImage) -> Option<PngImage> {
|
|||
return None;
|
||||
}
|
||||
|
||||
let mut minimum_bits = 1;
|
||||
|
||||
if let ColorType::Indexed { palette } = &png.ihdr.color_type {
|
||||
let minimum_bits = if let ColorType::Indexed { palette } = &png.ihdr.color_type {
|
||||
// We can easily determine minimum depth by the palette size
|
||||
minimum_bits = match palette.len() {
|
||||
match palette.len() {
|
||||
0..=2 => 1,
|
||||
3..=4 => 2,
|
||||
5..=16 => 4,
|
||||
_ => return None,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
let mut minimum_bits = 1;
|
||||
|
||||
// Finding minimum depth for grayscale is much more complicated
|
||||
let mut mask = 1;
|
||||
let mut divisions = 1..8;
|
||||
|
|
@ -110,7 +110,9 @@ pub fn reduced_bit_depth_8_or_less(png: &PngImage) -> Option<PngImage> {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
minimum_bits
|
||||
};
|
||||
|
||||
let mut reduced = Vec::with_capacity(png.data.len());
|
||||
let mask = (1 << minimum_bits) - 1;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
pmap.into_iter()
|
||||
.map(|px| {
|
||||
RGB::from(px).with_alpha(if Some(px) != transparency_pixel {
|
||||
255
|
||||
} else {
|
||||
RGB::from(px).with_alpha(if Some(px) == transparency_pixel {
|
||||
0
|
||||
} else {
|
||||
255
|
||||
})
|
||||
})
|
||||
.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));
|
||||
pmap.into_iter()
|
||||
.map(|px| {
|
||||
px.with_alpha(if Some(px) != transparency_pixel {
|
||||
255
|
||||
} else {
|
||||
px.with_alpha(if Some(px) == transparency_pixel {
|
||||
0
|
||||
} else {
|
||||
255
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
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) {
|
||||
if let &[first, .., last] = line.data {
|
||||
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
|
||||
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 {
|
||||
counts[val as usize] += 1;
|
||||
}
|
||||
|
|
@ -261,7 +261,7 @@ fn apply_most_popular_color(png: &PngImage, remapping: &mut [usize]) {
|
|||
|
||||
// Calculate co-occurences matrix
|
||||
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_val = None;
|
||||
for line in png.scan_lines(false) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ fn load_png_image_from_memory(png_data: &[u8]) -> Result<Vec<RgbaImage>, image::
|
|||
decoder
|
||||
.apng()?
|
||||
.into_frames()
|
||||
.map(|f| f.map(|f| f.into_buffer()))
|
||||
.map(|f| f.map(image::Frame::into_buffer))
|
||||
.collect()
|
||||
} else {
|
||||
DynamicImage::from_decoder(decoder).map(|i| vec![i.into_rgba8()])
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ fn test_it_converts(
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ fn test_it_converts(
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ fn test_it_converts_callbacks<CBPRE, CBPOST>(
|
|||
match oxipng::optimize(&InFile::Path(input), output, opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
@ -445,7 +445,7 @@ fn preserve_attrs() {
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ fn test_it_converts(
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ fn test_it_converts(
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ fn test_it_converts(
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
@ -999,7 +999,7 @@ fn palette_should_be_reduced_with_dupes() {
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
@ -1036,7 +1036,7 @@ fn palette_should_be_reduced_with_unused() {
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
@ -1074,7 +1074,7 @@ fn palette_should_be_reduced_with_bkgd() {
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
@ -1112,7 +1112,7 @@ fn palette_should_be_reduced_with_both() {
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
@ -1149,7 +1149,7 @@ fn palette_should_be_reduced_with_missing() {
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ fn test_it_converts(
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ fn test_it_converts(
|
|||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||
Ok(_) => (),
|
||||
Err(x) => panic!("{}", x),
|
||||
};
|
||||
}
|
||||
let output = output.path().unwrap();
|
||||
assert!(output.exists());
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue