From 75200fcd0708beedcdf9300990b35e83b76731a5 Mon Sep 17 00:00:00 2001 From: Josh Holmer Date: Fri, 7 Jul 2023 22:35:01 -0400 Subject: [PATCH] Provide BufferedZopfliDeflater and allow user to pass in a custom Deflater (#530) * Add .whitesource configuration file * Experimental: allow Zopfli to use any size BufWriter * Allow user to specify the output buffer size as well * Allow user to specify maximum block splits * Reformat and fix warnings * Use deflater on iCCP chunk as well * Bug fix: need to implement Zlib format * Make functions const when possible * Switch to using zopfli::Options in prep for https://github.com/zopfli-rs/zopfli/pull/21 * Switch to using zopfli::Options in prep for https://github.com/zopfli-rs/zopfli/pull/21 * Cargo fmt * Fix compilation * Fix tests * Fix more lints * Fix more lints * Fix compilation more --------- Co-authored-by: mend-bolt-for-github[bot] <42819689+mend-bolt-for-github[bot]@users.noreply.github.com> Co-authored-by: Chris Hennick Co-authored-by: Chris Hennick <4961925+Pr0methean@users.noreply.github.com> --- Cargo.lock | 1 + Cargo.toml | 3 ++- benches/zopfli.rs | 1 - src/deflate/mod.rs | 7 ++++++- src/lib.rs | 17 ++++++++++++++--- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa4dc97c..02c89caa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,6 +479,7 @@ dependencies = [ "rgb", "rustc-hash", "rustc_version", + "simd-adler32", "stderrlog", "wild", "zopfli", diff --git a/Cargo.toml b/Cargo.toml index 6a3fafee..48ce0bc8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ required-features = ["zopfli"] [dependencies] zopfli = {git = "https://github.com/Pr0methean/zopfli.git", default-features = false, features = ["zlib"] } simd-adler32 = { version = "0.3.5", optional = true, default-features = false } +simd-adler32 = { version = "0.3.5", optional = true, default-features = false } rgb = "0.8.36" indexmap = "2.0.0" libdeflater = "0.14.0" @@ -67,7 +68,7 @@ version = "0.24.6" rustc_version = "0.4.0" [features] -zopfli = ["zopfli/zlib", "simd-adler32"] +zopfli = ["zopfli/std", "zopfli/zlib", "simd-adler32"] binary = ["clap", "wild", "stderrlog"] default = ["binary", "filetime", "parallel", "zopfli"] parallel = ["rayon", "indexmap/rayon", "crossbeam-channel"] diff --git a/benches/zopfli.rs b/benches/zopfli.rs index 23dd67bb..74c888bf 100644 --- a/benches/zopfli.rs +++ b/benches/zopfli.rs @@ -5,7 +5,6 @@ extern crate test; use oxipng::internal_tests::*; use oxipng::*; -use std::num::NonZeroU8; use std::path::PathBuf; use test::Bencher; diff --git a/src/deflate/mod.rs b/src/deflate/mod.rs index e9ef7a12..02b95e48 100644 --- a/src/deflate/mod.rs +++ b/src/deflate/mod.rs @@ -7,6 +7,9 @@ pub use deflater::inflate; use std::io::{copy, BufWriter, Cursor, Write}; use std::{fmt, fmt::Display, io}; +#[cfg(feature = "zopfli")] +use std::io::{self, copy, BufWriter, Cursor, Write}; + #[cfg(feature = "zopfli")] use zopfli::{DeflateEncoder, Options}; #[cfg(feature = "zopfli")] @@ -14,6 +17,8 @@ mod zopfli_oxipng; #[cfg(feature = "zopfli")] use simd_adler32::Adler32; #[cfg(feature = "zopfli")] +use simd_adler32::Adler32; +#[cfg(feature = "zopfli")] pub use zopfli_oxipng::deflate as zopfli_deflate; #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -113,7 +118,7 @@ impl Deflater for BufferedZopfliDeflater { Ok(out.into_inner()) })(); let out = out.map_err(|e| PngError::new(&e.to_string()))?; - if max_size.get().is_some_and(|max| max < out.len()) { + if max_size.get().map(|max| max < out.len()).unwrap_or(false) { Err(PngError::DeflatedDataTooLong(out.len())) } else { Ok(out) diff --git a/src/lib.rs b/src/lib.rs index e6caf596..1ad15e6b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -588,7 +588,13 @@ fn optimize_png( } else { Some(png.estimated_output_size()) }; - if let Some(new_png) = optimize_raw(raw.clone(), &opts, deadline.clone(), max_size, &opts.deflate) { + if let Some(new_png) = optimize_raw( + raw.clone(), + &opts, + deadline.clone(), + max_size, + &opts.deflate, + ) { png.raw = new_png.raw; png.idat_data = new_png.idat_data; } @@ -861,8 +867,13 @@ fn report_format(prefix: &str, png: &PngImage) { } /// Perform cleanup of certain chunks from the `PngData` object, after optimization has been completed -fn postprocess_chunks(png: &mut PngData, opts: &Options, orig_ihdr: &IhdrData, deadline: Arc, deflater: &T) -where +fn postprocess_chunks( + png: &mut PngData, + opts: &Options, + deadline: Arc, + orig_ihdr: &IhdrData, + deflater: &T, +) where T: Deflater, { if let Some(iccp_idx) = png.aux_chunks.iter().position(|c| &c.name == b"iCCP") {