compression_codecs/mzstd/
params.rs1use compression_core::Level;
7use mzstd::{
8 CompressionParams, DecodeLimits, DecoderConfig, EncoderConfig, FrameMode, LdmParams,
9 LongDistanceMatching,
10};
11use std::convert::TryFrom;
12
13#[derive(Copy, Clone, Debug, PartialEq, Eq)]
22pub struct CParameter(CParameterInner);
23
24#[derive(Copy, Clone, Debug, PartialEq, Eq)]
25enum CParameterInner {
26 WindowLog(u32),
27 HashLog(u32),
28 ChainLog(u32),
29 SearchLog(u32),
30 MinMatch(u32),
31 TargetLength(u32),
32 EnableLongDistanceMatching(bool),
33 LdmHashLog(u32),
34 LdmMinMatch(u32),
35 LdmBucketSizeLog(u32),
36 LdmHashRateLog(u32),
37 ContentSizeFlag(bool),
38 ChecksumFlag(bool),
39}
40
41impl CParameter {
42 pub fn quality(level: Level) -> i32 {
43 const OUR_FASTEST: i32 = 1;
48
49 match level {
50 Level::Fastest => OUR_FASTEST,
51 Level::Best => mzstd::Level::MAX.get(),
52 Level::Precise(quality) => {
53 quality.clamp(mzstd::Level::MIN.get(), mzstd::Level::MAX.get())
54 }
55 _ => mzstd::Level::DEFAULT.get(),
56 }
57 }
58
59 pub fn window_log(value: u32) -> Self {
61 Self(CParameterInner::WindowLog(value))
62 }
63
64 pub fn hash_log(value: u32) -> Self {
66 Self(CParameterInner::HashLog(value))
67 }
68
69 pub fn chain_log(value: u32) -> Self {
71 Self(CParameterInner::ChainLog(value))
72 }
73
74 pub fn search_log(value: u32) -> Self {
76 Self(CParameterInner::SearchLog(value))
77 }
78
79 pub fn min_match(value: u32) -> Self {
81 Self(CParameterInner::MinMatch(value))
82 }
83
84 pub fn target_length(value: u32) -> Self {
86 Self(CParameterInner::TargetLength(value))
87 }
88
89 pub fn enable_long_distance_matching(value: bool) -> Self {
93 Self(CParameterInner::EnableLongDistanceMatching(value))
94 }
95
96 pub fn ldm_hash_log(value: u32) -> Self {
100 Self(CParameterInner::LdmHashLog(value))
101 }
102
103 pub fn ldm_min_match(value: u32) -> Self {
107 Self(CParameterInner::LdmMinMatch(value))
108 }
109
110 pub fn ldm_bucket_size_log(value: u32) -> Self {
114 Self(CParameterInner::LdmBucketSizeLog(value))
115 }
116
117 pub fn ldm_hash_rate_log(value: u32) -> Self {
121 Self(CParameterInner::LdmHashRateLog(value))
122 }
123
124 pub fn content_size_flag(value: bool) -> Self {
126 Self(CParameterInner::ContentSizeFlag(value))
127 }
128
129 pub fn checksum_flag(value: bool) -> Self {
131 Self(CParameterInner::ChecksumFlag(value))
132 }
133}
134
135pub(crate) fn encoder_config(level: i32, params: &[CParameter]) -> EncoderConfig {
141 let level = level.clamp(mzstd::Level::MIN.get(), mzstd::Level::MAX.get());
142 let mut config = EncoderConfig::new().with_level(mzstd::Level::try_from(level).unwrap());
144 let mut compression = CompressionParams::default();
145 let mut ldm = LdmParams::default();
146 let mut ldm_enabled = None;
147
148 for param in params {
149 match param.0 {
150 CParameterInner::WindowLog(value) => compression = compression.with_window_log(value),
151 CParameterInner::HashLog(value) => compression = compression.with_hash_log(value),
152 CParameterInner::ChainLog(value) => compression = compression.with_chain_log(value),
153 CParameterInner::SearchLog(value) => compression = compression.with_search_log(value),
154 CParameterInner::MinMatch(value) => compression = compression.with_min_match(value),
155 CParameterInner::TargetLength(value) => {
156 compression = compression.with_target_length(value)
157 }
158 CParameterInner::EnableLongDistanceMatching(value) => ldm_enabled = Some(value),
159 CParameterInner::LdmHashLog(value) => ldm = ldm.with_hash_log(value),
160 CParameterInner::LdmMinMatch(value) => ldm = ldm.with_min_match(value),
161 CParameterInner::LdmBucketSizeLog(value) => ldm = ldm.with_bucket_size_log(value),
162 CParameterInner::LdmHashRateLog(value) => ldm = ldm.with_hash_rate_log(value),
163 CParameterInner::ContentSizeFlag(value) => config = config.with_content_size(value),
164 CParameterInner::ChecksumFlag(value) => config = config.with_checksum(value),
165 }
166 }
167
168 let long_distance = match ldm_enabled {
171 None => LongDistanceMatching::Auto,
172 Some(false) => LongDistanceMatching::Disabled,
173 Some(true) => LongDistanceMatching::Enabled(ldm),
174 };
175
176 config
177 .with_params(compression)
178 .with_long_distance_matching(long_distance)
179}
180
181#[derive(Copy, Clone, Debug, PartialEq, Eq)]
187pub struct DParameter(DParameterInner);
188
189#[derive(Copy, Clone, Debug, PartialEq, Eq)]
190enum DParameterInner {
191 WindowLogMax(u32),
192}
193
194impl DParameter {
195 pub fn window_log_max(value: u32) -> Self {
197 Self(DParameterInner::WindowLogMax(value))
198 }
199}
200
201pub(crate) fn decoder_config(params: &[DParameter]) -> DecoderConfig {
210 let mut limits = DecodeLimits::DEFAULT;
211 for param in params {
212 match param.0 {
213 DParameterInner::WindowLogMax(0) => limits = DecodeLimits::DEFAULT,
214 DParameterInner::WindowLogMax(value) => {
215 let log = u8::try_from(value).unwrap_or(u8::MAX);
216 limits = limits.with_max_window_log(log).unwrap();
217 }
218 }
219 }
220
221 DecoderConfig::DEFAULT
222 .with_frame_mode(FrameMode::Single)
223 .with_limits(limits)
224}