Add zlib-ng

This commit is contained in:
Chris Hennick 2023-05-30 09:18:26 -07:00
parent d9c20c55c4
commit 9ec0ddc5ca
No known key found for this signature in database
GPG key ID: 25653935CC8B6C74
7 changed files with 100 additions and 99 deletions

View file

@ -190,4 +190,10 @@
### Added
- Zopfli for aggressive Deflate compression.
- Zopfli for aggressive Deflate compression.
## [0.9.2]
### Added
- `zlib-ng` for fast Deflate compression. This is now the default for compression levels 0-9.

View file

@ -1,6 +1,6 @@
[package]
name = "zip_next"
version = "0.9.1"
version = "0.9.2"
authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>", "Marli Frost <marli@frost.red>", "Ryan Levick <ryan.levick@gmail.com>",
"Chris Hennick <hennickc@amazon.com>"]
license = "MIT"
@ -43,9 +43,10 @@ aes-crypto = [ "aes", "constant_time_eq", "hmac", "pbkdf2", "sha1" ]
deflate = ["flate2/rust_backend"]
deflate-miniz = ["flate2/default"]
deflate-zlib = ["flate2/zlib"]
deflate-zlib-ng = ["flate2/zlib-ng"]
deflate-zopfli = ["zopfli"]
unreserved = []
default = ["aes-crypto", "bzip2", "deflate", "deflate-zopfli", "time", "zstd"]
default = ["aes-crypto", "bzip2", "deflate", "deflate-zlib-ng", "deflate-zopfli", "time", "zstd"]
[[bench]]
name = "read_entry"

View file

