Skip to content

Commit 29a411b

Browse files
authored
Merge pull request #242 from Nullus157/brotli-params
Brotli encoder params
2 parents 8af8b96 + b698b1a commit 29a411b

File tree

5 files changed

+212
-122
lines changed

5 files changed

+212
-122
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
66

77
## Unreleased
88

9+
- Add top-level `brotli` module containing stable `brotli` crate wrapper types.
10+
- Add `BrotliEncoder::with_quality_and_params()` constructors.
911
- Add `Deflate64Decoder` behind new crate feature `deflate64`.
1012

1113
## 0.4.1 - 2023-07-10
@@ -16,7 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
1618
## 0.4.0 - 2023-05-10
1719

1820
- `Level::Precise` variant now takes a `i32` instead of `u32`.
19-
- Add top level `zstd` module containing stable `zstd` crate wrapper types.
21+
- Add top-level `zstd` module containing stable `zstd` crate wrapper types.
2022
- Add `ZstdEncoder::with_quality_and_params()` constructors.
2123
- Update `zstd` dependency to `0.12`.
2224
- Remove deprecated `stream`, `futures-bufread` and `futures-write` crate features.

src/brotli.rs

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//! This module contains Brotli-specific types for async-compression.
2+
3+
use brotli::enc::backward_references::{BrotliEncoderMode, BrotliEncoderParams};
4+
5+
/// A compression parameter for Brotli. This is a stable wrapper around Brotli's own encoder params
6+
/// type, to abstract over different versions of the Brotli library.
7+
///
8+
/// See the [Brotli documentation](https://www.brotli.org/encode.html#a9a8) for more information on
9+
/// these parameters.
10+
11+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12+
pub struct EncoderParams {
13+
window_size: i32,
14+
block_size: i32,
15+
size_hint: usize,
16+
mode: BrotliEncoderMode,
17+
}
18+
19+
impl EncoderParams {
20+
/// Sets window size in bytes (as a power of two).
21+
///
22+
/// Used as Brotli's `lgwin` parameter.
23+
///
24+
/// `window_size` is clamped to `0 <= window_size <= 24`.
25+
pub fn window_size(mut self, window_size: i32) -> Self {
26+
self.window_size = window_size.clamp(0, 24);
27+
self
28+
}
29+
30+
/// Sets input block size in bytes (as a power of two).
31+
///
32+
/// Used as Brotli's `lgblock` parameter.
33+
///
34+
/// `block_size` is clamped to `16 <= block_size <= 24`.
35+
pub fn block_size(mut self, block_size: i32) -> Self {
36+
self.block_size = block_size.clamp(16, 24);
37+
self
38+
}
39+
40+
/// Sets hint for size of data to be compressed.
41+
pub fn size_hint(mut self, size_hint: usize) -> Self {
42+
self.size_hint = size_hint;
43+
self
44+
}
45+
46+
/// Sets encoder to text mode.
47+
///
48+
/// If input data is known to be UTF-8 text, this allows the compressor to make assumptions and
49+
/// optimizations.
50+
///
51+
/// Used as Brotli's `mode` parameter.
52+
pub fn text_mode(mut self) -> Self {
53+
self.mode = BrotliEncoderMode::BROTLI_MODE_TEXT;
54+
self
55+
}
56+
57+
pub(crate) fn as_brotli(&self) -> BrotliEncoderParams {
58+
BrotliEncoderParams {
59+
lgwin: self.window_size,
60+
lgblock: self.block_size,
61+
size_hint: self.size_hint,
62+
mode: self.mode,
63+
..Default::default()
64+
}
65+
}
66+
}

src/lib.rs

+13-121
Original file line numberDiff line numberDiff line change
@@ -154,28 +154,35 @@ mod unshared;
154154
mod util;
155155

