Reformat and fix warnings

This commit is contained in:
Chris Hennick 2023-06-20 08:44:00 -07:00
parent 971edf7b8c
commit d1a78f97bf
No known key found for this signature in database
GPG key ID: 25653935CC8B6C74
4 changed files with 74 additions and 37 deletions

View file

@ -9,12 +9,7 @@ use std::num::NonZeroU8;
use std::path::PathBuf; use std::path::PathBuf;
use test::Bencher; use test::Bencher;
const DEFAULT_DEFLATER: BufferedZopfliDeflater = BufferedZopfliDeflater::const_default();
const DEFAULT_DEFLATER: BufferedZopfliDeflater = BufferedZopfliDeflater::new(
// SAFETY: trivially safe. Stopgap solution until const unwrap is stabilized.
unsafe { NonZeroU8::new_unchecked(15) },
4 * 1024 * 1024
);
#[bench] #[bench]
fn zopfli_16_bits_strategy_0(b: &mut Bencher) { fn zopfli_16_bits_strategy_0(b: &mut Bencher) {
@ -23,7 +18,9 @@ fn zopfli_16_bits_strategy_0(b: &mut Bencher) {
let max_size = AtomicMin::new(Some(png.idat_data.len())); let max_size = AtomicMin::new(Some(png.idat_data.len()));
b.iter(|| { b.iter(|| {
DEFAULT_DEFLATER.deflate(png.raw.data.as_ref(), &max_size).ok(); DEFAULT_DEFLATER
.deflate(png.raw.data.as_ref(), &max_size)
.ok();
}); });
} }
@ -34,7 +31,9 @@ fn zopfli_8_bits_strategy_0(b: &mut Bencher) {
let max_size = AtomicMin::new(Some(png.idat_data.len())); let max_size = AtomicMin::new(Some(png.idat_data.len()));
b.iter(|| { b.iter(|| {
DEFAULT_DEFLATER.deflate(png.raw.data.as_ref(), &max_size).ok(); DEFAULT_DEFLATER
.deflate(png.raw.data.as_ref(), &max_size)
.ok();
}); });
} }
@ -47,7 +46,9 @@ fn zopfli_4_bits_strategy_0(b: &mut Bencher) {
let max_size = AtomicMin::new(Some(png.idat_data.len())); let max_size = AtomicMin::new(Some(png.idat_data.len()));
b.iter(|| { b.iter(|| {
DEFAULT_DEFLATER.deflate(png.raw.data.as_ref(), &max_size).ok(); DEFAULT_DEFLATER
.deflate(png.raw.data.as_ref(), &max_size)
.ok();
}); });
} }
@ -60,7 +61,9 @@ fn zopfli_2_bits_strategy_0(b: &mut Bencher) {
let max_size = AtomicMin::new(Some(png.idat_data.len())); let max_size = AtomicMin::new(Some(png.idat_data.len()));
b.iter(|| { b.iter(|| {
DEFAULT_DEFLATER.deflate(png.raw.data.as_ref(), &max_size).ok(); DEFAULT_DEFLATER
.deflate(png.raw.data.as_ref(), &max_size)
.ok();
}); });
} }
@ -73,6 +76,8 @@ fn zopfli_1_bits_strategy_0(b: &mut Bencher) {
let max_size = AtomicMin::new(Some(png.idat_data.len())); let max_size = AtomicMin::new(Some(png.idat_data.len()));
b.iter(|| { b.iter(|| {
DEFAULT_DEFLATER.deflate(png.raw.data.as_ref(), &max_size).ok(); DEFAULT_DEFLATER
.deflate(png.raw.data.as_ref(), &max_size)
.ok();
}); });
} }

View file

