miniz_oxide/deflate/
zlib.rs
1use crate::deflate::core::deflate_flags::{
2 TDEFL_FORCE_ALL_RAW_BLOCKS, TDEFL_GREEDY_PARSING_FLAG, TDEFL_RLE_MATCHES,
3};
4
5const DEFAULT_CM: u8 = 8;
6const DEFAULT_CINFO: u8 = 7 << 4;
7const _DEFAULT_FDICT: u8 = 0;
8const DEFAULT_CMF: u8 = DEFAULT_CM | DEFAULT_CINFO;
9const MIN_CMF: u8 = DEFAULT_CM; const FCHECK_DIVISOR: u8 = 31;
14
15#[inline]
19fn add_fcheck(cmf: u8, flg: u8) -> u8 {
20 let rem = ((usize::from(cmf) * 256) + usize::from(flg)) % usize::from(FCHECK_DIVISOR);
21
22 let flg = flg & 0b11100000;
24
25 flg + (FCHECK_DIVISOR - rem as u8)
28}
29
30#[inline]
31const fn zlib_level_from_flags(flags: u32) -> u8 {
32 use crate::deflate::core::NUM_PROBES;
33
34 let num_probes = flags & super::MAX_PROBES_MASK;
35 if (flags & TDEFL_GREEDY_PARSING_FLAG != 0) || (flags & TDEFL_RLE_MATCHES != 0) {
36 if num_probes <= 1 {
37 0
38 } else {
39 1
40 }
41 } else if num_probes >= NUM_PROBES[9] as u32 {
42 3
43 } else {
44 2
45 }
46}
47
48#[inline]
49const fn cmf_from_flags(flags: u32) -> u8 {
50 if (flags & TDEFL_RLE_MATCHES == 0) && (flags & TDEFL_FORCE_ALL_RAW_BLOCKS == 0) {
51 DEFAULT_CMF
52 } else {
55 MIN_CMF
56 }
57}
58
59#[inline]
62fn header_from_level(level: u8, flags: u32) -> [u8; 2] {
63 let cmf = cmf_from_flags(flags);
64 [cmf, add_fcheck(cmf, level << 6)]
65}
66
67#[inline]
70pub fn header_from_flags(flags: u32) -> [u8; 2] {
71 let level = zlib_level_from_flags(flags);
72 header_from_level(level, flags)
73}
74
75#[cfg(test)]
76mod test {
77 use crate::shared::MZ_DEFAULT_WINDOW_BITS;
78 #[test]
79 fn zlib() {
80 use super::super::*;
81 use super::*;
82
83 let test_level = |level, expected| {
84 let flags = create_comp_flags_from_zip_params(
85 level,
86 MZ_DEFAULT_WINDOW_BITS,
87 CompressionStrategy::Default as i32,
88 );
89 assert_eq!(zlib_level_from_flags(flags), expected);
90 };
91
92 assert_eq!(zlib_level_from_flags(DEFAULT_FLAGS), 2);
93 test_level(0, 0);
94 test_level(1, 0);
95 test_level(2, 1);
96 test_level(3, 1);
97 for i in 4..=8 {
98 test_level(i, 2)
99 }
100 test_level(9, 3);
101 test_level(10, 3);
102 }
103
104 #[test]
105 fn test_header() {
106 let header = super::header_from_level(3, 0);
107 assert_eq!(
108 ((usize::from(header[0]) * 256) + usize::from(header[1])) % 31,
109 0
110 );
111 }
112}