/rust/registry/src/index.crates.io-6f17d22bba15001f/deflate-1.0.0/src/compression_options.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! This module contains the various options to tweak how compression is performed. |
2 | | //! |
3 | | //! Note that due to the nature of the `DEFLATE` format, lower compression levels |
4 | | //! may for some data compress better than higher compression levels. |
5 | | //! |
6 | | //! For applications where a maximum level of compression (irrespective of compression |
7 | | //! speed) is required, consider using the [`Zopfli`](https://crates.io/crates/zopfli) |
8 | | //! compressor, which uses a specialised (but slow) algorithm to figure out the maximum |
9 | | //! of compression for the provided data. |
10 | | //! |
11 | | use crate::lz77::MatchingType; |
12 | | use std::convert::From; |
13 | | |
14 | | pub const HIGH_MAX_HASH_CHECKS: u16 = 1768; |
15 | | pub const HIGH_LAZY_IF_LESS_THAN: u16 = 128; |
16 | | /// The maximum number of hash checks that make sense as this is the length |
17 | | /// of the hash chain. |
18 | | pub const MAX_HASH_CHECKS: u16 = 32 * 1024; |
19 | | pub const DEFAULT_MAX_HASH_CHECKS: u16 = 128; |
20 | | pub const DEFAULT_LAZY_IF_LESS_THAN: u16 = 32; |
21 | | |
22 | | /// An enum describing the level of compression to be used by the encoder |
23 | | /// |
24 | | /// Higher compression ratios will take longer to encode. |
25 | | /// |
26 | | /// This is a simplified interface to specify a compression level. |
27 | | /// |
28 | | /// [See also `CompressionOptions`](./struct.CompressionOptions.html) which provides for |
29 | | /// tweaking the settings more finely. |
30 | | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] |
31 | | pub enum Compression { |
32 | | /// Fast minimal compression (`CompressionOptions::fast()`). |
33 | | Fast, |
34 | | /// Default level (`CompressionOptions::default()`). |
35 | | Default, |
36 | | /// Higher compression level (`CompressionOptions::high()`). |
37 | | /// |
38 | | /// Best in this context isn't actually the highest possible level |
39 | | /// the encoder can do, but is meant to emulate the `Best` setting in the `Flate2` |
40 | | /// library. |
41 | | Best, |
42 | | } |
43 | | |
44 | | impl Default for Compression { |
45 | 0 | fn default() -> Compression { |
46 | 0 | Compression::Default |
47 | 0 | } |
48 | | } |
49 | | |
50 | | /// Enum allowing some special options (not implemented yet)! |
51 | | #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] |
52 | | pub enum SpecialOptions { |
53 | | /// Compress normally. |
54 | | Normal, |
55 | | /// Force fixed Huffman tables. (Unimplemented!). |
56 | | _ForceFixed, |
57 | | /// Force stored (uncompressed) blocks only. (Unimplemented!). |
58 | | _ForceStored, |
59 | | } |
60 | | |
61 | | impl Default for SpecialOptions { |
62 | 0 | fn default() -> SpecialOptions { |
63 | 0 | SpecialOptions::Normal |
64 | 0 | } |
65 | | } |
66 | | |
67 | | pub const DEFAULT_OPTIONS: CompressionOptions = CompressionOptions { |
68 | | max_hash_checks: DEFAULT_MAX_HASH_CHECKS, |
69 | | lazy_if_less_than: DEFAULT_LAZY_IF_LESS_THAN, |
70 | | matching_type: MatchingType::Lazy, |
71 | | special: SpecialOptions::Normal, |
72 | | }; |
73 | | |
74 | | /// A struct describing the options for a compressor or compression function. |
75 | | /// |
76 | | /// These values are not stable and still subject to change! |
77 | | #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] |
78 | | pub struct CompressionOptions { |
79 | | /// The maximum number of checks to make in the hash table for matches. |
80 | | /// |
81 | | /// Higher numbers mean slower, but better compression. Very high (say `>1024`) values |
82 | | /// will impact compression speed a lot. The maximum match length is 2^15, so values higher than |
83 | | /// this won't make any difference, and will be truncated to 2^15 by the compression |
84 | | /// function/writer. |
85 | | /// |
86 | | /// Default value: `128` |
87 | | pub max_hash_checks: u16, |
88 | | // pub _window_size: u16, |
89 | | /// Only lazy match if we have a length less than this value. |
90 | | /// |
91 | | /// Higher values degrade compression slightly, but improve compression speed. |
92 | | /// |
93 | | /// * `0`: Never lazy match. (Same effect as setting `MatchingType` to greedy, but may be slower). |
94 | | /// * `1...257`: Only check for a better match if the first match was shorter than this value. |
95 | | /// * `258`: Always lazy match. |
96 | | /// |
97 | | /// As the maximum length of a match is `258`, values higher than this will have |
98 | | /// no further effect. |
99 | | /// |
100 | | /// * Default value: `32` |
101 | | pub lazy_if_less_than: u16, |
102 | | |
103 | | // pub _decent_match: u16, |
104 | | /// Whether to use lazy or greedy matching. |
105 | | /// |
106 | | /// Lazy matching will provide better compression, at the expense of compression speed. |
107 | | /// |
108 | | /// As a special case, if max_hash_checks is set to 0, and matching_type is set to lazy, |
109 | | /// compression using only run-length encoding (i.e maximum match distance of 1) is performed. |
110 | | /// (This may be changed in the future but is defined like this at the moment to avoid API |
111 | | /// breakage. |
112 | | /// |
113 | | /// [See `MatchingType`](./enum.MatchingType.html) |
114 | | /// |
115 | | /// * Default value: `MatchingType::Lazy` |
116 | | pub matching_type: MatchingType, |
117 | | /// Force fixed/stored blocks (Not implemented yet). |
118 | | /// * Default value: `SpecialOptions::Normal` |
119 | | pub special: SpecialOptions, |
120 | | } |
121 | | |
122 | | // Some standard profiles for the compression options. |
123 | | // Ord should be implemented at some point, but won't yet until the struct is stabilised. |
124 | | impl CompressionOptions { |
125 | | /// Returns compression settings roughly corresponding to the `HIGH(9)` setting in miniz. |
126 | 0 | pub const fn high() -> CompressionOptions { |
127 | 0 | CompressionOptions { |
128 | 0 | max_hash_checks: HIGH_MAX_HASH_CHECKS, |
129 | 0 | lazy_if_less_than: HIGH_LAZY_IF_LESS_THAN, |
130 | 0 | matching_type: MatchingType::Lazy, |
131 | 0 | special: SpecialOptions::Normal, |
132 | 0 | } |
133 | 0 | } |
134 | | |
135 | | /// Returns a fast set of compression settings |
136 | | /// |
137 | | /// Ideally this should roughly correspond to the `FAST(1)` setting in miniz. |
138 | | /// However, that setting makes miniz use a somewhat different algorithm, |
139 | | /// so currently hte fast level in this library is slower and better compressing |
140 | | /// than the corresponding level in miniz. |
141 | 0 | pub const fn fast() -> CompressionOptions { |
142 | 0 | CompressionOptions { |
143 | 0 | max_hash_checks: 1, |
144 | 0 | lazy_if_less_than: 0, |
145 | 0 | matching_type: MatchingType::Greedy, |
146 | 0 | special: SpecialOptions::Normal, |
147 | 0 | } |
148 | 0 | } |
149 | | |
150 | | /// Returns a set of compression settings that makes the compressor only compress using |
151 | | /// Huffman coding. (Ignoring any length/distance matching) |
152 | | /// |
153 | | /// This will normally have the worst compression ratio (besides only using uncompressed data), |
154 | | /// but may be the fastest method in some cases. |
155 | 0 | pub const fn huffman_only() -> CompressionOptions { |
156 | 0 | CompressionOptions { |
157 | 0 | max_hash_checks: 0, |
158 | 0 | lazy_if_less_than: 0, |
159 | 0 | matching_type: MatchingType::Greedy, |
160 | 0 | special: SpecialOptions::Normal, |
161 | 0 | } |
162 | 0 | } |
163 | | |
164 | | /// Returns a set of compression settings that makes the compressor compress only using |
165 | | /// run-length encoding (i.e only looking for matches one byte back). |
166 | | /// |
167 | | /// This is very fast, but tends to compress worse than looking for more matches using hash |
168 | | /// chains that the slower settings do. |
169 | | /// Works best on data that has runs of equivalent bytes, like binary or simple images, |
170 | | /// less good for text. |
171 | 0 | pub const fn rle() -> CompressionOptions { |
172 | 0 | CompressionOptions { |
173 | 0 | max_hash_checks: 0, |
174 | 0 | lazy_if_less_than: 0, |
175 | 0 | matching_type: MatchingType::Lazy, |
176 | 0 | special: SpecialOptions::Normal, |
177 | 0 | } |
178 | 0 | } |
179 | | } |
180 | | |
181 | | impl Default for CompressionOptions { |
182 | | /// Returns the options describing the default compression level. |
183 | 0 | fn default() -> CompressionOptions { |
184 | 0 | DEFAULT_OPTIONS |
185 | 0 | } |
186 | | } |
187 | | |
188 | | impl From<Compression> for CompressionOptions { |
189 | 0 | fn from(compression: Compression) -> CompressionOptions { |
190 | 0 | match compression { |
191 | 0 | Compression::Fast => CompressionOptions::fast(), |
192 | 0 | Compression::Default => CompressionOptions::default(), |
193 | 0 | Compression::Best => CompressionOptions::high(), |
194 | | } |
195 | 0 | } |
196 | | } |