libzstd_rs_sys/lib/compress/
zstd_compress_literals.rs1use libc::size_t;
2
3use crate::lib::common::error_private::{ERR_isError, Error};
4use crate::lib::common::huf::{
5 HUF_CElt, HUF_flags_bmi2, HUF_flags_optimalDepth, HUF_flags_preferRepeat,
6 HUF_flags_suspectUncompressible, HUF_repeat, HUF_repeat_check, HUF_repeat_none,
7 HUF_repeat_valid, HUF_OPTIMAL_DEPTH_THRESHOLD, HUF_SYMBOLVALUE_MAX,
8};
9use crate::lib::common::mem::{MEM_writeLE16, MEM_writeLE24, MEM_writeLE32};
10use crate::lib::common::zstd_internal::LitHufLog;
11use crate::lib::compress::huf_compress::{HUF_compress1X_repeat, HUF_compress4X_repeat};
12use crate::lib::compress::zstd_compress::ZSTD_hufCTables_t;
13use crate::lib::zstd::*;
14
15pub type SymbolEncodingType_e = core::ffi::c_uint;
16pub const set_repeat: SymbolEncodingType_e = 3;
17pub const set_compressed: SymbolEncodingType_e = 2;
18pub const set_rle: SymbolEncodingType_e = 1;
19pub const set_basic: SymbolEncodingType_e = 0;
20pub type huf_compress_f = Option<
21 unsafe extern "C" fn(
22 *mut core::ffi::c_void,
23 size_t,
24 *const core::ffi::c_void,
25 size_t,
26 core::ffi::c_uint,
27 core::ffi::c_uint,
28 *mut core::ffi::c_void,
29 size_t,
30 *mut HUF_CElt,
31 *mut HUF_repeat,
32 core::ffi::c_int,
33 ) -> size_t,
34>;
35#[inline]
36unsafe fn ZSTD_minGain(srcSize: size_t, strat: ZSTD_strategy) -> size_t {
37 let minlog =
38 if strat as core::ffi::c_uint >= ZSTD_btultra as core::ffi::c_int as core::ffi::c_uint {
39 strat.wrapping_sub(1)
40 } else {
41 6
42 };
43 (srcSize >> minlog).wrapping_add(2)
44}
45pub unsafe fn ZSTD_noCompressLiterals(
46 dst: *mut core::ffi::c_void,
47 dstCapacity: size_t,
48 src: *const core::ffi::c_void,
49 srcSize: size_t,
50) -> size_t {
51 let ostart = dst as *mut u8;
52 let flSize =
53 (1 + (srcSize > 31) as core::ffi::c_int + (srcSize > 4095) as core::ffi::c_int) as u32;
54 if srcSize.wrapping_add(flSize as size_t) > dstCapacity {
55 return Error::dstSize_tooSmall.to_error_code();
56 }
57 match flSize {
58 1 => {
59 *ostart.offset(0) =
60 (set_basic as core::ffi::c_int as u32 as size_t).wrapping_add(srcSize << 3) as u8;
61 }
62 2 => {
63 MEM_writeLE16(
64 ostart as *mut core::ffi::c_void,
65 ((set_basic as core::ffi::c_int as u32).wrapping_add(((1) << 2) as u32) as size_t)
66 .wrapping_add(srcSize << 4) as u16,
67 );
68 }
69 3 => {
70 MEM_writeLE32(
71 ostart as *mut core::ffi::c_void,
72 ((set_basic as core::ffi::c_int as u32).wrapping_add(((3) << 2) as u32) as size_t)
73 .wrapping_add(srcSize << 4) as u32,
74 );
75 }
76 _ => {}
77 }
78 libc::memcpy(
79 ostart.offset(flSize as isize) as *mut core::ffi::c_void,
80 src,
81 srcSize as libc::size_t,
82 );
83 srcSize.wrapping_add(flSize as size_t)
84}
85unsafe fn allBytesIdentical(src: *const core::ffi::c_void, srcSize: size_t) -> core::ffi::c_int {
86 let b = *(src as *const u8).offset(0);
87 let mut p: size_t = 0;
88 p = 1;
89 while p < srcSize {
90 if *(src as *const u8).add(p) as core::ffi::c_int != b as core::ffi::c_int {
91 return 0;
92 }
93 p = p.wrapping_add(1);
94 }
95 1
96}
97pub unsafe fn ZSTD_compressRleLiteralsBlock(
98 dst: *mut core::ffi::c_void,
99 dstCapacity: size_t,
100 src: *const core::ffi::c_void,
101 srcSize: size_t,
102) -> size_t {
103 let ostart = dst as *mut u8;
104 let flSize =
105 (1 + (srcSize > 31) as core::ffi::c_int + (srcSize > 4095) as core::ffi::c_int) as u32;
106 match flSize {
107 1 => {
108 *ostart.offset(0) =
109 (set_rle as core::ffi::c_int as u32 as size_t).wrapping_add(srcSize << 3) as u8;
110 }
111 2 => {
112 MEM_writeLE16(
113 ostart as *mut core::ffi::c_void,
114 ((set_rle as core::ffi::c_int as u32).wrapping_add(((1) << 2) as u32) as size_t)
115 .wrapping_add(srcSize << 4) as u16,
116 );
117 }
118 3 => {
119 MEM_writeLE32(
120 ostart as *mut core::ffi::c_void,
121 ((set_rle as core::ffi::c_int as u32).wrapping_add(((3) << 2) as u32) as size_t)
122 .wrapping_add(srcSize << 4) as u32,
123 );
124 }
125 _ => {}
126 }
127 *ostart.offset(flSize as isize) = *(src as *const u8);
128 flSize.wrapping_add(1) as size_t
129}
130unsafe fn ZSTD_minLiteralsToCompress(strategy: ZSTD_strategy, huf_repeat: HUF_repeat) -> size_t {
131 let shift = if (9 - strategy as core::ffi::c_int) < 3 {
132 9 - strategy as core::ffi::c_int
133 } else {
134 3
135 };
136
137 if huf_repeat as core::ffi::c_uint == HUF_repeat_valid as core::ffi::c_int as core::ffi::c_uint
138 {
139 6
140 } else {
141 (8) << shift
142 }
143}
144pub unsafe fn ZSTD_compressLiterals(
145 dst: *mut core::ffi::c_void,
146 dstCapacity: size_t,
147 src: *const core::ffi::c_void,
148 srcSize: size_t,
149 entropyWorkspace: *mut core::ffi::c_void,
150 entropyWorkspaceSize: size_t,
151 prevHuf: *const ZSTD_hufCTables_t,
152 nextHuf: *mut ZSTD_hufCTables_t,
153 strategy: ZSTD_strategy,
154 disableLiteralCompression: core::ffi::c_int,
155 suspectUncompressible: core::ffi::c_int,
156 bmi2: core::ffi::c_int,
157) -> size_t {
158 let lhSize = (3
159 + (srcSize >= ((1) << 10) as size_t) as core::ffi::c_int
160 + (srcSize >= (16 * ((1) << 10)) as size_t) as core::ffi::c_int) as size_t;
161 let ostart = dst as *mut u8;
162 let mut singleStream = (srcSize < 256) as core::ffi::c_int as u32;
163 let mut hType = set_compressed;
164 let mut cLitSize: size_t = 0;
165 libc::memcpy(
166 nextHuf as *mut core::ffi::c_void,
167 prevHuf as *const core::ffi::c_void,
168 ::core::mem::size_of::<ZSTD_hufCTables_t>() as core::ffi::c_ulong as libc::size_t,
169 );
170 if disableLiteralCompression != 0 {
171 return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
172 }
173 if srcSize < ZSTD_minLiteralsToCompress(strategy, (*prevHuf).repeatMode) {
174 return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
175 }
176 if dstCapacity < lhSize.wrapping_add(1) {
177 return Error::dstSize_tooSmall.to_error_code();
178 }
179 let mut repeat = (*prevHuf).repeatMode;
180 let flags =
181 (if bmi2 != 0 {
182 HUF_flags_bmi2 as core::ffi::c_int
183 } else {
184 0
185 }) | (if (strategy as core::ffi::c_uint)
186 < ZSTD_lazy as core::ffi::c_int as core::ffi::c_uint
187 && srcSize <= 1024
188 {
189 HUF_flags_preferRepeat as core::ffi::c_int
190 } else {
191 0
192 }) | (if strategy as core::ffi::c_uint >= HUF_OPTIMAL_DEPTH_THRESHOLD as core::ffi::c_uint {
193 HUF_flags_optimalDepth as core::ffi::c_int
194 } else {
195 0
196 }) | (if suspectUncompressible != 0 {
197 HUF_flags_suspectUncompressible as core::ffi::c_int
198 } else {
199 0
200 });
201 let mut huf_compress: huf_compress_f = None;
202 if repeat as core::ffi::c_uint == HUF_repeat_valid as core::ffi::c_int as core::ffi::c_uint
203 && lhSize == 3
204 {
205 singleStream = 1;
206 }
207 huf_compress = if singleStream != 0 {
208 Some(
209 HUF_compress1X_repeat
210 as unsafe extern "C" fn(
211 *mut core::ffi::c_void,
212 size_t,
213 *const core::ffi::c_void,
214 size_t,
215 core::ffi::c_uint,
216 core::ffi::c_uint,
217 *mut core::ffi::c_void,
218 size_t,
219 *mut HUF_CElt,
220 *mut HUF_repeat,
221 core::ffi::c_int,
222 ) -> size_t,
223 )
224 } else {
225 Some(
226 HUF_compress4X_repeat
227 as unsafe extern "C" fn(
228 *mut core::ffi::c_void,
229 size_t,
230 *const core::ffi::c_void,
231 size_t,
232 core::ffi::c_uint,
233 core::ffi::c_uint,
234 *mut core::ffi::c_void,
235 size_t,
236 *mut HUF_CElt,
237 *mut HUF_repeat,
238 core::ffi::c_int,
239 ) -> size_t,
240 )
241 };
242 cLitSize = huf_compress.unwrap_unchecked()(
243 ostart.add(lhSize) as *mut core::ffi::c_void,
244 dstCapacity.wrapping_sub(lhSize),
245 src,
246 srcSize,
247 HUF_SYMBOLVALUE_MAX as core::ffi::c_uint,
248 LitHufLog as core::ffi::c_uint,
249 entropyWorkspace,
250 entropyWorkspaceSize,
251 ((*nextHuf).CTable).as_mut_ptr(),
252 &mut repeat,
253 flags,
254 );
255 if repeat as core::ffi::c_uint != HUF_repeat_none as core::ffi::c_int as core::ffi::c_uint {
256 hType = set_repeat;
257 }
258 let minGain = ZSTD_minGain(srcSize, strategy);
259 if cLitSize == 0 || cLitSize >= srcSize.wrapping_sub(minGain) || ERR_isError(cLitSize) {
260 libc::memcpy(
261 nextHuf as *mut core::ffi::c_void,
262 prevHuf as *const core::ffi::c_void,
263 ::core::mem::size_of::<ZSTD_hufCTables_t>() as core::ffi::c_ulong as libc::size_t,
264 );
265 return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
266 }
267 if cLitSize == 1 && (srcSize >= 8 || allBytesIdentical(src, srcSize) != 0) {
268 libc::memcpy(
269 nextHuf as *mut core::ffi::c_void,
270 prevHuf as *const core::ffi::c_void,
271 ::core::mem::size_of::<ZSTD_hufCTables_t>() as core::ffi::c_ulong as libc::size_t,
272 );
273 return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
274 }
275 if hType as core::ffi::c_uint == set_compressed as core::ffi::c_int as core::ffi::c_uint {
276 (*nextHuf).repeatMode = HUF_repeat_check;
277 }
278 match lhSize {
279 3 => {
280 singleStream == 0;
281 let lhc = (hType as core::ffi::c_uint)
282 .wrapping_add(((singleStream == 0) as core::ffi::c_int as u32) << 2)
283 .wrapping_add((srcSize as u32) << 4)
284 .wrapping_add((cLitSize as u32) << 14);
285 MEM_writeLE24(ostart as *mut core::ffi::c_void, lhc);
286 }
287 4 => {
288 let lhc_0 = (hType as core::ffi::c_uint)
289 .wrapping_add(((2) << 2) as core::ffi::c_uint)
290 .wrapping_add((srcSize as u32) << 4)
291 .wrapping_add((cLitSize as u32) << 18);
292 MEM_writeLE32(ostart as *mut core::ffi::c_void, lhc_0);
293 }
294 5 => {
295 let lhc_1 = (hType as core::ffi::c_uint)
296 .wrapping_add(((3) << 2) as core::ffi::c_uint)
297 .wrapping_add((srcSize as u32) << 4)
298 .wrapping_add((cLitSize as u32) << 22);
299 MEM_writeLE32(ostart as *mut core::ffi::c_void, lhc_1);
300 *ostart.offset(4) = (cLitSize >> 10) as u8;
301 }
302 _ => {}
303 }
304 lhSize.wrapping_add(cLitSize)
305}