156156
#[cfg(feature = "brotli")]
157-
use brotli::enc::backward_references::BrotliEncoderParams;
157+
pub mod brotli;
158+
#[cfg(feature = "zstd")]
159+
pub mod zstd;
158160

159161
/// Level of compression data should be compressed with.
160162
#[non_exhaustive]
161163
#[derive(Clone, Copy, Debug)]
162164
pub enum Level {
163165
/// Fastest quality of compression, usually produces bigger size.
164166
Fastest,
167+
165168
/// Best quality of compression, usually produces the smallest size.
166169
Best,
170+
167171
/// Default quality of compression defined by the selected compression algorithm.
168172
Default,
169-
/// Precise quality based on the underlying compression algorithms'
170-
/// qualities. The interpretation of this depends on the algorithm chosen
171-
/// and the specific implementation backing it.
172-
/// Qualities are implicitly clamped to the algorithm's maximum.
173+
174+
/// Precise quality based on the underlying compression algorithms' qualities. The
175+
/// interpretation of this depends on the algorithm chosen and the specific implementation
176+
/// backing it. Qualities are implicitly clamped to the algorithm's maximum.
173177
Precise(i32),
174178
}
175179

176180
impl Level {
177181
#[cfg(feature = "brotli")]
178-
fn into_brotli(self, mut params: BrotliEncoderParams) -> BrotliEncoderParams {
182+
fn into_brotli(
183+
self,
184+
mut params: ::brotli::enc::backward_references::BrotliEncoderParams,
185+
) -> ::brotli::enc::backward_references::BrotliEncoderParams {
179186
match self {
180187
Self::Fastest => params.quality = 0,
181188
Self::Best => params.quality = 11,
@@ -243,118 +250,3 @@ impl Level {
243250
}
244251
}
245252
}
246-
247-
#[cfg(feature = "zstd")]
248-
/// This module contains zstd-specific types for async-compression.
249-
pub mod zstd {
250-
use libzstd::stream::raw::CParameter::*;
251-
252-
/// A compression parameter for zstd. This is a stable wrapper around zstd's own `CParameter`
253-
/// type, to abstract over different versions of the zstd library.
254-
///
255-
/// See the [zstd documentation](https://facebook.github.io/zstd/zstd_manual.html) for more
256-
/// information on these parameters.
257-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
258-
pub struct CParameter(libzstd::stream::raw::CParameter);
259-
260-
impl CParameter {
261-
/// Window size in bytes (as a power of two)
262-
pub fn window_log(value: u32) -> Self {
263-
Self(WindowLog(value))
264-
}
265-
266-
/// Size of the initial probe table in 4-byte entries (as a power of two)
267-
pub fn hash_log(value: u32) -> Self {
268-
Self(HashLog(value))
269-
}
270-
271-
/// Size of the multi-probe table in 4-byte entries (as a power of two)
272-
pub fn chain_log(value: u32) -> Self {
273-
Self(ChainLog(value))
274-
}
275-
276-
/// Number of search attempts (as a power of two)
277-
pub fn search_log(value: u32) -> Self {
278-
Self(SearchLog(value))
279-
}
280-
281-
/// Minimum size of matches searched for
282-
pub fn min_match(value: u32) -> Self {
283-
Self(MinMatch(value))
284-
}
285-
286-
/// Strategy-dependent length modifier
287-
pub fn target_length(value: u32) -> Self {
288-
Self(TargetLength(value))
289-
}
290-
291-
/// Enable long-distance matching mode to look for and emit long-distance references.
292-
///
293-
/// This increases the default window size.
294-
pub fn enable_long_distance_matching(value: bool) -> Self {
295-
Self(EnableLongDistanceMatching(value))
296-
}
297-
298-
/// Size of the long-distance matching table (as a power of two)
299-
pub fn ldm_hash_log(value: u32) -> Self {
300-
Self(LdmHashLog(value))
301-
}
302-
303-
/// Minimum size of long-distance matches searched for
304-
pub fn ldm_min_match(value: u32) -> Self {
305-
Self(LdmMinMatch(value))
306-
}
307-
308-
/// Size of each bucket in the LDM hash table for collision resolution (as a power of two)
309-
pub fn ldm_bucket_size_log(value: u32) -> Self {
310-
Self(LdmBucketSizeLog(value))
311-
}
312-
313-
/// Frequency of using the LDM hash table (as a power of two)
314-
pub fn ldm_hash_rate_log(value: u32) -> Self {
315-
Self(LdmHashRateLog(value))
316-
}
317-
318-
/// Emit the size of the content (default: true).
319-
pub fn content_size_flag(value: bool) -> Self {
320-
Self(ContentSizeFlag(value))
321-
}
322-
323-
/// Emit a checksum (default: false).
324-
pub fn checksum_flag(value: bool) -> Self {
325-
Self(ChecksumFlag(value))
326-
}
327-
328-
/// Emit a dictionary ID when using a custom dictionary (default: true).
329-
pub fn dict_id_flag(value: bool) -> Self {
330-
Self(DictIdFlag(value))
331-
}
332-
333-
/// Number of threads to spawn.
334-
///
335-
/// If set to 0, compression functions will block; if set to 1 or more, compression will
336-
/// run in background threads and `flush` pushes bytes through the compressor.
337-
///
338-
/// # Panics
339-
///
340-
/// This parameter requires feature `zstdmt` to be enabled, otherwise it will cause a panic
341-
/// when used in `ZstdEncoder::with_quality_and_params()` calls.
342-
//
343-
// TODO: make this a normal feature guarded fn on next breaking release
344-
#[cfg_attr(docsrs, doc(cfg(feature = "zstdmt")))]
345-
pub fn nb_workers(value: u32) -> Self {
346-
Self(NbWorkers(value))
347-
}
348-
349-
/// Number of bytes given to each worker.
350-
///
351-
/// If set to 0, zstd selects a job size based on compression parameters.
352-
pub fn job_size(value: u32) -> Self {
353-
Self(JobSize(value))
354-
}
355-
356-
pub(crate) fn as_zstd(&self) -> libzstd::stream::raw::CParameter {
357-
self.0
358-
}
359-
}
360-
}

src/macros.rs

+18
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,31 @@ macro_rules! algos {
4444
{ @enc
4545
pub fn with_quality(inner: $inner, level: crate::Level) -> Self {
4646
let params = brotli::enc::backward_references::BrotliEncoderParams::default();
47+
4748
Self {
4849
inner: crate::$($mod::)+generic::Encoder::new(
4950
inner,
5051
crate::codec::BrotliEncoder::new(level.into_brotli(params)),
5152
),
5253
}
5354
}
55+
56+
/// Creates a new encoder, using the specified compression level and parameters, which
57+
/// will read uncompressed data from the given stream and emit a compressed stream.
58+
pub fn with_quality_and_params(
59+
inner: $inner,
60+
level: crate::Level,
61+
params: crate::brotli::EncoderParams,
62+
) -> Self {
63+
let params = level.into_brotli(params.as_brotli());
64+
65+
Self {
66+
inner: crate::$($mod::)+generic::Encoder::new(
67+
inner,
68+
crate::codec::BrotliEncoder::new(params),
69+
),
70+
}
71+
}
5472
}
5573
{ @dec }
5674
);

src/zstd.rs

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
//! This module contains zstd-specific types for async-compression.
2+
3+
use libzstd::stream::raw::CParameter::*;
4+
5+
/// A compression parameter for zstd. This is a stable wrapper around zstd's own `CParameter`
6+
/// type, to abstract over different versions of the zstd library.
7+
///
8+
/// See the [zstd documentation](https://facebook.github.io/zstd/zstd_manual.html) for more
9+
/// information on these parameters.
10+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11+
pub struct CParameter(libzstd::stream::raw::CParameter);
12+
13+
impl CParameter {
14+
/// Window size in bytes (as a power of two)
15+
pub fn window_log(value: u32) -> Self {
16+
Self(WindowLog(value))
17+
}
18+
19+
/// Size of the initial probe table in 4-byte entries (as a power of two)
20+
pub fn hash_log(value: u32) -> Self {
21+
Self(HashLog(value))
22+
}
23+
24+
/// Size of the multi-probe table in 4-byte entries (as a power of two)
25+
pub fn chain_log(value: u32) -> Self {
26+
Self(ChainLog(value))
27+
}
28+
29+
/// Number of search attempts (as a power of two)
30+
pub fn search_log(value: u32) -> Self {
31+
Self(SearchLog(value))
32+
}
33+
34+
/// Minimum size of matches searched for
35+
pub fn min_match(value: u32) -> Self {
36+
Self(MinMatch(value))
37+
}
38+
39+
/// Strategy-dependent length modifier
40+
pub fn target_length(value: u32) -> Self {
41+
Self(TargetLength(value))
42+
}
43+
44+
/// Enable long-distance matching mode to look for and emit long-distance references.
45+
///
46+
/// This increases the default window size.
47+
pub fn enable_long_distance_matching(value: bool) -> Self {
48+
Self(EnableLongDistanceMatching(value))
49+
}
50+
51+
/// Size of the long-distance matching table (as a power of two)
52+
pub fn ldm_hash_log(value: u32) -> Self {
53+
Self(LdmHashLog(value))
54+
}
55+
56+
/// Minimum size of long-distance matches searched for
57+
pub fn ldm_min_match(value: u32) -> Self {
58+
Self(LdmMinMatch(value))
59+
}
60+
61+
/// Size of each bucket in the LDM hash table for collision resolution (as a power of two)
62+
pub fn ldm_bucket_size_log(value: u32) -> Self {
63+
Self(LdmBucketSizeLog(value))
64+
}
65+
66+
/// Frequency of using the LDM hash table (as a power of two)
67+
pub fn ldm_hash_rate_log(value: u32) -> Self {
68+
Self(LdmHashRateLog(value))
69+
}
70+
71+
/// Emit the size of the content (default: true).
72+
pub fn content_size_flag(value: bool) -> Self {
73+
Self(ContentSizeFlag(value))
74+
}
75+
76+
/// Emit a checksum (default: false).
77+
pub fn checksum_flag(value: bool) -> Self {
78+
Self(ChecksumFlag(value))
79+
}
80+
81+
/// Emit a dictionary ID when using a custom dictionary (default: true).
82+
pub fn dict_id_flag(value: bool) -> Self {
83+
Self(DictIdFlag(value))
84+
}
85+
86+
/// Number of threads to spawn.
87+
///
88+
/// If set to 0, compression functions will block; if set to 1 or more, compression will
89+
/// run in background threads and `flush` pushes bytes through the compressor.
90+
///
91+
/// # Panics
92+
///
93+
/// This parameter requires feature `zstdmt` to be enabled, otherwise it will cause a panic
94+
/// when used in `ZstdEncoder::with_quality_and_params()` calls.
95+
//
96+
// TODO: make this a normal feature guarded fn on next breaking release
97+
#[cfg_attr(docsrs, doc(cfg(feature = "zstdmt")))]
98+
pub fn nb_workers(value: u32) -> Self {
99+
Self(NbWorkers(value))
100+
}
101+
102+
/// Number of bytes given to each worker.
103+
///
104+
/// If set to 0, zstd selects a job size based on compression parameters.
105+
pub fn job_size(value: u32) -> Self {
106+
Self(JobSize(value))
107+
}
108+
109+
pub(crate) fn as_zstd(&self) -> libzstd::stream::raw::CParameter {
110+
self.0
111+
}
112+
}

0 commit comments

Comments
 (0)