@ -4,7 +4,7 @@ zip_next
[![Build Status](https://github.com/Pr0methean/zip-next/actions/workflows/ci.yaml/badge.svg)](https://github.com/Pr0methean/zip-next/actions?query=branch%3Amaster+workflow%3ACI)
[![Crates.io version](https://img.shields.io/crates/v/zip_next.svg)](https://crates.io/crates/zip_next)
[Documentation](https://docs.rs/zip_next/0.9.1/zip_next/)
[Documentation](https://docs.rs/zip_next/0.9.2/zip_next/)
Info
----
@ -32,25 +32,31 @@ With all default features:
```toml
[dependencies]
zip_next = "0.9.1"
zip_next = "0.9.2"
```
Without the default features:
```toml
[dependencies]
zip_next = { version = "0.9.1", default-features = false }
zip_next = { version = "0.9.2", default-features = false }
```
The features available are:
* `aes-crypto`: Enables decryption of files which were encrypted with AES. Supports AE-1 and AE-2 methods.
* `deflate`: Enables the deflate compression algorithm, which is the default for zip files.
* `deflate`: Enables decompressing the deflate compression algorithm, which is the default for zip files.
* `deflate-miniz`: Enables deflating files with the `miniz_oxide` library (used when compression quality is 0..=9).
* `deflate-zlib`: Enables deflating files with the `zlib` library (used when compression quality is 0..=9).
* `deflate-zlib-ng`: Enables deflating files with the `zlib-ng` library (used when compression quality is 0..=9).
This is the fastest `deflate` implementation available.
* `deflate-zopfli`: Enables deflating files with the `zopfli` library (used when compression quality is 10..=264). This
is the most effective `deflate` implementation available.
* `bzip2`: Enables the BZip2 compression algorithm.
* `time`: Enables features using the [time](https://github.com/rust-lang-deprecated/time) crate.
* `zstd`: Enables the Zstandard compression algorithm.
All of these are enabled by default.
By default `aes-crypto`, `deflate`, `deflate-zlib-ng`, `deflate-zopfli`, `bzip2`, `time` and `zstd` are enabled.
MSRV
----

View file

@ -18,14 +18,17 @@ const METHOD_STORED: Option<zip_next::CompressionMethod> =
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
const METHOD_DEFLATED: Option<zip_next::CompressionMethod> =
Some(zip_next::CompressionMethod::Deflated);
#[cfg(not(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
)))]
const METHOD_DEFLATED: Option<zip_next::CompressionMethod> = None;

View file

@ -21,6 +21,7 @@ pub enum CompressionMethod {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
Deflated,
@ -57,6 +58,7 @@ impl CompressionMethod {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
pub const DEFLATE: Self = CompressionMethod::Deflated;
@ -64,6 +66,7 @@ impl CompressionMethod {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
)))]
pub const DEFLATE: Self = CompressionMethod::Unsupported(8);
@ -105,6 +108,7 @@ impl CompressionMethod {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
8 => CompressionMethod::Deflated,
@ -132,6 +136,7 @@ impl CompressionMethod {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
CompressionMethod::Deflated => 8,
@ -161,6 +166,7 @@ pub const SUPPORTED_COMPRESSION_METHODS: &[CompressionMethod] = &[
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
CompressionMethod::Deflated,

View file

@ -19,7 +19,8 @@ use std::sync::Arc;
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
use flate2::read::DeflateDecoder;
@ -126,7 +127,8 @@ pub(crate) enum ZipFileReader<'a> {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
Deflated(Crc32Reader<DeflateDecoder<CryptoReader<'a>>>),
#[cfg(feature = "bzip2")]
@ -144,7 +146,8 @@ impl<'a> Read for ZipFileReader<'a> {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
ZipFileReader::Deflated(r) => r.read(buf),
#[cfg(feature = "bzip2")]
@ -165,7 +168,8 @@ impl<'a> ZipFileReader<'a> {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
ZipFileReader::Deflated(r) => r.into_inner().into_inner().into_inner(),
#[cfg(feature = "bzip2")]
@ -271,7 +275,8 @@ pub(crate) fn make_reader(
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
CompressionMethod::Deflated => {
let deflate_reader = DeflateDecoder::new(reader);

View file

@ -21,7 +21,8 @@ use std::sync::Arc;
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
use flate2::write::DeflateEncoder;
@ -60,7 +61,8 @@ enum GenericZipWriter<W: Write + Seek> {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
Deflater(DeflateEncoder<MaybeEncrypted<W>>),
#[cfg(feature = "deflate-zopfli")]
@ -348,13 +350,16 @@ impl Default for FileOptions {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
compression_method: Deflated,
#[cfg(not(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
)))]
compression_method: Stored,
@ -1157,6 +1162,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
{
#[allow(deprecated)]
#[allow(unreachable_code)]
match compression {
Stored => {
if compression_level.is_some() {
@ -1171,23 +1177,19 @@ impl<W: Write + Seek> GenericZipWriter<W> {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
Deflated => {
#[cfg(all(
not(feature = "deflate"),
not(feature = "deflate-miniz"),
not(feature = "deflate-zlib"),
feature = "deflate-zopfli"
))]
let default = 24;
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
))]
let default = Compression::default().level() as i32;
let default = if cfg!(feature = "deflate")
|| cfg!(feature = "deflate-miniz")
|| cfg!(feature = "deflate-zlib")
|| cfg!(feature = "deflate-zlib-ng")
{
Compression::default().level() as i32
} else {
24
};
let level = clamp_opt(
compression_level.unwrap_or(default),
@ -1197,48 +1199,8 @@ impl<W: Write + Seek> GenericZipWriter<W> {
"Unsupported compression level",
))? as u32;
#[cfg(not(feature = "deflate-zopfli"))]
return Ok(Box::new(move |bare| {
GenericZipWriter::Deflater(DeflateEncoder::new(
bare,
flate2::Compression::new(level),
))
}));
#[cfg(all(
not(feature = "deflate"),
not(feature = "deflate-miniz"),
not(feature = "deflate-zlib"),
feature = "deflate-zopfli"
))]
return Ok(Box::new(move |bare| {
let mut options = Options::default();
options.iteration_count =
NonZeroU8::try_from((level - best_non_zopfli) as u8).unwrap();
match deflate_buffer_size {
Some(size) => {
GenericZipWriter::BufferedZopfliDeflater(BufWriter::with_capacity(
size,
zopfli::DeflateEncoder::new(options, Default::default(), bare),
))
}
None => GenericZipWriter::ZopfliDeflater(zopfli::DeflateEncoder::new(
options,
Default::default(),
bare,
)),
}
}));
#[cfg(all(
any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
),
feature = "deflate-zopfli"
))]
Ok(Box::new(move |bare| {
#[cfg(feature = "deflate-zopfli")]
{
let best_non_zopfli = Compression::best().level();
if level > best_non_zopfli {
let options = Options {
@ -1248,7 +1210,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
.unwrap(),
..Default::default()
};
match zopfli_buffer_size {
return Ok(Box::new(move |bare| match zopfli_buffer_size {
Some(size) => GenericZipWriter::BufferedZopfliDeflater(
BufWriter::with_capacity(
size,
@ -1262,14 +1224,25 @@ impl<W: Write + Seek> GenericZipWriter<W> {
None => GenericZipWriter::ZopfliDeflater(
zopfli::DeflateEncoder::new(options, Default::default(), bare),
),
}
} else {
}));
}
}
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
))]
{
return Ok(Box::new(move |bare| {
GenericZipWriter::Deflater(DeflateEncoder::new(
bare,
Compression::new(level),
))
}
}))
}));
}
unreachable!()
}
#[cfg(feature = "bzip2")]
CompressionMethod::Bzip2 => {
@ -1316,7 +1289,8 @@ impl<W: Write + Seek> GenericZipWriter<W> {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
GenericZipWriter::Deflater(w) => w.finish()?,
#[cfg(feature = "deflate-zopfli")]
@ -1345,7 +1319,8 @@ impl<W: Write + Seek> GenericZipWriter<W> {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib"
feature = "deflate-zlib",
feature = "deflate-zlib-ng"
))]
GenericZipWriter::Deflater(ref mut w) => Some(w as &mut dyn Write),
#[cfg(feature = "deflate-zopfli")]
@ -1383,28 +1358,26 @@ impl<W: Write + Seek> GenericZipWriter<W> {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli"
))]
fn deflate_compression_level_range() -> std::ops::RangeInclusive<i32> {
#[cfg(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
))]
let min = Compression::none().level() as i32;
let min = if cfg!(feature = "deflate")
|| cfg!(feature = "deflate-miniz")
|| cfg!(feature = "deflate-zlib")
|| cfg!(feature = "deflate-zlib-ng")
{
Compression::none().level() as i32
} else {
Compression::best().level() as i32 + 1
};
#[cfg(not(any(
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
)))]
let min = flate2::Compression::best().level() + 1 as i32;
#[cfg(not(feature = "deflate-zopfli"))]
let max = flate2::Compression::best().level() as i32;
#[cfg(feature = "deflate-zopfli")]
let max = Compression::best().level() as i32 + u8::MAX as i32;
let max = Compression::best().level() as i32
+ if cfg!(feature = "deflate-zopfli") {
u8::MAX as i32
} else {
0
};
min..=max
}
@ -1420,6 +1393,7 @@ fn bzip2_compression_level_range() -> std::ops::RangeInclusive<i32> {
feature = "deflate",
feature = "deflate-miniz",
feature = "deflate-zlib",
feature = "deflate-zlib-ng",
feature = "deflate-zopfli",
feature = "bzip2",
feature = "zstd"