Skip to main content

libzstd_rs_sys/lib/compress/
huf_compress.rs

1use core::ptr;
2
3use libc::size_t;
4
5use crate::lib::common::entropy_common::HUF_readStats;
6use crate::lib::common::error_private::{ERR_isError, Error};
7use crate::lib::common::fse::FSE_CTable;
8use crate::lib::common::huf::{
9    HUF_CElt, HUF_CTableHeader, HUF_flags_bmi2, HUF_flags_optimalDepth, HUF_flags_preferRepeat,
10    HUF_flags_suspectUncompressible, HUF_repeat, HUF_repeat_check, HUF_repeat_none,
11    HUF_repeat_valid, HUF_BLOCKSIZE_MAX, HUF_CTABLEBOUND, HUF_SYMBOLVALUE_MAX,
12    HUF_TABLELOG_DEFAULT, HUF_TABLELOG_MAX,
13};
14use crate::lib::common::mem::{MEM_32bits, MEM_writeLE16, MEM_writeLEST};
15use crate::lib::compress::fse_compress::{
16    FSE_buildCTable_wksp, FSE_compress_usingCTable, FSE_normalizeCount, FSE_optimalTableLog,
17    FSE_optimalTableLog_internal, FSE_writeNCount,
18};
19use crate::lib::compress::hist::{HIST_count_simple, HIST_count_wksp};
20pub type nodeElt = nodeElt_s;
21#[derive(Copy, Clone)]
22#[repr(C)]
23pub struct nodeElt_s {
24    pub count: u32,
25    pub parent: u16,
26    pub byte: u8,
27    pub nbBits: u8,
28}
29pub type huffNodeTable = [nodeElt; 512];
30#[derive(Copy, Clone)]
31#[repr(C)]
32pub struct HUF_buildCTable_wksp_tables {
33    pub huffNodeTbl: huffNodeTable,
34    pub rankPosition: [rankPos; 192],
35}
36#[derive(Copy, Clone)]
37#[repr(C)]
38pub struct rankPos {
39    pub base: u16,
40    pub curr: u16,
41}
42#[derive(Copy, Clone)]
43#[repr(C)]
44pub struct HUF_WriteCTableWksp {
45    pub wksp: HUF_CompressWeightsWksp,
46    pub bitsToWeight: [u8; 13],
47    pub huffWeight: [u8; 255],
48}
49#[derive(Copy, Clone)]
50#[repr(C)]
51pub struct HUF_CompressWeightsWksp {
52    pub CTable: [FSE_CTable; 59],
53    pub scratchBuffer: [u32; 41],
54    pub count: [core::ffi::c_uint; 13],
55    pub norm: [i16; 13],
56}
57#[repr(C)]
58pub struct HUF_CStream_t {
59    pub bitContainer: [size_t; 2],
60    pub bitPos: [size_t; 2],
61    pub startPtr: *mut u8,
62    pub ptr: *mut u8,
63    pub endPtr: *mut u8,
64}
65pub type HUF_nbStreams_e = core::ffi::c_uint;
66pub const HUF_fourStreams: HUF_nbStreams_e = 1;
67pub const HUF_singleStream: HUF_nbStreams_e = 0;
68#[derive(Copy, Clone)]
69#[repr(C)]
70pub struct HUF_compress_tables_t {
71    pub count: [core::ffi::c_uint; 256],
72    pub CTable: [HUF_CElt; 257],
73    pub wksps: C2RustUnnamed_1,
74}
75#[derive(Copy, Clone)]
76#[repr(C)]
77pub union C2RustUnnamed_1 {
78    pub buildCTable_wksp: HUF_buildCTable_wksp_tables,
79    pub writeCTable_wksp: HUF_WriteCTableWksp,
80    pub hist_wksp: [u32; 1024],
81}
82#[inline]
83const fn ZSTD_countLeadingZeros32(val: u32) -> core::ffi::c_uint {
84    val.leading_zeros() as i32 as core::ffi::c_uint
85}
86#[inline]
87const fn ZSTD_highbit32(val: u32) -> core::ffi::c_uint {
88    (31 as core::ffi::c_uint).wrapping_sub(ZSTD_countLeadingZeros32(val))
89}
90unsafe fn HUF_alignUpWorkspace(
91    workspace: *mut core::ffi::c_void,
92    workspaceSizePtr: *mut size_t,
93    align: size_t,
94) -> *mut core::ffi::c_void {
95    let mask = align.wrapping_sub(1);
96    let rem = workspace as size_t & mask;
97    let add = align.wrapping_sub(rem) & mask;
98    let aligned = (workspace as *mut u8).add(add);
99    if *workspaceSizePtr >= add {
100        *workspaceSizePtr = (*workspaceSizePtr).wrapping_sub(add);
101        aligned as *mut core::ffi::c_void
102    } else {
103        *workspaceSizePtr = 0;
104        core::ptr::null_mut()
105    }
106}
107pub const MAX_FSE_TABLELOG_FOR_HUFF_HEADER: core::ffi::c_int = 6;
108unsafe fn HUF_compressWeights(
109    dst: *mut core::ffi::c_void,
110    dstSize: size_t,
111    weightTable: *const core::ffi::c_void,
112    wtSize: size_t,
113    workspace: *mut core::ffi::c_void,
114    mut workspaceSize: size_t,
115) -> size_t {
116    let ostart = dst as *mut u8;
117    let mut op = ostart;
118    let oend = ostart.add(dstSize);
119    let mut maxSymbolValue = HUF_TABLELOG_MAX as core::ffi::c_uint;
120    let mut tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER as u32;
121    let wksp = HUF_alignUpWorkspace(
122        workspace,
123        &mut workspaceSize,
124        ::core::mem::align_of::<u32>(),
125    ) as *mut HUF_CompressWeightsWksp;
126    if workspaceSize < ::core::mem::size_of::<HUF_CompressWeightsWksp>() {
127        return Error::GENERIC.to_error_code();
128    }
129    if wtSize <= 1 {
130        return 0;
131    }
132    let maxCount = HIST_count_simple(
133        ((*wksp).count).as_mut_ptr(),
134        &mut maxSymbolValue,
135        weightTable,
136        wtSize,
137    );
138    if maxCount as size_t == wtSize {
139        return 1;
140    }
141    if maxCount == 1 {
142        return 0;
143    }
144    tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
145    let _var_err__ = FSE_normalizeCount(
146        ((*wksp).norm).as_mut_ptr(),
147        tableLog,
148        ((*wksp).count).as_mut_ptr(),
149        wtSize,
150        maxSymbolValue,
151        0,
152    );
153    if ERR_isError(_var_err__) {
154        return _var_err__;
155    }
156    let hSize = FSE_writeNCount(
157        op as *mut core::ffi::c_void,
158        oend.offset_from(op) as size_t,
159        ((*wksp).norm).as_mut_ptr(),
160        maxSymbolValue,
161        tableLog,
162    );
163    if ERR_isError(hSize) {
164        return hSize;
165    }
166    op = op.add(hSize);
167    let _var_err___0 = FSE_buildCTable_wksp(
168        ((*wksp).CTable).as_mut_ptr(),
169        ((*wksp).norm).as_mut_ptr(),
170        maxSymbolValue,
171        tableLog,
172        ((*wksp).scratchBuffer).as_mut_ptr() as *mut core::ffi::c_void,
173        ::core::mem::size_of::<[u32; 41]>(),
174    );
175    if ERR_isError(_var_err___0) {
176        return _var_err___0;
177    }
178    let cSize = FSE_compress_usingCTable(
179        op as *mut core::ffi::c_void,
180        oend.offset_from(op) as size_t,
181        weightTable,
182        wtSize,
183        ((*wksp).CTable).as_mut_ptr(),
184    );
185    if ERR_isError(cSize) {
186        return cSize;
187    }
188    if cSize == 0 {
189        return 0;
190    }
191    op = op.add(cSize);
192    op.offset_from(ostart) as size_t
193}
194fn HUF_getNbBits(elt: HUF_CElt) -> size_t {
195    elt & 0xff as core::ffi::c_int as HUF_CElt
196}
197fn HUF_getNbBitsFast(elt: HUF_CElt) -> size_t {
198    elt
199}
200fn HUF_getValue(elt: HUF_CElt) -> size_t {
201    elt & !(0xff as core::ffi::c_int as size_t)
202}
203fn HUF_getValueFast(elt: HUF_CElt) -> size_t {
204    elt
205}
206unsafe fn HUF_setNbBits(elt: *mut HUF_CElt, nbBits: size_t) {
207    *elt = nbBits;
208}
209unsafe fn HUF_setValue(elt: *mut HUF_CElt, value: size_t) {
210    let nbBits = HUF_getNbBits(*elt);
211    if nbBits > 0 {
212        *elt |= value
213            << (::core::mem::size_of::<HUF_CElt>())
214                .wrapping_mul(8)
215                .wrapping_sub(nbBits);
216    }
217}
218pub(super) unsafe fn HUF_readCTableHeader(ctable: *const HUF_CElt) -> HUF_CTableHeader {
219    let mut header = HUF_CTableHeader {
220        tableLog: 0,
221        maxSymbolValue: 0,
222        unused: [0; _],
223    };
224    libc::memcpy(
225        &mut header as *mut HUF_CTableHeader as *mut core::ffi::c_void,
226        ctable as *const core::ffi::c_void,
227        ::core::mem::size_of::<HUF_CTableHeader>() as core::ffi::c_ulong as libc::size_t,
228    );
229    header
230}
231unsafe fn HUF_writeCTableHeader(ctable: *mut HUF_CElt, tableLog: u32, maxSymbolValue: u32) {
232    let mut header = HUF_CTableHeader {
233        tableLog: 0,
234        maxSymbolValue: 0,
235        unused: [0; _],
236    };
237    ptr::write_bytes(
238        &mut header as *mut HUF_CTableHeader as *mut u8,
239        0,
240        ::core::mem::size_of::<HUF_CTableHeader>(),
241    );
242    header.tableLog = tableLog as u8;
243    header.maxSymbolValue = maxSymbolValue as u8;
244    libc::memcpy(
245        ctable as *mut core::ffi::c_void,
246        &mut header as *mut HUF_CTableHeader as *const core::ffi::c_void,
247        ::core::mem::size_of::<HUF_CTableHeader>() as core::ffi::c_ulong as libc::size_t,
248    );
249}
250pub unsafe fn HUF_writeCTable_wksp(
251    dst: *mut core::ffi::c_void,
252    maxDstSize: size_t,
253    CTable: *const HUF_CElt,
254    maxSymbolValue: core::ffi::c_uint,
255    huffLog: core::ffi::c_uint,
256    workspace: *mut core::ffi::c_void,
257    mut workspaceSize: size_t,
258) -> size_t {
259    let ct = CTable.offset(1);
260    let op = dst as *mut u8;
261    let mut n: u32 = 0;
262    let wksp = HUF_alignUpWorkspace(
263        workspace,
264        &mut workspaceSize,
265        ::core::mem::align_of::<u32>() as size_t,
266    ) as *mut HUF_WriteCTableWksp;
267    if workspaceSize < ::core::mem::size_of::<HUF_WriteCTableWksp>() {
268        return Error::GENERIC.to_error_code();
269    }
270    if maxSymbolValue > HUF_SYMBOLVALUE_MAX as core::ffi::c_uint {
271        return Error::maxSymbolValue_tooLarge.to_error_code();
272    }
273    *((*wksp).bitsToWeight).as_mut_ptr().offset(0) = 0;
274    n = 1;
275    while n < huffLog.wrapping_add(1) {
276        *((*wksp).bitsToWeight).as_mut_ptr().offset(n as isize) =
277            huffLog.wrapping_add(1).wrapping_sub(n) as u8;
278        n = n.wrapping_add(1);
279    }
280    n = 0;
281    while n < maxSymbolValue {
282        *((*wksp).huffWeight).as_mut_ptr().offset(n as isize) = *((*wksp).bitsToWeight)
283            .as_mut_ptr()
284            .add(HUF_getNbBits(*ct.offset(n as isize)));
285        n = n.wrapping_add(1);
286    }
287    if maxDstSize < 1 {
288        return Error::dstSize_tooSmall.to_error_code();
289    }
290    let hSize = HUF_compressWeights(
291        op.offset(1) as *mut core::ffi::c_void,
292        maxDstSize.wrapping_sub(1),
293        ((*wksp).huffWeight).as_mut_ptr() as *const core::ffi::c_void,
294        maxSymbolValue as size_t,
295        &mut (*wksp).wksp as *mut HUF_CompressWeightsWksp as *mut core::ffi::c_void,
296        ::core::mem::size_of::<HUF_CompressWeightsWksp>(),
297    );
298    if ERR_isError(hSize) {
299        return hSize;
300    }
301    if (hSize > 1) as core::ffi::c_int
302        & (hSize < maxSymbolValue.wrapping_div(2) as size_t) as core::ffi::c_int
303        != 0
304    {
305        *op.offset(0) = hSize as u8;
306        return hSize.wrapping_add(1);
307    }
308    if maxSymbolValue > (256 - 128) as core::ffi::c_uint {
309        return Error::GENERIC.to_error_code();
310    }
311    if maxSymbolValue
312        .wrapping_add(1)
313        .wrapping_div(2)
314        .wrapping_add(1) as size_t
315        > maxDstSize
316    {
317        return Error::dstSize_tooSmall.to_error_code();
318    }
319    *op.offset(0) = (128 as core::ffi::c_uint).wrapping_add(maxSymbolValue.wrapping_sub(1)) as u8;
320    *((*wksp).huffWeight)
321        .as_mut_ptr()
322        .offset(maxSymbolValue as isize) = 0;
323    n = 0;
324    while n < maxSymbolValue {
325        *op.offset((n / 2).wrapping_add(1) as isize) =
326            (((*((*wksp).huffWeight).as_mut_ptr().offset(n as isize) as core::ffi::c_int) << 4)
327                + *((*wksp).huffWeight)
328                    .as_mut_ptr()
329                    .offset(n.wrapping_add(1) as isize) as core::ffi::c_int) as u8;
330        n = n.wrapping_add(2);
331    }
332    maxSymbolValue
333        .wrapping_add(1)
334        .wrapping_div(2)
335        .wrapping_add(1) as size_t
336}
337
338pub unsafe fn HUF_readCTable(
339    CTable: *mut HUF_CElt,
340    maxSymbolValuePtr: *mut core::ffi::c_uint,
341    src: *const core::ffi::c_void,
342    srcSize: size_t,
343    hasZeroWeights: *mut core::ffi::c_uint,
344) -> size_t {
345    let src = core::slice::from_raw_parts(src.cast(), srcSize);
346
347    let mut huffWeight: [u8; 256] = [0; 256];
348    let mut rankVal: [u32; 13] = [0; 13];
349    let mut tableLog = 0;
350    let mut nbSymbols = 0;
351    let ct = CTable.offset(1);
352    let readSize = HUF_readStats(
353        &mut huffWeight,
354        (255 + 1) as size_t,
355        &mut rankVal,
356        &mut nbSymbols,
357        &mut tableLog,
358        src,
359    );
360    if ERR_isError(readSize) {
361        return readSize;
362    }
363    *hasZeroWeights =
364        (*rankVal.as_mut_ptr().offset(0) > 0) as core::ffi::c_int as core::ffi::c_uint;
365    if tableLog > HUF_TABLELOG_MAX as u32 {
366        return Error::tableLog_tooLarge.to_error_code();
367    }
368    if nbSymbols > (*maxSymbolValuePtr).wrapping_add(1) {
369        return Error::maxSymbolValue_tooSmall.to_error_code();
370    }
371    *maxSymbolValuePtr = nbSymbols.wrapping_sub(1);
372    HUF_writeCTableHeader(CTable, tableLog, *maxSymbolValuePtr);
373    let mut n: u32 = 0;
374    let mut nextRankStart = 0u32;
375    n = 1;
376    while n <= tableLog {
377        let curr = nextRankStart;
378        nextRankStart = nextRankStart
379            .wrapping_add(*rankVal.as_mut_ptr().offset(n as isize) << n.wrapping_sub(1));
380        *rankVal.as_mut_ptr().offset(n as isize) = curr;
381        n = n.wrapping_add(1);
382    }
383    let mut n_0: u32 = 0;
384    n_0 = 0;
385    while n_0 < nbSymbols {
386        let w = *huffWeight.as_mut_ptr().offset(n_0 as isize) as u32;
387        HUF_setNbBits(
388            ct.offset(n_0 as isize),
389            (tableLog.wrapping_add(1).wrapping_sub(w) as u8 as core::ffi::c_int
390                & -((w != 0) as core::ffi::c_int)) as size_t,
391        );
392        n_0 = n_0.wrapping_add(1);
393    }
394    let mut nbPerRank: [u16; 14] = [0; 14];
395    let mut valPerRank: [u16; 14] = [0; 14];
396    let mut n_1: u32 = 0;
397    n_1 = 0;
398    while n_1 < nbSymbols {
399        let fresh0 = &mut (*nbPerRank
400            .as_mut_ptr()
401            .add(HUF_getNbBits(*ct.offset(n_1 as isize))));
402        *fresh0 = (*fresh0).wrapping_add(1);
403        n_1 = n_1.wrapping_add(1);
404    }
405    *valPerRank
406        .as_mut_ptr()
407        .offset(tableLog.wrapping_add(1) as isize) = 0;
408    let mut min = 0;
409    let mut n_2: u32 = 0;
410    n_2 = tableLog;
411    while n_2 > 0 {
412        *valPerRank.as_mut_ptr().offset(n_2 as isize) = min;
413        min = (min as core::ffi::c_int
414            + *nbPerRank.as_mut_ptr().offset(n_2 as isize) as core::ffi::c_int)
415            as u16;
416        min = (min as core::ffi::c_int >> 1) as u16;
417        n_2 = n_2.wrapping_sub(1);
418    }
419    let mut n_3: u32 = 0;
420    n_3 = 0;
421    while n_3 < nbSymbols {
422        let fresh1 = &mut (*valPerRank
423            .as_mut_ptr()
424            .add(HUF_getNbBits(*ct.offset(n_3 as isize))));
425        let fresh2 = *fresh1;
426        *fresh1 = (*fresh1).wrapping_add(1);
427        HUF_setValue(ct.offset(n_3 as isize), fresh2 as size_t);
428        n_3 = n_3.wrapping_add(1);
429    }
430    readSize
431}
432pub unsafe fn HUF_getNbBitsFromCTable(CTable: *const HUF_CElt, symbolValue: u32) -> u32 {
433    let ct = CTable.offset(1);
434    if symbolValue > (HUF_readCTableHeader(CTable)).maxSymbolValue as u32 {
435        return 0;
436    }
437    HUF_getNbBits(*ct.offset(symbolValue as isize)) as u32
438}
439unsafe fn HUF_setMaxHeight(huffNode: *mut nodeElt, lastNonNull: u32, targetNbBits: u32) -> u32 {
440    let largestBits = (*huffNode.offset(lastNonNull as isize)).nbBits as u32;
441    if largestBits <= targetNbBits {
442        return largestBits;
443    }
444    let mut totalCost = 0;
445    let baseCost = ((1) << largestBits.wrapping_sub(targetNbBits)) as u32;
446    let mut n = lastNonNull as core::ffi::c_int;
447    while (*huffNode.offset(n as isize)).nbBits as u32 > targetNbBits {
448        totalCost = (totalCost as u32).wrapping_add(baseCost.wrapping_sub(
449            ((1) << largestBits.wrapping_sub((*huffNode.offset(n as isize)).nbBits as u32)) as u32,
450        )) as core::ffi::c_int as core::ffi::c_int;
451        (*huffNode.offset(n as isize)).nbBits = targetNbBits as u8;
452        n -= 1;
453    }
454    while (*huffNode.offset(n as isize)).nbBits as u32 == targetNbBits {
455        n -= 1;
456    }
457    totalCost >>= largestBits.wrapping_sub(targetNbBits);
458    let noSymbol = 0xf0f0f0f0 as core::ffi::c_uint;
459    let mut rankLast: [u32; 14] = [0; 14];
460    ptr::write_bytes(
461        rankLast.as_mut_ptr() as *mut u8,
462        0xf0,
463        ::core::mem::size_of::<[u32; 14]>(),
464    );
465    let mut currentNbBits = targetNbBits;
466    let mut pos: core::ffi::c_int = 0;
467    pos = n;
468    while pos >= 0 {
469        if ((*huffNode.offset(pos as isize)).nbBits as u32) < currentNbBits {
470            currentNbBits = (*huffNode.offset(pos as isize)).nbBits as u32;
471            *rankLast
472                .as_mut_ptr()
473                .offset(targetNbBits.wrapping_sub(currentNbBits) as isize) = pos as u32;
474        }
475        pos -= 1;
476    }
477    while totalCost > 0 {
478        let mut nBitsToDecrease = (ZSTD_highbit32(totalCost as u32)).wrapping_add(1);
479        while nBitsToDecrease > 1 {
480            let highPos = *rankLast.as_mut_ptr().offset(nBitsToDecrease as isize);
481            let lowPos = *rankLast
482                .as_mut_ptr()
483                .offset(nBitsToDecrease.wrapping_sub(1) as isize);
484            if highPos != noSymbol {
485                if lowPos == noSymbol {
486                    break;
487                }
488                let highTotal = (*huffNode.offset(highPos as isize)).count;
489                let lowTotal = 2 * (*huffNode.offset(lowPos as isize)).count;
490                if highTotal <= lowTotal {
491                    break;
492                }
493            }
494            nBitsToDecrease = nBitsToDecrease.wrapping_sub(1);
495        }
496        while nBitsToDecrease <= HUF_TABLELOG_MAX as u32
497            && *rankLast.as_mut_ptr().offset(nBitsToDecrease as isize) == noSymbol
498        {
499            nBitsToDecrease = nBitsToDecrease.wrapping_add(1);
500        }
501        totalCost -= (1) << nBitsToDecrease.wrapping_sub(1);
502        let fresh3 = &mut (*huffNode
503            .offset(*rankLast.as_mut_ptr().offset(nBitsToDecrease as isize) as isize))
504        .nbBits;
505        *fresh3 = (*fresh3).wrapping_add(1);
506        if *rankLast
507            .as_mut_ptr()
508            .offset(nBitsToDecrease.wrapping_sub(1) as isize)
509            == noSymbol
510        {
511            *rankLast
512                .as_mut_ptr()
513                .offset(nBitsToDecrease.wrapping_sub(1) as isize) =
514                *rankLast.as_mut_ptr().offset(nBitsToDecrease as isize);
515        }
516        if *rankLast.as_mut_ptr().offset(nBitsToDecrease as isize) == 0 {
517            *rankLast.as_mut_ptr().offset(nBitsToDecrease as isize) = noSymbol;
518        } else {
519            let fresh4 = &mut (*rankLast.as_mut_ptr().offset(nBitsToDecrease as isize));
520            *fresh4 = (*fresh4).wrapping_sub(1);
521            if (*huffNode.offset(*rankLast.as_mut_ptr().offset(nBitsToDecrease as isize) as isize))
522                .nbBits as u32
523                != targetNbBits.wrapping_sub(nBitsToDecrease)
524            {
525                *rankLast.as_mut_ptr().offset(nBitsToDecrease as isize) = noSymbol;
526            }
527        }
528    }
529    while totalCost < 0 {
530        if *rankLast.as_mut_ptr().offset(1) == noSymbol {
531            while (*huffNode.offset(n as isize)).nbBits as u32 == targetNbBits {
532                n -= 1;
533            }
534            let fresh5 = &mut (*huffNode.offset((n + 1) as isize)).nbBits;
535            *fresh5 = (*fresh5).wrapping_sub(1);
536            *rankLast.as_mut_ptr().offset(1) = (n + 1) as u32;
537            totalCost += 1;
538        } else {
539            let fresh6 = &mut (*huffNode
540                .offset((*rankLast.as_mut_ptr().offset(1)).wrapping_add(1) as isize))
541            .nbBits;
542            *fresh6 = (*fresh6).wrapping_sub(1);
543            let fresh7 = &mut (*rankLast.as_mut_ptr().offset(1));
544            *fresh7 = (*fresh7).wrapping_add(1);
545            totalCost += 1;
546        }
547    }
548    targetNbBits
549}
550pub const RANK_POSITION_TABLE_SIZE: core::ffi::c_int = 192;
551pub const RANK_POSITION_MAX_COUNT_LOG: core::ffi::c_int = 32;
552pub const RANK_POSITION_LOG_BUCKETS_BEGIN: core::ffi::c_int =
553    RANK_POSITION_TABLE_SIZE - 1 - RANK_POSITION_MAX_COUNT_LOG - 1;
554pub const RANK_POSITION_DISTINCT_COUNT_CUTOFF: core::ffi::c_uint = (RANK_POSITION_LOG_BUCKETS_BEGIN
555    as core::ffi::c_uint)
556    .wrapping_add(ZSTD_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN as u32));
557unsafe fn HUF_getIndex(count: u32) -> u32 {
558    if count < RANK_POSITION_DISTINCT_COUNT_CUTOFF {
559        count
560    } else {
561        (ZSTD_highbit32(count)).wrapping_add(RANK_POSITION_LOG_BUCKETS_BEGIN as core::ffi::c_uint)
562    }
563}
564unsafe fn HUF_swapNodes(a: *mut nodeElt, b: *mut nodeElt) {
565    core::ptr::swap(a, b);
566}
567#[inline(always)]
568unsafe fn HUF_insertionSort(
569    mut huffNode: *mut nodeElt,
570    low: core::ffi::c_int,
571    high: core::ffi::c_int,
572) {
573    let mut i: core::ffi::c_int = 0;
574    let size = high - low + 1;
575    huffNode = huffNode.offset(low as isize);
576    i = 1;
577    while i < size {
578        let key = *huffNode.offset(i as isize);
579        let mut j = i - 1;
580        while j >= 0 && (*huffNode.offset(j as isize)).count < key.count {
581            *huffNode.offset((j + 1) as isize) = *huffNode.offset(j as isize);
582            j -= 1;
583        }
584        *huffNode.offset((j + 1) as isize) = key;
585        i += 1;
586    }
587}
588unsafe fn HUF_quickSortPartition(
589    arr: *mut nodeElt,
590    low: core::ffi::c_int,
591    high: core::ffi::c_int,
592) -> core::ffi::c_int {
593    let pivot = (*arr.offset(high as isize)).count;
594    let mut i = low - 1;
595    let mut j = low;
596    while j < high {
597        if (*arr.offset(j as isize)).count > pivot {
598            i += 1;
599            HUF_swapNodes(&mut *arr.offset(i as isize), &mut *arr.offset(j as isize));
600        }
601        j += 1;
602    }
603    HUF_swapNodes(
604        &mut *arr.offset((i + 1) as isize),
605        &mut *arr.offset(high as isize),
606    );
607    i + 1
608}
609unsafe fn HUF_simpleQuickSort(
610    arr: *mut nodeElt,
611    mut low: core::ffi::c_int,
612    mut high: core::ffi::c_int,
613) {
614    let kInsertionSortThreshold = 8;
615    if high - low < kInsertionSortThreshold {
616        HUF_insertionSort(arr, low, high);
617        return;
618    }
619    while low < high {
620        let idx = HUF_quickSortPartition(arr, low, high);
621        if idx - low < high - idx {
622            HUF_simpleQuickSort(arr, low, idx - 1);
623            low = idx + 1;
624        } else {
625            HUF_simpleQuickSort(arr, idx + 1, high);
626            high = idx - 1;
627        }
628    }
629}
630unsafe fn HUF_sort(
631    huffNode: *mut nodeElt,
632    count: *const core::ffi::c_uint,
633    maxSymbolValue: u32,
634    rankPosition: *mut rankPos,
635) {
636    let mut n: u32 = 0;
637    let maxSymbolValue1 = maxSymbolValue.wrapping_add(1);
638    ptr::write_bytes(
639        rankPosition as *mut u8,
640        0,
641        ::core::mem::size_of::<rankPos>() * 192,
642    );
643    n = 0;
644    while n < maxSymbolValue1 {
645        let lowerRank = HUF_getIndex(*count.offset(n as isize));
646        let fresh8 = &mut (*rankPosition.offset(lowerRank as isize)).base;
647        *fresh8 = (*fresh8).wrapping_add(1);
648        n = n.wrapping_add(1);
649    }
650    n = (RANK_POSITION_TABLE_SIZE - 1) as u32;
651    while n > 0 {
652        let fresh9 = &mut (*rankPosition.offset(n.wrapping_sub(1) as isize)).base;
653        *fresh9 = (*fresh9 as core::ffi::c_int
654            + (*rankPosition.offset(n as isize)).base as core::ffi::c_int) as u16;
655        (*rankPosition.offset(n.wrapping_sub(1) as isize)).curr =
656            (*rankPosition.offset(n.wrapping_sub(1) as isize)).base;
657        n = n.wrapping_sub(1);
658    }
659    n = 0;
660    while n < maxSymbolValue1 {
661        let c = *count.offset(n as isize);
662        let r = (HUF_getIndex(c)).wrapping_add(1);
663        let fresh10 = &mut (*rankPosition.offset(r as isize)).curr;
664        let fresh11 = *fresh10;
665        *fresh10 = (*fresh10).wrapping_add(1);
666        let pos = fresh11 as u32;
667        (*huffNode.offset(pos as isize)).count = c;
668        (*huffNode.offset(pos as isize)).byte = n as u8;
669        n = n.wrapping_add(1);
670    }
671    n = RANK_POSITION_DISTINCT_COUNT_CUTOFF;
672    while n < (RANK_POSITION_TABLE_SIZE - 1) as u32 {
673        let bucketSize = (*rankPosition.offset(n as isize)).curr as core::ffi::c_int
674            - (*rankPosition.offset(n as isize)).base as core::ffi::c_int;
675        let bucketStartIdx = (*rankPosition.offset(n as isize)).base as u32;
676        if bucketSize > 1 {
677            HUF_simpleQuickSort(huffNode.offset(bucketStartIdx as isize), 0, bucketSize - 1);
678        }
679        n = n.wrapping_add(1);
680    }
681}
682pub const STARTNODE: core::ffi::c_int = HUF_SYMBOLVALUE_MAX + 1;
683unsafe fn HUF_buildTree(huffNode: *mut nodeElt, maxSymbolValue: u32) -> core::ffi::c_int {
684    let huffNode0 = huffNode.offset(-(1));
685    let mut nonNullRank: core::ffi::c_int = 0;
686    let mut lowS: core::ffi::c_int = 0;
687    let mut lowN: core::ffi::c_int = 0;
688    let mut nodeNb = STARTNODE;
689    let mut n: core::ffi::c_int = 0;
690    let mut nodeRoot: core::ffi::c_int = 0;
691    nonNullRank = maxSymbolValue as core::ffi::c_int;
692    while (*huffNode.offset(nonNullRank as isize)).count == 0 {
693        nonNullRank -= 1;
694    }
695    lowS = nonNullRank;
696    nodeRoot = nodeNb + lowS - 1;
697    lowN = nodeNb;
698    (*huffNode.offset(nodeNb as isize)).count = ((*huffNode.offset(lowS as isize)).count)
699        .wrapping_add((*huffNode.offset((lowS - 1) as isize)).count);
700    let fresh12 = &mut (*huffNode.offset((lowS - 1) as isize)).parent;
701    *fresh12 = nodeNb as u16;
702    (*huffNode.offset(lowS as isize)).parent = *fresh12;
703    nodeNb += 1;
704    lowS -= 2;
705    n = nodeNb;
706    while n <= nodeRoot {
707        (*huffNode.offset(n as isize)).count = (1) << 30;
708        n += 1;
709    }
710    (*huffNode0.offset(0)).count = (1) << 31;
711    while nodeNb <= nodeRoot {
712        let n1 =
713            if (*huffNode.offset(lowS as isize)).count < (*huffNode.offset(lowN as isize)).count {
714                let fresh13 = lowS;
715                lowS -= 1;
716                fresh13
717            } else {
718                let fresh14 = lowN;
719                lowN += 1;
720                fresh14
721            };
722        let n2 =
723            if (*huffNode.offset(lowS as isize)).count < (*huffNode.offset(lowN as isize)).count {
724                let fresh15 = lowS;
725                lowS -= 1;
726                fresh15
727            } else {
728                let fresh16 = lowN;
729                lowN += 1;
730                fresh16
731            };
732        (*huffNode.offset(nodeNb as isize)).count = ((*huffNode.offset(n1 as isize)).count)
733            .wrapping_add((*huffNode.offset(n2 as isize)).count);
734        let fresh17 = &mut (*huffNode.offset(n2 as isize)).parent;
735        *fresh17 = nodeNb as u16;
736        (*huffNode.offset(n1 as isize)).parent = *fresh17;
737        nodeNb += 1;
738    }
739    (*huffNode.offset(nodeRoot as isize)).nbBits = 0;
740    n = nodeRoot - 1;
741    while n >= STARTNODE {
742        (*huffNode.offset(n as isize)).nbBits = ((*huffNode
743            .offset((*huffNode.offset(n as isize)).parent as isize))
744        .nbBits as core::ffi::c_int
745            + 1) as u8;
746        n -= 1;
747    }
748    n = 0;
749    while n <= nonNullRank {
750        (*huffNode.offset(n as isize)).nbBits = ((*huffNode
751            .offset((*huffNode.offset(n as isize)).parent as isize))
752        .nbBits as core::ffi::c_int
753            + 1) as u8;
754        n += 1;
755    }
756    nonNullRank
757}
758unsafe fn HUF_buildCTableFromTree(
759    CTable: *mut HUF_CElt,
760    huffNode: *const nodeElt,
761    nonNullRank: core::ffi::c_int,
762    maxSymbolValue: u32,
763    maxNbBits: u32,
764) {
765    let ct = CTable.offset(1);
766    let mut n: core::ffi::c_int = 0;
767    let mut nbPerRank: [u16; 13] = [0; 13];
768    let mut valPerRank: [u16; 13] = [0; 13];
769    let alphabetSize = maxSymbolValue.wrapping_add(1) as core::ffi::c_int;
770    n = 0;
771    while n <= nonNullRank {
772        let fresh18 = &mut (*nbPerRank
773            .as_mut_ptr()
774            .offset((*huffNode.offset(n as isize)).nbBits as isize));
775        *fresh18 = (*fresh18).wrapping_add(1);
776        n += 1;
777    }
778    let mut min = 0;
779    n = maxNbBits as core::ffi::c_int;
780    while n > 0 {
781        *valPerRank.as_mut_ptr().offset(n as isize) = min;
782        min = (min as core::ffi::c_int
783            + *nbPerRank.as_mut_ptr().offset(n as isize) as core::ffi::c_int) as u16;
784        min = (min as core::ffi::c_int >> 1) as u16;
785        n -= 1;
786    }
787    n = 0;
788    while n < alphabetSize {
789        HUF_setNbBits(
790            ct.offset((*huffNode.offset(n as isize)).byte as core::ffi::c_int as isize),
791            (*huffNode.offset(n as isize)).nbBits as size_t,
792        );
793        n += 1;
794    }
795    n = 0;
796    while n < alphabetSize {
797        let fresh19 = &mut (*valPerRank
798            .as_mut_ptr()
799            .add(HUF_getNbBits(*ct.offset(n as isize))));
800        let fresh20 = *fresh19;
801        *fresh19 = (*fresh19).wrapping_add(1);
802        HUF_setValue(ct.offset(n as isize), fresh20 as size_t);
803        n += 1;
804    }
805    HUF_writeCTableHeader(CTable, maxNbBits, maxSymbolValue);
806}
807pub unsafe fn HUF_buildCTable_wksp(
808    CTable: *mut HUF_CElt,
809    count: *const core::ffi::c_uint,
810    maxSymbolValue: u32,
811    mut maxNbBits: u32,
812    workSpace: *mut core::ffi::c_void,
813    mut wkspSize: size_t,
814) -> size_t {
815    let wksp_tables = HUF_alignUpWorkspace(
816        workSpace,
817        &mut wkspSize,
818        ::core::mem::align_of::<u32>() as size_t,
819    ) as *mut HUF_buildCTable_wksp_tables;
820    let huffNode0 = ((*wksp_tables).huffNodeTbl).as_mut_ptr();
821    let huffNode = huffNode0.offset(1);
822    let mut nonNullRank: core::ffi::c_int = 0;
823    if wkspSize < ::core::mem::size_of::<HUF_buildCTable_wksp_tables>() {
824        return Error::workSpace_tooSmall.to_error_code();
825    }
826    if maxNbBits == 0 {
827        maxNbBits = HUF_TABLELOG_DEFAULT as u32;
828    }
829    if maxSymbolValue > HUF_SYMBOLVALUE_MAX as u32 {
830        return Error::maxSymbolValue_tooLarge.to_error_code();
831    }
832    ptr::write_bytes(
833        huffNode0 as *mut u8,
834        0,
835        ::core::mem::size_of::<huffNodeTable>(),
836    );
837    HUF_sort(
838        huffNode,
839        count,
840        maxSymbolValue,
841        ((*wksp_tables).rankPosition).as_mut_ptr(),
842    );
843    nonNullRank = HUF_buildTree(huffNode, maxSymbolValue);
844    maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank as u32, maxNbBits);
845    if maxNbBits > HUF_TABLELOG_MAX as u32 {
846        return Error::GENERIC.to_error_code();
847    }
848    HUF_buildCTableFromTree(CTable, huffNode, nonNullRank, maxSymbolValue, maxNbBits);
849    maxNbBits as size_t
850}
851pub unsafe fn HUF_estimateCompressedSize(
852    CTable: *const HUF_CElt,
853    count: *const core::ffi::c_uint,
854    maxSymbolValue: core::ffi::c_uint,
855) -> size_t {
856    let ct = CTable.offset(1);
857    let mut nbBits = 0 as size_t;
858    let mut s: core::ffi::c_int = 0;
859    s = 0;
860    while s <= maxSymbolValue as core::ffi::c_int {
861        nbBits = nbBits.wrapping_add(
862            HUF_getNbBits(*ct.offset(s as isize)) * *count.offset(s as isize) as size_t,
863        );
864        s += 1;
865    }
866    nbBits >> 3
867}
868pub unsafe fn HUF_validateCTable(
869    CTable: *const HUF_CElt,
870    count: *const core::ffi::c_uint,
871    maxSymbolValue: core::ffi::c_uint,
872) -> core::ffi::c_int {
873    let header = HUF_readCTableHeader(CTable);
874    let ct = CTable.offset(1);
875    let mut bad = 0;
876    let mut s: core::ffi::c_int = 0;
877    if (header.maxSymbolValue as core::ffi::c_uint) < maxSymbolValue {
878        return 0;
879    }
880    s = 0;
881    while s <= maxSymbolValue as core::ffi::c_int {
882        bad |= (*count.offset(s as isize) != 0) as core::ffi::c_int
883            & (HUF_getNbBits(*ct.offset(s as isize)) == 0) as core::ffi::c_int;
884        s += 1;
885    }
886    (bad == 0) as core::ffi::c_int
887}
888pub fn HUF_compressBound(size: size_t) -> size_t {
889    (HUF_CTABLEBOUND as size_t).wrapping_add(size.wrapping_add(size >> 8).wrapping_add(8))
890}
891pub const HUF_BITS_IN_CONTAINER: size_t = (::core::mem::size_of::<size_t>()).wrapping_mul(8);
892unsafe fn HUF_initCStream(
893    bitC: *mut HUF_CStream_t,
894    startPtr: *mut core::ffi::c_void,
895    dstCapacity: size_t,
896) -> size_t {
897    ptr::write_bytes(bitC as *mut u8, 0, ::core::mem::size_of::<HUF_CStream_t>());
898    (*bitC).startPtr = startPtr as *mut u8;
899    (*bitC).ptr = (*bitC).startPtr;
900    (*bitC).endPtr = ((*bitC).startPtr)
901        .add(dstCapacity)
902        .offset(-(::core::mem::size_of::<size_t>() as core::ffi::c_ulong as isize));
903    if dstCapacity <= ::core::mem::size_of::<size_t>() {
904        return Error::dstSize_tooSmall.to_error_code();
905    }
906    0
907}
908#[inline(always)]
909unsafe fn HUF_addBits(
910    bitC: *mut HUF_CStream_t,
911    elt: HUF_CElt,
912    idx: core::ffi::c_int,
913    kFast: core::ffi::c_int,
914) {
915    *((*bitC).bitContainer).as_mut_ptr().offset(idx as isize) >>= HUF_getNbBits(elt);
916    *((*bitC).bitContainer).as_mut_ptr().offset(idx as isize) |= if kFast != 0 {
917        HUF_getValueFast(elt)
918    } else {
919        HUF_getValue(elt)
920    };
921    let fresh21 = &mut (*((*bitC).bitPos).as_mut_ptr().offset(idx as isize));
922    *fresh21 = (*fresh21).wrapping_add(HUF_getNbBitsFast(elt));
923}
924#[inline(always)]
925unsafe fn HUF_zeroIndex1(bitC: *mut HUF_CStream_t) {
926    *((*bitC).bitContainer).as_mut_ptr().offset(1) = 0;
927    *((*bitC).bitPos).as_mut_ptr().offset(1) = 0;
928}
929#[inline(always)]
930unsafe fn HUF_mergeIndex1(bitC: *mut HUF_CStream_t) {
931    *((*bitC).bitContainer).as_mut_ptr().offset(0) >>=
932        *((*bitC).bitPos).as_mut_ptr().offset(1) & 0xff as core::ffi::c_int as size_t;
933    *((*bitC).bitContainer).as_mut_ptr().offset(0) |=
934        *((*bitC).bitContainer).as_mut_ptr().offset(1);
935    let fresh22 = &mut (*((*bitC).bitPos).as_mut_ptr().offset(0));
936    *fresh22 = (*fresh22).wrapping_add(*((*bitC).bitPos).as_mut_ptr().offset(1));
937}
938#[inline(always)]
939unsafe fn HUF_flushBits(bitC: *mut HUF_CStream_t, kFast: core::ffi::c_int) {
940    let nbBits = *((*bitC).bitPos).as_mut_ptr().offset(0) & 0xff as core::ffi::c_int as size_t;
941    let nbBytes = nbBits >> 3;
942    let bitContainer = *((*bitC).bitContainer).as_mut_ptr().offset(0)
943        >> HUF_BITS_IN_CONTAINER.wrapping_sub(nbBits);
944    *((*bitC).bitPos).as_mut_ptr().offset(0) &= 7;
945    MEM_writeLEST((*bitC).ptr as *mut core::ffi::c_void, bitContainer);
946    (*bitC).ptr = ((*bitC).ptr).add(nbBytes);
947    if kFast == 0 && (*bitC).ptr > (*bitC).endPtr {
948        (*bitC).ptr = (*bitC).endPtr;
949    }
950}
951unsafe fn HUF_endMark() -> HUF_CElt {
952    let mut endMark: HUF_CElt = 0;
953    HUF_setNbBits(&mut endMark, 1);
954    HUF_setValue(&mut endMark, 1);
955    endMark
956}
957unsafe fn HUF_closeCStream(bitC: *mut HUF_CStream_t) -> size_t {
958    HUF_addBits(bitC, HUF_endMark(), 0, 0);
959    HUF_flushBits(bitC, 0);
960    let nbBits = *((*bitC).bitPos).as_mut_ptr().offset(0) & 0xff as core::ffi::c_int as size_t;
961    if (*bitC).ptr >= (*bitC).endPtr {
962        return 0;
963    }
964    (((*bitC).ptr).offset_from((*bitC).startPtr) as size_t)
965        .wrapping_add((nbBits > 0) as core::ffi::c_int as size_t)
966}
967#[inline(always)]
968unsafe fn HUF_encodeSymbol(
969    bitCPtr: *mut HUF_CStream_t,
970    symbol: u32,
971    CTable: *const HUF_CElt,
972    idx: core::ffi::c_int,
973    fast: core::ffi::c_int,
974) {
975    HUF_addBits(bitCPtr, *CTable.offset(symbol as isize), idx, fast);
976}
977#[inline(always)]
978unsafe fn HUF_compress1X_usingCTable_internal_body_loop(
979    bitC: *mut HUF_CStream_t,
980    ip: *const u8,
981    srcSize: size_t,
982    ct: *const HUF_CElt,
983    kUnroll: core::ffi::c_int,
984    kFastFlush: core::ffi::c_int,
985    kLastFast: core::ffi::c_int,
986) {
987    let mut n = srcSize as core::ffi::c_int;
988    let mut rem = n % kUnroll;
989    if rem > 0 {
990        while rem > 0 {
991            n -= 1;
992            HUF_encodeSymbol(bitC, *ip.offset(n as isize) as u32, ct, 0, 0);
993            rem -= 1;
994        }
995        HUF_flushBits(bitC, kFastFlush);
996    }
997    if n % (2 * kUnroll) != 0 {
998        let mut u: core::ffi::c_int = 0;
999        u = 1;
1000        while u < kUnroll {
1001            HUF_encodeSymbol(bitC, *ip.offset((n - u) as isize) as u32, ct, 0, 1);
1002            u += 1;
1003        }
1004        HUF_encodeSymbol(
1005            bitC,
1006            *ip.offset((n - kUnroll) as isize) as u32,
1007            ct,
1008            0,
1009            kLastFast,
1010        );
1011        HUF_flushBits(bitC, kFastFlush);
1012        n -= kUnroll;
1013    }
1014    while n > 0 {
1015        let mut u_0: core::ffi::c_int = 0;
1016        u_0 = 1;
1017        while u_0 < kUnroll {
1018            HUF_encodeSymbol(bitC, *ip.offset((n - u_0) as isize) as u32, ct, 0, 1);
1019            u_0 += 1;
1020        }
1021        HUF_encodeSymbol(
1022            bitC,
1023            *ip.offset((n - kUnroll) as isize) as u32,
1024            ct,
1025            0,
1026            kLastFast,
1027        );
1028        HUF_flushBits(bitC, kFastFlush);
1029        HUF_zeroIndex1(bitC);
1030        u_0 = 1;
1031        while u_0 < kUnroll {
1032            HUF_encodeSymbol(
1033                bitC,
1034                *ip.offset((n - kUnroll - u_0) as isize) as u32,
1035                ct,
1036                1,
1037                1,
1038            );
1039            u_0 += 1;
1040        }
1041        HUF_encodeSymbol(
1042            bitC,
1043            *ip.offset((n - kUnroll - kUnroll) as isize) as u32,
1044            ct,
1045            1,
1046            kLastFast,
1047        );
1048        HUF_mergeIndex1(bitC);
1049        HUF_flushBits(bitC, kFastFlush);
1050        n -= 2 * kUnroll;
1051    }
1052}
1053fn HUF_tightCompressBound(srcSize: size_t, tableLog: size_t) -> size_t {
1054    ((srcSize * tableLog) >> 3).wrapping_add(8)
1055}
1056#[inline(always)]
1057unsafe fn HUF_compress1X_usingCTable_internal_body(
1058    dst: *mut core::ffi::c_void,
1059    dstSize: size_t,
1060    src: *const core::ffi::c_void,
1061    srcSize: size_t,
1062    CTable: *const HUF_CElt,
1063) -> size_t {
1064    let tableLog = (HUF_readCTableHeader(CTable)).tableLog as u32;
1065    let ct = CTable.offset(1);
1066    let ip = src as *const u8;
1067    let ostart = dst as *mut u8;
1068    let oend = ostart.add(dstSize);
1069    let mut bitC = HUF_CStream_t {
1070        bitContainer: [0; 2],
1071        bitPos: [0; 2],
1072        startPtr: core::ptr::null_mut::<u8>(),
1073        ptr: core::ptr::null_mut::<u8>(),
1074        endPtr: core::ptr::null_mut::<u8>(),
1075    };
1076    if dstSize < 8 {
1077        return 0;
1078    }
1079    let op = ostart;
1080    let initErr = HUF_initCStream(
1081        &mut bitC,
1082        op as *mut core::ffi::c_void,
1083        oend.offset_from(op) as size_t,
1084    );
1085    if ERR_isError(initErr) {
1086        return 0;
1087    }
1088    if dstSize < HUF_tightCompressBound(srcSize, tableLog as size_t) || tableLog > 11 {
1089        HUF_compress1X_usingCTable_internal_body_loop(
1090            &mut bitC,
1091            ip,
1092            srcSize,
1093            ct,
1094            if MEM_32bits() != 0 { 2 } else { 4 },
1095            0,
1096            0,
1097        );
1098    } else if MEM_32bits() != 0 {
1099        match tableLog {
1100            11 => {
1101                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 2, 1, 0);
1102            }
1103            8..=10 => {
1104                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 2, 1, 1);
1105            }
1106            7 | _ => {
1107                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 3, 1, 1);
1108            }
1109        }
1110    } else {
1111        match tableLog {
1112            11 => {
1113                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 5, 1, 0);
1114            }
1115            10 => {
1116                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 5, 1, 1);
1117            }
1118            9 => {
1119                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 6, 1, 0);
1120            }
1121            8 => {
1122                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 7, 1, 0);
1123            }
1124            7 => {
1125                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 8, 1, 0);
1126            }
1127            6 | _ => {
1128                HUF_compress1X_usingCTable_internal_body_loop(&mut bitC, ip, srcSize, ct, 9, 1, 1);
1129            }
1130        }
1131    }
1132    HUF_closeCStream(&mut bitC)
1133}
1134unsafe fn HUF_compress1X_usingCTable_internal_bmi2(
1135    dst: *mut core::ffi::c_void,
1136    dstSize: size_t,
1137    src: *const core::ffi::c_void,
1138    srcSize: size_t,
1139    CTable: *const HUF_CElt,
1140) -> size_t {
1141    HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable)
1142}
1143unsafe fn HUF_compress1X_usingCTable_internal_default(
1144    dst: *mut core::ffi::c_void,
1145    dstSize: size_t,
1146    src: *const core::ffi::c_void,
1147    srcSize: size_t,
1148    CTable: *const HUF_CElt,
1149) -> size_t {
1150    HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable)
1151}
1152unsafe fn HUF_compress1X_usingCTable_internal(
1153    dst: *mut core::ffi::c_void,
1154    dstSize: size_t,
1155    src: *const core::ffi::c_void,
1156    srcSize: size_t,
1157    CTable: *const HUF_CElt,
1158    flags: core::ffi::c_int,
1159) -> size_t {
1160    if flags & HUF_flags_bmi2 as core::ffi::c_int != 0 {
1161        return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable);
1162    }
1163    HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable)
1164}
1165pub unsafe fn HUF_compress1X_usingCTable(
1166    dst: *mut core::ffi::c_void,
1167    dstSize: size_t,
1168    src: *const core::ffi::c_void,
1169    srcSize: size_t,
1170    CTable: *const HUF_CElt,
1171    flags: core::ffi::c_int,
1172) -> size_t {
1173    HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags)
1174}
1175unsafe fn HUF_compress4X_usingCTable_internal(
1176    dst: *mut core::ffi::c_void,
1177    dstSize: size_t,
1178    src: *const core::ffi::c_void,
1179    srcSize: size_t,
1180    CTable: *const HUF_CElt,
1181    flags: core::ffi::c_int,
1182) -> size_t {
1183    let segmentSize = srcSize.wrapping_add(3) / 4;
1184    let mut ip = src as *const u8;
1185    let iend = ip.add(srcSize);
1186    let ostart = dst as *mut u8;
1187    let oend = ostart.add(dstSize);
1188    let mut op = ostart;
1189    if dstSize < (6 + 1 + 1 + 1 + 8) as size_t {
1190        return 0;
1191    }
1192    if srcSize < 12 {
1193        return 0;
1194    }
1195    op = op.offset(6);
1196    let cSize = HUF_compress1X_usingCTable_internal(
1197        op as *mut core::ffi::c_void,
1198        oend.offset_from(op) as size_t,
1199        ip as *const core::ffi::c_void,
1200        segmentSize,
1201        CTable,
1202        flags,
1203    );
1204    if ERR_isError(cSize) {
1205        return cSize;
1206    }
1207    if cSize == 0 || cSize > 65535 {
1208        return 0;
1209    }
1210    MEM_writeLE16(ostart as *mut core::ffi::c_void, cSize as u16);
1211    op = op.add(cSize);
1212    ip = ip.add(segmentSize);
1213    let cSize_0 = HUF_compress1X_usingCTable_internal(
1214        op as *mut core::ffi::c_void,
1215        oend.offset_from(op) as size_t,
1216        ip as *const core::ffi::c_void,
1217        segmentSize,
1218        CTable,
1219        flags,
1220    );
1221    if ERR_isError(cSize_0) {
1222        return cSize_0;
1223    }
1224    if cSize_0 == 0 || cSize_0 > 65535 {
1225        return 0;
1226    }
1227    MEM_writeLE16(ostart.offset(2) as *mut core::ffi::c_void, cSize_0 as u16);
1228    op = op.add(cSize_0);
1229    ip = ip.add(segmentSize);
1230    let cSize_1 = HUF_compress1X_usingCTable_internal(
1231        op as *mut core::ffi::c_void,
1232        oend.offset_from(op) as size_t,
1233        ip as *const core::ffi::c_void,
1234        segmentSize,
1235        CTable,
1236        flags,
1237    );
1238    if ERR_isError(cSize_1) {
1239        return cSize_1;
1240    }
1241    if cSize_1 == 0 || cSize_1 > 65535 {
1242        return 0;
1243    }
1244    MEM_writeLE16(ostart.offset(4) as *mut core::ffi::c_void, cSize_1 as u16);
1245    op = op.add(cSize_1);
1246    ip = ip.add(segmentSize);
1247    let cSize_2 = HUF_compress1X_usingCTable_internal(
1248        op as *mut core::ffi::c_void,
1249        oend.offset_from(op) as size_t,
1250        ip as *const core::ffi::c_void,
1251        iend.offset_from(ip) as size_t,
1252        CTable,
1253        flags,
1254    );
1255    if ERR_isError(cSize_2) {
1256        return cSize_2;
1257    }
1258    if cSize_2 == 0 || cSize_2 > 65535 {
1259        return 0;
1260    }
1261    op = op.add(cSize_2);
1262    op.offset_from(ostart) as size_t
1263}
1264pub unsafe fn HUF_compress4X_usingCTable(
1265    dst: *mut core::ffi::c_void,
1266    dstSize: size_t,
1267    src: *const core::ffi::c_void,
1268    srcSize: size_t,
1269    CTable: *const HUF_CElt,
1270    flags: core::ffi::c_int,
1271) -> size_t {
1272    HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags)
1273}
1274unsafe fn HUF_compressCTable_internal(
1275    ostart: *mut u8,
1276    mut op: *mut u8,
1277    oend: *mut u8,
1278    src: *const core::ffi::c_void,
1279    srcSize: size_t,
1280    nbStreams: HUF_nbStreams_e,
1281    CTable: *const HUF_CElt,
1282    flags: core::ffi::c_int,
1283) -> size_t {
1284    let cSize = if nbStreams as core::ffi::c_uint
1285        == HUF_singleStream as core::ffi::c_int as core::ffi::c_uint
1286    {
1287        HUF_compress1X_usingCTable_internal(
1288            op as *mut core::ffi::c_void,
1289            oend.offset_from(op) as size_t,
1290            src,
1291            srcSize,
1292            CTable,
1293            flags,
1294        )
1295    } else {
1296        HUF_compress4X_usingCTable_internal(
1297            op as *mut core::ffi::c_void,
1298            oend.offset_from(op) as size_t,
1299            src,
1300            srcSize,
1301            CTable,
1302            flags,
1303        )
1304    };
1305    if ERR_isError(cSize) {
1306        return cSize;
1307    }
1308    if cSize == 0 {
1309        return 0;
1310    }
1311    op = op.add(cSize);
1312    if op.offset_from(ostart) as size_t >= srcSize.wrapping_sub(1) {
1313        return 0;
1314    }
1315    op.offset_from(ostart) as size_t
1316}
1317pub const SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE: core::ffi::c_int = 4096;
1318pub const SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO: core::ffi::c_int = 10;
1319pub unsafe fn HUF_cardinality(
1320    count: *const core::ffi::c_uint,
1321    maxSymbolValue: core::ffi::c_uint,
1322) -> core::ffi::c_uint {
1323    let mut cardinality = 0 as core::ffi::c_uint;
1324    let mut i: core::ffi::c_uint = 0;
1325    i = 0;
1326    while i < maxSymbolValue.wrapping_add(1) {
1327        if *count.offset(i as isize) != 0 {
1328            cardinality = cardinality.wrapping_add(1);
1329        }
1330        i = i.wrapping_add(1);
1331    }
1332    cardinality
1333}
1334pub fn HUF_minTableLog(symbolCardinality: core::ffi::c_uint) -> core::ffi::c_uint {
1335    (ZSTD_highbit32(symbolCardinality)).wrapping_add(1)
1336}
1337pub unsafe fn HUF_optimalTableLog(
1338    maxTableLog: core::ffi::c_uint,
1339    srcSize: size_t,
1340    maxSymbolValue: core::ffi::c_uint,
1341    workSpace: *mut core::ffi::c_void,
1342    wkspSize: size_t,
1343    table: *mut HUF_CElt,
1344    count: *const core::ffi::c_uint,
1345    flags: core::ffi::c_int,
1346) -> core::ffi::c_uint {
1347    if flags & HUF_flags_optimalDepth as core::ffi::c_int == 0 {
1348        return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
1349    }
1350    let dst = (workSpace as *mut u8)
1351        .offset(::core::mem::size_of::<HUF_WriteCTableWksp>() as core::ffi::c_ulong as isize);
1352    let dstSize = wkspSize.wrapping_sub(::core::mem::size_of::<HUF_WriteCTableWksp>());
1353    let mut hSize: size_t = 0;
1354    let mut newSize: size_t = 0;
1355    let symbolCardinality = HUF_cardinality(count, maxSymbolValue);
1356    let minTableLog = HUF_minTableLog(symbolCardinality);
1357    let mut optSize = (!(0) as size_t).wrapping_sub(1);
1358    let mut optLog = maxTableLog;
1359    let mut optLogGuess: core::ffi::c_uint = 0;
1360    optLogGuess = minTableLog;
1361    while optLogGuess <= maxTableLog {
1362        let maxBits = HUF_buildCTable_wksp(
1363            table,
1364            count,
1365            maxSymbolValue,
1366            optLogGuess,
1367            workSpace,
1368            wkspSize,
1369        );
1370        if !ERR_isError(maxBits) {
1371            if maxBits < optLogGuess as size_t && optLogGuess > minTableLog {
1372                break;
1373            }
1374            hSize = HUF_writeCTable_wksp(
1375                dst as *mut core::ffi::c_void,
1376                dstSize,
1377                table,
1378                maxSymbolValue,
1379                maxBits as u32,
1380                workSpace,
1381                wkspSize,
1382            );
1383            if !ERR_isError(hSize) {
1384                newSize =
1385                    (HUF_estimateCompressedSize(table, count, maxSymbolValue)).wrapping_add(hSize);
1386                if newSize > optSize.wrapping_add(1) {
1387                    break;
1388                }
1389                if newSize < optSize {
1390                    optSize = newSize;
1391                    optLog = optLogGuess;
1392                }
1393            }
1394        }
1395        optLogGuess = optLogGuess.wrapping_add(1);
1396    }
1397    optLog
1398}
1399unsafe fn HUF_compress_internal(
1400    dst: *mut core::ffi::c_void,
1401    dstSize: size_t,
1402    src: *const core::ffi::c_void,
1403    srcSize: size_t,
1404    mut maxSymbolValue: core::ffi::c_uint,
1405    mut huffLog: core::ffi::c_uint,
1406    nbStreams: HUF_nbStreams_e,
1407    workSpace: *mut core::ffi::c_void,
1408    mut wkspSize: size_t,
1409    oldHufTable: *mut HUF_CElt,
1410    repeat: *mut HUF_repeat,
1411    flags: core::ffi::c_int,
1412) -> size_t {
1413    let table = HUF_alignUpWorkspace(
1414        workSpace,
1415        &mut wkspSize,
1416        ::core::mem::align_of::<size_t>() as size_t,
1417    ) as *mut HUF_compress_tables_t;
1418    let ostart = dst as *mut u8;
1419    let oend = ostart.add(dstSize);
1420    let mut op = ostart;
1421    if wkspSize < ::core::mem::size_of::<HUF_compress_tables_t>() {
1422        return Error::workSpace_tooSmall.to_error_code();
1423    }
1424    if srcSize == 0 {
1425        return 0;
1426    }
1427    if dstSize == 0 {
1428        return 0;
1429    }
1430    if srcSize > HUF_BLOCKSIZE_MAX as size_t {
1431        return Error::srcSize_wrong.to_error_code();
1432    }
1433    if huffLog > HUF_TABLELOG_MAX as core::ffi::c_uint {
1434        return Error::tableLog_tooLarge.to_error_code();
1435    }
1436    if maxSymbolValue > HUF_SYMBOLVALUE_MAX as core::ffi::c_uint {
1437        return Error::maxSymbolValue_tooLarge.to_error_code();
1438    }
1439    if maxSymbolValue == 0 {
1440        maxSymbolValue = HUF_SYMBOLVALUE_MAX as core::ffi::c_uint;
1441    }
1442    if huffLog == 0 {
1443        huffLog = HUF_TABLELOG_DEFAULT as core::ffi::c_uint;
1444    }
1445    if flags & HUF_flags_preferRepeat as core::ffi::c_int != 0
1446        && !repeat.is_null()
1447        && *repeat as core::ffi::c_uint == HUF_repeat_valid as core::ffi::c_int as core::ffi::c_uint
1448    {
1449        return HUF_compressCTable_internal(
1450            ostart,
1451            op,
1452            oend,
1453            src,
1454            srcSize,
1455            nbStreams,
1456            oldHufTable,
1457            flags,
1458        );
1459    }
1460    if flags & HUF_flags_suspectUncompressible as core::ffi::c_int != 0
1461        && srcSize
1462            >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO) as size_t
1463    {
1464        let mut largestTotal = 0 as size_t;
1465        let mut maxSymbolValueBegin = maxSymbolValue;
1466        let largestBegin = HIST_count_simple(
1467            ((*table).count).as_mut_ptr(),
1468            &mut maxSymbolValueBegin,
1469            src as *const u8 as *const core::ffi::c_void,
1470            4096,
1471        ) as size_t;
1472        if ERR_isError(largestBegin) {
1473            return largestBegin;
1474        }
1475        largestTotal = largestTotal.wrapping_add(largestBegin);
1476        let mut maxSymbolValueEnd = maxSymbolValue;
1477        let largestEnd = HIST_count_simple(
1478            ((*table).count).as_mut_ptr(),
1479            &mut maxSymbolValueEnd,
1480            (src as *const u8).add(srcSize).offset(-(4096)) as *const core::ffi::c_void,
1481            4096,
1482        ) as size_t;
1483        if ERR_isError(largestEnd) {
1484            return largestEnd;
1485        }
1486        largestTotal = largestTotal.wrapping_add(largestEnd);
1487        if largestTotal <= (((2 * SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) >> 7) + 4) as size_t {
1488            return 0;
1489        }
1490    }
1491    let largest = HIST_count_wksp(
1492        ((*table).count).as_mut_ptr(),
1493        &mut maxSymbolValue,
1494        src as *const u8 as *const core::ffi::c_void,
1495        srcSize,
1496        ((*table).wksps.hist_wksp).as_mut_ptr() as *mut core::ffi::c_void,
1497        ::core::mem::size_of::<[u32; 1024]>(),
1498    );
1499    if ERR_isError(largest) {
1500        return largest;
1501    }
1502    if largest == srcSize {
1503        *ostart = *(src as *const u8).offset(0);
1504        return 1;
1505    }
1506    if largest <= (srcSize >> 7).wrapping_add(4) {
1507        return 0;
1508    }
1509    if !repeat.is_null()
1510        && *repeat as core::ffi::c_uint == HUF_repeat_check as core::ffi::c_int as core::ffi::c_uint
1511        && HUF_validateCTable(oldHufTable, ((*table).count).as_mut_ptr(), maxSymbolValue) == 0
1512    {
1513        *repeat = HUF_repeat_none;
1514    }
1515    if flags & HUF_flags_preferRepeat as core::ffi::c_int != 0
1516        && !repeat.is_null()
1517        && *repeat as core::ffi::c_uint != HUF_repeat_none as core::ffi::c_int as core::ffi::c_uint
1518    {
1519        return HUF_compressCTable_internal(
1520            ostart,
1521            op,
1522            oend,
1523            src,
1524            srcSize,
1525            nbStreams,
1526            oldHufTable,
1527            flags,
1528        );
1529    }
1530    huffLog = HUF_optimalTableLog(
1531        huffLog,
1532        srcSize,
1533        maxSymbolValue,
1534        &mut (*table).wksps as *mut C2RustUnnamed_1 as *mut core::ffi::c_void,
1535        ::core::mem::size_of::<C2RustUnnamed_1>(),
1536        ((*table).CTable).as_mut_ptr(),
1537        ((*table).count).as_mut_ptr(),
1538        flags,
1539    );
1540    let maxBits = HUF_buildCTable_wksp(
1541        ((*table).CTable).as_mut_ptr(),
1542        ((*table).count).as_mut_ptr(),
1543        maxSymbolValue,
1544        huffLog,
1545        &mut (*table).wksps.buildCTable_wksp as *mut HUF_buildCTable_wksp_tables
1546            as *mut core::ffi::c_void,
1547        ::core::mem::size_of::<HUF_buildCTable_wksp_tables>(),
1548    );
1549    let _var_err__ = maxBits;
1550    if ERR_isError(_var_err__) {
1551        return _var_err__;
1552    }
1553    huffLog = maxBits as u32;
1554    let hSize = HUF_writeCTable_wksp(
1555        op as *mut core::ffi::c_void,
1556        dstSize,
1557        ((*table).CTable).as_mut_ptr(),
1558        maxSymbolValue,
1559        huffLog,
1560        &mut (*table).wksps.writeCTable_wksp as *mut HUF_WriteCTableWksp as *mut core::ffi::c_void,
1561        ::core::mem::size_of::<HUF_WriteCTableWksp>(),
1562    );
1563    if ERR_isError(hSize) {
1564        return hSize;
1565    }
1566    if !repeat.is_null()
1567        && *repeat as core::ffi::c_uint != HUF_repeat_none as core::ffi::c_int as core::ffi::c_uint
1568    {
1569        let oldSize =
1570            HUF_estimateCompressedSize(oldHufTable, ((*table).count).as_mut_ptr(), maxSymbolValue);
1571        let newSize = HUF_estimateCompressedSize(
1572            ((*table).CTable).as_mut_ptr(),
1573            ((*table).count).as_mut_ptr(),
1574            maxSymbolValue,
1575        );
1576        if oldSize <= hSize.wrapping_add(newSize) || hSize.wrapping_add(12) >= srcSize {
1577            return HUF_compressCTable_internal(
1578                ostart,
1579                op,
1580                oend,
1581                src,
1582                srcSize,
1583                nbStreams,
1584                oldHufTable,
1585                flags,
1586            );
1587        }
1588    }
1589    if hSize.wrapping_add(12) >= srcSize {
1590        return 0;
1591    }
1592    op = op.add(hSize);
1593    if !repeat.is_null() {
1594        *repeat = HUF_repeat_none;
1595    }
1596    if !oldHufTable.is_null() {
1597        libc::memcpy(
1598            oldHufTable as *mut core::ffi::c_void,
1599            ((*table).CTable).as_mut_ptr() as *const core::ffi::c_void,
1600            ::core::mem::size_of::<[HUF_CElt; 257]>() as core::ffi::c_ulong as libc::size_t,
1601        );
1602    }
1603    HUF_compressCTable_internal(
1604        ostart,
1605        op,
1606        oend,
1607        src,
1608        srcSize,
1609        nbStreams,
1610        ((*table).CTable).as_mut_ptr(),
1611        flags,
1612    )
1613}
1614pub unsafe extern "C" fn HUF_compress1X_repeat(
1615    dst: *mut core::ffi::c_void,
1616    dstSize: size_t,
1617    src: *const core::ffi::c_void,
1618    srcSize: size_t,
1619    maxSymbolValue: core::ffi::c_uint,
1620    huffLog: core::ffi::c_uint,
1621    workSpace: *mut core::ffi::c_void,
1622    wkspSize: size_t,
1623    hufTable: *mut HUF_CElt,
1624    repeat: *mut HUF_repeat,
1625    flags: core::ffi::c_int,
1626) -> size_t {
1627    HUF_compress_internal(
1628        dst,
1629        dstSize,
1630        src,
1631        srcSize,
1632        maxSymbolValue,
1633        huffLog,
1634        HUF_singleStream,
1635        workSpace,
1636        wkspSize,
1637        hufTable,
1638        repeat,
1639        flags,
1640    )
1641}
1642pub unsafe extern "C" fn HUF_compress4X_repeat(
1643    dst: *mut core::ffi::c_void,
1644    dstSize: size_t,
1645    src: *const core::ffi::c_void,
1646    srcSize: size_t,
1647    maxSymbolValue: core::ffi::c_uint,
1648    huffLog: core::ffi::c_uint,
1649    workSpace: *mut core::ffi::c_void,
1650    wkspSize: size_t,
1651    hufTable: *mut HUF_CElt,
1652    repeat: *mut HUF_repeat,
1653    flags: core::ffi::c_int,
1654) -> size_t {
1655    HUF_compress_internal(
1656        dst,
1657        dstSize,
1658        src,
1659        srcSize,
1660        maxSymbolValue,
1661        huffLog,
1662        HUF_fourStreams,
1663        workSpace,
1664        wkspSize,
1665        hufTable,
1666        repeat,
1667        flags,
1668    )
1669}