@ -4,8 +4,8 @@ use crate::{PngError, PngResult};
pub use deflater::crc32; pub use deflater::crc32;
pub use deflater::deflate; pub use deflater::deflate;
pub use deflater::inflate; pub use deflater::inflate;
use std::{fmt, fmt::Display, io};
use std::io::{BufWriter, Cursor, Write}; use std::io::{BufWriter, Cursor, Write};
use std::{fmt, fmt::Display, io};
#[cfg(feature = "zopfli")] #[cfg(feature = "zopfli")]
use std::num::NonZeroU8; use std::num::NonZeroU8;
@ -61,29 +61,60 @@ pub struct BufferedZopfliDeflater {
iterations: NonZeroU8, iterations: NonZeroU8,
input_buffer_size: usize, input_buffer_size: usize,
output_buffer_size: usize, output_buffer_size: usize,
max_block_splits: u16 max_block_splits: u16,
} }
#[cfg(feature = "zopfli")]
impl BufferedZopfliDeflater { impl BufferedZopfliDeflater {
pub const fn new(iterations: NonZeroU8, pub const fn new(
input_buffer_size: usize, iterations: NonZeroU8,
output_buffer_size: usize, input_buffer_size: usize,
max_block_splits: u16) -> Self { output_buffer_size: usize,
BufferedZopfliDeflater {iterations, input_buffer_size, output_buffer_size, max_block_splits } max_block_splits: u16,
) -> Self {
BufferedZopfliDeflater {
iterations,
input_buffer_size,
output_buffer_size,
max_block_splits,
}
}
pub const fn const_default() -> Self {
BufferedZopfliDeflater {
// SAFETY: trivially safe. Stopgap solution until const unwrap is stabilized.
iterations: unsafe { NonZeroU8::new_unchecked(15) },
input_buffer_size: 1024 * 1024,
output_buffer_size: 64 * 1024,
max_block_splits: 15,
}
}
}
#[cfg(feature = "zopfli")]
impl Default for BufferedZopfliDeflater {
fn default() -> Self {
Self::const_default()
} }
} }
#[cfg(feature = "zopfli")] #[cfg(feature = "zopfli")]
impl Deflater for BufferedZopfliDeflater { impl Deflater for BufferedZopfliDeflater {
fn deflate(&self, data: &[u8], max_size: &AtomicMin) -> PngResult<Vec<u8>> { fn deflate(&self, data: &[u8], max_size: &AtomicMin) -> PngResult<Vec<u8>> {
#[allow(clippy::needless_update)]
let options = Options { let options = Options {
iteration_count: self.iterations, iteration_count: self.iterations,
maximum_block_splits: self.max_block_splits, maximum_block_splits: self.max_block_splits,
..Default::default() ..Default::default() // for forward compatibility
}; };
let mut buffer = BufWriter::with_capacity(self.input_buffer_size, let mut buffer = BufWriter::with_capacity(
DeflateEncoder::new( self.input_buffer_size,
options, Default::default(), Cursor::new(Vec::new()))); DeflateEncoder::new(
options,
Default::default(),
Cursor::new(Vec::with_capacity(self.output_buffer_size)),
),
);
let result = (|| -> io::Result<Vec<u8>> { let result = (|| -> io::Result<Vec<u8>> {
buffer.write_all(data)?; buffer.write_all(data)?;
Ok(buffer.into_inner()?.finish()?.into_inner()) Ok(buffer.into_inner()?.finish()?.into_inner())

View file

@ -1,5 +1,5 @@
use crate::colors::{BitDepth, ColorType}; use crate::colors::{BitDepth, ColorType};
use crate::deflate::{crc32, Deflater, inflate}; use crate::deflate::{crc32, inflate, Deflater};
use crate::error::PngError; use crate::error::PngError;
use crate::interlace::Interlacing; use crate::interlace::Interlacing;
use crate::AtomicMin; use crate::AtomicMin;

View file

@ -41,6 +41,7 @@ use std::sync::Arc;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
pub use crate::colors::{BitDepth, ColorType}; pub use crate::colors::{BitDepth, ColorType};
use crate::deflate::Deflater;
pub use crate::deflate::Deflaters; pub use crate::deflate::Deflaters;
pub use crate::error::PngError; pub use crate::error::PngError;
pub use crate::filters::RowFilter; pub use crate::filters::RowFilter;
@ -48,7 +49,6 @@ pub use crate::headers::StripChunks;
pub use crate::interlace::Interlacing; pub use crate::interlace::Interlacing;
pub use indexmap::{indexset, IndexSet}; pub use indexmap::{indexset, IndexSet};
pub use rgb::{RGB16, RGBA8}; pub use rgb::{RGB16, RGBA8};
use crate::deflate::Deflater;
mod atomicmin; mod atomicmin;
mod colors; mod colors;
@ -387,11 +387,13 @@ impl RawImage {
} }
/// Create an optimized png from the raw image data using the options provided /// Create an optimized png from the raw image data using the options provided
pub fn create_optimized_png<T: Deflater> pub fn create_optimized_png<T: Deflater>(
(&self, opts: &Options, deflater: &T) -> PngResult<Vec<u8>> { &self,
opts: &Options,
deflater: &T,
) -> PngResult<Vec<u8>> {
let deadline = Arc::new(Deadline::new(opts.timeout)); let deadline = Arc::new(Deadline::new(opts.timeout));
let mut png = optimize_raw(self.png.clone(), let mut png = optimize_raw(self.png.clone(), opts, deadline, None, deflater)
opts, deadline, None, deflater)
.ok_or_else(|| PngError::new("Failed to optimize input data"))?; .ok_or_else(|| PngError::new("Failed to optimize input data"))?;
// Process aux chunks // Process aux chunks
@ -572,8 +574,7 @@ fn optimize_png(
} else { } else {
Some(png.estimated_output_size()) Some(png.estimated_output_size())
}; };
if let Some(new_png) = optimize_raw(raw.clone(), opts, deadline, max_size, if let Some(new_png) = optimize_raw(raw.clone(), opts, deadline, max_size, &opts.deflate) {
&opts.deflate) {
png.raw = new_png.raw; png.raw = new_png.raw;
png.idat_data = new_png.idat_data; png.idat_data = new_png.idat_data;
} }
@ -623,7 +624,7 @@ fn optimize_raw<T: Deflater>(
opts: &Options, opts: &Options,
deadline: Arc<Deadline>, deadline: Arc<Deadline>,
max_size: Option<usize>, max_size: Option<usize>,
deflater: &T deflater: &T,
) -> Option<PngData> { ) -> Option<PngData> {
// Must use normal (lazy) compression, as faster ones (greedy) are not representative // Must use normal (lazy) compression, as faster ones (greedy) are not representative
let eval_compression = 5; let eval_compression = 5;
@ -765,7 +766,7 @@ fn perform_trial<T: Deflater>(
opts: &Options, opts: &Options,
filter: RowFilter, filter: RowFilter,
best_size: &AtomicMin, best_size: &AtomicMin,
deflater: &T deflater: &T,
) -> Option<TrialResult> { ) -> Option<TrialResult> {
let result = deflater.deflate(filtered, best_size); let result = deflater.deflate(filtered, best_size);
match result { match result {
@ -782,11 +783,11 @@ fn perform_trial<T: Deflater>(
} }
Err(PngError::DeflatedDataTooLong(bytes)) => { Err(PngError::DeflatedDataTooLong(bytes)) => {
trace!( trace!(
" zc = {} f = {:8} >{} bytes", " zc = {} f = {:8} >{} bytes",
opts.deflate, opts.deflate,
filter, filter,
bytes, bytes,
); );
None None
} }
Err(e) => { Err(e) => {