Apply clippy fixes

This commit is contained in:
Josh Holmer 2018-07-28 16:51:54 -04:00
parent 868fd502b9
commit f862a0df24
10 changed files with 99 additions and 93 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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);

View file

@ -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) {

View file

@ -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) {

View file

@ -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] {

View file

@ -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()

View file

@ -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())
}

View file

@ -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 {

View file

@ -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;
}
}
}