Skip to content

Commit

Permalink
Don't leak flate2 as an implementation detail by default (#564)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shnatsel authored Feb 10, 2025
1 parent 466bdae commit c839711
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 12 deletions.
9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ include = [
bitflags = "2.0"
crc32fast = "1.2.0"
fdeflate = "0.3.3"
flate2 = "1.0.11"
flate2 = "1.0.35"
miniz_oxide = { version = "0.8", features = ["simd"] }

[dev-dependencies]
Expand All @@ -38,7 +38,14 @@ rand = "0.8.4"
term = "1.0.1"

[features]
# Use nightly-only features for a minor performance boost in PNG decoding
unstable = ["crc32fast/nightly"]
# Use zlib-rs for faster PNG encoding at the cost of some `unsafe` code.
# WARNING: this changes the flate2 backend for your entire dependency tree!
# While the `png` crate always uses fully memory-safe decoding,
# this enables zlib-rs and introduces some unsafe code to all other crates
# that rely on flate2, including the decoding codepaths.
zlib-rs = ["flate2/zlib-rs"]
benchmarks = []

[lints.rust]
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/roundtrip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn encode_png<'a>(width: u8, filter: u8, compression: u8, color_type: u8, raw_bi
// compression
let compression = match compression {
0 => png::DeflateCompression::NoCompression,
level @ 1..=9 => png::DeflateCompression::Flate2(level),
level @ 1..=9 => png::DeflateCompression::Level(level),
10 => png::DeflateCompression::FdeflateUltraFast,
_ => return None,
};
Expand Down
18 changes: 11 additions & 7 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,15 @@ pub enum DeflateCompression {
/// while still providing a decent compression ratio.
FdeflateUltraFast,

/// Uses [flate2](https://crates.io/crates/flate2) crate with the specified [compression level](flate2::Compression::new).
/// Compression level between 1 and 9, where higher values mean better compression at the cost of
/// speed.
///
/// Flate2 has several backends that make different trade-offs.
/// See the flate2 documentation for the available backends for more information.
Flate2(u8),
/// This is currently implemented via [flate2](https://crates.io/crates/flate2) crate
/// by passing through the [compression level](flate2::Compression::new).
///
/// The implementation details and the exact meaning of each level may change in the future,
/// including in semver-compatible releases.
Level(u8),
// Other variants can be added in the future
}

Expand All @@ -398,16 +402,16 @@ impl DeflateCompression {
Compression::NoCompression => Self::NoCompression,
Compression::Fastest => Self::FdeflateUltraFast,
Compression::Fast => Self::FdeflateUltraFast,
Compression::Balanced => Self::Flate2(flate2::Compression::default().level() as u8),
Compression::High => Self::Flate2(flate2::Compression::best().level() as u8),
Compression::Balanced => Self::Level(flate2::Compression::default().level() as u8),
Compression::High => Self::Level(flate2::Compression::best().level() as u8),
}
}

pub(crate) fn closest_flate2_level(&self) -> flate2::Compression {
match self {
DeflateCompression::NoCompression => flate2::Compression::none(),
DeflateCompression::FdeflateUltraFast => flate2::Compression::new(1),
DeflateCompression::Flate2(level) => flate2::Compression::new(u32::from(*level)),
DeflateCompression::Level(level) => flate2::Compression::new(u32::from(*level)),
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ impl<W: Write> Writer<W> {
compressed
}
}
DeflateCompression::Flate2(level) => {
DeflateCompression::Level(level) => {
let mut current = vec![0; in_len];

let mut zlib =
Expand Down Expand Up @@ -1774,7 +1774,7 @@ mod tests {
let mut buf = vec![0; reader.output_buffer_size()];
let info = reader.next_frame(&mut buf).unwrap();
use DeflateCompression::*;
for compression in [NoCompression, FdeflateUltraFast, Flate2(4)] {
for compression in [NoCompression, FdeflateUltraFast, Level(4)] {
// Encode decoded image
let mut out = Vec::new();
{
Expand Down Expand Up @@ -1832,7 +1832,7 @@ mod tests {
let mut buf = vec![0; reader.output_buffer_size()];
let info = reader.next_frame(&mut buf).unwrap();
use DeflateCompression::*;
for compression in [NoCompression, FdeflateUltraFast, Flate2(4)] {
for compression in [NoCompression, FdeflateUltraFast, Level(4)] {
// Encode decoded image
let mut out = Vec::new();
{
Expand Down

0 comments on commit c839711

Please sign in to comment.