Skip to main content

libzstd_rs_sys/lib/compress/
zstd_opt.rs

1use core::ptr;
2#[repr(C)]
3pub struct ZSTD_entropyCTables_t {
4    pub huf: ZSTD_hufCTables_t,
5    pub fse: ZSTD_fseCTables_t,
6}
7#[repr(C)]
8pub struct ZSTD_fseCTables_t {
9    pub offcodeCTable: [FSE_CTable; 193],
10    pub matchlengthCTable: [FSE_CTable; 363],
11    pub litlengthCTable: [FSE_CTable; 329],
12    pub offcode_repeatMode: FSE_repeat,
13    pub matchlength_repeatMode: FSE_repeat,
14    pub litlength_repeatMode: FSE_repeat,
15}
16#[repr(C)]
17pub struct ZSTD_hufCTables_t {
18    pub CTable: [HUF_CElt; 257],
19    pub repeatMode: HUF_repeat,
20}
21
22pub type ZSTD_dictMode_e = core::ffi::c_uint;
23pub const ZSTD_dedicatedDictSearch: ZSTD_dictMode_e = 3;
24pub const ZSTD_dictMatchState: ZSTD_dictMode_e = 2;
25pub const ZSTD_extDict: ZSTD_dictMode_e = 1;
26pub const ZSTD_noDict: ZSTD_dictMode_e = 0;
27#[repr(C)]
28pub struct repcodes_s {
29    pub rep: [u32; 3],
30}
31pub type Repcodes_t = repcodes_s;
32pub type ZSTD_getAllMatchesFn = Option<
33    unsafe fn(
34        *mut ZSTD_match_t,
35        &mut ZSTD_MatchState_t,
36        *mut u32,
37        *const u8,
38        *const u8,
39        *const u32,
40        u32,
41        u32,
42    ) -> u32,
43>;
44#[repr(C)]
45pub struct ZSTD_optLdm_t {
46    pub seqStore: RawSeqStore_t,
47    pub startPosInBlock: u32,
48    pub endPosInBlock: u32,
49    pub offset: u32,
50}
51pub type base_directive_e = core::ffi::c_uint;
52pub const base_1guaranteed: base_directive_e = 1;
53pub const base_0possible: base_directive_e = 0;
54
55use libc::size_t;
56
57use crate::lib::common::bits::ZSTD_highbit32;
58use crate::lib::common::fse::{
59    FSE_CState_t, FSE_CTable, FSE_getMaxNbBits, FSE_initCState, FSE_repeat,
60};
61use crate::lib::common::huf::{HUF_CElt, HUF_repeat, HUF_repeat_valid};
62use crate::lib::common::mem::MEM_read32;
63use crate::lib::common::zstd_internal::{
64    LL_bits, ML_bits, MaxLL, MaxLit, MaxML, MaxOff, MINMATCH, ZSTD_OPT_NUM, ZSTD_REP_NUM,
65};
66use crate::lib::compress::hist::HIST_count_simple;
67use crate::lib::compress::huf_compress::HUF_getNbBitsFromCTable;
68use crate::lib::compress::zstd_compress::{
69    optState_t, rawSeq, ParamSwitch, RawSeqStore_t, SeqStore_t, ZSTD_MatchState_t, ZSTD_match_t,
70    ZSTD_optimal_t, ZSTD_resetSeqStore,
71};
72use crate::lib::compress::zstd_compress_internal::{
73    zop_dynamic, zop_predef, ZSTD_count, ZSTD_count_2segments, ZSTD_getLowestMatchIndex,
74    ZSTD_hash3Ptr, ZSTD_hashPtr, ZSTD_index_overlap_check, ZSTD_storeSeq, ZSTD_updateRep,
75};
76use crate::lib::zstd::{ZSTD_compressionParameters, ZSTD_BLOCKSIZE_MAX};
77static mut kNullRawSeqStore: RawSeqStore_t = RawSeqStore_t {
78    seq: core::ptr::null_mut(),
79    pos: 0,
80    posInSequence: 0,
81    size: 0,
82    capacity: 0,
83};
84#[inline]
85unsafe fn ZSTD_LLcode(litLength: u32) -> u32 {
86    static LL_Code: [u8; 64] = [
87        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
88        20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
89        24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
90    ];
91    static LL_deltaCode: u32 = 19;
92    if litLength > 63 {
93        (ZSTD_highbit32(litLength)).wrapping_add(LL_deltaCode)
94    } else {
95        *LL_Code.as_ptr().offset(litLength as isize) as core::ffi::c_uint
96    }
97}
98#[inline]
99unsafe fn ZSTD_MLcode(mlBase: u32) -> u32 {
100    static ML_Code: [u8; 128] = [
101        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
102        25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
103        38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40,
104        40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
105        41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
106        42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
107    ];
108    static ML_deltaCode: u32 = 36;
109    if mlBase > 127 {
110        (ZSTD_highbit32(mlBase)).wrapping_add(ML_deltaCode)
111    } else {
112        *ML_Code.as_ptr().offset(mlBase as isize) as core::ffi::c_uint
113    }
114}
115
116#[inline]
117unsafe fn ZSTD_newRep(rep: *const u32, offBase: u32, ll0: u32) -> Repcodes_t {
118    let mut newReps = repcodes_s { rep: [0; 3] };
119    libc::memcpy(
120        &mut newReps as *mut Repcodes_t as *mut core::ffi::c_void,
121        rep as *const core::ffi::c_void,
122        ::core::mem::size_of::<Repcodes_t>() as core::ffi::c_ulong as libc::size_t,
123    );
124    ZSTD_updateRep((newReps.rep).as_mut_ptr(), offBase, ll0);
125    newReps
126}
127
128pub const UINT_MAX: core::ffi::c_uint = (__INT_MAX__ as core::ffi::c_uint)
129    .wrapping_mul(2)
130    .wrapping_add(1);
131pub const ZSTD_LITFREQ_ADD: core::ffi::c_int = 2;
132pub const ZSTD_MAX_PRICE: core::ffi::c_int = (1) << 30;
133pub const ZSTD_PREDEF_THRESHOLD: core::ffi::c_int = 8;
134pub const BITCOST_ACCURACY: core::ffi::c_int = 8;
135pub const BITCOST_MULTIPLIER: core::ffi::c_int = (1) << BITCOST_ACCURACY;
136#[inline]
137unsafe fn ZSTD_bitWeight(stat: u32) -> u32 {
138    (ZSTD_highbit32(stat.wrapping_add(1))).wrapping_mul(BITCOST_MULTIPLIER as core::ffi::c_uint)
139}
140#[inline]
141unsafe fn ZSTD_fracWeight(rawStat: u32) -> u32 {
142    let stat = rawStat.wrapping_add(1);
143    let hb = ZSTD_highbit32(stat);
144    let BWeight = hb * BITCOST_MULTIPLIER as u32;
145    let FWeight = stat << BITCOST_ACCURACY >> hb;
146
147    BWeight.wrapping_add(FWeight)
148}
149unsafe fn ZSTD_compressedLiterals(optPtr: *const optState_t) -> core::ffi::c_int {
150    ((*optPtr).literalCompressionMode != ParamSwitch::Disable) as core::ffi::c_int
151}
152unsafe fn ZSTD_setBasePrices(optPtr: *mut optState_t, optLevel: core::ffi::c_int) {
153    if ZSTD_compressedLiterals(optPtr) != 0 {
154        (*optPtr).litSumBasePrice = if optLevel != 0 {
155            ZSTD_fracWeight((*optPtr).litSum)
156        } else {
157            ZSTD_bitWeight((*optPtr).litSum)
158        };
159    }
160    (*optPtr).litLengthSumBasePrice = if optLevel != 0 {
161        ZSTD_fracWeight((*optPtr).litLengthSum)
162    } else {
163        ZSTD_bitWeight((*optPtr).litLengthSum)
164    };
165    (*optPtr).matchLengthSumBasePrice = if optLevel != 0 {
166        ZSTD_fracWeight((*optPtr).matchLengthSum)
167    } else {
168        ZSTD_bitWeight((*optPtr).matchLengthSum)
169    };
170    (*optPtr).offCodeSumBasePrice = if optLevel != 0 {
171        ZSTD_fracWeight((*optPtr).offCodeSum)
172    } else {
173        ZSTD_bitWeight((*optPtr).offCodeSum)
174    };
175}
176unsafe fn sum_u32(table: *const core::ffi::c_uint, nbElts: size_t) -> u32 {
177    let mut n: size_t = 0;
178    let mut total = 0;
179    n = 0;
180    while n < nbElts {
181        total = (total as core::ffi::c_uint).wrapping_add(*table.add(n)) as u32 as u32;
182        n = n.wrapping_add(1);
183    }
184    total
185}
186unsafe fn ZSTD_downscaleStats(
187    table: *mut core::ffi::c_uint,
188    lastEltIndex: u32,
189    shift: u32,
190    base1: base_directive_e,
191) -> u32 {
192    let mut s: u32 = 0;
193    let mut sum = 0;
194    s = 0;
195    while s < lastEltIndex.wrapping_add(1) {
196        let base = (if base1 as core::ffi::c_uint != 0 {
197            1
198        } else {
199            (*table.offset(s as isize) > 0) as core::ffi::c_int
200        }) as core::ffi::c_uint;
201        let newStat = base.wrapping_add(*table.offset(s as isize) >> shift);
202        sum = (sum as core::ffi::c_uint).wrapping_add(newStat);
203        *table.offset(s as isize) = newStat;
204        s = s.wrapping_add(1);
205    }
206    sum
207}
208unsafe fn ZSTD_scaleStats(table: *mut core::ffi::c_uint, lastEltIndex: u32, logTarget: u32) -> u32 {
209    let prevsum = sum_u32(
210        table as *const core::ffi::c_uint,
211        lastEltIndex.wrapping_add(1) as size_t,
212    );
213    let factor = prevsum >> logTarget;
214    if factor <= 1 {
215        return prevsum;
216    }
217    ZSTD_downscaleStats(
218        table,
219        lastEltIndex,
220        ZSTD_highbit32(factor),
221        base_1guaranteed,
222    )
223}
224unsafe fn ZSTD_rescaleFreqs(
225    optPtr: *mut optState_t,
226    src: *const u8,
227    srcSize: size_t,
228    optLevel: core::ffi::c_int,
229) {
230    let compressedLiterals = ZSTD_compressedLiterals(optPtr);
231    (*optPtr).priceType = zop_dynamic;
232    if (*optPtr).litLengthSum == 0 {
233        if srcSize <= ZSTD_PREDEF_THRESHOLD as size_t {
234            (*optPtr).priceType = zop_predef;
235        }
236        if (*(*optPtr).symbolCosts).huf.repeatMode as core::ffi::c_uint
237            == HUF_repeat_valid as core::ffi::c_int as core::ffi::c_uint
238        {
239            (*optPtr).priceType = zop_dynamic;
240            if compressedLiterals != 0 {
241                let mut lit: core::ffi::c_uint = 0;
242                (*optPtr).litSum = 0;
243                lit = 0;
244                while lit <= MaxLit {
245                    let scaleLog = 11u32;
246                    let bitCost = HUF_getNbBitsFromCTable(
247                        ((*(*optPtr).symbolCosts).huf.CTable).as_ptr(),
248                        lit,
249                    );
250                    *((*optPtr).litFreq).offset(lit as isize) = (if bitCost != 0 {
251                        (1) << scaleLog.wrapping_sub(bitCost)
252                    } else {
253                        1
254                    })
255                        as core::ffi::c_uint;
256                    (*optPtr).litSum = ((*optPtr).litSum as core::ffi::c_uint)
257                        .wrapping_add(*((*optPtr).litFreq).offset(lit as isize))
258                        as u32 as u32;
259                    lit = lit.wrapping_add(1);
260                }
261            }
262            let mut ll: core::ffi::c_uint = 0;
263            let mut llstate = FSE_CState_t {
264                value: 0,
265                stateTable: core::ptr::null::<core::ffi::c_void>(),
266                symbolTT: core::ptr::null::<core::ffi::c_void>(),
267                stateLog: 0,
268            };
269            FSE_initCState(
270                &mut llstate,
271                ((*(*optPtr).symbolCosts).fse.litlengthCTable).as_ptr(),
272            );
273            (*optPtr).litLengthSum = 0;
274            ll = 0;
275            while ll <= MaxLL {
276                let scaleLog_0 = 10u32;
277                let bitCost_0 = FSE_getMaxNbBits(llstate.symbolTT, ll);
278                *((*optPtr).litLengthFreq).offset(ll as isize) = (if bitCost_0 != 0 {
279                    (1) << scaleLog_0.wrapping_sub(bitCost_0)
280                } else {
281                    1
282                })
283                    as core::ffi::c_uint;
284                (*optPtr).litLengthSum = ((*optPtr).litLengthSum as core::ffi::c_uint)
285                    .wrapping_add(*((*optPtr).litLengthFreq).offset(ll as isize))
286                    as u32 as u32;
287                ll = ll.wrapping_add(1);
288            }
289            let mut ml: core::ffi::c_uint = 0;
290            let mut mlstate = FSE_CState_t {
291                value: 0,
292                stateTable: core::ptr::null::<core::ffi::c_void>(),
293                symbolTT: core::ptr::null::<core::ffi::c_void>(),
294                stateLog: 0,
295            };
296            FSE_initCState(
297                &mut mlstate,
298                ((*(*optPtr).symbolCosts).fse.matchlengthCTable).as_ptr(),
299            );
300            (*optPtr).matchLengthSum = 0;
301            ml = 0;
302            while ml <= MaxML {
303                let scaleLog_1 = 10u32;
304                let bitCost_1 = FSE_getMaxNbBits(mlstate.symbolTT, ml);
305                *((*optPtr).matchLengthFreq).offset(ml as isize) = (if bitCost_1 != 0 {
306                    (1) << scaleLog_1.wrapping_sub(bitCost_1)
307                } else {
308                    1
309                })
310                    as core::ffi::c_uint;
311                (*optPtr).matchLengthSum = ((*optPtr).matchLengthSum as core::ffi::c_uint)
312                    .wrapping_add(*((*optPtr).matchLengthFreq).offset(ml as isize))
313                    as u32 as u32;
314                ml = ml.wrapping_add(1);
315            }
316            let mut of: core::ffi::c_uint = 0;
317            let mut ofstate = FSE_CState_t {
318                value: 0,
319                stateTable: core::ptr::null::<core::ffi::c_void>(),
320                symbolTT: core::ptr::null::<core::ffi::c_void>(),
321                stateLog: 0,
322            };
323            FSE_initCState(
324                &mut ofstate,
325                ((*(*optPtr).symbolCosts).fse.offcodeCTable).as_ptr(),
326            );
327            (*optPtr).offCodeSum = 0;
328            of = 0;
329            while of <= MaxOff {
330                let scaleLog_2 = 10u32;
331                let bitCost_2 = FSE_getMaxNbBits(ofstate.symbolTT, of);
332                *((*optPtr).offCodeFreq).offset(of as isize) = (if bitCost_2 != 0 {
333                    (1) << scaleLog_2.wrapping_sub(bitCost_2)
334                } else {
335                    1
336                })
337                    as core::ffi::c_uint;
338                (*optPtr).offCodeSum = ((*optPtr).offCodeSum as core::ffi::c_uint)
339                    .wrapping_add(*((*optPtr).offCodeFreq).offset(of as isize))
340                    as u32;
341                of = of.wrapping_add(1);
342            }
343        } else {
344            if compressedLiterals != 0 {
345                let mut lit_0 = MaxLit;
346                HIST_count_simple(
347                    (*optPtr).litFreq,
348                    &mut lit_0,
349                    src as *const core::ffi::c_void,
350                    srcSize,
351                );
352                (*optPtr).litSum =
353                    ZSTD_downscaleStats((*optPtr).litFreq, MaxLit, 8, base_0possible);
354            }
355            let baseLLfreqs: [core::ffi::c_uint; 36] = [
356                4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
357                1, 1, 1, 1, 1, 1, 1, 1,
358            ];
359            libc::memcpy(
360                (*optPtr).litLengthFreq as *mut core::ffi::c_void,
361                baseLLfreqs.as_ptr() as *const core::ffi::c_void,
362                ::core::mem::size_of::<[core::ffi::c_uint; 36]>() as core::ffi::c_ulong
363                    as libc::size_t,
364            );
365            (*optPtr).litLengthSum = sum_u32(baseLLfreqs.as_ptr(), (MaxLL + 1) as size_t);
366            let mut ml_0: core::ffi::c_uint = 0;
367            ml_0 = 0;
368            while ml_0 <= MaxML {
369                *((*optPtr).matchLengthFreq).offset(ml_0 as isize) = 1;
370                ml_0 = ml_0.wrapping_add(1);
371            }
372            (*optPtr).matchLengthSum = MaxML + 1;
373            let baseOFCfreqs: [core::ffi::c_uint; 32] = [
374                6, 2, 1, 1, 2, 3, 4, 4, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
375                1, 1, 1, 1,
376            ];
377            libc::memcpy(
378                (*optPtr).offCodeFreq as *mut core::ffi::c_void,
379                baseOFCfreqs.as_ptr() as *const core::ffi::c_void,
380                ::core::mem::size_of::<[core::ffi::c_uint; 32]>() as core::ffi::c_ulong
381                    as libc::size_t,
382            );
383            (*optPtr).offCodeSum = sum_u32(baseOFCfreqs.as_ptr(), (MaxOff + 1) as size_t);
384        }
385    } else {
386        if compressedLiterals != 0 {
387            (*optPtr).litSum = ZSTD_scaleStats((*optPtr).litFreq, MaxLit, 12);
388        }
389        (*optPtr).litLengthSum = ZSTD_scaleStats((*optPtr).litLengthFreq, MaxLL, 11);
390        (*optPtr).matchLengthSum = ZSTD_scaleStats((*optPtr).matchLengthFreq, MaxML, 11);
391        (*optPtr).offCodeSum = ZSTD_scaleStats((*optPtr).offCodeFreq, MaxOff, 11);
392    }
393    ZSTD_setBasePrices(optPtr, optLevel);
394}
395unsafe fn ZSTD_rawLiteralsCost(
396    literals: *const u8,
397    litLength: u32,
398    optPtr: *const optState_t,
399    optLevel: core::ffi::c_int,
400) -> u32 {
401    if litLength == 0 {
402        return 0;
403    }
404    if ZSTD_compressedLiterals(optPtr) == 0 {
405        return (litLength << 3) * BITCOST_MULTIPLIER as u32;
406    }
407    if (*optPtr).priceType == zop_predef {
408        return litLength * 6 * BITCOST_MULTIPLIER as u32;
409    }
410    let mut price = (*optPtr).litSumBasePrice * litLength;
411    let litPriceMax = ((*optPtr).litSumBasePrice).wrapping_sub(BITCOST_MULTIPLIER as u32);
412    let mut u: u32 = 0;
413    u = 0;
414    while u < litLength {
415        let mut litPrice = if optLevel != 0 {
416            ZSTD_fracWeight(*((*optPtr).litFreq).offset(*literals.offset(u as isize) as isize))
417        } else {
418            ZSTD_bitWeight(*((*optPtr).litFreq).offset(*literals.offset(u as isize) as isize))
419        };
420        if litPrice > litPriceMax {
421            litPrice = litPriceMax;
422        }
423        price = price.wrapping_sub(litPrice);
424        u = u.wrapping_add(1);
425    }
426    price
427}
428unsafe fn ZSTD_litLengthPrice(
429    litLength: u32,
430    optPtr: *const optState_t,
431    optLevel: core::ffi::c_int,
432) -> u32 {
433    if (*optPtr).priceType == zop_predef {
434        return if optLevel != 0 {
435            ZSTD_fracWeight(litLength)
436        } else {
437            ZSTD_bitWeight(litLength)
438        };
439    }
440    if litLength == ZSTD_BLOCKSIZE_MAX as u32 {
441        return (BITCOST_MULTIPLIER as u32).wrapping_add(ZSTD_litLengthPrice(
442            (ZSTD_BLOCKSIZE_MAX - 1) as u32,
443            optPtr,
444            optLevel,
445        ));
446    }
447    let llCode = ZSTD_LLcode(litLength);
448    ((*LL_bits.as_ptr().offset(llCode as isize) as core::ffi::c_int * BITCOST_MULTIPLIER) as u32)
449        .wrapping_add((*optPtr).litLengthSumBasePrice)
450        .wrapping_sub(if optLevel != 0 {
451            ZSTD_fracWeight(*((*optPtr).litLengthFreq).offset(llCode as isize))
452        } else {
453            ZSTD_bitWeight(*((*optPtr).litLengthFreq).offset(llCode as isize))
454        })
455}
456#[inline(always)]
457unsafe fn ZSTD_getMatchPrice(
458    offBase: u32,
459    matchLength: u32,
460    optPtr: *const optState_t,
461    optLevel: core::ffi::c_int,
462) -> u32 {
463    let mut price: u32 = 0;
464    let offCode = ZSTD_highbit32(offBase);
465    let mlBase = matchLength.wrapping_sub(MINMATCH as u32);
466    if (*optPtr).priceType == zop_predef {
467        return (if optLevel != 0 {
468            ZSTD_fracWeight(mlBase)
469        } else {
470            ZSTD_bitWeight(mlBase)
471        })
472        .wrapping_add(16u32.wrapping_add(offCode) * BITCOST_MULTIPLIER as u32);
473    }
474    price = (offCode * BITCOST_MULTIPLIER as u32).wrapping_add(
475        ((*optPtr).offCodeSumBasePrice).wrapping_sub(if optLevel != 0 {
476            ZSTD_fracWeight(*((*optPtr).offCodeFreq).offset(offCode as isize))
477        } else {
478            ZSTD_bitWeight(*((*optPtr).offCodeFreq).offset(offCode as isize))
479        }),
480    );
481    if optLevel < 2 && offCode >= 20 {
482        price = price.wrapping_add(offCode.wrapping_sub(19) * 2 * BITCOST_MULTIPLIER as u32);
483    }
484    let mlCode = ZSTD_MLcode(mlBase);
485    price = price.wrapping_add(
486        ((*ML_bits.as_ptr().offset(mlCode as isize) as core::ffi::c_int * BITCOST_MULTIPLIER)
487            as u32)
488            .wrapping_add(
489                ((*optPtr).matchLengthSumBasePrice).wrapping_sub(if optLevel != 0 {
490                    ZSTD_fracWeight(*((*optPtr).matchLengthFreq).offset(mlCode as isize))
491                } else {
492                    ZSTD_bitWeight(*((*optPtr).matchLengthFreq).offset(mlCode as isize))
493                }),
494            ),
495    );
496    price = price.wrapping_add((BITCOST_MULTIPLIER / 5) as u32);
497    price
498}
499unsafe fn ZSTD_updateStats(
500    optPtr: *mut optState_t,
501    litLength: u32,
502    literals: *const u8,
503    offBase: u32,
504    matchLength: u32,
505) {
506    if ZSTD_compressedLiterals(optPtr) != 0 {
507        let mut u: u32 = 0;
508        u = 0;
509        while u < litLength {
510            let fresh2 = &mut (*((*optPtr).litFreq).offset(*literals.offset(u as isize) as isize));
511            *fresh2 = (*fresh2).wrapping_add(ZSTD_LITFREQ_ADD as core::ffi::c_uint);
512            u = u.wrapping_add(1);
513        }
514        (*optPtr).litSum = ((*optPtr).litSum).wrapping_add(litLength * ZSTD_LITFREQ_ADD as u32);
515    }
516    let llCode = ZSTD_LLcode(litLength);
517    let fresh3 = &mut (*((*optPtr).litLengthFreq).offset(llCode as isize));
518    *fresh3 = (*fresh3).wrapping_add(1);
519    (*optPtr).litLengthSum = ((*optPtr).litLengthSum).wrapping_add(1);
520    let offCode = ZSTD_highbit32(offBase);
521    let fresh4 = &mut (*((*optPtr).offCodeFreq).offset(offCode as isize));
522    *fresh4 = (*fresh4).wrapping_add(1);
523    (*optPtr).offCodeSum = ((*optPtr).offCodeSum).wrapping_add(1);
524    let mlBase = matchLength.wrapping_sub(MINMATCH as u32);
525    let mlCode = ZSTD_MLcode(mlBase);
526    let fresh5 = &mut (*((*optPtr).matchLengthFreq).offset(mlCode as isize));
527    *fresh5 = (*fresh5).wrapping_add(1);
528    (*optPtr).matchLengthSum = ((*optPtr).matchLengthSum).wrapping_add(1);
529}
530#[inline]
531unsafe fn ZSTD_readMINMATCH(memPtr: *const core::ffi::c_void, length: u32) -> u32 {
532    match length {
533        3 => {
534            if cfg!(target_endian = "little") {
535                MEM_read32(memPtr) << 8
536            } else {
537                MEM_read32(memPtr) >> 8
538            }
539        }
540        4 | _ => MEM_read32(memPtr),
541    }
542}
543unsafe fn ZSTD_insertAndFindFirstIndexHash3(
544    ms: *const ZSTD_MatchState_t,
545    nextToUpdate3: *mut u32,
546    ip: *const u8,
547) -> u32 {
548    let hashTable3 = (*ms).hashTable3;
549    let hashLog3 = (*ms).hashLog3;
550    let base = (*ms).window.base;
551    let mut idx = *nextToUpdate3;
552    let target = ip.offset_from(base) as core::ffi::c_long as u32;
553    let hash3 = ZSTD_hash3Ptr(ip as *const core::ffi::c_void, hashLog3);
554    while idx < target {
555        *hashTable3.add(ZSTD_hash3Ptr(
556            base.offset(idx as isize) as *const core::ffi::c_void,
557            hashLog3,
558        )) = idx;
559        idx = idx.wrapping_add(1);
560    }
561    *nextToUpdate3 = target;
562    *hashTable3.add(hash3)
563}
564unsafe fn ZSTD_insertBt1(
565    ms: *const ZSTD_MatchState_t,
566    ip: *const u8,
567    iend: *const u8,
568    target: u32,
569    mls: u32,
570    extDict: core::ffi::c_int,
571) -> u32 {
572    let cParams: *const ZSTD_compressionParameters = &(*ms).cParams;
573    let hashTable = (*ms).hashTable;
574    let hashLog = (*cParams).hashLog;
575    let h = ZSTD_hashPtr(ip as *const core::ffi::c_void, hashLog, mls);
576    let bt = (*ms).chainTable;
577    let btLog = ((*cParams).chainLog).wrapping_sub(1);
578    let btMask = (((1) << btLog) - 1) as u32;
579    let mut matchIndex = *hashTable.add(h);
580    let mut commonLengthSmaller = 0;
581    let mut commonLengthLarger = 0;
582    let base = (*ms).window.base;
583    let dictBase = (*ms).window.dictBase;
584    let dictLimit = (*ms).window.dictLimit;
585    let dictEnd = dictBase.offset(dictLimit as isize);
586    let prefixStart = base.offset(dictLimit as isize);
587    let mut match_0 = core::ptr::null::<u8>();
588    let curr = ip.offset_from(base) as core::ffi::c_long as u32;
589    let btLow = if btMask >= curr {
590        0
591    } else {
592        curr.wrapping_sub(btMask)
593    };
594    let mut smallerPtr = bt.offset((2 * (curr & btMask)) as isize);
595    let mut largerPtr = smallerPtr.add(1);
596    let mut dummy32: u32 = 0;
597    let windowLow = ZSTD_getLowestMatchIndex(ms, target, (*cParams).windowLog);
598    let mut matchEndIdx = curr.wrapping_add(8).wrapping_add(1);
599    let mut bestLength = 8;
600    let mut nbCompares = (1 as core::ffi::c_uint) << (*cParams).searchLog;
601    *hashTable.add(h) = curr;
602    while nbCompares != 0 && matchIndex >= windowLow {
603        let nextPtr = bt.offset((2 * (matchIndex & btMask)) as isize);
604        let mut matchLength = if commonLengthSmaller < commonLengthLarger {
605            commonLengthSmaller
606        } else {
607            commonLengthLarger
608        };
609        if extDict == 0 || (matchIndex as size_t).wrapping_add(matchLength) >= dictLimit as size_t {
610            match_0 = base.offset(matchIndex as isize);
611            matchLength = matchLength.wrapping_add(ZSTD_count(
612                ip.add(matchLength),
613                match_0.add(matchLength),
614                iend,
615            ));
616        } else {
617            match_0 = dictBase.offset(matchIndex as isize);
618            matchLength = matchLength.wrapping_add(ZSTD_count_2segments(
619                ip.add(matchLength),
620                match_0.add(matchLength),
621                iend,
622                dictEnd,
623                prefixStart,
624            ));
625            if (matchIndex as size_t).wrapping_add(matchLength) >= dictLimit as size_t {
626                match_0 = base.offset(matchIndex as isize);
627            }
628        }
629        if matchLength > bestLength {
630            bestLength = matchLength;
631            if matchLength > matchEndIdx.wrapping_sub(matchIndex) as size_t {
632                matchEndIdx = matchIndex.wrapping_add(matchLength as u32);
633            }
634        }
635        if ip.add(matchLength) == iend {
636            break;
637        } else {
638            if (*match_0.add(matchLength) as core::ffi::c_int)
639                < *ip.add(matchLength) as core::ffi::c_int
640            {
641                *smallerPtr = matchIndex;
642                commonLengthSmaller = matchLength;
643                if matchIndex <= btLow {
644                    smallerPtr = &mut dummy32;
645                    break;
646                } else {
647                    smallerPtr = nextPtr.add(1);
648                    matchIndex = *nextPtr.add(1);
649                }
650            } else {
651                *largerPtr = matchIndex;
652                commonLengthLarger = matchLength;
653                if matchIndex <= btLow {
654                    largerPtr = &mut dummy32;
655                    break;
656                } else {
657                    largerPtr = nextPtr;
658                    matchIndex = *nextPtr;
659                }
660            }
661            nbCompares = nbCompares.wrapping_sub(1);
662        }
663    }
664    *largerPtr = 0;
665    *smallerPtr = *largerPtr;
666    let mut positions = 0;
667    if bestLength > 384 {
668        positions = if (192) < bestLength.wrapping_sub(384) as u32 {
669            192
670        } else {
671            bestLength.wrapping_sub(384) as u32
672        };
673    }
674    if positions > matchEndIdx.wrapping_sub(curr.wrapping_add(8)) {
675        positions
676    } else {
677        matchEndIdx.wrapping_sub(curr.wrapping_add(8))
678    }
679}
680#[inline(always)]
681unsafe fn ZSTD_updateTree_internal(
682    ms: &mut ZSTD_MatchState_t,
683    ip: *const u8,
684    iend: *const u8,
685    mls: u32,
686    dictMode: ZSTD_dictMode_e,
687) {
688    let base = ms.window.base;
689    let target = ip.offset_from(base) as core::ffi::c_long as u32;
690    let mut idx = ms.nextToUpdate;
691    while idx < target {
692        let forward = ZSTD_insertBt1(
693            ms,
694            base.offset(idx as isize),
695            iend,
696            target,
697            mls,
698            (dictMode as core::ffi::c_uint == ZSTD_extDict as core::ffi::c_int as core::ffi::c_uint)
699                as core::ffi::c_int,
700        );
701        idx = idx.wrapping_add(forward);
702    }
703    ms.nextToUpdate = target;
704}
705pub unsafe fn ZSTD_updateTree(ms: &mut ZSTD_MatchState_t, ip: *const u8, iend: *const u8) {
706    ZSTD_updateTree_internal(ms, ip, iend, ms.cParams.minMatch, ZSTD_noDict);
707}
708#[inline(always)]
709unsafe fn ZSTD_insertBtAndGetAllMatches(
710    matches: *mut ZSTD_match_t,
711    ms: &mut ZSTD_MatchState_t,
712    nextToUpdate3: *mut u32,
713    ip: *const u8,
714    iLimit: *const u8,
715    dictMode: ZSTD_dictMode_e,
716    rep: *const u32,
717    ll0: u32,
718    lengthToBeat: u32,
719    mls: u32,
720) -> u32 {
721    let cParams: *const ZSTD_compressionParameters = &mut ms.cParams;
722    let sufficient_len = if (*cParams).targetLength < (((1) << 12) - 1) as core::ffi::c_uint {
723        (*cParams).targetLength
724    } else {
725        (((1) << 12) - 1) as core::ffi::c_uint
726    };
727    let base = ms.window.base;
728    let curr = ip.offset_from(base) as core::ffi::c_long as u32;
729    let hashLog = (*cParams).hashLog;
730    let minMatch = (if mls == 3 { 3 } else { 4 }) as u32;
731    let hashTable = ms.hashTable;
732    let h = ZSTD_hashPtr(ip as *const core::ffi::c_void, hashLog, mls);
733    let mut matchIndex = *hashTable.add(h);
734    let bt = ms.chainTable;
735    let btLog = ((*cParams).chainLog).wrapping_sub(1 as core::ffi::c_uint);
736    let btMask = ((1 as core::ffi::c_uint) << btLog).wrapping_sub(1);
737    let mut commonLengthSmaller = 0;
738    let mut commonLengthLarger = 0;
739    let dictBase = ms.window.dictBase;
740    let dictLimit = ms.window.dictLimit;
741    let dictEnd = dictBase.offset(dictLimit as isize);
742    let prefixStart = base.offset(dictLimit as isize);
743    let btLow = if btMask >= curr {
744        0
745    } else {
746        curr.wrapping_sub(btMask)
747    };
748    let windowLow = ZSTD_getLowestMatchIndex(ms, curr, (*cParams).windowLog);
749    let matchLow = if windowLow != 0 { windowLow } else { 1 };
750    let mut smallerPtr = bt.offset((2 * (curr & btMask)) as isize);
751    let mut largerPtr = bt.offset((2 * (curr & btMask)) as isize).add(1);
752    let mut matchEndIdx = curr.wrapping_add(8).wrapping_add(1);
753    let mut dummy32: u32 = 0;
754    let mut mnum = 0u32;
755    let mut nbCompares = (1 as core::ffi::c_uint) << (*cParams).searchLog;
756    let dms = if dictMode as core::ffi::c_uint
757        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
758    {
759        ms.dictMatchState
760    } else {
761        core::ptr::null()
762    };
763    let dmsCParams = if dictMode as core::ffi::c_uint
764        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
765    {
766        &(*dms).cParams
767    } else {
768        core::ptr::null()
769    };
770    let dmsBase = if dictMode as core::ffi::c_uint
771        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
772    {
773        (*dms).window.base
774    } else {
775        core::ptr::null()
776    };
777    let dmsEnd = if dictMode as core::ffi::c_uint
778        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
779    {
780        (*dms).window.nextSrc
781    } else {
782        core::ptr::null()
783    };
784    let dmsHighLimit = if dictMode as core::ffi::c_uint
785        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
786    {
787        dmsEnd.offset_from(dmsBase) as core::ffi::c_long as u32
788    } else {
789        0
790    };
791    let dmsLowLimit = if dictMode as core::ffi::c_uint
792        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
793    {
794        (*dms).window.lowLimit
795    } else {
796        0
797    };
798    let dmsIndexDelta = if dictMode as core::ffi::c_uint
799        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
800    {
801        windowLow.wrapping_sub(dmsHighLimit)
802    } else {
803        0
804    };
805    let dmsHashLog = if dictMode as core::ffi::c_uint
806        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
807    {
808        (*dmsCParams).hashLog
809    } else {
810        hashLog
811    };
812    let dmsBtLog = if dictMode as core::ffi::c_uint
813        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
814    {
815        ((*dmsCParams).chainLog).wrapping_sub(1)
816    } else {
817        btLog
818    };
819    let dmsBtMask = if dictMode as core::ffi::c_uint
820        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
821    {
822        ((1 as core::ffi::c_uint) << dmsBtLog).wrapping_sub(1)
823    } else {
824        0
825    };
826    let dmsBtLow = if dictMode as core::ffi::c_uint
827        == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
828        && dmsBtMask < dmsHighLimit.wrapping_sub(dmsLowLimit)
829    {
830        dmsHighLimit.wrapping_sub(dmsBtMask)
831    } else {
832        dmsLowLimit
833    };
834    let mut bestLength = lengthToBeat.wrapping_sub(1) as size_t;
835    let lastR = (ZSTD_REP_NUM as u32).wrapping_add(ll0);
836    let mut repCode: u32 = 0;
837    repCode = ll0;
838    while repCode < lastR {
839        let repOffset = if repCode == ZSTD_REP_NUM as u32 {
840            (*rep).wrapping_sub(1)
841        } else {
842            *rep.offset(repCode as isize)
843        };
844        let repIndex = curr.wrapping_sub(repOffset);
845        let mut repLen = 0;
846        if repOffset.wrapping_sub(1) < curr.wrapping_sub(dictLimit) {
847            if (repIndex >= windowLow) as core::ffi::c_int
848                & (ZSTD_readMINMATCH(ip as *const core::ffi::c_void, minMatch)
849                    == ZSTD_readMINMATCH(
850                        ip.offset(-(repOffset as isize)) as *const core::ffi::c_void,
851                        minMatch,
852                    )) as core::ffi::c_int
853                != 0
854            {
855                repLen = (ZSTD_count(
856                    ip.offset(minMatch as isize),
857                    ip.offset(minMatch as isize).offset(-(repOffset as isize)),
858                    iLimit,
859                ) as u32)
860                    .wrapping_add(minMatch);
861            }
862        } else {
863            let repMatch = if dictMode as core::ffi::c_uint
864                == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
865            {
866                dmsBase
867                    .offset(repIndex as isize)
868                    .offset(-(dmsIndexDelta as isize))
869            } else {
870                dictBase.offset(repIndex as isize)
871            };
872            if dictMode as core::ffi::c_uint
873                == ZSTD_extDict as core::ffi::c_int as core::ffi::c_uint
874                && (repOffset.wrapping_sub(1) < curr.wrapping_sub(windowLow)) as core::ffi::c_int
875                    & ZSTD_index_overlap_check(dictLimit, repIndex)
876                    != 0
877                && ZSTD_readMINMATCH(ip as *const core::ffi::c_void, minMatch)
878                    == ZSTD_readMINMATCH(repMatch as *const core::ffi::c_void, minMatch)
879            {
880                repLen = (ZSTD_count_2segments(
881                    ip.offset(minMatch as isize),
882                    repMatch.offset(minMatch as isize),
883                    iLimit,
884                    dictEnd,
885                    prefixStart,
886                ) as u32)
887                    .wrapping_add(minMatch);
888            }
889            if dictMode as core::ffi::c_uint
890                == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
891                && (repOffset.wrapping_sub(1)
892                    < curr.wrapping_sub(dmsLowLimit.wrapping_add(dmsIndexDelta)))
893                    as core::ffi::c_int
894                    & ZSTD_index_overlap_check(dictLimit, repIndex)
895                    != 0
896                && ZSTD_readMINMATCH(ip as *const core::ffi::c_void, minMatch)
897                    == ZSTD_readMINMATCH(repMatch as *const core::ffi::c_void, minMatch)
898            {
899                repLen = (ZSTD_count_2segments(
900                    ip.offset(minMatch as isize),
901                    repMatch.offset(minMatch as isize),
902                    iLimit,
903                    dmsEnd,
904                    prefixStart,
905                ) as u32)
906                    .wrapping_add(minMatch);
907            }
908        }
909        if repLen as size_t > bestLength {
910            bestLength = repLen as size_t;
911            (*matches.offset(mnum as isize)).off = repCode.wrapping_sub(ll0).wrapping_add(1);
912            (*matches.offset(mnum as isize)).len = repLen;
913            mnum = mnum.wrapping_add(1);
914            if (repLen > sufficient_len) as core::ffi::c_int
915                | (ip.offset(repLen as isize) == iLimit) as core::ffi::c_int
916                != 0
917            {
918                return mnum;
919            }
920        }
921        repCode = repCode.wrapping_add(1);
922    }
923    if mls == 3 && bestLength < mls as size_t {
924        let matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
925        if (matchIndex3 >= matchLow) as core::ffi::c_int
926            & (curr.wrapping_sub(matchIndex3) < ((1) << 18) as u32) as core::ffi::c_int
927            != 0
928        {
929            let mut mlen: size_t = 0;
930            if dictMode as core::ffi::c_uint == ZSTD_noDict as core::ffi::c_int as core::ffi::c_uint
931                || dictMode as core::ffi::c_uint
932                    == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
933                || matchIndex3 >= dictLimit
934            {
935                let match_0 = base.offset(matchIndex3 as isize);
936                mlen = ZSTD_count(ip, match_0, iLimit);
937            } else {
938                let match_1 = dictBase.offset(matchIndex3 as isize);
939                mlen = ZSTD_count_2segments(ip, match_1, iLimit, dictEnd, prefixStart);
940            }
941            if mlen >= mls as size_t {
942                bestLength = mlen;
943                (*matches).off = curr
944                    .wrapping_sub(matchIndex3)
945                    .wrapping_add(ZSTD_REP_NUM as u32);
946                (*matches).len = mlen as u32;
947                mnum = 1;
948                if (mlen > sufficient_len as size_t) as core::ffi::c_int
949                    | (ip.add(mlen) == iLimit) as core::ffi::c_int
950                    != 0
951                {
952                    ms.nextToUpdate = curr.wrapping_add(1);
953                    return 1;
954                }
955            }
956        }
957    }
958    *hashTable.add(h) = curr;
959    while nbCompares != 0 && matchIndex >= matchLow {
960        let nextPtr = bt.offset((2 * (matchIndex & btMask)) as isize);
961        let mut match_2 = core::ptr::null::<u8>();
962        let mut matchLength = if commonLengthSmaller < commonLengthLarger {
963            commonLengthSmaller
964        } else {
965            commonLengthLarger
966        };
967        if dictMode as core::ffi::c_uint == ZSTD_noDict as core::ffi::c_int as core::ffi::c_uint
968            || dictMode as core::ffi::c_uint
969                == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
970            || (matchIndex as size_t).wrapping_add(matchLength) >= dictLimit as size_t
971        {
972            match_2 = base.offset(matchIndex as isize);
973            if matchIndex >= dictLimit {
974                debug_assert!(libc::memcmp(match_2.cast(), ip.cast(), matchLength) == 0);
975                /* ensure early section of match is equal as expected */
976            }
977            matchLength = matchLength.wrapping_add(ZSTD_count(
978                ip.add(matchLength),
979                match_2.add(matchLength),
980                iLimit,
981            ));
982        } else {
983            match_2 = dictBase.offset(matchIndex as isize);
984            matchLength = matchLength.wrapping_add(ZSTD_count_2segments(
985                ip.add(matchLength),
986                match_2.add(matchLength),
987                iLimit,
988                dictEnd,
989                prefixStart,
990            ));
991            if (matchIndex as size_t).wrapping_add(matchLength) >= dictLimit as size_t {
992                match_2 = base.offset(matchIndex as isize);
993            }
994        }
995        if matchLength > bestLength {
996            if matchLength > matchEndIdx.wrapping_sub(matchIndex) as size_t {
997                matchEndIdx = matchIndex.wrapping_add(matchLength as u32);
998            }
999            bestLength = matchLength;
1000            (*matches.offset(mnum as isize)).off = curr
1001                .wrapping_sub(matchIndex)
1002                .wrapping_add(ZSTD_REP_NUM as u32);
1003            (*matches.offset(mnum as isize)).len = matchLength as u32;
1004            mnum = mnum.wrapping_add(1);
1005            if (matchLength > ZSTD_OPT_NUM as size_t) as core::ffi::c_int
1006                | (ip.add(matchLength) == iLimit) as core::ffi::c_int
1007                != 0
1008            {
1009                if dictMode as core::ffi::c_uint
1010                    == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
1011                {
1012                    nbCompares = 0;
1013                }
1014                break;
1015            }
1016        }
1017        if (*match_2.add(matchLength) as core::ffi::c_int)
1018            < *ip.add(matchLength) as core::ffi::c_int
1019        {
1020            *smallerPtr = matchIndex;
1021            commonLengthSmaller = matchLength;
1022            if matchIndex <= btLow {
1023                smallerPtr = &mut dummy32;
1024                break;
1025            } else {
1026                smallerPtr = nextPtr.add(1);
1027                matchIndex = *nextPtr.add(1);
1028            }
1029        } else {
1030            *largerPtr = matchIndex;
1031            commonLengthLarger = matchLength;
1032            if matchIndex <= btLow {
1033                largerPtr = &mut dummy32;
1034                break;
1035            } else {
1036                largerPtr = nextPtr;
1037                matchIndex = *nextPtr;
1038            }
1039        }
1040        nbCompares = nbCompares.wrapping_sub(1);
1041    }
1042    *largerPtr = 0;
1043    *smallerPtr = *largerPtr;
1044    if dictMode as core::ffi::c_uint == ZSTD_dictMatchState as core::ffi::c_int as core::ffi::c_uint
1045        && nbCompares != 0
1046    {
1047        let dmsH = ZSTD_hashPtr(ip as *const core::ffi::c_void, dmsHashLog, mls);
1048        let mut dictMatchIndex = *((*dms).hashTable).add(dmsH);
1049        let dmsBt: *const u32 = (*dms).chainTable;
1050        commonLengthLarger = 0;
1051        commonLengthSmaller = commonLengthLarger;
1052        while nbCompares != 0 && dictMatchIndex > dmsLowLimit {
1053            let nextPtr_0 = dmsBt.offset((2 * (dictMatchIndex & dmsBtMask)) as isize);
1054            let mut matchLength_0 = if commonLengthSmaller < commonLengthLarger {
1055                commonLengthSmaller
1056            } else {
1057                commonLengthLarger
1058            };
1059            let mut match_3 = dmsBase.offset(dictMatchIndex as isize);
1060            matchLength_0 = matchLength_0.wrapping_add(ZSTD_count_2segments(
1061                ip.add(matchLength_0),
1062                match_3.add(matchLength_0),
1063                iLimit,
1064                dmsEnd,
1065                prefixStart,
1066            ));
1067            if (dictMatchIndex as size_t).wrapping_add(matchLength_0) >= dmsHighLimit as size_t {
1068                match_3 = base
1069                    .offset(dictMatchIndex as isize)
1070                    .offset(dmsIndexDelta as isize);
1071            }
1072            if matchLength_0 > bestLength {
1073                matchIndex = dictMatchIndex.wrapping_add(dmsIndexDelta);
1074                if matchLength_0 > matchEndIdx.wrapping_sub(matchIndex) as size_t {
1075                    matchEndIdx = matchIndex.wrapping_add(matchLength_0 as u32);
1076                }
1077                bestLength = matchLength_0;
1078                (*matches.offset(mnum as isize)).off = curr
1079                    .wrapping_sub(matchIndex)
1080                    .wrapping_add(ZSTD_REP_NUM as u32);
1081                (*matches.offset(mnum as isize)).len = matchLength_0 as u32;
1082                mnum = mnum.wrapping_add(1);
1083                if (matchLength_0 > ZSTD_OPT_NUM as size_t) as core::ffi::c_int
1084                    | (ip.add(matchLength_0) == iLimit) as core::ffi::c_int
1085                    != 0
1086                {
1087                    break;
1088                }
1089            }
1090            if dictMatchIndex <= dmsBtLow {
1091                break;
1092            }
1093            if (*match_3.add(matchLength_0) as core::ffi::c_int)
1094                < *ip.add(matchLength_0) as core::ffi::c_int
1095            {
1096                commonLengthSmaller = matchLength_0;
1097                dictMatchIndex = *nextPtr_0.add(1);
1098            } else {
1099                commonLengthLarger = matchLength_0;
1100                dictMatchIndex = *nextPtr_0;
1101            }
1102            nbCompares = nbCompares.wrapping_sub(1);
1103        }
1104    }
1105    ms.nextToUpdate = matchEndIdx.wrapping_sub(8);
1106    mnum
1107}
1108#[inline(always)]
1109unsafe fn ZSTD_btGetAllMatches_internal(
1110    matches: *mut ZSTD_match_t,
1111    ms: &mut ZSTD_MatchState_t,
1112    nextToUpdate3: *mut u32,
1113    ip: *const u8,
1114    iHighLimit: *const u8,
1115    rep: *const u32,
1116    ll0: u32,
1117    lengthToBeat: u32,
1118    dictMode: ZSTD_dictMode_e,
1119    mls: u32,
1120) -> u32 {
1121    if ip < (ms.window.base).offset(ms.nextToUpdate as isize) {
1122        return 0;
1123    }
1124    ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode);
1125    ZSTD_insertBtAndGetAllMatches(
1126        matches,
1127        ms,
1128        nextToUpdate3,
1129        ip,
1130        iHighLimit,
1131        dictMode,
1132        rep,
1133        ll0,
1134        lengthToBeat,
1135        mls,
1136    )
1137}
1138unsafe fn ZSTD_btGetAllMatches_noDict_5(
1139    matches: *mut ZSTD_match_t,
1140    ms: &mut ZSTD_MatchState_t,
1141    nextToUpdate3: *mut u32,
1142    ip: *const u8,
1143    iHighLimit: *const u8,
1144    rep: *const u32,
1145    ll0: u32,
1146    lengthToBeat: u32,
1147) -> u32 {
1148    ZSTD_btGetAllMatches_internal(
1149        matches,
1150        ms,
1151        nextToUpdate3,
1152        ip,
1153        iHighLimit,
1154        rep,
1155        ll0,
1156        lengthToBeat,
1157        ZSTD_noDict,
1158        5,
1159    )
1160}
1161unsafe fn ZSTD_btGetAllMatches_noDict_6(
1162    matches: *mut ZSTD_match_t,
1163    ms: &mut ZSTD_MatchState_t,
1164    nextToUpdate3: *mut u32,
1165    ip: *const u8,
1166    iHighLimit: *const u8,
1167    rep: *const u32,
1168    ll0: u32,
1169    lengthToBeat: u32,
1170) -> u32 {
1171    ZSTD_btGetAllMatches_internal(
1172        matches,
1173        ms,
1174        nextToUpdate3,
1175        ip,
1176        iHighLimit,
1177        rep,
1178        ll0,
1179        lengthToBeat,
1180        ZSTD_noDict,
1181        6,
1182    )
1183}
1184unsafe fn ZSTD_btGetAllMatches_noDict_4(
1185    matches: *mut ZSTD_match_t,
1186    ms: &mut ZSTD_MatchState_t,
1187    nextToUpdate3: *mut u32,
1188    ip: *const u8,
1189    iHighLimit: *const u8,
1190    rep: *const u32,
1191    ll0: u32,
1192    lengthToBeat: u32,
1193) -> u32 {
1194    ZSTD_btGetAllMatches_internal(
1195        matches,
1196        ms,
1197        nextToUpdate3,
1198        ip,
1199        iHighLimit,
1200        rep,
1201        ll0,
1202        lengthToBeat,
1203        ZSTD_noDict,
1204        4,
1205    )
1206}
1207unsafe fn ZSTD_btGetAllMatches_noDict_3(
1208    matches: *mut ZSTD_match_t,
1209    ms: &mut ZSTD_MatchState_t,
1210    nextToUpdate3: *mut u32,
1211    ip: *const u8,
1212    iHighLimit: *const u8,
1213    rep: *const u32,
1214    ll0: u32,
1215    lengthToBeat: u32,
1216) -> u32 {
1217    ZSTD_btGetAllMatches_internal(
1218        matches,
1219        ms,
1220        nextToUpdate3,
1221        ip,
1222        iHighLimit,
1223        rep,
1224        ll0,
1225        lengthToBeat,
1226        ZSTD_noDict,
1227        3,
1228    )
1229}
1230unsafe fn ZSTD_btGetAllMatches_extDict_5(
1231    matches: *mut ZSTD_match_t,
1232    ms: &mut ZSTD_MatchState_t,
1233    nextToUpdate3: *mut u32,
1234    ip: *const u8,
1235    iHighLimit: *const u8,
1236    rep: *const u32,
1237    ll0: u32,
1238    lengthToBeat: u32,
1239) -> u32 {
1240    ZSTD_btGetAllMatches_internal(
1241        matches,
1242        ms,
1243        nextToUpdate3,
1244        ip,
1245        iHighLimit,
1246        rep,
1247        ll0,
1248        lengthToBeat,
1249        ZSTD_extDict,
1250        5,
1251    )
1252}
1253unsafe fn ZSTD_btGetAllMatches_extDict_6(
1254    matches: *mut ZSTD_match_t,
1255    ms: &mut ZSTD_MatchState_t,
1256    nextToUpdate3: *mut u32,
1257    ip: *const u8,
1258    iHighLimit: *const u8,
1259    rep: *const u32,
1260    ll0: u32,
1261    lengthToBeat: u32,
1262) -> u32 {
1263    ZSTD_btGetAllMatches_internal(
1264        matches,
1265        ms,
1266        nextToUpdate3,
1267        ip,
1268        iHighLimit,
1269        rep,
1270        ll0,
1271        lengthToBeat,
1272        ZSTD_extDict,
1273        6,
1274    )
1275}
1276unsafe fn ZSTD_btGetAllMatches_extDict_4(
1277    matches: *mut ZSTD_match_t,
1278    ms: &mut ZSTD_MatchState_t,
1279    nextToUpdate3: *mut u32,
1280    ip: *const u8,
1281    iHighLimit: *const u8,
1282    rep: *const u32,
1283    ll0: u32,
1284    lengthToBeat: u32,
1285) -> u32 {
1286    ZSTD_btGetAllMatches_internal(
1287        matches,
1288        ms,
1289        nextToUpdate3,
1290        ip,
1291        iHighLimit,
1292        rep,
1293        ll0,
1294        lengthToBeat,
1295        ZSTD_extDict,
1296        4,
1297    )
1298}
1299unsafe fn ZSTD_btGetAllMatches_extDict_3(
1300    matches: *mut ZSTD_match_t,
1301    ms: &mut ZSTD_MatchState_t,
1302    nextToUpdate3: *mut u32,
1303    ip: *const u8,
1304    iHighLimit: *const u8,
1305    rep: *const u32,
1306    ll0: u32,
1307    lengthToBeat: u32,
1308) -> u32 {
1309    ZSTD_btGetAllMatches_internal(
1310        matches,
1311        ms,
1312        nextToUpdate3,
1313        ip,
1314        iHighLimit,
1315        rep,
1316        ll0,
1317        lengthToBeat,
1318        ZSTD_extDict,
1319        3,
1320    )
1321}
1322unsafe fn ZSTD_btGetAllMatches_dictMatchState_5(
1323    matches: *mut ZSTD_match_t,
1324    ms: &mut ZSTD_MatchState_t,
1325    nextToUpdate3: *mut u32,
1326    ip: *const u8,
1327    iHighLimit: *const u8,
1328    rep: *const u32,
1329    ll0: u32,
1330    lengthToBeat: u32,
1331) -> u32 {
1332    ZSTD_btGetAllMatches_internal(
1333        matches,
1334        ms,
1335        nextToUpdate3,
1336        ip,
1337        iHighLimit,
1338        rep,
1339        ll0,
1340        lengthToBeat,
1341        ZSTD_dictMatchState,
1342        5,
1343    )
1344}
1345unsafe fn ZSTD_btGetAllMatches_dictMatchState_6(
1346    matches: *mut ZSTD_match_t,
1347    ms: &mut ZSTD_MatchState_t,
1348    nextToUpdate3: *mut u32,
1349    ip: *const u8,
1350    iHighLimit: *const u8,
1351    rep: *const u32,
1352    ll0: u32,
1353    lengthToBeat: u32,
1354) -> u32 {
1355    ZSTD_btGetAllMatches_internal(
1356        matches,
1357        ms,
1358        nextToUpdate3,
1359        ip,
1360        iHighLimit,
1361        rep,
1362        ll0,
1363        lengthToBeat,
1364        ZSTD_dictMatchState,
1365        6,
1366    )
1367}
1368unsafe fn ZSTD_btGetAllMatches_dictMatchState_3(
1369    matches: *mut ZSTD_match_t,
1370    ms: &mut ZSTD_MatchState_t,
1371    nextToUpdate3: *mut u32,
1372    ip: *const u8,
1373    iHighLimit: *const u8,
1374    rep: *const u32,
1375    ll0: u32,
1376    lengthToBeat: u32,
1377) -> u32 {
1378    ZSTD_btGetAllMatches_internal(
1379        matches,
1380        ms,
1381        nextToUpdate3,
1382        ip,
1383        iHighLimit,
1384        rep,
1385        ll0,
1386        lengthToBeat,
1387        ZSTD_dictMatchState,
1388        3,
1389    )
1390}
1391unsafe fn ZSTD_btGetAllMatches_dictMatchState_4(
1392    matches: *mut ZSTD_match_t,
1393    ms: &mut ZSTD_MatchState_t,
1394    nextToUpdate3: *mut u32,
1395    ip: *const u8,
1396    iHighLimit: *const u8,
1397    rep: *const u32,
1398    ll0: u32,
1399    lengthToBeat: u32,
1400) -> u32 {
1401    ZSTD_btGetAllMatches_internal(
1402        matches,
1403        ms,
1404        nextToUpdate3,
1405        ip,
1406        iHighLimit,
1407        rep,
1408        ll0,
1409        lengthToBeat,
1410        ZSTD_dictMatchState,
1411        4,
1412    )
1413}
1414unsafe fn ZSTD_selectBtGetAllMatches(
1415    ms: *const ZSTD_MatchState_t,
1416    dictMode: ZSTD_dictMode_e,
1417) -> ZSTD_getAllMatchesFn {
1418    let getAllMatchesFns: [[ZSTD_getAllMatchesFn; 4]; 3] = [
1419        [
1420            Some(
1421                ZSTD_btGetAllMatches_noDict_3
1422                    as unsafe fn(
1423                        *mut ZSTD_match_t,
1424                        &mut ZSTD_MatchState_t,
1425                        *mut u32,
1426                        *const u8,
1427                        *const u8,
1428                        *const u32,
1429                        u32,
1430                        u32,
1431                    ) -> u32,
1432            ),
1433            Some(
1434                ZSTD_btGetAllMatches_noDict_4
1435                    as unsafe fn(
1436                        *mut ZSTD_match_t,
1437                        &mut ZSTD_MatchState_t,
1438                        *mut u32,
1439                        *const u8,
1440                        *const u8,
1441                        *const u32,
1442                        u32,
1443                        u32,
1444                    ) -> u32,
1445            ),
1446            Some(
1447                ZSTD_btGetAllMatches_noDict_5
1448                    as unsafe fn(
1449                        *mut ZSTD_match_t,
1450                        &mut ZSTD_MatchState_t,
1451                        *mut u32,
1452                        *const u8,
1453                        *const u8,
1454                        *const u32,
1455                        u32,
1456                        u32,
1457                    ) -> u32,
1458            ),
1459            Some(
1460                ZSTD_btGetAllMatches_noDict_6
1461                    as unsafe fn(
1462                        *mut ZSTD_match_t,
1463                        &mut ZSTD_MatchState_t,
1464                        *mut u32,
1465                        *const u8,
1466                        *const u8,
1467                        *const u32,
1468                        u32,
1469                        u32,
1470                    ) -> u32,
1471            ),
1472        ],
1473        [
1474            Some(
1475                ZSTD_btGetAllMatches_extDict_3
1476                    as unsafe fn(
1477                        *mut ZSTD_match_t,
1478                        &mut ZSTD_MatchState_t,
1479                        *mut u32,
1480                        *const u8,
1481                        *const u8,
1482                        *const u32,
1483                        u32,
1484                        u32,
1485                    ) -> u32,
1486            ),
1487            Some(
1488                ZSTD_btGetAllMatches_extDict_4
1489                    as unsafe fn(
1490                        *mut ZSTD_match_t,
1491                        &mut ZSTD_MatchState_t,
1492                        *mut u32,
1493                        *const u8,
1494                        *const u8,
1495                        *const u32,
1496                        u32,
1497                        u32,
1498                    ) -> u32,
1499            ),
1500            Some(
1501                ZSTD_btGetAllMatches_extDict_5
1502                    as unsafe fn(
1503                        *mut ZSTD_match_t,
1504                        &mut ZSTD_MatchState_t,
1505                        *mut u32,
1506                        *const u8,
1507                        *const u8,
1508                        *const u32,
1509                        u32,
1510                        u32,
1511                    ) -> u32,
1512            ),
1513            Some(
1514                ZSTD_btGetAllMatches_extDict_6
1515                    as unsafe fn(
1516                        *mut ZSTD_match_t,
1517                        &mut ZSTD_MatchState_t,
1518                        *mut u32,
1519                        *const u8,
1520                        *const u8,
1521                        *const u32,
1522                        u32,
1523                        u32,
1524                    ) -> u32,
1525            ),
1526        ],
1527        [
1528            Some(
1529                ZSTD_btGetAllMatches_dictMatchState_3
1530                    as unsafe fn(
1531                        *mut ZSTD_match_t,
1532                        &mut ZSTD_MatchState_t,
1533                        *mut u32,
1534                        *const u8,
1535                        *const u8,
1536                        *const u32,
1537                        u32,
1538                        u32,
1539                    ) -> u32,
1540            ),
1541            Some(
1542                ZSTD_btGetAllMatches_dictMatchState_4
1543                    as unsafe fn(
1544                        *mut ZSTD_match_t,
1545                        &mut ZSTD_MatchState_t,
1546                        *mut u32,
1547                        *const u8,
1548                        *const u8,
1549                        *const u32,
1550                        u32,
1551                        u32,
1552                    ) -> u32,
1553            ),
1554            Some(
1555                ZSTD_btGetAllMatches_dictMatchState_5
1556                    as unsafe fn(
1557                        *mut ZSTD_match_t,
1558                        &mut ZSTD_MatchState_t,
1559                        *mut u32,
1560                        *const u8,
1561                        *const u8,
1562                        *const u32,
1563                        u32,
1564                        u32,
1565                    ) -> u32,
1566            ),
1567            Some(
1568                ZSTD_btGetAllMatches_dictMatchState_6
1569                    as unsafe fn(
1570                        *mut ZSTD_match_t,
1571                        &mut ZSTD_MatchState_t,
1572                        *mut u32,
1573                        *const u8,
1574                        *const u8,
1575                        *const u32,
1576                        u32,
1577                        u32,
1578                    ) -> u32,
1579            ),
1580        ],
1581    ];
1582    let mls = if 3
1583        > (if (*ms).cParams.minMatch < 6 {
1584            (*ms).cParams.minMatch
1585        } else {
1586            6
1587        }) {
1588        3
1589    } else if (*ms).cParams.minMatch < 6 {
1590        (*ms).cParams.minMatch
1591    } else {
1592        6
1593    };
1594    *(*getAllMatchesFns
1595        .as_ptr()
1596        .offset(dictMode as core::ffi::c_int as isize))
1597    .as_ptr()
1598    .offset(mls.wrapping_sub(3) as isize)
1599}
1600unsafe fn ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore: *mut RawSeqStore_t, nbBytes: size_t) {
1601    let mut currPos = ((*rawSeqStore).posInSequence).wrapping_add(nbBytes) as u32;
1602    while currPos != 0 && (*rawSeqStore).pos < (*rawSeqStore).size {
1603        let currSeq = *((*rawSeqStore).seq).add((*rawSeqStore).pos);
1604        if currPos >= (currSeq.litLength).wrapping_add(currSeq.matchLength) {
1605            currPos = currPos.wrapping_sub((currSeq.litLength).wrapping_add(currSeq.matchLength));
1606            (*rawSeqStore).pos = ((*rawSeqStore).pos).wrapping_add(1);
1607        } else {
1608            (*rawSeqStore).posInSequence = currPos as size_t;
1609            break;
1610        }
1611    }
1612    if currPos == 0 || (*rawSeqStore).pos == (*rawSeqStore).size {
1613        (*rawSeqStore).posInSequence = 0;
1614    }
1615}
1616unsafe fn ZSTD_opt_getNextMatchAndUpdateSeqStore(
1617    optLdm: *mut ZSTD_optLdm_t,
1618    currPosInBlock: u32,
1619    blockBytesRemaining: u32,
1620) {
1621    let mut currSeq = rawSeq {
1622        offset: 0,
1623        litLength: 0,
1624        matchLength: 0,
1625    };
1626    let mut currBlockEndPos: u32 = 0;
1627    let mut literalsBytesRemaining: u32 = 0;
1628    let mut matchBytesRemaining: u32 = 0;
1629    if (*optLdm).seqStore.size == 0 || (*optLdm).seqStore.pos >= (*optLdm).seqStore.size {
1630        (*optLdm).startPosInBlock = UINT_MAX;
1631        (*optLdm).endPosInBlock = UINT_MAX;
1632        return;
1633    }
1634    currSeq = *((*optLdm).seqStore.seq).add((*optLdm).seqStore.pos);
1635    currBlockEndPos = currPosInBlock.wrapping_add(blockBytesRemaining);
1636    literalsBytesRemaining = if (*optLdm).seqStore.posInSequence < currSeq.litLength as size_t {
1637        (currSeq.litLength).wrapping_sub((*optLdm).seqStore.posInSequence as u32)
1638    } else {
1639        0
1640    };
1641    matchBytesRemaining = if literalsBytesRemaining == 0 {
1642        (currSeq.matchLength)
1643            .wrapping_sub(((*optLdm).seqStore.posInSequence as u32).wrapping_sub(currSeq.litLength))
1644    } else {
1645        currSeq.matchLength
1646    };
1647    if literalsBytesRemaining >= blockBytesRemaining {
1648        (*optLdm).startPosInBlock = UINT_MAX;
1649        (*optLdm).endPosInBlock = UINT_MAX;
1650        ZSTD_optLdm_skipRawSeqStoreBytes(&mut (*optLdm).seqStore, blockBytesRemaining as size_t);
1651        return;
1652    }
1653    (*optLdm).startPosInBlock = currPosInBlock.wrapping_add(literalsBytesRemaining);
1654    (*optLdm).endPosInBlock = ((*optLdm).startPosInBlock).wrapping_add(matchBytesRemaining);
1655    (*optLdm).offset = currSeq.offset;
1656    if (*optLdm).endPosInBlock > currBlockEndPos {
1657        (*optLdm).endPosInBlock = currBlockEndPos;
1658        ZSTD_optLdm_skipRawSeqStoreBytes(
1659            &mut (*optLdm).seqStore,
1660            currBlockEndPos.wrapping_sub(currPosInBlock) as size_t,
1661        );
1662    } else {
1663        ZSTD_optLdm_skipRawSeqStoreBytes(
1664            &mut (*optLdm).seqStore,
1665            literalsBytesRemaining.wrapping_add(matchBytesRemaining) as size_t,
1666        );
1667    }
1668}
1669unsafe fn ZSTD_optLdm_maybeAddMatch(
1670    matches: *mut ZSTD_match_t,
1671    nbMatches: *mut u32,
1672    optLdm: *const ZSTD_optLdm_t,
1673    currPosInBlock: u32,
1674    minMatch: u32,
1675) {
1676    let posDiff = currPosInBlock.wrapping_sub((*optLdm).startPosInBlock);
1677    let candidateMatchLength = ((*optLdm).endPosInBlock)
1678        .wrapping_sub((*optLdm).startPosInBlock)
1679        .wrapping_sub(posDiff);
1680    if currPosInBlock < (*optLdm).startPosInBlock
1681        || currPosInBlock >= (*optLdm).endPosInBlock
1682        || candidateMatchLength < minMatch
1683    {
1684        return;
1685    }
1686    if *nbMatches == 0
1687        || candidateMatchLength > (*matches.offset((*nbMatches).wrapping_sub(1) as isize)).len
1688            && *nbMatches < ZSTD_OPT_NUM as u32
1689    {
1690        let candidateOffBase = ((*optLdm).offset).wrapping_add(ZSTD_REP_NUM as u32);
1691        (*matches.offset(*nbMatches as isize)).len = candidateMatchLength;
1692        (*matches.offset(*nbMatches as isize)).off = candidateOffBase;
1693        *nbMatches = (*nbMatches).wrapping_add(1);
1694    }
1695}
1696unsafe fn ZSTD_optLdm_processMatchCandidate(
1697    optLdm: *mut ZSTD_optLdm_t,
1698    matches: *mut ZSTD_match_t,
1699    nbMatches: *mut u32,
1700    currPosInBlock: u32,
1701    remainingBytes: u32,
1702    minMatch: u32,
1703) {
1704    if (*optLdm).seqStore.size == 0 || (*optLdm).seqStore.pos >= (*optLdm).seqStore.size {
1705        return;
1706    }
1707    if currPosInBlock >= (*optLdm).endPosInBlock {
1708        if currPosInBlock > (*optLdm).endPosInBlock {
1709            let posOvershoot = currPosInBlock.wrapping_sub((*optLdm).endPosInBlock);
1710            ZSTD_optLdm_skipRawSeqStoreBytes(&mut (*optLdm).seqStore, posOvershoot as size_t);
1711        }
1712        ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
1713    }
1714    ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock, minMatch);
1715}
1716#[inline(always)]
1717unsafe fn ZSTD_compressBlock_opt_generic(
1718    ms: &mut ZSTD_MatchState_t,
1719    seqStore: &mut SeqStore_t,
1720    rep: *mut u32,
1721    src: *const core::ffi::c_void,
1722    srcSize: size_t,
1723    optLevel: core::ffi::c_int,
1724    dictMode: ZSTD_dictMode_e,
1725) -> size_t {
1726    let mut current_block: u64;
1727    let optStatePtr: *mut optState_t = &mut ms.opt;
1728    let istart = src as *const u8;
1729    let mut ip = istart;
1730    let mut anchor = istart;
1731    let iend = istart.add(srcSize);
1732    let ilimit = iend.sub(8);
1733    let base = ms.window.base;
1734    let prefixStart = base.offset(ms.window.dictLimit as isize);
1735    let cParams: *const ZSTD_compressionParameters = &mut ms.cParams;
1736    let getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode);
1737    let sufficient_len = if (*cParams).targetLength < (((1) << 12) - 1) as core::ffi::c_uint {
1738        (*cParams).targetLength
1739    } else {
1740        (((1) << 12) - 1) as core::ffi::c_uint
1741    };
1742    let minMatch = (if (*cParams).minMatch == 3 { 3 } else { 4 }) as u32;
1743    let mut nextToUpdate3 = ms.nextToUpdate;
1744    let opt = (*optStatePtr).priceTable;
1745    let matches = (*optStatePtr).matchTable;
1746    let mut lastStretch = ZSTD_optimal_t {
1747        price: 0,
1748        off: 0,
1749        mlen: 0,
1750        litlen: 0,
1751        rep: [0; 3],
1752    };
1753    let mut optLdm = ZSTD_optLdm_t {
1754        seqStore: RawSeqStore_t {
1755            seq: core::ptr::null_mut::<rawSeq>(),
1756            pos: 0,
1757            posInSequence: 0,
1758            size: 0,
1759            capacity: 0,
1760        },
1761        startPosInBlock: 0,
1762        endPosInBlock: 0,
1763        offset: 0,
1764    };
1765    ptr::write_bytes(
1766        &mut lastStretch as *mut ZSTD_optimal_t as *mut u8,
1767        0,
1768        ::core::mem::size_of::<ZSTD_optimal_t>(),
1769    );
1770    optLdm.seqStore = if !(ms.ldmSeqStore).is_null() {
1771        *ms.ldmSeqStore
1772    } else {
1773        kNullRawSeqStore
1774    };
1775    optLdm.offset = 0;
1776    optLdm.startPosInBlock = optLdm.offset;
1777    optLdm.endPosInBlock = optLdm.startPosInBlock;
1778    ZSTD_opt_getNextMatchAndUpdateSeqStore(
1779        &mut optLdm,
1780        ip.offset_from(istart) as core::ffi::c_long as u32,
1781        iend.offset_from(ip) as core::ffi::c_long as u32,
1782    );
1783    ZSTD_rescaleFreqs(optStatePtr, src as *const u8, srcSize, optLevel);
1784    ip = ip.offset((ip == prefixStart) as core::ffi::c_int as isize);
1785    while ip < ilimit {
1786        let mut cur: u32 = 0;
1787        let mut last_pos = 0;
1788        let litlen = ip.offset_from(anchor) as core::ffi::c_long as u32;
1789        let ll0 = (litlen == 0) as core::ffi::c_int as u32;
1790        let mut nbMatches = getAllMatches.unwrap_unchecked()(
1791            matches,
1792            ms,
1793            &mut nextToUpdate3,
1794            ip,
1795            iend,
1796            rep as *const u32,
1797            ll0,
1798            minMatch,
1799        );
1800        ZSTD_optLdm_processMatchCandidate(
1801            &mut optLdm,
1802            matches,
1803            &mut nbMatches,
1804            ip.offset_from(istart) as core::ffi::c_long as u32,
1805            iend.offset_from(ip) as core::ffi::c_long as u32,
1806            minMatch,
1807        );
1808        if nbMatches == 0 {
1809            ip = ip.add(1);
1810        } else {
1811            (*opt).mlen = 0;
1812            (*opt).litlen = litlen;
1813            (*opt).price = ZSTD_litLengthPrice(litlen, optStatePtr, optLevel) as core::ffi::c_int;
1814            libc::memcpy(
1815                &mut (*opt).rep as *mut [u32; 3] as *mut core::ffi::c_void,
1816                rep as *const core::ffi::c_void,
1817                ::core::mem::size_of::<[u32; 3]>() as core::ffi::c_ulong as libc::size_t,
1818            );
1819            let maxML = (*matches.offset(nbMatches.wrapping_sub(1) as isize)).len;
1820            let maxOffBase = (*matches.offset(nbMatches.wrapping_sub(1) as isize)).off;
1821            if maxML > sufficient_len {
1822                lastStretch.litlen = 0;
1823                lastStretch.mlen = maxML;
1824                lastStretch.off = maxOffBase;
1825                cur = 0;
1826                last_pos = maxML;
1827            } else {
1828                let mut pos: u32 = 0;
1829                let mut matchNb: u32 = 0;
1830                pos = 1;
1831                while pos < minMatch {
1832                    (*opt.offset(pos as isize)).price = ZSTD_MAX_PRICE;
1833                    (*opt.offset(pos as isize)).mlen = 0;
1834                    (*opt.offset(pos as isize)).litlen = litlen.wrapping_add(pos);
1835                    pos = pos.wrapping_add(1);
1836                }
1837                matchNb = 0;
1838                while matchNb < nbMatches {
1839                    let offBase = (*matches.offset(matchNb as isize)).off;
1840                    let end = (*matches.offset(matchNb as isize)).len;
1841                    while pos <= end {
1842                        let matchPrice = ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel)
1843                            as core::ffi::c_int;
1844                        let sequencePrice = (*opt).price + matchPrice;
1845                        (*opt.offset(pos as isize)).mlen = pos;
1846                        (*opt.offset(pos as isize)).off = offBase;
1847                        (*opt.offset(pos as isize)).litlen = 0;
1848                        (*opt.offset(pos as isize)).price = sequencePrice
1849                            + ZSTD_litLengthPrice(0, optStatePtr, optLevel) as core::ffi::c_int;
1850                        pos = pos.wrapping_add(1);
1851                    }
1852                    matchNb = matchNb.wrapping_add(1);
1853                }
1854                last_pos = pos.wrapping_sub(1);
1855                (*opt.offset(pos as isize)).price = ZSTD_MAX_PRICE;
1856                cur = 1;
1857                loop {
1858                    if cur > last_pos {
1859                        current_block = 10357520176418200368;
1860                        break;
1861                    }
1862                    let inr = ip.offset(cur as isize);
1863                    let litlen_0 =
1864                        ((*opt.offset(cur.wrapping_sub(1) as isize)).litlen).wrapping_add(1);
1865                    let price = (*opt.offset(cur.wrapping_sub(1) as isize)).price
1866                        + ZSTD_rawLiteralsCost(
1867                            ip.offset(cur as isize).sub(1),
1868                            1,
1869                            optStatePtr,
1870                            optLevel,
1871                        ) as core::ffi::c_int
1872                        + (ZSTD_litLengthPrice(litlen_0, optStatePtr, optLevel)
1873                            as core::ffi::c_int
1874                            - ZSTD_litLengthPrice(litlen_0.wrapping_sub(1), optStatePtr, optLevel)
1875                                as core::ffi::c_int);
1876                    if price <= (*opt.offset(cur as isize)).price {
1877                        let prevMatch = *opt.offset(cur as isize);
1878                        *opt.offset(cur as isize) = *opt.offset(cur.wrapping_sub(1) as isize);
1879                        (*opt.offset(cur as isize)).litlen = litlen_0;
1880                        (*opt.offset(cur as isize)).price = price;
1881                        if optLevel >= 1
1882                            && prevMatch.litlen == 0
1883                            && (ZSTD_litLengthPrice(1, optStatePtr, optLevel) as core::ffi::c_int
1884                                - ZSTD_litLengthPrice((1 - 1) as u32, optStatePtr, optLevel)
1885                                    as core::ffi::c_int)
1886                                < 0
1887                            && (ip.offset(cur as isize) < iend) as core::ffi::c_int
1888                                as core::ffi::c_long
1889                                != 0
1890                        {
1891                            let with1literal = prevMatch.price
1892                                + ZSTD_rawLiteralsCost(
1893                                    ip.offset(cur as isize),
1894                                    1,
1895                                    optStatePtr,
1896                                    optLevel,
1897                                ) as core::ffi::c_int
1898                                + (ZSTD_litLengthPrice(1, optStatePtr, optLevel)
1899                                    as core::ffi::c_int
1900                                    - ZSTD_litLengthPrice((1 - 1) as u32, optStatePtr, optLevel)
1901                                        as core::ffi::c_int);
1902                            let withMoreLiterals = price
1903                                + ZSTD_rawLiteralsCost(
1904                                    ip.offset(cur as isize),
1905                                    1,
1906                                    optStatePtr,
1907                                    optLevel,
1908                                ) as core::ffi::c_int
1909                                + (ZSTD_litLengthPrice(
1910                                    litlen_0.wrapping_add(1),
1911                                    optStatePtr,
1912                                    optLevel,
1913                                ) as core::ffi::c_int
1914                                    - ZSTD_litLengthPrice(
1915                                        litlen_0.wrapping_add(1).wrapping_sub(1),
1916                                        optStatePtr,
1917                                        optLevel,
1918                                    ) as core::ffi::c_int);
1919                            if with1literal < withMoreLiterals
1920                                && with1literal < (*opt.offset(cur.wrapping_add(1) as isize)).price
1921                            {
1922                                let prev = cur.wrapping_sub(prevMatch.mlen);
1923                                let newReps = ZSTD_newRep(
1924                                    ((*opt.offset(prev as isize)).rep).as_mut_ptr() as *const u32,
1925                                    prevMatch.off,
1926                                    ((*opt.offset(prev as isize)).litlen == 0) as core::ffi::c_int
1927                                        as u32,
1928                                );
1929                                *opt.offset(cur.wrapping_add(1) as isize) = prevMatch;
1930                                libc::memcpy(
1931                                    ((*opt.offset(cur.wrapping_add(1) as isize)).rep).as_mut_ptr()
1932                                        as *mut core::ffi::c_void,
1933                                    &newReps as *const Repcodes_t as *const core::ffi::c_void,
1934                                    ::core::mem::size_of::<Repcodes_t>() as core::ffi::c_ulong
1935                                        as libc::size_t,
1936                                );
1937                                (*opt.offset(cur.wrapping_add(1) as isize)).litlen = 1;
1938                                (*opt.offset(cur.wrapping_add(1) as isize)).price = with1literal;
1939                                if last_pos < cur.wrapping_add(1) {
1940                                    last_pos = cur.wrapping_add(1);
1941                                }
1942                            }
1943                        }
1944                    }
1945                    if (*opt.offset(cur as isize)).litlen == 0 {
1946                        let prev_0 = cur.wrapping_sub((*opt.offset(cur as isize)).mlen);
1947                        let newReps_0 = ZSTD_newRep(
1948                            ((*opt.offset(prev_0 as isize)).rep).as_mut_ptr() as *const u32,
1949                            (*opt.offset(cur as isize)).off,
1950                            ((*opt.offset(prev_0 as isize)).litlen == 0) as core::ffi::c_int as u32,
1951                        );
1952                        libc::memcpy(
1953                            ((*opt.offset(cur as isize)).rep).as_mut_ptr()
1954                                as *mut core::ffi::c_void,
1955                            &newReps_0 as *const Repcodes_t as *const core::ffi::c_void,
1956                            ::core::mem::size_of::<Repcodes_t>() as core::ffi::c_ulong
1957                                as libc::size_t,
1958                        );
1959                    }
1960                    if inr <= ilimit {
1961                        if cur == last_pos {
1962                            current_block = 10357520176418200368;
1963                            break;
1964                        }
1965                        if !(optLevel == 0
1966                            && (*opt.offset(cur.wrapping_add(1) as isize)).price
1967                                <= (*opt.offset(cur as isize)).price + BITCOST_MULTIPLIER / 2)
1968                        {
1969                            let ll0_0 = ((*opt.offset(cur as isize)).litlen == 0)
1970                                as core::ffi::c_int as u32;
1971                            let previousPrice = (*opt.offset(cur as isize)).price;
1972                            let basePrice = previousPrice
1973                                + ZSTD_litLengthPrice(0, optStatePtr, optLevel) as core::ffi::c_int;
1974                            let mut nbMatches_0 = getAllMatches.unwrap_unchecked()(
1975                                matches,
1976                                ms,
1977                                &mut nextToUpdate3,
1978                                inr,
1979                                iend,
1980                                ((*opt.offset(cur as isize)).rep).as_mut_ptr() as *const u32,
1981                                ll0_0,
1982                                minMatch,
1983                            );
1984                            let mut matchNb_0: u32 = 0;
1985                            ZSTD_optLdm_processMatchCandidate(
1986                                &mut optLdm,
1987                                matches,
1988                                &mut nbMatches_0,
1989                                inr.offset_from(istart) as core::ffi::c_long as u32,
1990                                iend.offset_from(inr) as core::ffi::c_long as u32,
1991                                minMatch,
1992                            );
1993                            if nbMatches_0 != 0 {
1994                                let longestML =
1995                                    (*matches.offset(nbMatches_0.wrapping_sub(1) as isize)).len;
1996                                if longestML > sufficient_len
1997                                    || cur.wrapping_add(longestML) >= ZSTD_OPT_NUM as u32
1998                                    || ip.offset(cur as isize).offset(longestML as isize) >= iend
1999                                {
2000                                    lastStretch.mlen = longestML;
2001                                    lastStretch.off =
2002                                        (*matches.offset(nbMatches_0.wrapping_sub(1) as isize)).off;
2003                                    lastStretch.litlen = 0;
2004                                    last_pos = cur.wrapping_add(longestML);
2005                                    current_block = 12608488225262500095;
2006                                    break;
2007                                } else {
2008                                    matchNb_0 = 0;
2009                                    while matchNb_0 < nbMatches_0 {
2010                                        let offset = (*matches.offset(matchNb_0 as isize)).off;
2011                                        let lastML = (*matches.offset(matchNb_0 as isize)).len;
2012                                        let startML = if matchNb_0 > 0 {
2013                                            ((*matches.offset(matchNb_0.wrapping_sub(1) as isize))
2014                                                .len)
2015                                                .wrapping_add(1)
2016                                        } else {
2017                                            minMatch
2018                                        };
2019                                        let mut mlen: u32 = 0;
2020                                        mlen = lastML;
2021                                        while mlen >= startML {
2022                                            let pos_0 = cur.wrapping_add(mlen);
2023                                            let price_0 = basePrice
2024                                                + ZSTD_getMatchPrice(
2025                                                    offset,
2026                                                    mlen,
2027                                                    optStatePtr,
2028                                                    optLevel,
2029                                                )
2030                                                    as core::ffi::c_int;
2031                                            if pos_0 > last_pos
2032                                                || price_0 < (*opt.offset(pos_0 as isize)).price
2033                                            {
2034                                                while last_pos < pos_0 {
2035                                                    last_pos = last_pos.wrapping_add(1);
2036                                                    (*opt.offset(last_pos as isize)).price =
2037                                                        ZSTD_MAX_PRICE;
2038                                                    (*opt.offset(last_pos as isize)).litlen =
2039                                                        (0 == 0) as core::ffi::c_int as u32;
2040                                                }
2041                                                (*opt.offset(pos_0 as isize)).mlen = mlen;
2042                                                (*opt.offset(pos_0 as isize)).off = offset;
2043                                                (*opt.offset(pos_0 as isize)).litlen = 0;
2044                                                (*opt.offset(pos_0 as isize)).price = price_0;
2045                                            } else if optLevel == 0 {
2046                                                break;
2047                                            }
2048                                            mlen = mlen.wrapping_sub(1);
2049                                        }
2050                                        matchNb_0 = matchNb_0.wrapping_add(1);
2051                                    }
2052                                    (*opt.offset(last_pos.wrapping_add(1) as isize)).price =
2053                                        ZSTD_MAX_PRICE;
2054                                }
2055                            }
2056                        }
2057                    }
2058                    cur = cur.wrapping_add(1);
2059                }
2060                match current_block {
2061                    12608488225262500095 => {}
2062                    _ => {
2063                        lastStretch = *opt.offset(last_pos as isize);
2064                        cur = last_pos.wrapping_sub(lastStretch.mlen);
2065                    }
2066                }
2067            }
2068            if lastStretch.mlen == 0 {
2069                ip = ip.offset(last_pos as isize);
2070            } else {
2071                if lastStretch.litlen == 0 {
2072                    let reps = ZSTD_newRep(
2073                        ((*opt.offset(cur as isize)).rep).as_mut_ptr() as *const u32,
2074                        lastStretch.off,
2075                        ((*opt.offset(cur as isize)).litlen == 0) as core::ffi::c_int as u32,
2076                    );
2077                    libc::memcpy(
2078                        rep as *mut core::ffi::c_void,
2079                        &reps as *const Repcodes_t as *const core::ffi::c_void,
2080                        ::core::mem::size_of::<Repcodes_t>() as core::ffi::c_ulong as libc::size_t,
2081                    );
2082                } else {
2083                    libc::memcpy(
2084                        rep as *mut core::ffi::c_void,
2085                        (lastStretch.rep).as_mut_ptr() as *const core::ffi::c_void,
2086                        ::core::mem::size_of::<Repcodes_t>() as core::ffi::c_ulong as libc::size_t,
2087                    );
2088                    cur = cur.wrapping_sub(lastStretch.litlen);
2089                }
2090                let storeEnd = cur.wrapping_add(2);
2091                let mut storeStart = storeEnd;
2092                let mut stretchPos = cur;
2093                if lastStretch.litlen > 0 {
2094                    (*opt.offset(storeEnd as isize)).litlen = lastStretch.litlen;
2095                    (*opt.offset(storeEnd as isize)).mlen = 0;
2096                    storeStart = storeEnd.wrapping_sub(1);
2097                    *opt.offset(storeStart as isize) = lastStretch;
2098                }
2099                *opt.offset(storeEnd as isize) = lastStretch;
2100                storeStart = storeEnd;
2101                loop {
2102                    let nextStretch = *opt.offset(stretchPos as isize);
2103                    (*opt.offset(storeStart as isize)).litlen = nextStretch.litlen;
2104                    if nextStretch.mlen == 0 {
2105                        break;
2106                    }
2107                    storeStart = storeStart.wrapping_sub(1);
2108                    *opt.offset(storeStart as isize) = nextStretch;
2109                    stretchPos = stretchPos
2110                        .wrapping_sub((nextStretch.litlen).wrapping_add(nextStretch.mlen));
2111                }
2112                let mut storePos: u32 = 0;
2113                storePos = storeStart;
2114                while storePos <= storeEnd {
2115                    let llen = (*opt.offset(storePos as isize)).litlen;
2116                    let mlen_0 = (*opt.offset(storePos as isize)).mlen;
2117                    let offBase_0 = (*opt.offset(storePos as isize)).off;
2118                    let advance = llen.wrapping_add(mlen_0);
2119                    if mlen_0 == 0 {
2120                        ip = anchor.offset(llen as isize);
2121                    } else {
2122                        ZSTD_updateStats(optStatePtr, llen, anchor, offBase_0, mlen_0);
2123                        ZSTD_storeSeq(
2124                            seqStore,
2125                            llen as size_t,
2126                            anchor,
2127                            iend,
2128                            offBase_0,
2129                            mlen_0 as size_t,
2130                        );
2131                        anchor = anchor.offset(advance as isize);
2132                        ip = anchor;
2133                    }
2134                    storePos = storePos.wrapping_add(1);
2135                }
2136                ZSTD_setBasePrices(optStatePtr, optLevel);
2137            }
2138        }
2139    }
2140    iend.offset_from_unsigned(anchor)
2141}
2142unsafe fn ZSTD_compressBlock_opt0(
2143    ms: &mut ZSTD_MatchState_t,
2144    seqStore: &mut SeqStore_t,
2145    rep: *mut u32,
2146    src: *const core::ffi::c_void,
2147    srcSize: size_t,
2148    dictMode: ZSTD_dictMode_e,
2149) -> size_t {
2150    ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0, dictMode)
2151}
2152unsafe fn ZSTD_compressBlock_opt2(
2153    ms: &mut ZSTD_MatchState_t,
2154    seqStore: &mut SeqStore_t,
2155    rep: *mut u32,
2156    src: *const core::ffi::c_void,
2157    srcSize: size_t,
2158    dictMode: ZSTD_dictMode_e,
2159) -> size_t {
2160    ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2, dictMode)
2161}
2162pub unsafe fn ZSTD_compressBlock_btopt(
2163    ms: &mut ZSTD_MatchState_t,
2164    seqStore: &mut SeqStore_t,
2165    rep: *mut u32,
2166    src: *const core::ffi::c_void,
2167    srcSize: size_t,
2168) -> size_t {
2169    ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict)
2170}
2171unsafe fn ZSTD_initStats_ultra(
2172    ms: &mut ZSTD_MatchState_t,
2173    seqStore: &mut SeqStore_t,
2174    rep: *mut u32,
2175    src: *const core::ffi::c_void,
2176    srcSize: size_t,
2177) {
2178    let mut tmpRep: [u32; 3] = [0; 3];
2179    libc::memcpy(
2180        tmpRep.as_mut_ptr() as *mut core::ffi::c_void,
2181        rep as *const core::ffi::c_void,
2182        ::core::mem::size_of::<[u32; 3]>() as core::ffi::c_ulong as libc::size_t,
2183    );
2184    ZSTD_compressBlock_opt2(ms, seqStore, tmpRep.as_mut_ptr(), src, srcSize, ZSTD_noDict);
2185    ZSTD_resetSeqStore(seqStore);
2186    ms.window.base = (ms.window.base).offset(-(srcSize as isize));
2187    ms.window.dictLimit = (ms.window.dictLimit).wrapping_add(srcSize as u32);
2188    ms.window.lowLimit = ms.window.dictLimit;
2189    ms.nextToUpdate = ms.window.dictLimit;
2190}
2191pub unsafe fn ZSTD_compressBlock_btultra(
2192    ms: &mut ZSTD_MatchState_t,
2193    seqStore: &mut SeqStore_t,
2194    rep: *mut u32,
2195    src: *const core::ffi::c_void,
2196    srcSize: size_t,
2197) -> size_t {
2198    ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict)
2199}
2200pub unsafe fn ZSTD_compressBlock_btultra2(
2201    ms: &mut ZSTD_MatchState_t,
2202    seqStore: &mut SeqStore_t,
2203    rep: *mut u32,
2204    src: *const core::ffi::c_void,
2205    srcSize: size_t,
2206) -> size_t {
2207    let curr = (src as *const u8).offset_from(ms.window.base) as core::ffi::c_long as u32;
2208    if ms.opt.litLengthSum == 0
2209        && seqStore.sequences == seqStore.sequencesStart
2210        && ms.window.dictLimit == ms.window.lowLimit
2211        && curr == ms.window.dictLimit
2212        && srcSize > ZSTD_PREDEF_THRESHOLD as size_t
2213    {
2214        ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
2215    }
2216    ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict)
2217}
2218pub unsafe fn ZSTD_compressBlock_btopt_dictMatchState(
2219    ms: &mut ZSTD_MatchState_t,
2220    seqStore: &mut SeqStore_t,
2221    rep: *mut u32,
2222    src: *const core::ffi::c_void,
2223    srcSize: size_t,
2224) -> size_t {
2225    ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState)
2226}
2227pub unsafe fn ZSTD_compressBlock_btopt_extDict(
2228    ms: &mut ZSTD_MatchState_t,
2229    seqStore: &mut SeqStore_t,
2230    rep: *mut u32,
2231    src: *const core::ffi::c_void,
2232    srcSize: size_t,
2233) -> size_t {
2234    ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict)
2235}
2236pub unsafe fn ZSTD_compressBlock_btultra_dictMatchState(
2237    ms: &mut ZSTD_MatchState_t,
2238    seqStore: &mut SeqStore_t,
2239    rep: *mut u32,
2240    src: *const core::ffi::c_void,
2241    srcSize: size_t,
2242) -> size_t {
2243    ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState)
2244}
2245pub unsafe fn ZSTD_compressBlock_btultra_extDict(
2246    ms: &mut ZSTD_MatchState_t,
2247    seqStore: &mut SeqStore_t,
2248    rep: *mut u32,
2249    src: *const core::ffi::c_void,
2250    srcSize: size_t,
2251) -> size_t {
2252    ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict)
2253}
2254pub const __INT_MAX__: core::ffi::c_int = 2147483647;