Apply clippy fixes
This commit is contained in:
parent
868fd502b9
commit
f862a0df24
10 changed files with 99 additions and 93 deletions
|
|
@ -25,7 +25,8 @@ impl AtomicMin {
|
|||
let mut current_val = self.val.load(Relaxed);
|
||||
loop {
|
||||
if new_val < current_val {
|
||||
if let Err(v) = self.val
|
||||
if let Err(v) = self
|
||||
.val
|
||||
.compare_exchange(current_val, new_val, SeqCst, Relaxed)
|
||||
{
|
||||
current_val = v;
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ impl fmt::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 {
|
||||
match *self {
|
||||
pub fn png_header_code(self) -> u8 {
|
||||
match self {
|
||||
ColorType::Grayscale => 0,
|
||||
ColorType::RGB => 2,
|
||||
ColorType::Indexed => 3,
|
||||
|
|
@ -46,8 +46,8 @@ impl ColorType {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn channels_per_pixel(&self) -> u8 {
|
||||
match *self {
|
||||
pub fn channels_per_pixel(self) -> u8 {
|
||||
match self {
|
||||
ColorType::Grayscale | ColorType::Indexed => 1,
|
||||
ColorType::GrayscaleAlpha => 2,
|
||||
ColorType::RGB => 3,
|
||||
|
|
@ -91,8 +91,8 @@ impl fmt::Display for BitDepth {
|
|||
impl BitDepth {
|
||||
/// Retrieve the number of bits per channel per pixel as a `u8`
|
||||
#[inline]
|
||||
pub fn as_u8(&self) -> u8 {
|
||||
match *self {
|
||||
pub fn as_u8(self) -> u8 {
|
||||
match self {
|
||||
BitDepth::One => 1,
|
||||
BitDepth::Two => 2,
|
||||
BitDepth::Four => 4,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use atomicmin::AtomicMin;
|
||||
use error::PngError;
|
||||
use miniz_oxide::deflate::core::*;
|
||||
use PngResult;
|
||||
|
||||
pub fn compress_to_vec_oxipng(
|
||||
input: &[u8],
|
||||
|
|
@ -8,7 +9,7 @@ pub fn compress_to_vec_oxipng(
|
|||
window_bits: i32,
|
||||
strategy: i32,
|
||||
max_size: &AtomicMin,
|
||||
) -> Result<Vec<u8>, PngError> {
|
||||
) -> PngResult<Vec<u8>> {
|
||||
// The comp flags function sets the zlib flag if the window_bits parameter is > 0.
|
||||
let flags = create_comp_flags_from_zip_params(level.into(), window_bits, strategy);
|
||||
let mut compressor = CompressorOxide::new(flags);
|
||||
|
|
|
|||
|
|
@ -3,24 +3,19 @@ use error::PngError;
|
|||
use miniz_oxide;
|
||||
use std::cmp::max;
|
||||
use zopfli;
|
||||
use PngResult;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod miniz_stream;
|
||||
|
||||
/// Decompress a data stream using the DEFLATE algorithm
|
||||
pub fn inflate(data: &[u8]) -> Result<Vec<u8>, PngError> {
|
||||
pub fn inflate(data: &[u8]) -> PngResult<Vec<u8>> {
|
||||
miniz_oxide::inflate::decompress_to_vec_zlib(data)
|
||||
.map_err(|e| PngError::new(&format!("Error on decompress: {:?}", e)))
|
||||
}
|
||||
|
||||
/// Compress a data stream using the DEFLATE algorithm
|
||||
pub fn deflate(
|
||||
data: &[u8],
|
||||
zc: u8,
|
||||
zs: u8,
|
||||
zw: u8,
|
||||
max_size: &AtomicMin,
|
||||
) -> Result<Vec<u8>, PngError> {
|
||||
pub fn deflate(data: &[u8], zc: u8, zs: u8, zw: u8, max_size: &AtomicMin) -> PngResult<Vec<u8>> {
|
||||
#[cfg(feature = "cfzlib")]
|
||||
{
|
||||
if is_cfzlib_supported() {
|
||||
|
|
@ -55,7 +50,7 @@ pub fn cfzlib_deflate(
|
|||
strategy: u8,
|
||||
window_bits: u8,
|
||||
max_size: &AtomicMin,
|
||||
) -> Result<Vec<u8>, PngError> {
|
||||
) -> PngResult<Vec<u8>> {
|
||||
use cloudflare_zlib_sys::*;
|
||||
use std::mem;
|
||||
|
||||
|
|
@ -98,7 +93,7 @@ pub fn cfzlib_deflate(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn zopfli_deflate(data: &[u8]) -> Result<Vec<u8>, PngError> {
|
||||
pub fn zopfli_deflate(data: &[u8]) -> PngResult<Vec<u8>> {
|
||||
let mut output = Vec::with_capacity(max(1024, data.len() / 20));
|
||||
let options = zopfli::Options::default();
|
||||
match zopfli::compress(&options, &zopfli::Format::Zlib, data, &mut output) {
|
||||
|
|
|
|||
|
|
@ -32,9 +32,8 @@ pub fn filter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> Vec
|
|||
});
|
||||
} else {
|
||||
filtered.push(match i.checked_sub(bpp) {
|
||||
Some(x) => byte.wrapping_sub(
|
||||
((u16::from(data[x]) + u16::from(last_line[i])) >> 1) as u8,
|
||||
),
|
||||
Some(x) => byte
|
||||
.wrapping_sub(((u16::from(data[x]) + u16::from(last_line[i])) >> 1) as u8),
|
||||
None => byte.wrapping_sub(last_line[i] >> 1),
|
||||
});
|
||||
};
|
||||
|
|
@ -87,31 +86,33 @@ pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> V
|
|||
);
|
||||
};
|
||||
}
|
||||
3 => for (i, byte) in data.iter().enumerate() {
|
||||
if last_line.is_empty() {
|
||||
match i.checked_sub(bpp) {
|
||||
Some(x) => {
|
||||
let b = unfiltered[x];
|
||||
unfiltered.push(byte.wrapping_add(b >> 1));
|
||||
}
|
||||
None => {
|
||||
unfiltered.push(*byte);
|
||||
}
|
||||
3 => {
|
||||
for (i, byte) in data.iter().enumerate() {
|
||||
if last_line.is_empty() {
|
||||
match i.checked_sub(bpp) {
|
||||
Some(x) => {
|
||||
let b = unfiltered[x];
|
||||
unfiltered.push(byte.wrapping_add(b >> 1));
|
||||
}
|
||||
None => {
|
||||
unfiltered.push(*byte);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
match i.checked_sub(bpp) {
|
||||
Some(x) => {
|
||||
let b = unfiltered[x];
|
||||
unfiltered.push(byte.wrapping_add(
|
||||
((u16::from(b) + u16::from(last_line[i])) >> 1) as u8,
|
||||
));
|
||||
}
|
||||
None => {
|
||||
unfiltered.push(byte.wrapping_add(last_line[i] >> 1));
|
||||
}
|
||||
};
|
||||
};
|
||||
} else {
|
||||
match i.checked_sub(bpp) {
|
||||
Some(x) => {
|
||||
let b = unfiltered[x];
|
||||
unfiltered.push(byte.wrapping_add(
|
||||
((u16::from(b) + u16::from(last_line[i])) >> 1) as u8,
|
||||
));
|
||||
}
|
||||
None => {
|
||||
unfiltered.push(byte.wrapping_add(last_line[i] >> 1));
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
4 => for (i, byte) in data.iter().enumerate() {
|
||||
if last_line.is_empty() {
|
||||
match i.checked_sub(bpp) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crc::crc32;
|
|||
use error::PngError;
|
||||
use std::collections::HashSet;
|
||||
use std::io::Cursor;
|
||||
use PngResult;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
/// Headers from the IHDR chunk of the image
|
||||
|
|
@ -46,14 +47,22 @@ pub fn file_header_is_valid(bytes: &[u8]) -> bool {
|
|||
*bytes == expected_header
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RawHeader<'a> {
|
||||
pub name: &'a [u8],
|
||||
pub data: &'a [u8],
|
||||
}
|
||||
|
||||
pub fn parse_next_header<'a>(
|
||||
byte_data: &'a [u8],
|
||||
byte_offset: &mut usize,
|
||||
fix_errors: bool,
|
||||
) -> Result<Option<(&'a [u8], &'a [u8])>, PngError> {
|
||||
let mut rdr = Cursor::new(byte_data
|
||||
.get(*byte_offset..*byte_offset + 4)
|
||||
.ok_or(PngError::TruncatedData)?);
|
||||
) -> PngResult<Option<RawHeader<'a>>> {
|
||||
let mut rdr = Cursor::new(
|
||||
byte_data
|
||||
.get(*byte_offset..*byte_offset + 4)
|
||||
.ok_or(PngError::TruncatedData)?,
|
||||
);
|
||||
let length = rdr.read_u32::<BigEndian>().unwrap();
|
||||
*byte_offset += 4;
|
||||
|
||||
|
|
@ -71,9 +80,11 @@ pub fn parse_next_header<'a>(
|
|||
.get(*byte_offset..*byte_offset + length as usize)
|
||||
.ok_or(PngError::TruncatedData)?;
|
||||
*byte_offset += length as usize;
|
||||
let mut rdr = Cursor::new(byte_data
|
||||
.get(*byte_offset..*byte_offset + 4)
|
||||
.ok_or(PngError::TruncatedData)?);
|
||||
let mut rdr = Cursor::new(
|
||||
byte_data
|
||||
.get(*byte_offset..*byte_offset + 4)
|
||||
.ok_or(PngError::TruncatedData)?,
|
||||
);
|
||||
let crc = rdr.read_u32::<BigEndian>().unwrap();
|
||||
*byte_offset += 4;
|
||||
|
||||
|
|
@ -87,10 +98,13 @@ pub fn parse_next_header<'a>(
|
|||
)));
|
||||
}
|
||||
|
||||
Ok(Some((chunk_name, data)))
|
||||
Ok(Some(RawHeader {
|
||||
name: chunk_name,
|
||||
data,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn parse_ihdr_header(byte_data: &[u8]) -> Result<IhdrData, PngError> {
|
||||
pub fn parse_ihdr_header(byte_data: &[u8]) -> PngResult<IhdrData> {
|
||||
let mut rdr = Cursor::new(&byte_data[0..8]);
|
||||
Ok(IhdrData {
|
||||
color_type: match byte_data[9] {
|
||||
|
|
|
|||
25
src/lib.rs
25
src/lib.rs
|
|
@ -21,7 +21,7 @@ use std::fmt;
|
|||
use std::fs::{copy, File};
|
||||
use std::io::{stdin, stdout, BufWriter, Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub use colors::AlphaOptim;
|
||||
|
|
@ -96,6 +96,8 @@ impl<T: Into<PathBuf>> From<T> for InFile {
|
|||
}
|
||||
}
|
||||
|
||||
pub type PngResult<T> = Result<T, PngError>;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Options controlling the output of the `optimize` function
|
||||
pub struct Options {
|
||||
|
|
@ -321,7 +323,7 @@ impl Default for Options {
|
|||
}
|
||||
|
||||
/// Perform optimization on the input file using the options provided
|
||||
pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> Result<(), PngError> {
|
||||
pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<()> {
|
||||
// Initialize the thread pool with correct number of threads
|
||||
#[cfg(feature = "parallel")]
|
||||
let thread_count = opts.threads;
|
||||
|
|
@ -418,7 +420,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> Result<(),
|
|||
|
||||
/// Perform optimization on the input file using the options provided, where the file is already
|
||||
/// loaded in-memory
|
||||
pub fn optimize_from_memory(data: &[u8], opts: &Options) -> Result<Vec<u8>, PngError> {
|
||||
pub fn optimize_from_memory(data: &[u8], opts: &Options) -> PngResult<Vec<u8>> {
|
||||
// Initialize the thread pool with correct number of threads
|
||||
#[cfg(feature = "parallel")]
|
||||
let thread_count = opts.threads;
|
||||
|
|
@ -454,11 +456,7 @@ struct TrialOptions {
|
|||
}
|
||||
|
||||
/// Perform optimization on the input PNG object using the options provided
|
||||
fn optimize_png(
|
||||
png: &mut PngData,
|
||||
original_data: &[u8],
|
||||
opts: &Options,
|
||||
) -> Result<Vec<u8>, PngError> {
|
||||
fn optimize_png(png: &mut PngData, original_data: &[u8], opts: &Options) -> PngResult<Vec<u8>> {
|
||||
type TrialWithData = (TrialOptions, Vec<u8>);
|
||||
|
||||
let deadline = Deadline::new(opts);
|
||||
|
|
@ -771,7 +769,7 @@ fn perform_reductions(png: &mut PngData, opts: &Options, deadline: &Deadline) ->
|
|||
struct Deadline {
|
||||
start: Instant,
|
||||
timeout: Option<Duration>,
|
||||
print_message: Mutex<bool>,
|
||||
print_message: AtomicBool,
|
||||
}
|
||||
|
||||
impl Deadline {
|
||||
|
|
@ -779,7 +777,7 @@ impl Deadline {
|
|||
Self {
|
||||
start: Instant::now(),
|
||||
timeout: opts.timeout,
|
||||
print_message: Mutex::new(opts.verbosity.is_some()),
|
||||
print_message: AtomicBool::new(opts.verbosity.is_some()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -789,9 +787,8 @@ impl Deadline {
|
|||
pub fn passed(&self) -> bool {
|
||||
if let Some(timeout) = self.timeout {
|
||||
if self.start.elapsed() > timeout {
|
||||
let mut print_message = self.print_message.lock().unwrap();
|
||||
if *print_message {
|
||||
*print_message = false;
|
||||
if self.print_message.load(Ordering::Relaxed) {
|
||||
self.print_message.store(false, Ordering::Relaxed);
|
||||
eprintln!("Timed out after {} second(s)", timeout.as_secs());
|
||||
}
|
||||
return true;
|
||||
|
|
@ -852,7 +849,7 @@ fn is_fully_optimized(original_size: usize, optimized_size: usize, opts: &Option
|
|||
original_size <= optimized_size && !opts.force && opts.interlace.is_none()
|
||||
}
|
||||
|
||||
fn perform_backup(input_path: &Path) -> Result<(), PngError> {
|
||||
fn perform_backup(input_path: &Path) -> PngResult<()> {
|
||||
let backup_file = input_path.with_extension(format!(
|
||||
"bak.{}",
|
||||
input_path.extension().unwrap().to_str().unwrap()
|
||||
|
|
|
|||
13
src/main.rs
13
src/main.rs
|
|
@ -9,8 +9,9 @@ use clap::{App, AppSettings, Arg, ArgMatches};
|
|||
use oxipng::AlphaOptim;
|
||||
use oxipng::Deflaters;
|
||||
use oxipng::Headers;
|
||||
use oxipng::Options;
|
||||
use oxipng::PngResult;
|
||||
use oxipng::{InFile, OutFile};
|
||||
use oxipng::{Options, PngError};
|
||||
use std::collections::HashSet;
|
||||
use std::fs::DirBuilder;
|
||||
use std::path::PathBuf;
|
||||
|
|
@ -240,7 +241,7 @@ fn main() {
|
|||
true,
|
||||
);
|
||||
|
||||
let res: Result<(), PngError> = files
|
||||
let res: PngResult<()> = files
|
||||
.into_iter()
|
||||
.map(|(input, output)| oxipng::optimize(&input, &output, &opts))
|
||||
.collect();
|
||||
|
|
@ -321,7 +322,8 @@ fn parse_opts_into_struct(
|
|||
}
|
||||
|
||||
if let Some(x) = matches.value_of("timeout") {
|
||||
let num = x.parse()
|
||||
let num = x
|
||||
.parse()
|
||||
.map_err(|_| "Timeout must be a number".to_owned())?;
|
||||
opts.timeout = Some(Duration::from_secs(num));
|
||||
}
|
||||
|
|
@ -435,7 +437,8 @@ fn parse_opts_into_struct(
|
|||
}
|
||||
|
||||
if let Some(hdrs) = matches.value_of("strip") {
|
||||
let hdrs = hdrs.split(',')
|
||||
let hdrs = hdrs
|
||||
.split(',')
|
||||
.map(|x| x.trim().to_owned())
|
||||
.collect::<Vec<String>>();
|
||||
if hdrs.contains(&"safe".to_owned()) || hdrs.contains(&"all".to_owned()) {
|
||||
|
|
@ -525,5 +528,5 @@ fn parse_numeric_range_opts(
|
|||
return Ok(items);
|
||||
}
|
||||
|
||||
return Err(ERROR_MESSAGE.to_owned());
|
||||
Err(ERROR_MESSAGE.to_owned())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,19 +95,14 @@ impl PngData {
|
|||
// Read the data headers
|
||||
let mut aux_headers: HashMap<String, Vec<u8>> = HashMap::new();
|
||||
let mut idat_headers: Vec<u8> = Vec::new();
|
||||
loop {
|
||||
let header = parse_next_header(byte_data, &mut byte_offset, fix_errors)?;
|
||||
let (name, data) = match header {
|
||||
Some(x) => x,
|
||||
None => break,
|
||||
};
|
||||
match name {
|
||||
b"IDAT" => idat_headers.extend(data),
|
||||
while let Some(header) = parse_next_header(byte_data, &mut byte_offset, fix_errors)? {
|
||||
match header.name {
|
||||
b"IDAT" => idat_headers.extend(header.data),
|
||||
b"acTL" => return Err(PngError::APNGNotSupported),
|
||||
_ => {
|
||||
let name =
|
||||
String::from_utf8(name.to_owned()).map_err(|_| PngError::InvalidData)?;
|
||||
aux_headers.insert(name, data.to_owned());
|
||||
let name = String::from_utf8(header.name.to_owned())
|
||||
.map_err(|_| PngError::InvalidData)?;
|
||||
aux_headers.insert(name, header.data.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -184,7 +179,8 @@ impl PngData {
|
|||
let _ = ihdr_data.write_u8(self.ihdr_data.interlaced);
|
||||
write_png_block(b"IHDR", &ihdr_data, &mut output);
|
||||
// Ancillary headers
|
||||
for (key, header) in self.aux_headers
|
||||
for (key, header) in self
|
||||
.aux_headers
|
||||
.iter()
|
||||
.filter(|&(key, _)| !(*key == "bKGD" || *key == "hIST" || *key == "tRNS"))
|
||||
{
|
||||
|
|
@ -202,7 +198,8 @@ impl PngData {
|
|||
write_png_block(b"tRNS", transparency_pixel, &mut output);
|
||||
}
|
||||
// Special ancillary headers that need to come after PLTE but before IDAT
|
||||
for (key, header) in self.aux_headers
|
||||
for (key, header) in self
|
||||
.aux_headers
|
||||
.iter()
|
||||
.filter(|&(key, _)| *key == "bKGD" || *key == "hIST" || *key == "tRNS")
|
||||
{
|
||||
|
|
@ -713,12 +710,11 @@ impl PngData {
|
|||
|
||||
fn reduce_alpha_to_up(&self, bpc: usize, bpp: usize) -> Vec<u8> {
|
||||
let mut lines = Vec::new();
|
||||
let mut scan_lines = self.scan_lines()
|
||||
.collect::<Vec<ScanLine>>();
|
||||
let mut scan_lines = self.scan_lines().collect::<Vec<ScanLine>>();
|
||||
scan_lines.reverse();
|
||||
let mut last_line = vec![0; scan_lines[0].data.len()];
|
||||
let mut current_line = Vec::with_capacity(last_line.len());
|
||||
for line in scan_lines.into_iter() {
|
||||
for line in scan_lines {
|
||||
current_line.push(line.filter);
|
||||
for (pixel, last_pixel) in line.data.chunks(bpp).zip(last_line.chunks(bpp)) {
|
||||
if pixel.iter().skip(bpp - bpc).fold(0, |sum, i| sum | i) == 0 {
|
||||
|
|
|
|||
|
|
@ -8,10 +8,8 @@ pub fn reduce_alpha_channel(png: &mut PngData, channels: u8) -> Option<Vec<u8>>
|
|||
let colored_bytes = bpp - byte_depth;
|
||||
for line in png.scan_lines() {
|
||||
for (i, &byte) in line.data.iter().enumerate() {
|
||||
if i as u8 & bpp_mask >= colored_bytes {
|
||||
if byte != 255 {
|
||||
return None;
|
||||
}
|
||||
if i as u8 & bpp_mask >= colored_bytes && byte != 255 {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue