Coverage Report

Created: 2025-03-15 06:58

/src/zstd/lib/decompress/huf_decompress.c
Line
Count
Source (jump to first uncovered line)
1
/* ******************************************************************
2
 * huff0 huffman decoder,
3
 * part of Finite State Entropy library
4
 * Copyright (c) Meta Platforms, Inc. and affiliates.
5
 *
6
 *  You can contact the author at :
7
 *  - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
8
 *
9
 * This source code is licensed under both the BSD-style license (found in the
10
 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11
 * in the COPYING file in the root directory of this source tree).
12
 * You may select, at your option, one of the above-listed licenses.
13
****************************************************************** */
14
15
/* **************************************************************
16
*  Dependencies
17
****************************************************************/
18
#include <stddef.h>               /* size_t */
19
#include "../common/zstd_deps.h"  /* ZSTD_memcpy, ZSTD_memset */
20
#include "../common/compiler.h"
21
#include "../common/bitstream.h"  /* BIT_* */
22
#include "../common/fse.h"        /* to compress headers */
23
#include "../common/huf.h"
24
#include "../common/error_private.h"
25
#include "../common/zstd_internal.h"
26
#include "../common/bits.h"       /* ZSTD_highbit32, ZSTD_countTrailingZeros64 */
27
28
/* **************************************************************
29
*  Constants
30
****************************************************************/
31
32
42.7k
#define HUF_DECODER_FAST_TABLELOG 11
33
34
/* **************************************************************
35
*  Macros
36
****************************************************************/
37
38
#ifdef HUF_DISABLE_FAST_DECODE
39
# define HUF_ENABLE_FAST_DECODE 0
40
#else
41
18.9k
# define HUF_ENABLE_FAST_DECODE 1
42
#endif
43
44
/* These two optional macros force the use one way or another of the two
45
 * Huffman decompression implementations. You can't force in both directions
46
 * at the same time.
47
 */
48
#if defined(HUF_FORCE_DECOMPRESS_X1) && \
49
    defined(HUF_FORCE_DECOMPRESS_X2)
50
#error "Cannot force the use of the X1 and X2 decoders at the same time!"
51
#endif
52
53
/* When DYNAMIC_BMI2 is enabled, fast decoders are only called when bmi2 is
54
 * supported at runtime, so we can add the BMI2 target attribute.
55
 * When it is disabled, we will still get BMI2 if it is enabled statically.
56
 */
57
#if DYNAMIC_BMI2
58
# define HUF_FAST_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE
59
#else
60
# define HUF_FAST_BMI2_ATTRS
61
#endif
62
63
#ifdef __cplusplus
64
# define HUF_EXTERN_C extern "C"
65
#else
66
# define HUF_EXTERN_C
67
#endif
68
#define HUF_ASM_DECL HUF_EXTERN_C
69
70
#if DYNAMIC_BMI2
71
# define HUF_NEED_BMI2_FUNCTION 1
72
#else
73
# define HUF_NEED_BMI2_FUNCTION 0
74
#endif
75
76
/* **************************************************************
77
*  Error Management
78
****************************************************************/
79
22.1k
#define HUF_isError ERR_isError
80
81
82
/* **************************************************************
83
*  Byte alignment for workSpace management
84
****************************************************************/
85
#define HUF_ALIGN(x, a)         HUF_ALIGN_MASK((x), (a) - 1)
86
#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
87
88
89
/* **************************************************************
90
*  BMI2 Variant Wrappers
91
****************************************************************/
92
typedef size_t (*HUF_DecompressUsingDTableFn)(void *dst, size_t dstSize,
93
                                              const void *cSrc,
94
                                              size_t cSrcSize,
95
                                              const HUF_DTable *DTable);
96
97
#if DYNAMIC_BMI2
98
99
#define HUF_DGEN(fn)                                                        \
100
                                                                            \
101
    static size_t fn##_default(                                             \
102
                  void* dst,  size_t dstSize,                               \
103
            const void* cSrc, size_t cSrcSize,                              \
104
            const HUF_DTable* DTable)                                       \
105
0
    {                                                                       \
106
0
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
107
0
    }                                                                       \
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X2_usingDTable_internal_default
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X1_usingDTable_internal_default
108
                                                                            \
109
    static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2(                          \
110
                  void* dst,  size_t dstSize,                               \
111
            const void* cSrc, size_t cSrcSize,                              \
112
            const HUF_DTable* DTable)                                       \
113
234
    {                                                                       \
114
234
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
115
234
    }                                                                       \
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X2_usingDTable_internal_bmi2
huf_decompress.c:HUF_decompress1X1_usingDTable_internal_bmi2
Line
Count
Source
113
234
    {                                                                       \
114
234
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
115
234
    }                                                                       \
116
                                                                            \
117
    static size_t fn(void* dst, size_t dstSize, void const* cSrc,           \
118
                     size_t cSrcSize, HUF_DTable const* DTable, int flags)  \
119
234
    {                                                                       \
120
234
        if (flags & HUF_flags_bmi2) {                                       \
121
234
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
122
234
        }                                                                   \
123
234
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
124
234
    }
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X2_usingDTable_internal
huf_decompress.c:HUF_decompress1X1_usingDTable_internal
Line
Count
Source
119
234
    {                                                                       \
120
234
        if (flags & HUF_flags_bmi2) {                                       \
121
234
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
122
234
        }                                                                   \
123
234
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
124
234
    }
125
126
#else
127
128
#define HUF_DGEN(fn)                                                        \
129
    static size_t fn(void* dst, size_t dstSize, void const* cSrc,           \
130
                     size_t cSrcSize, HUF_DTable const* DTable, int flags)  \
131
    {                                                                       \
132
        (void)flags;                                                        \
133
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
134
    }
135
136
#endif
137
138
139
/*-***************************/
140
/*  generic DTableDesc       */
141
/*-***************************/
142
typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
143
144
static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
145
22.3k
{
146
22.3k
    DTableDesc dtd;
147
22.3k
    ZSTD_memcpy(&dtd, table, sizeof(dtd));
148
22.3k
    return dtd;
149
22.3k
}
150
151
26.6k
static size_t HUF_initFastDStream(BYTE const* ip) {
152
26.6k
    BYTE const lastByte = ip[7];
153
26.6k
    size_t const bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
154
26.6k
    size_t const value = MEM_readLEST(ip) | 1;
155
26.6k
    assert(bitsConsumed <= 8);
156
26.6k
    assert(sizeof(size_t) == 8);
157
26.6k
    return value << bitsConsumed;
158
26.6k
}
159
160
161
/**
162
 * The input/output arguments to the Huffman fast decoding loop:
163
 *
164
 * ip [in/out] - The input pointers, must be updated to reflect what is consumed.
165
 * op [in/out] - The output pointers, must be updated to reflect what is written.
166
 * bits [in/out] - The bitstream containers, must be updated to reflect the current state.
167
 * dt [in] - The decoding table.
168
 * ilowest [in] - The beginning of the valid range of the input. Decoders may read
169
 *                down to this pointer. It may be below iend[0].
170
 * oend [in] - The end of the output stream. op[3] must not cross oend.
171
 * iend [in] - The end of each input stream. ip[i] may cross iend[i],
172
 *             as long as it is above ilowest, but that indicates corruption.
173
 */
174
typedef struct {
175
    BYTE const* ip[4];
176
    BYTE* op[4];
177
    U64 bits[4];
178
    void const* dt;
179
    BYTE const* ilowest;
180
    BYTE* oend;
181
    BYTE const* iend[4];
182
} HUF_DecompressFastArgs;
183
184
typedef void (*HUF_DecompressFastLoopFn)(HUF_DecompressFastArgs*);
185
186
/**
187
 * Initializes args for the fast decoding loop.
188
 * @returns 1 on success
189
 *          0 if the fallback implementation should be used.
190
 *          Or an error code on failure.
191
 */
192
static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable)
193
9.46k
{
194
9.46k
    void const* dt = DTable + 1;
195
9.46k
    U32 const dtLog = HUF_getDTableDesc(DTable).tableLog;
196
197
9.46k
    const BYTE* const istart = (const BYTE*)src;
198
199
9.46k
    BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
200
201
    /* The fast decoding loop assumes 64-bit little-endian.
202
     * This condition is false on x32.
203
     */
204
9.46k
    if (!MEM_isLittleEndian() || MEM_32bits())
205
0
        return 0;
206
207
    /* Avoid nullptr addition */
208
9.46k
    if (dstSize == 0)
209
0
        return 0;
210
9.46k
    assert(dst != NULL);
211
212
    /* strict minimum : jump table + 1 byte per stream */
213
9.46k
    if (srcSize < 10)
214
66
        return ERROR(corruption_detected);
215
216
    /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers.
217
     * If table log is not correct at this point, fallback to the old decoder.
218
     * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder.
219
     */
220
9.40k
    if (dtLog != HUF_DECODER_FAST_TABLELOG)
221
721
        return 0;
222
223
    /* Read the jump table. */
224
8.68k
    {
225
8.68k
        size_t const length1 = MEM_readLE16(istart);
226
8.68k
        size_t const length2 = MEM_readLE16(istart+2);
227
8.68k
        size_t const length3 = MEM_readLE16(istart+4);
228
8.68k
        size_t const length4 = srcSize - (length1 + length2 + length3 + 6);
229
8.68k
        args->iend[0] = istart + 6;  /* jumpTable */
230
8.68k
        args->iend[1] = args->iend[0] + length1;
231
8.68k
        args->iend[2] = args->iend[1] + length2;
232
8.68k
        args->iend[3] = args->iend[2] + length3;
233
234
        /* HUF_initFastDStream() requires this, and this small of an input
235
         * won't benefit from the ASM loop anyways.
236
         */
237
8.68k
        if (length1 < 8 || length2 < 8 || length3 < 8 || length4 < 8)
238
1.76k
            return 0;
239
6.92k
        if (length4 > srcSize) return ERROR(corruption_detected);   /* overflow */
240
6.92k
    }
241
    /* ip[] contains the position that is currently loaded into bits[]. */
242
6.66k
    args->ip[0] = args->iend[1] - sizeof(U64);
243
6.66k
    args->ip[1] = args->iend[2] - sizeof(U64);
244
6.66k
    args->ip[2] = args->iend[3] - sizeof(U64);
245
6.66k
    args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64);
246
247
    /* op[] contains the output pointers. */
248
6.66k
    args->op[0] = (BYTE*)dst;
249
6.66k
    args->op[1] = args->op[0] + (dstSize+3)/4;
250
6.66k
    args->op[2] = args->op[1] + (dstSize+3)/4;
251
6.66k
    args->op[3] = args->op[2] + (dstSize+3)/4;
252
253
    /* No point to call the ASM loop for tiny outputs. */
254
6.66k
    if (args->op[3] >= oend)
255
1
        return 0;
256
257
    /* bits[] is the bit container.
258
        * It is read from the MSB down to the LSB.
259
        * It is shifted left as it is read, and zeros are
260
        * shifted in. After the lowest valid bit a 1 is
261
        * set, so that CountTrailingZeros(bits[]) can be used
262
        * to count how many bits we've consumed.
263
        */
264
6.66k
    args->bits[0] = HUF_initFastDStream(args->ip[0]);
265
6.66k
    args->bits[1] = HUF_initFastDStream(args->ip[1]);
266
6.66k
    args->bits[2] = HUF_initFastDStream(args->ip[2]);
267
6.66k
    args->bits[3] = HUF_initFastDStream(args->ip[3]);
268
269
    /* The decoders must be sure to never read beyond ilowest.
270
     * This is lower than iend[0], but allowing decoders to read
271
     * down to ilowest can allow an extra iteration or two in the
272
     * fast loop.
273
     */
274
6.66k
    args->ilowest = istart;
275
276
6.66k
    args->oend = oend;
277
6.66k
    args->dt = dt;
278
279
6.66k
    return 1;
280
6.66k
}
281
282
static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArgs const* args, int stream, BYTE* segmentEnd)
283
26.4k
{
284
    /* Validate that we haven't overwritten. */
285
26.4k
    if (args->op[stream] > segmentEnd)
286
0
        return ERROR(corruption_detected);
287
    /* Validate that we haven't read beyond iend[].
288
        * Note that ip[] may be < iend[] because the MSB is
289
        * the next bit to read, and we may have consumed 100%
290
        * of the stream, so down to iend[i] - 8 is valid.
291
        */
292
26.4k
    if (args->ip[stream] < args->iend[stream] - 8)
293
135
        return ERROR(corruption_detected);
294
295
    /* Construct the BIT_DStream_t. */
296
26.3k
    assert(sizeof(size_t) == 8);
297
26.3k
    bit->bitContainer = MEM_readLEST(args->ip[stream]);
298
26.3k
    bit->bitsConsumed = ZSTD_countTrailingZeros64(args->bits[stream]);
299
26.3k
    bit->start = (const char*)args->ilowest;
300
26.3k
    bit->limitPtr = bit->start + sizeof(size_t);
301
26.3k
    bit->ptr = (const char*)args->ip[stream];
302
303
26.3k
    return 0;
304
26.4k
}
305
306
/* Calls X(N) for each stream 0, 1, 2, 3. */
307
#define HUF_4X_FOR_EACH_STREAM(X) \
308
0
    do {                          \
309
0
        X(0);                     \
310
0
        X(1);                     \
311
0
        X(2);                     \
312
0
        X(3);                     \
313
0
    } while (0)
314
315
/* Calls X(N, var) for each stream 0, 1, 2, 3. */
316
#define HUF_4X_FOR_EACH_STREAM_WITH_VAR(X, var) \
317
0
    do {                                        \
318
0
        X(0, (var));                            \
319
0
        X(1, (var));                            \
320
0
        X(2, (var));                            \
321
0
        X(3, (var));                            \
322
0
    } while (0)
323
324
325
#ifndef HUF_FORCE_DECOMPRESS_X2
326
327
/*-***************************/
328
/*  single-symbol decoding   */
329
/*-***************************/
330
typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1;   /* single-symbol decoding */
331
332
/**
333
 * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at
334
 * a time.
335
 */
336
123k
static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
337
123k
    U64 D4;
338
123k
    if (MEM_isLittleEndian()) {
339
123k
        D4 = (U64)((symbol << 8) + nbBits);
340
123k
    } else {
341
0
        D4 = (U64)(symbol + (nbBits << 8));
342
0
    }
343
123k
    assert(D4 < (1U << 16));
344
123k
    D4 *= 0x0001000100010001ULL;
345
123k
    return D4;
346
123k
}
347
348
/**
349
 * Increase the tableLog to targetTableLog and rescales the stats.
350
 * If tableLog > targetTableLog this is a no-op.
351
 * @returns New tableLog
352
 */
353
static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog)
354
7.55k
{
355
7.55k
    if (tableLog > targetTableLog)
356
144
        return tableLog;
357
7.40k
    if (tableLog < targetTableLog) {
358
7.36k
        U32 const scale = targetTableLog - tableLog;
359
7.36k
        U32 s;
360
        /* Increase the weight for all non-zero probability symbols by scale. */
361
173k
        for (s = 0; s < nbSymbols; ++s) {
362
166k
            huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale);
363
166k
        }
364
        /* Update rankVal to reflect the new weights.
365
         * All weights except 0 get moved to weight + scale.
366
         * Weights [1, scale] are empty.
367
         */
368
33.1k
        for (s = targetTableLog; s > scale; --s) {
369
25.8k
            rankVal[s] = rankVal[s - scale];
370
25.8k
        }
371
62.5k
        for (s = scale; s > 0; --s) {
372
55.1k
            rankVal[s] = 0;
373
55.1k
        }
374
7.36k
    }
375
7.40k
    return targetTableLog;
376
7.55k
}
377
378
typedef struct {
379
        U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
380
        U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1];
381
        U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
382
        BYTE symbols[HUF_SYMBOLVALUE_MAX + 1];
383
        BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
384
} HUF_ReadDTableX1_Workspace;
385
386
size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags)
387
8.60k
{
388
8.60k
    U32 tableLog = 0;
389
8.60k
    U32 nbSymbols = 0;
390
8.60k
    size_t iSize;
391
8.60k
    void* const dtPtr = DTable + 1;
392
8.60k
    HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;
393
8.60k
    HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace;
394
395
8.60k
    DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp));
396
8.60k
    if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge);
397
398
8.60k
    DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
399
    /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */   /* is not necessary, even though some analyzer complain ... */
400
401
8.60k
    iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), flags);
402
8.60k
    if (HUF_isError(iSize)) return iSize;
403
404
405
    /* Table header */
406
7.55k
    {   DTableDesc dtd = HUF_getDTableDesc(DTable);
407
7.55k
        U32 const maxTableLog = dtd.maxTableLog + 1;
408
7.55k
        U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG);
409
7.55k
        tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog);
410
7.55k
        if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */
411
7.55k
        dtd.tableType = 0;
412
7.55k
        dtd.tableLog = (BYTE)tableLog;
413
7.55k
        ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
414
7.55k
    }
415
416
    /* Compute symbols and rankStart given rankVal:
417
     *
418
     * rankVal already contains the number of values of each weight.
419
     *
420
     * symbols contains the symbols ordered by weight. First are the rankVal[0]
421
     * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on.
422
     * symbols[0] is filled (but unused) to avoid a branch.
423
     *
424
     * rankStart contains the offset where each rank belongs in the DTable.
425
     * rankStart[0] is not filled because there are no entries in the table for
426
     * weight 0.
427
     */
428
0
    {   int n;
429
7.55k
        U32 nextRankStart = 0;
430
7.55k
        int const unroll = 4;
431
7.55k
        int const nLimit = (int)nbSymbols - unroll + 1;
432
98.2k
        for (n=0; n<(int)tableLog+1; n++) {
433
90.7k
            U32 const curr = nextRankStart;
434
90.7k
            nextRankStart += wksp->rankVal[n];
435
90.7k
            wksp->rankStart[n] = curr;
436
90.7k
        }
437
51.1k
        for (n=0; n < nLimit; n += unroll) {
438
43.6k
            int u;
439
218k
            for (u=0; u < unroll; ++u) {
440
174k
                size_t const w = wksp->huffWeight[n+u];
441
174k
                wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u);
442
174k
            }
443
43.6k
        }
444
20.6k
        for (; n < (int)nbSymbols; ++n) {
445
13.1k
            size_t const w = wksp->huffWeight[n];
446
13.1k
            wksp->symbols[wksp->rankStart[w]++] = (BYTE)n;
447
13.1k
        }
448
7.55k
    }
449
450
    /* fill DTable
451
     * We fill all entries of each weight in order.
452
     * That way length is a constant for each iteration of the outer loop.
453
     * We can switch based on the length to a different inner loop which is
454
     * optimized for that particular case.
455
     */
456
7.55k
    {   U32 w;
457
7.55k
        int symbol = wksp->rankVal[0];
458
7.55k
        int rankStart = 0;
459
90.7k
        for (w=1; w<tableLog+1; ++w) {
460
83.1k
            int const symbolCount = wksp->rankVal[w];
461
83.1k
            int const length = (1 << w) >> 1;
462
83.1k
            int uStart = rankStart;
463
83.1k
            BYTE const nbBits = (BYTE)(tableLog + 1 - w);
464
83.1k
            int s;
465
83.1k
            int u;
466
83.1k
            switch (length) {
467
7.55k
            case 1:
468
14.4k
                for (s=0; s<symbolCount; ++s) {
469
6.93k
                    HUF_DEltX1 D;
470
6.93k
                    D.byte = wksp->symbols[symbol + s];
471
6.93k
                    D.nbBits = nbBits;
472
6.93k
                    dt[uStart] = D;
473
6.93k
                    uStart += 1;
474
6.93k
                }
475
7.55k
                break;
476
7.55k
            case 2:
477
9.10k
                for (s=0; s<symbolCount; ++s) {
478
1.55k
                    HUF_DEltX1 D;
479
1.55k
                    D.byte = wksp->symbols[symbol + s];
480
1.55k
                    D.nbBits = nbBits;
481
1.55k
                    dt[uStart+0] = D;
482
1.55k
                    dt[uStart+1] = D;
483
1.55k
                    uStart += 2;
484
1.55k
                }
485
7.55k
                break;
486
7.55k
            case 4:
487
9.15k
                for (s=0; s<symbolCount; ++s) {
488
1.60k
                    U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
489
1.60k
                    MEM_write64(dt + uStart, D4);
490
1.60k
                    uStart += 4;
491
1.60k
                }
492
7.55k
                break;
493
7.55k
            case 8:
494
50.0k
                for (s=0; s<symbolCount; ++s) {
495
42.4k
                    U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
496
42.4k
                    MEM_write64(dt + uStart, D4);
497
42.4k
                    MEM_write64(dt + uStart + 4, D4);
498
42.4k
                    uStart += 8;
499
42.4k
                }
500
7.55k
                break;
501
52.9k
            default:
502
132k
                for (s=0; s<symbolCount; ++s) {
503
79.4k
                    U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
504
1.04M
                    for (u=0; u < length; u += 16) {
505
962k
                        MEM_write64(dt + uStart + u + 0, D4);
506
962k
                        MEM_write64(dt + uStart + u + 4, D4);
507
962k
                        MEM_write64(dt + uStart + u + 8, D4);
508
962k
                        MEM_write64(dt + uStart + u + 12, D4);
509
962k
                    }
510
79.4k
                    assert(u == length);
511
79.4k
                    uStart += length;
512
79.4k
                }
513
52.9k
                break;
514
83.1k
            }
515
83.1k
            symbol += symbolCount;
516
83.1k
            rankStart += symbolCount * length;
517
83.1k
        }
518
7.55k
    }
519
7.55k
    return iSize;
520
7.55k
}
521
522
FORCE_INLINE_TEMPLATE BYTE
523
HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)
524
1.55M
{
525
1.55M
    size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
526
1.55M
    BYTE const c = dt[val].byte;
527
1.55M
    BIT_skipBits(Dstream, dt[val].nbBits);
528
1.55M
    return c;
529
1.55M
}
530
531
#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \
532
1.55M
    do { *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog); } while (0)
533
534
#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr)      \
535
225k
    do {                                            \
536
225k
        if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
537
225k
            HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \
538
225k
    } while (0)
539
540
#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr)      \
541
450k
    do {                                            \
542
450k
        if (MEM_64bits())                           \
543
450k
            HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \
544
450k
    } while (0)
545
546
HINT_INLINE size_t
547
HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog)
548
27.6k
{
549
27.6k
    BYTE* const pStart = p;
550
551
    /* up to 4 symbols at a time */
552
27.6k
    if ((pEnd - p) > 3) {
553
249k
        while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {
554
223k
            HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
555
223k
            HUF_DECODE_SYMBOLX1_1(p, bitDPtr);
556
223k
            HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
557
223k
            HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
558
223k
        }
559
26.1k
    } else {
560
1.42k
        BIT_reloadDStream(bitDPtr);
561
1.42k
    }
562
563
    /* [0-3] symbols remaining */
564
27.6k
    if (MEM_32bits())
565
0
        while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd))
566
0
            HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
567
568
    /* no more data to retrieve from bitstream, no need to reload */
569
679k
    while (p < pEnd)
570
652k
        HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
571
572
27.6k
    return (size_t)(pEnd-pStart);
573
27.6k
}
574
575
FORCE_INLINE_TEMPLATE size_t
576
HUF_decompress1X1_usingDTable_internal_body(
577
          void* dst,  size_t dstSize,
578
    const void* cSrc, size_t cSrcSize,
579
    const HUF_DTable* DTable)
580
234
{
581
234
    BYTE* op = (BYTE*)dst;
582
234
    BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(op, (ptrdiff_t)dstSize);
583
234
    const void* dtPtr = DTable + 1;
584
234
    const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
585
234
    BIT_DStream_t bitD;
586
234
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
587
234
    U32 const dtLog = dtd.tableLog;
588
589
234
    CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
590
591
161
    HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog);
592
593
161
    if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
594
595
33
    return dstSize;
596
161
}
597
598
/* HUF_decompress4X1_usingDTable_internal_body():
599
 * Conditions :
600
 * @dstSize >= 6
601
 */
602
FORCE_INLINE_TEMPLATE size_t
603
HUF_decompress4X1_usingDTable_internal_body(
604
          void* dst,  size_t dstSize,
605
    const void* cSrc, size_t cSrcSize,
606
    const HUF_DTable* DTable)
607
772
{
608
    /* Check */
609
772
    if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
610
772
    if (dstSize < 6) return ERROR(corruption_detected);         /* stream 4-split doesn't work */
611
612
772
    {   const BYTE* const istart = (const BYTE*) cSrc;
613
772
        BYTE* const ostart = (BYTE*) dst;
614
772
        BYTE* const oend = ostart + dstSize;
615
772
        BYTE* const olimit = oend - 3;
616
772
        const void* const dtPtr = DTable + 1;
617
772
        const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
618
619
        /* Init */
620
772
        BIT_DStream_t bitD1;
621
772
        BIT_DStream_t bitD2;
622
772
        BIT_DStream_t bitD3;
623
772
        BIT_DStream_t bitD4;
624
772
        size_t const length1 = MEM_readLE16(istart);
625
772
        size_t const length2 = MEM_readLE16(istart+2);
626
772
        size_t const length3 = MEM_readLE16(istart+4);
627
772
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
628
772
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
629
772
        const BYTE* const istart2 = istart1 + length1;
630
772
        const BYTE* const istart3 = istart2 + length2;
631
772
        const BYTE* const istart4 = istart3 + length3;
632
772
        const size_t segmentSize = (dstSize+3) / 4;
633
772
        BYTE* const opStart2 = ostart + segmentSize;
634
772
        BYTE* const opStart3 = opStart2 + segmentSize;
635
772
        BYTE* const opStart4 = opStart3 + segmentSize;
636
772
        BYTE* op1 = ostart;
637
772
        BYTE* op2 = opStart2;
638
772
        BYTE* op3 = opStart3;
639
772
        BYTE* op4 = opStart4;
640
772
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
641
772
        U32 const dtLog = dtd.tableLog;
642
772
        U32 endSignal = 1;
643
644
772
        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
645
716
        if (opStart4 > oend) return ERROR(corruption_detected);      /* overflow */
646
716
        assert(dstSize >= 6); /* validated above */
647
716
        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
648
665
        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
649
562
        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
650
472
        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
651
652
        /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
653
396
        if ((size_t)(oend - op4) >= sizeof(size_t)) {
654
642
            for ( ; (endSignal) & (op4 < olimit) ; ) {
655
360
                HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
656
360
                HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
657
360
                HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
658
360
                HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
659
360
                HUF_DECODE_SYMBOLX1_1(op1, &bitD1);
660
360
                HUF_DECODE_SYMBOLX1_1(op2, &bitD2);
661
360
                HUF_DECODE_SYMBOLX1_1(op3, &bitD3);
662
360
                HUF_DECODE_SYMBOLX1_1(op4, &bitD4);
663
360
                HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
664
360
                HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
665
360
                HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
666
360
                HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
667
360
                HUF_DECODE_SYMBOLX1_0(op1, &bitD1);
668
360
                HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
669
360
                HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
670
360
                HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
671
360
                endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
672
360
                endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
673
360
                endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
674
360
                endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
675
360
            }
676
282
        }
677
678
        /* check corruption */
679
        /* note : should not be necessary : op# advance in lock step, and we control op4.
680
         *        but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */
681
396
        if (op1 > opStart2) return ERROR(corruption_detected);
682
396
        if (op2 > opStart3) return ERROR(corruption_detected);
683
396
        if (op3 > opStart4) return ERROR(corruption_detected);
684
        /* note : op4 supposed already verified within main loop */
685
686
        /* finish bitStreams one by one */
687
396
        HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog);
688
396
        HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog);
689
396
        HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog);
690
396
        HUF_decodeStreamX1(op4, &bitD4, oend,     dt, dtLog);
691
692
        /* check */
693
396
        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
694
396
          if (!endCheck) return ERROR(corruption_detected); }
695
696
        /* decoded size */
697
0
        return dstSize;
698
396
    }
699
396
}
700
701
#if HUF_NEED_BMI2_FUNCTION
702
static BMI2_TARGET_ATTRIBUTE
703
size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
704
772
                    size_t cSrcSize, HUF_DTable const* DTable) {
705
772
    return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
706
772
}
707
#endif
708
709
static
710
size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
711
0
                    size_t cSrcSize, HUF_DTable const* DTable) {
712
0
    return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
713
0
}
714
715
#if ZSTD_ENABLE_ASM_X86_64_BMI2
716
717
HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN;
718
719
#endif
720
721
static HUF_FAST_BMI2_ATTRS
722
void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args)
723
0
{
724
0
    U64 bits[4];
725
0
    BYTE const* ip[4];
726
0
    BYTE* op[4];
727
0
    U16 const* const dtable = (U16 const*)args->dt;
728
0
    BYTE* const oend = args->oend;
729
0
    BYTE const* const ilowest = args->ilowest;
730
731
    /* Copy the arguments to local variables */
732
0
    ZSTD_memcpy(&bits, &args->bits, sizeof(bits));
733
0
    ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip));
734
0
    ZSTD_memcpy(&op, &args->op, sizeof(op));
735
736
0
    assert(MEM_isLittleEndian());
737
0
    assert(!MEM_32bits());
738
739
0
    for (;;) {
740
0
        BYTE* olimit;
741
0
        int stream;
742
743
        /* Assert loop preconditions */
744
#ifndef NDEBUG
745
        for (stream = 0; stream < 4; ++stream) {
746
            assert(op[stream] <= (stream == 3 ? oend : op[stream + 1]));
747
            assert(ip[stream] >= ilowest);
748
        }
749
#endif
750
        /* Compute olimit */
751
0
        {
752
            /* Each iteration produces 5 output symbols per stream */
753
0
            size_t const oiters = (size_t)(oend - op[3]) / 5;
754
            /* Each iteration consumes up to 11 bits * 5 = 55 bits < 7 bytes
755
             * per stream.
756
             */
757
0
            size_t const iiters = (size_t)(ip[0] - ilowest) / 7;
758
            /* We can safely run iters iterations before running bounds checks */
759
0
            size_t const iters = MIN(oiters, iiters);
760
0
            size_t const symbols = iters * 5;
761
762
            /* We can simply check that op[3] < olimit, instead of checking all
763
             * of our bounds, since we can't hit the other bounds until we've run
764
             * iters iterations, which only happens when op[3] == olimit.
765
             */
766
0
            olimit = op[3] + symbols;
767
768
            /* Exit fast decoding loop once we reach the end. */
769
0
            if (op[3] == olimit)
770
0
                break;
771
772
            /* Exit the decoding loop if any input pointer has crossed the
773
             * previous one. This indicates corruption, and a precondition
774
             * to our loop is that ip[i] >= ip[0].
775
             */
776
0
            for (stream = 1; stream < 4; ++stream) {
777
0
                if (ip[stream] < ip[stream - 1])
778
0
                    goto _out;
779
0
            }
780
0
        }
781
782
#ifndef NDEBUG
783
        for (stream = 1; stream < 4; ++stream) {
784
            assert(ip[stream] >= ip[stream - 1]);
785
        }
786
#endif
787
788
0
#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol)                 \
789
0
    do {                                                        \
790
0
        int const index = (int)(bits[(_stream)] >> 53);         \
791
0
        int const entry = (int)dtable[index];                   \
792
0
        bits[(_stream)] <<= (entry & 0x3F);                     \
793
0
        op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \
794
0
    } while (0)
795
796
0
#define HUF_4X1_RELOAD_STREAM(_stream)                              \
797
0
    do {                                                            \
798
0
        int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
799
0
        int const nbBits = ctz & 7;                                 \
800
0
        int const nbBytes = ctz >> 3;                               \
801
0
        op[(_stream)] += 5;                                         \
802
0
        ip[(_stream)] -= nbBytes;                                   \
803
0
        bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1;            \
804
0
        bits[(_stream)] <<= nbBits;                                 \
805
0
    } while (0)
806
807
        /* Manually unroll the loop because compilers don't consistently
808
         * unroll the inner loops, which destroys performance.
809
         */
810
0
        do {
811
            /* Decode 5 symbols in each of the 4 streams */
812
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 0);
813
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 1);
814
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 2);
815
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 3);
816
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4);
817
818
            /* Reload each of the 4 the bitstreams */
819
0
            HUF_4X_FOR_EACH_STREAM(HUF_4X1_RELOAD_STREAM);
820
0
        } while (op[3] < olimit);
821
822
0
#undef HUF_4X1_DECODE_SYMBOL
823
0
#undef HUF_4X1_RELOAD_STREAM
824
0
    }
825
826
0
_out:
827
828
    /* Save the final values of each of the state variables back to args. */
829
0
    ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
830
0
    ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip));
831
0
    ZSTD_memcpy(&args->op, &op, sizeof(op));
832
0
}
833
834
/**
835
 * @returns @p dstSize on success (>= 6)
836
 *          0 if the fallback implementation should be used
837
 *          An error if an error occurred
838
 */
839
static HUF_FAST_BMI2_ATTRS
840
size_t
841
HUF_decompress4X1_usingDTable_internal_fast(
842
          void* dst,  size_t dstSize,
843
    const void* cSrc, size_t cSrcSize,
844
    const HUF_DTable* DTable,
845
    HUF_DecompressFastLoopFn loopFn)
846
7.41k
{
847
7.41k
    void const* dt = DTable + 1;
848
7.41k
    BYTE const* const ilowest = (BYTE const*)cSrc;
849
7.41k
    BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
850
7.41k
    HUF_DecompressFastArgs args;
851
7.41k
    {   size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
852
7.41k
        FORWARD_IF_ERROR(ret, "Failed to init fast loop args");
853
7.26k
        if (ret == 0)
854
772
            return 0;
855
7.26k
    }
856
857
6.49k
    assert(args.ip[0] >= args.ilowest);
858
6.49k
    loopFn(&args);
859
860
    /* Our loop guarantees that ip[] >= ilowest and that we haven't
861
    * overwritten any op[].
862
    */
863
6.49k
    assert(args.ip[0] >= ilowest);
864
6.49k
    assert(args.ip[0] >= ilowest);
865
6.49k
    assert(args.ip[1] >= ilowest);
866
6.49k
    assert(args.ip[2] >= ilowest);
867
6.49k
    assert(args.ip[3] >= ilowest);
868
6.49k
    assert(args.op[3] <= oend);
869
870
6.49k
    assert(ilowest == args.ilowest);
871
6.49k
    assert(ilowest + 6 == args.iend[0]);
872
6.49k
    (void)ilowest;
873
874
    /* finish bit streams one by one. */
875
6.49k
    {   size_t const segmentSize = (dstSize+3) / 4;
876
6.49k
        BYTE* segmentEnd = (BYTE*)dst;
877
6.49k
        int i;
878
32.3k
        for (i = 0; i < 4; ++i) {
879
25.9k
            BIT_DStream_t bit;
880
25.9k
            if (segmentSize <= (size_t)(oend - segmentEnd))
881
25.0k
                segmentEnd += segmentSize;
882
867
            else
883
867
                segmentEnd = oend;
884
25.9k
            FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
885
            /* Decompress and validate that we've produced exactly the expected length. */
886
25.8k
            args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG);
887
25.8k
            if (args.op[i] != segmentEnd) return ERROR(corruption_detected);
888
25.8k
        }
889
6.49k
    }
890
891
    /* decoded size */
892
6.44k
    assert(dstSize != 0);
893
6.44k
    return dstSize;
894
6.49k
}
895
896
HUF_DGEN(HUF_decompress1X1_usingDTable_internal)
897
898
static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
899
                    size_t cSrcSize, HUF_DTable const* DTable, int flags)
900
7.41k
{
901
7.41k
    HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X1_usingDTable_internal_default;
902
7.41k
    HUF_DecompressFastLoopFn loopFn = HUF_decompress4X1_usingDTable_internal_fast_c_loop;
903
904
7.41k
#if DYNAMIC_BMI2
905
7.41k
    if (flags & HUF_flags_bmi2) {
906
7.41k
        fallbackFn = HUF_decompress4X1_usingDTable_internal_bmi2;
907
7.41k
# if ZSTD_ENABLE_ASM_X86_64_BMI2
908
7.41k
        if (!(flags & HUF_flags_disableAsm)) {
909
7.41k
            loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop;
910
7.41k
        }
911
7.41k
# endif
912
7.41k
    } else {
913
0
        return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
914
0
    }
915
7.41k
#endif
916
917
#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
918
    if (!(flags & HUF_flags_disableAsm)) {
919
        loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop;
920
    }
921
#endif
922
923
7.41k
    if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) {
924
7.41k
        size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
925
7.41k
        if (ret != 0)
926
6.64k
            return ret;
927
7.41k
    }
928
772
    return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
929
7.41k
}
930
931
static size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
932
                                   const void* cSrc, size_t cSrcSize,
933
                                   void* workSpace, size_t wkspSize, int flags)
934
8.29k
{
935
8.29k
    const BYTE* ip = (const BYTE*) cSrc;
936
937
8.29k
    size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags);
938
8.29k
    if (HUF_isError(hSize)) return hSize;
939
7.40k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
940
7.38k
    ip += hSize; cSrcSize -= hSize;
941
942
7.38k
    return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
943
7.40k
}
944
945
#endif /* HUF_FORCE_DECOMPRESS_X2 */
946
947
948
#ifndef HUF_FORCE_DECOMPRESS_X1
949
950
/* *************************/
951
/* double-symbols decoding */
952
/* *************************/
953
954
typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2;  /* double-symbols decoding */
955
typedef struct { BYTE symbol; } sortedSymbol_t;
956
typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1];
957
typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];
958
959
/**
960
 * Constructs a HUF_DEltX2 in a U32.
961
 */
962
static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level)
963
657k
{
964
657k
    U32 seq;
965
657k
    DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0);
966
657k
    DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2);
967
657k
    DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3);
968
657k
    DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32));
969
657k
    if (MEM_isLittleEndian()) {
970
657k
        seq = level == 1 ? symbol : (baseSeq + (symbol << 8));
971
657k
        return seq + (nbBits << 16) + ((U32)level << 24);
972
657k
    } else {
973
0
        seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol);
974
0
        return (seq << 16) + (nbBits << 8) + (U32)level;
975
0
    }
976
657k
}
977
978
/**
979
 * Constructs a HUF_DEltX2.
980
 */
981
static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level)
982
325k
{
983
325k
    HUF_DEltX2 DElt;
984
325k
    U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
985
325k
    DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val));
986
325k
    ZSTD_memcpy(&DElt, &val, sizeof(val));
987
325k
    return DElt;
988
325k
}
989
990
/**
991
 * Constructs 2 HUF_DEltX2s and packs them into a U64.
992
 */
993
static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level)
994
331k
{
995
331k
    U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
996
331k
    return (U64)DElt + ((U64)DElt << 32);
997
331k
}
998
999
/**
1000
 * Fills the DTable rank with all the symbols from [begin, end) that are each
1001
 * nbBits long.
1002
 *
1003
 * @param DTableRank The start of the rank in the DTable.
1004
 * @param begin The first symbol to fill (inclusive).
1005
 * @param end The last symbol to fill (exclusive).
1006
 * @param nbBits Each symbol is nbBits long.
1007
 * @param tableLog The table log.
1008
 * @param baseSeq If level == 1 { 0 } else { the first level symbol }
1009
 * @param level The level in the table. Must be 1 or 2.
1010
 */
1011
static void HUF_fillDTableX2ForWeight(
1012
    HUF_DEltX2* DTableRank,
1013
    sortedSymbol_t const* begin, sortedSymbol_t const* end,
1014
    U32 nbBits, U32 tableLog,
1015
    U16 baseSeq, int const level)
1016
350k
{
1017
350k
    U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */);
1018
350k
    const sortedSymbol_t* ptr;
1019
350k
    assert(level >= 1 && level <= 2);
1020
350k
    switch (length) {
1021
78.1k
    case 1:
1022
283k
        for (ptr = begin; ptr != end; ++ptr) {
1023
204k
            HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
1024
204k
            *DTableRank++ = DElt;
1025
204k
        }
1026
78.1k
        break;
1027
76.4k
    case 2:
1028
197k
        for (ptr = begin; ptr != end; ++ptr) {
1029
120k
            HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
1030
120k
            DTableRank[0] = DElt;
1031
120k
            DTableRank[1] = DElt;
1032
120k
            DTableRank += 2;
1033
120k
        }
1034
76.4k
        break;
1035
71.6k
    case 4:
1036
177k
        for (ptr = begin; ptr != end; ++ptr) {
1037
106k
            U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
1038
106k
            ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
1039
106k
            ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
1040
106k
            DTableRank += 4;
1041
106k
        }
1042
71.6k
        break;
1043
62.1k
    case 8:
1044
119k
        for (ptr = begin; ptr != end; ++ptr) {
1045
57.2k
            U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
1046
57.2k
            ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
1047
57.2k
            ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
1048
57.2k
            ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
1049
57.2k
            ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
1050
57.2k
            DTableRank += 8;
1051
57.2k
        }
1052
62.1k
        break;
1053
62.5k
    default:
1054
156k
        for (ptr = begin; ptr != end; ++ptr) {
1055
93.7k
            U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
1056
93.7k
            HUF_DEltX2* const DTableRankEnd = DTableRank + length;
1057
500k
            for (; DTableRank != DTableRankEnd; DTableRank += 8) {
1058
406k
                ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
1059
406k
                ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
1060
406k
                ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
1061
406k
                ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
1062
406k
            }
1063
93.7k
        }
1064
62.5k
        break;
1065
350k
    }
1066
350k
}
1067
1068
/* HUF_fillDTableX2Level2() :
1069
 * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
1070
static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits,
1071
                           const U32* rankVal, const int minWeight, const int maxWeight1,
1072
                           const sortedSymbol_t* sortedSymbols, U32 const* rankStart,
1073
                           U32 nbBitsBaseline, U16 baseSeq)
1074
82.9k
{
1075
    /* Fill skipped values (all positions up to rankVal[minWeight]).
1076
     * These are positions only get a single symbol because the combined weight
1077
     * is too large.
1078
     */
1079
82.9k
    if (minWeight>1) {
1080
74.8k
        U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */);
1081
74.8k
        U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1);
1082
74.8k
        int const skipSize = rankVal[minWeight];
1083
74.8k
        assert(length > 1);
1084
74.8k
        assert((U32)skipSize < length);
1085
74.8k
        switch (length) {
1086
524
        case 2:
1087
524
            assert(skipSize == 1);
1088
524
            ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2));
1089
524
            break;
1090
4.87k
        case 4:
1091
4.87k
            assert(skipSize <= 4);
1092
4.87k
            ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2));
1093
4.87k
            ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2));
1094
4.87k
            break;
1095
69.4k
        default:
1096
69.4k
            {
1097
69.4k
                int i;
1098
205k
                for (i = 0; i < skipSize; i += 8) {
1099
136k
                    ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2));
1100
136k
                    ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2));
1101
136k
                    ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2));
1102
136k
                    ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2));
1103
136k
                }
1104
69.4k
            }
1105
74.8k
        }
1106
74.8k
    }
1107
1108
    /* Fill each of the second level symbols by weight. */
1109
82.9k
    {
1110
82.9k
        int w;
1111
432k
        for (w = minWeight; w < maxWeight1; ++w) {
1112
349k
            int const begin = rankStart[w];
1113
349k
            int const end = rankStart[w+1];
1114
349k
            U32 const nbBits = nbBitsBaseline - w;
1115
349k
            U32 const totalBits = nbBits + consumedBits;
1116
349k
            HUF_fillDTableX2ForWeight(
1117
349k
                DTable + rankVal[w],
1118
349k
                sortedSymbols + begin, sortedSymbols + end,
1119
349k
                totalBits, targetLog,
1120
349k
                baseSeq, /* level */ 2);
1121
349k
        }
1122
82.9k
    }
1123
82.9k
}
1124
1125
static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
1126
                           const sortedSymbol_t* sortedList,
1127
                           const U32* rankStart, rankValCol_t* rankValOrigin, const U32 maxWeight,
1128
                           const U32 nbBitsBaseline)
1129
2.05k
{
1130
2.05k
    U32* const rankVal = rankValOrigin[0];
1131
2.05k
    const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */
1132
2.05k
    const U32 minBits  = nbBitsBaseline - maxWeight;
1133
2.05k
    int w;
1134
2.05k
    int const wEnd = (int)maxWeight + 1;
1135
1136
    /* Fill DTable in order of weight. */
1137
18.3k
    for (w = 1; w < wEnd; ++w) {
1138
16.3k
        int const begin = (int)rankStart[w];
1139
16.3k
        int const end = (int)rankStart[w+1];
1140
16.3k
        U32 const nbBits = nbBitsBaseline - w;
1141
1142
16.3k
        if (targetLog-nbBits >= minBits) {
1143
            /* Enough room for a second symbol. */
1144
14.8k
            int start = rankVal[w];
1145
14.8k
            U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */);
1146
14.8k
            int minWeight = nbBits + scaleLog;
1147
14.8k
            int s;
1148
14.8k
            if (minWeight < 1) minWeight = 1;
1149
            /* Fill the DTable for every symbol of weight w.
1150
             * These symbols get at least 1 second symbol.
1151
             */
1152
97.7k
            for (s = begin; s != end; ++s) {
1153
82.9k
                HUF_fillDTableX2Level2(
1154
82.9k
                    DTable + start, targetLog, nbBits,
1155
82.9k
                    rankValOrigin[nbBits], minWeight, wEnd,
1156
82.9k
                    sortedList, rankStart,
1157
82.9k
                    nbBitsBaseline, sortedList[s].symbol);
1158
82.9k
                start += length;
1159
82.9k
            }
1160
14.8k
        } else {
1161
            /* Only a single symbol. */
1162
1.47k
            HUF_fillDTableX2ForWeight(
1163
1.47k
                DTable + rankVal[w],
1164
1.47k
                sortedList + begin, sortedList + end,
1165
1.47k
                nbBits, targetLog,
1166
1.47k
                /* baseSeq */ 0, /* level */ 1);
1167
1.47k
        }
1168
16.3k
    }
1169
2.05k
}
1170
1171
typedef struct {
1172
    rankValCol_t rankVal[HUF_TABLELOG_MAX];
1173
    U32 rankStats[HUF_TABLELOG_MAX + 1];
1174
    U32 rankStart0[HUF_TABLELOG_MAX + 3];
1175
    sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
1176
    BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
1177
    U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
1178
} HUF_ReadDTableX2_Workspace;
1179
1180
size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
1181
                       const void* src, size_t srcSize,
1182
                             void* workSpace, size_t wkspSize, int flags)
1183
2.48k
{
1184
2.48k
    U32 tableLog, maxW, nbSymbols;
1185
2.48k
    DTableDesc dtd = HUF_getDTableDesc(DTable);
1186
2.48k
    U32 maxTableLog = dtd.maxTableLog;
1187
2.48k
    size_t iSize;
1188
2.48k
    void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */
1189
2.48k
    HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
1190
2.48k
    U32 *rankStart;
1191
1192
2.48k
    HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace;
1193
1194
2.48k
    if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC);
1195
1196
2.48k
    rankStart = wksp->rankStart0 + 1;
1197
2.48k
    ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats));
1198
2.48k
    ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0));
1199
1200
2.48k
    DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable));   /* if compiler fails here, assertion is wrong */
1201
2.48k
    if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
1202
    /* ZSTD_memset(weightList, 0, sizeof(weightList)); */  /* is not necessary, even though some analyzer complain ... */
1203
1204
2.48k
    iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), flags);
1205
2.48k
    if (HUF_isError(iSize)) return iSize;
1206
1207
    /* check result */
1208
2.05k
    if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */
1209
2.05k
    if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG;
1210
1211
    /* find maxWeight */
1212
3.27k
    for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */
1213
1214
    /* Get start index of each weight */
1215
2.05k
    {   U32 w, nextRankStart = 0;
1216
18.3k
        for (w=1; w<maxW+1; w++) {
1217
16.3k
            U32 curr = nextRankStart;
1218
16.3k
            nextRankStart += wksp->rankStats[w];
1219
16.3k
            rankStart[w] = curr;
1220
16.3k
        }
1221
2.05k
        rankStart[0] = nextRankStart;   /* put all 0w symbols at the end of sorted list*/
1222
2.05k
        rankStart[maxW+1] = nextRankStart;
1223
2.05k
    }
1224
1225
    /* sort symbols by weight */
1226
2.05k
    {   U32 s;
1227
141k
        for (s=0; s<nbSymbols; s++) {
1228
139k
            U32 const w = wksp->weightList[s];
1229
139k
            U32 const r = rankStart[w]++;
1230
139k
            wksp->sortedSymbol[r].symbol = (BYTE)s;
1231
139k
        }
1232
2.05k
        rankStart[0] = 0;   /* forget 0w symbols; this is beginning of weight(1) */
1233
2.05k
    }
1234
1235
    /* Build rankVal */
1236
2.05k
    {   U32* const rankVal0 = wksp->rankVal[0];
1237
2.05k
        {   int const rescale = (maxTableLog-tableLog) - 1;   /* tableLog <= maxTableLog */
1238
2.05k
            U32 nextRankVal = 0;
1239
2.05k
            U32 w;
1240
18.3k
            for (w=1; w<maxW+1; w++) {
1241
16.3k
                U32 curr = nextRankVal;
1242
16.3k
                nextRankVal += wksp->rankStats[w] << (w+rescale);
1243
16.3k
                rankVal0[w] = curr;
1244
16.3k
        }   }
1245
2.05k
        {   U32 const minBits = tableLog+1 - maxW;
1246
2.05k
            U32 consumed;
1247
20.7k
            for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
1248
18.7k
                U32* const rankValPtr = wksp->rankVal[consumed];
1249
18.7k
                U32 w;
1250
176k
                for (w = 1; w < maxW+1; w++) {
1251
157k
                    rankValPtr[w] = rankVal0[w] >> consumed;
1252
157k
    }   }   }   }
1253
1254
2.05k
    HUF_fillDTableX2(dt, maxTableLog,
1255
2.05k
                   wksp->sortedSymbol,
1256
2.05k
                   wksp->rankStart0, wksp->rankVal, maxW,
1257
2.05k
                   tableLog+1);
1258
1259
2.05k
    dtd.tableLog = (BYTE)maxTableLog;
1260
2.05k
    dtd.tableType = 1;
1261
2.05k
    ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
1262
2.05k
    return iSize;
1263
2.05k
}
1264
1265
1266
FORCE_INLINE_TEMPLATE U32
1267
HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
1268
759k
{
1269
759k
    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
1270
759k
    ZSTD_memcpy(op, &dt[val].sequence, 2);
1271
759k
    BIT_skipBits(DStream, dt[val].nbBits);
1272
759k
    return dt[val].length;
1273
759k
}
1274
1275
FORCE_INLINE_TEMPLATE U32
1276
HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
1277
3.15k
{
1278
3.15k
    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
1279
3.15k
    ZSTD_memcpy(op, &dt[val].sequence, 1);
1280
3.15k
    if (dt[val].length==1) {
1281
1.16k
        BIT_skipBits(DStream, dt[val].nbBits);
1282
1.99k
    } else {
1283
1.99k
        if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
1284
514
            BIT_skipBits(DStream, dt[val].nbBits);
1285
514
            if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
1286
                /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
1287
32
                DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);
1288
514
        }
1289
1.99k
    }
1290
3.15k
    return 1;
1291
3.15k
}
1292
1293
#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
1294
704k
    do { ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); } while (0)
1295
1296
#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr)                     \
1297
18.4k
    do {                                                           \
1298
18.4k
        if (MEM_64bits() || (HUF_TABLELOG_MAX<=12))                \
1299
18.4k
            ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \
1300
18.4k
    } while (0)
1301
1302
#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr)                     \
1303
36.8k
    do {                                                           \
1304
36.8k
        if (MEM_64bits())                                          \
1305
36.8k
            ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \
1306
36.8k
    } while (0)
1307
1308
HINT_INLINE size_t
1309
HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd,
1310
                const HUF_DEltX2* const dt, const U32 dtLog)
1311
4.98k
{
1312
4.98k
    BYTE* const pStart = p;
1313
1314
    /* up to 8 symbols at a time */
1315
4.98k
    if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) {
1316
4.93k
        if (dtLog <= 11 && MEM_64bits()) {
1317
            /* up to 10 symbols at a time */
1318
28.1k
            while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) {
1319
25.1k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1320
25.1k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1321
25.1k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1322
25.1k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1323
25.1k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1324
25.1k
            }
1325
3.03k
        } else {
1326
            /* up to 8 symbols at a time */
1327
15.5k
            while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
1328
13.6k
                HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
1329
13.6k
                HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
1330
13.6k
                HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
1331
13.6k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1332
13.6k
            }
1333
1.89k
        }
1334
4.93k
    } else {
1335
58
        BIT_reloadDStream(bitDPtr);
1336
58
    }
1337
1338
    /* closer to end : up to 2 symbols at a time */
1339
4.98k
    if ((size_t)(pEnd - p) >= 2) {
1340
6.05k
        while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
1341
1.31k
            HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1342
1343
563k
        while (p <= pEnd-2)
1344
559k
            HUF_DECODE_SYMBOLX2_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */
1345
4.73k
    }
1346
1347
4.98k
    if (p < pEnd)
1348
3.15k
        p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog);
1349
1350
4.98k
    return p-pStart;
1351
4.98k
}
1352
1353
FORCE_INLINE_TEMPLATE size_t
1354
HUF_decompress1X2_usingDTable_internal_body(
1355
          void* dst,  size_t dstSize,
1356
    const void* cSrc, size_t cSrcSize,
1357
    const HUF_DTable* DTable)
1358
0
{
1359
0
    BIT_DStream_t bitD;
1360
1361
    /* Init */
1362
0
    CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
1363
1364
    /* decode */
1365
0
    {   BYTE* const ostart = (BYTE*) dst;
1366
0
        BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(ostart, (ptrdiff_t)dstSize);
1367
0
        const void* const dtPtr = DTable+1;   /* force compiler to not use strict-aliasing */
1368
0
        const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
1369
0
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
1370
0
        HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog);
1371
0
    }
1372
1373
    /* check */
1374
0
    if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
1375
1376
    /* decoded size */
1377
0
    return dstSize;
1378
0
}
1379
1380
/* HUF_decompress4X2_usingDTable_internal_body():
1381
 * Conditions:
1382
 * @dstSize >= 6
1383
 */
1384
FORCE_INLINE_TEMPLATE size_t
1385
HUF_decompress4X2_usingDTable_internal_body(
1386
          void* dst,  size_t dstSize,
1387
    const void* cSrc, size_t cSrcSize,
1388
    const HUF_DTable* DTable)
1389
1.71k
{
1390
1.71k
    if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */
1391
1.71k
    if (dstSize < 6) return ERROR(corruption_detected);         /* stream 4-split doesn't work */
1392
1393
1.71k
    {   const BYTE* const istart = (const BYTE*) cSrc;
1394
1.71k
        BYTE* const ostart = (BYTE*) dst;
1395
1.71k
        BYTE* const oend = ostart + dstSize;
1396
1.71k
        BYTE* const olimit = oend - (sizeof(size_t)-1);
1397
1.71k
        const void* const dtPtr = DTable+1;
1398
1.71k
        const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
1399
1400
        /* Init */
1401
1.71k
        BIT_DStream_t bitD1;
1402
1.71k
        BIT_DStream_t bitD2;
1403
1.71k
        BIT_DStream_t bitD3;
1404
1.71k
        BIT_DStream_t bitD4;
1405
1.71k
        size_t const length1 = MEM_readLE16(istart);
1406
1.71k
        size_t const length2 = MEM_readLE16(istart+2);
1407
1.71k
        size_t const length3 = MEM_readLE16(istart+4);
1408
1.71k
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
1409
1.71k
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
1410
1.71k
        const BYTE* const istart2 = istart1 + length1;
1411
1.71k
        const BYTE* const istart3 = istart2 + length2;
1412
1.71k
        const BYTE* const istart4 = istart3 + length3;
1413
1.71k
        size_t const segmentSize = (dstSize+3) / 4;
1414
1.71k
        BYTE* const opStart2 = ostart + segmentSize;
1415
1.71k
        BYTE* const opStart3 = opStart2 + segmentSize;
1416
1.71k
        BYTE* const opStart4 = opStart3 + segmentSize;
1417
1.71k
        BYTE* op1 = ostart;
1418
1.71k
        BYTE* op2 = opStart2;
1419
1.71k
        BYTE* op3 = opStart3;
1420
1.71k
        BYTE* op4 = opStart4;
1421
1.71k
        U32 endSignal = 1;
1422
1.71k
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
1423
1.71k
        U32 const dtLog = dtd.tableLog;
1424
1425
1.71k
        if (length4 > cSrcSize) return ERROR(corruption_detected);  /* overflow */
1426
1.65k
        if (opStart4 > oend) return ERROR(corruption_detected);     /* overflow */
1427
1.65k
        assert(dstSize >= 6 /* validated above */);
1428
1.65k
        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
1429
1.55k
        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
1430
1.34k
        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
1431
1.20k
        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
1432
1433
        /* 16-32 symbols per loop (4-8 symbols per stream) */
1434
1.13k
        if ((size_t)(oend - op4) >= sizeof(size_t)) {
1435
2.33k
            for ( ; (endSignal) & (op4 < olimit); ) {
1436
1.19k
#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
1437
1.19k
                HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1438
1.19k
                HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
1439
1.19k
                HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1440
1.19k
                HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
1441
1.19k
                HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1442
1.19k
                HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
1443
1.19k
                HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1444
1.19k
                HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
1445
1.19k
                endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
1446
1.19k
                endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
1447
1.19k
                HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1448
1.19k
                HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
1449
1.19k
                HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1450
1.19k
                HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
1451
1.19k
                HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1452
1.19k
                HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
1453
1.19k
                HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1454
1.19k
                HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
1455
1.19k
                endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
1456
1.19k
                endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
1457
#else
1458
                HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1459
                HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1460
                HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1461
                HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1462
                HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
1463
                HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
1464
                HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
1465
                HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
1466
                HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1467
                HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1468
                HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1469
                HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1470
                HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
1471
                HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
1472
                HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
1473
                HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
1474
                endSignal = (U32)LIKELY((U32)
1475
                            (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
1476
                        & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
1477
                        & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
1478
                        & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished));
1479
#endif
1480
1.19k
            }
1481
1.13k
        }
1482
1483
        /* check corruption */
1484
1.13k
        if (op1 > opStart2) return ERROR(corruption_detected);
1485
1.13k
        if (op2 > opStart3) return ERROR(corruption_detected);
1486
1.13k
        if (op3 > opStart4) return ERROR(corruption_detected);
1487
        /* note : op4 already verified within main loop */
1488
1489
        /* finish bitStreams one by one */
1490
1.13k
        HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
1491
1.13k
        HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
1492
1.13k
        HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
1493
1.13k
        HUF_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);
1494
1495
        /* check */
1496
1.13k
        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
1497
1.13k
          if (!endCheck) return ERROR(corruption_detected); }
1498
1499
        /* decoded size */
1500
0
        return dstSize;
1501
1.13k
    }
1502
1.13k
}
1503
1504
#if HUF_NEED_BMI2_FUNCTION
1505
static BMI2_TARGET_ATTRIBUTE
1506
size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
1507
1.71k
                    size_t cSrcSize, HUF_DTable const* DTable) {
1508
1.71k
    return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
1509
1.71k
}
1510
#endif
1511
1512
static
1513
size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
1514
0
                    size_t cSrcSize, HUF_DTable const* DTable) {
1515
0
    return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
1516
0
}
1517
1518
#if ZSTD_ENABLE_ASM_X86_64_BMI2
1519
1520
HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN;
1521
1522
#endif
1523
1524
static HUF_FAST_BMI2_ATTRS
1525
void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args)
1526
0
{
1527
0
    U64 bits[4];
1528
0
    BYTE const* ip[4];
1529
0
    BYTE* op[4];
1530
0
    BYTE* oend[4];
1531
0
    HUF_DEltX2 const* const dtable = (HUF_DEltX2 const*)args->dt;
1532
0
    BYTE const* const ilowest = args->ilowest;
1533
1534
    /* Copy the arguments to local registers. */
1535
0
    ZSTD_memcpy(&bits, &args->bits, sizeof(bits));
1536
0
    ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip));
1537
0
    ZSTD_memcpy(&op, &args->op, sizeof(op));
1538
1539
0
    oend[0] = op[1];
1540
0
    oend[1] = op[2];
1541
0
    oend[2] = op[3];
1542
0
    oend[3] = args->oend;
1543
1544
0
    assert(MEM_isLittleEndian());
1545
0
    assert(!MEM_32bits());
1546
1547
0
    for (;;) {
1548
0
        BYTE* olimit;
1549
0
        int stream;
1550
1551
        /* Assert loop preconditions */
1552
#ifndef NDEBUG
1553
        for (stream = 0; stream < 4; ++stream) {
1554
            assert(op[stream] <= oend[stream]);
1555
            assert(ip[stream] >= ilowest);
1556
        }
1557
#endif
1558
        /* Compute olimit */
1559
0
        {
1560
            /* Each loop does 5 table lookups for each of the 4 streams.
1561
             * Each table lookup consumes up to 11 bits of input, and produces
1562
             * up to 2 bytes of output.
1563
             */
1564
            /* We can consume up to 7 bytes of input per iteration per stream.
1565
             * We also know that each input pointer is >= ip[0]. So we can run
1566
             * iters loops before running out of input.
1567
             */
1568
0
            size_t iters = (size_t)(ip[0] - ilowest) / 7;
1569
            /* Each iteration can produce up to 10 bytes of output per stream.
1570
             * Each output stream my advance at different rates. So take the
1571
             * minimum number of safe iterations among all the output streams.
1572
             */
1573
0
            for (stream = 0; stream < 4; ++stream) {
1574
0
                size_t const oiters = (size_t)(oend[stream] - op[stream]) / 10;
1575
0
                iters = MIN(iters, oiters);
1576
0
            }
1577
1578
            /* Each iteration produces at least 5 output symbols. So until
1579
             * op[3] crosses olimit, we know we haven't executed iters
1580
             * iterations yet. This saves us maintaining an iters counter,
1581
             * at the expense of computing the remaining # of iterations
1582
             * more frequently.
1583
             */
1584
0
            olimit = op[3] + (iters * 5);
1585
1586
            /* Exit the fast decoding loop once we reach the end. */
1587
0
            if (op[3] == olimit)
1588
0
                break;
1589
1590
            /* Exit the decoding loop if any input pointer has crossed the
1591
             * previous one. This indicates corruption, and a precondition
1592
             * to our loop is that ip[i] >= ip[0].
1593
             */
1594
0
            for (stream = 1; stream < 4; ++stream) {
1595
0
                if (ip[stream] < ip[stream - 1])
1596
0
                    goto _out;
1597
0
            }
1598
0
        }
1599
1600
#ifndef NDEBUG
1601
        for (stream = 1; stream < 4; ++stream) {
1602
            assert(ip[stream] >= ip[stream - 1]);
1603
        }
1604
#endif
1605
1606
0
#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3)                      \
1607
0
    do {                                                              \
1608
0
        if ((_decode3) || (_stream) != 3) {                           \
1609
0
            int const index = (int)(bits[(_stream)] >> 53);           \
1610
0
            HUF_DEltX2 const entry = dtable[index];                   \
1611
0
            MEM_write16(op[(_stream)], entry.sequence); \
1612
0
            bits[(_stream)] <<= (entry.nbBits) & 0x3F;                \
1613
0
            op[(_stream)] += (entry.length);                          \
1614
0
        }                                                             \
1615
0
    } while (0)
1616
1617
0
#define HUF_4X2_RELOAD_STREAM(_stream)                                  \
1618
0
    do {                                                                \
1619
0
        HUF_4X2_DECODE_SYMBOL(3, 1);                                    \
1620
0
        {                                                               \
1621
0
            int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
1622
0
            int const nbBits = ctz & 7;                                 \
1623
0
            int const nbBytes = ctz >> 3;                               \
1624
0
            ip[(_stream)] -= nbBytes;                                   \
1625
0
            bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1;            \
1626
0
            bits[(_stream)] <<= nbBits;                                 \
1627
0
        }                                                               \
1628
0
    } while (0)
1629
1630
        /* Manually unroll the loop because compilers don't consistently
1631
         * unroll the inner loops, which destroys performance.
1632
         */
1633
0
        do {
1634
            /* Decode 5 symbols from each of the first 3 streams.
1635
             * The final stream will be decoded during the reload phase
1636
             * to reduce register pressure.
1637
             */
1638
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
1639
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
1640
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
1641
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
1642
0
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
1643
1644
            /* Decode one symbol from the final stream */
1645
0
            HUF_4X2_DECODE_SYMBOL(3, 1);
1646
1647
            /* Decode 4 symbols from the final stream & reload bitstreams.
1648
             * The final stream is reloaded last, meaning that all 5 symbols
1649
             * are decoded from the final stream before it is reloaded.
1650
             */
1651
0
            HUF_4X_FOR_EACH_STREAM(HUF_4X2_RELOAD_STREAM);
1652
0
        } while (op[3] < olimit);
1653
0
    }
1654
1655
0
#undef HUF_4X2_DECODE_SYMBOL
1656
0
#undef HUF_4X2_RELOAD_STREAM
1657
1658
0
_out:
1659
1660
    /* Save the final values of each of the state variables back to args. */
1661
0
    ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
1662
0
    ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip));
1663
0
    ZSTD_memcpy(&args->op, &op, sizeof(op));
1664
0
}
1665
1666
1667
static HUF_FAST_BMI2_ATTRS size_t
1668
HUF_decompress4X2_usingDTable_internal_fast(
1669
          void* dst,  size_t dstSize,
1670
    const void* cSrc, size_t cSrcSize,
1671
    const HUF_DTable* DTable,
1672
2.05k
    HUF_DecompressFastLoopFn loopFn) {
1673
2.05k
    void const* dt = DTable + 1;
1674
2.05k
    const BYTE* const ilowest = (const BYTE*)cSrc;
1675
2.05k
    BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
1676
2.05k
    HUF_DecompressFastArgs args;
1677
2.05k
    {
1678
2.05k
        size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
1679
2.05k
        FORWARD_IF_ERROR(ret, "Failed to init asm args");
1680
1.88k
        if (ret == 0)
1681
1.71k
            return 0;
1682
1.88k
    }
1683
1684
171
    assert(args.ip[0] >= args.ilowest);
1685
171
    loopFn(&args);
1686
1687
    /* note : op4 already verified within main loop */
1688
171
    assert(args.ip[0] >= ilowest);
1689
171
    assert(args.ip[1] >= ilowest);
1690
171
    assert(args.ip[2] >= ilowest);
1691
171
    assert(args.ip[3] >= ilowest);
1692
171
    assert(args.op[3] <= oend);
1693
1694
171
    assert(ilowest == args.ilowest);
1695
171
    assert(ilowest + 6 == args.iend[0]);
1696
171
    (void)ilowest;
1697
1698
    /* finish bitStreams one by one */
1699
171
    {
1700
171
        size_t const segmentSize = (dstSize+3) / 4;
1701
171
        BYTE* segmentEnd = (BYTE*)dst;
1702
171
        int i;
1703
612
        for (i = 0; i < 4; ++i) {
1704
525
            BIT_DStream_t bit;
1705
525
            if (segmentSize <= (size_t)(oend - segmentEnd))
1706
438
                segmentEnd += segmentSize;
1707
87
            else
1708
87
                segmentEnd = oend;
1709
525
            FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
1710
441
            args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG);
1711
441
            if (args.op[i] != segmentEnd)
1712
0
                return ERROR(corruption_detected);
1713
441
        }
1714
171
    }
1715
1716
    /* decoded size */
1717
87
    return dstSize;
1718
171
}
1719
1720
static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
1721
                    size_t cSrcSize, HUF_DTable const* DTable, int flags)
1722
2.05k
{
1723
2.05k
    HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X2_usingDTable_internal_default;
1724
2.05k
    HUF_DecompressFastLoopFn loopFn = HUF_decompress4X2_usingDTable_internal_fast_c_loop;
1725
1726
2.05k
#if DYNAMIC_BMI2
1727
2.05k
    if (flags & HUF_flags_bmi2) {
1728
2.05k
        fallbackFn = HUF_decompress4X2_usingDTable_internal_bmi2;
1729
2.05k
# if ZSTD_ENABLE_ASM_X86_64_BMI2
1730
2.05k
        if (!(flags & HUF_flags_disableAsm)) {
1731
2.05k
            loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop;
1732
2.05k
        }
1733
2.05k
# endif
1734
2.05k
    } else {
1735
0
        return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
1736
0
    }
1737
2.05k
#endif
1738
1739
#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
1740
    if (!(flags & HUF_flags_disableAsm)) {
1741
        loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop;
1742
    }
1743
#endif
1744
1745
2.05k
    if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) {
1746
2.05k
        size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
1747
2.05k
        if (ret != 0)
1748
344
            return ret;
1749
2.05k
    }
1750
1.71k
    return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
1751
2.05k
}
1752
1753
HUF_DGEN(HUF_decompress1X2_usingDTable_internal)
1754
1755
size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
1756
                                   const void* cSrc, size_t cSrcSize,
1757
                                   void* workSpace, size_t wkspSize, int flags)
1758
0
{
1759
0
    const BYTE* ip = (const BYTE*) cSrc;
1760
1761
0
    size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize,
1762
0
                                               workSpace, wkspSize, flags);
1763
0
    if (HUF_isError(hSize)) return hSize;
1764
0
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1765
0
    ip += hSize; cSrcSize -= hSize;
1766
1767
0
    return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, flags);
1768
0
}
1769
1770
static size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
1771
                                   const void* cSrc, size_t cSrcSize,
1772
                                   void* workSpace, size_t wkspSize, int flags)
1773
2.48k
{
1774
2.48k
    const BYTE* ip = (const BYTE*) cSrc;
1775
1776
2.48k
    size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize,
1777
2.48k
                                         workSpace, wkspSize, flags);
1778
2.48k
    if (HUF_isError(hSize)) return hSize;
1779
2.05k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1780
2.05k
    ip += hSize; cSrcSize -= hSize;
1781
1782
2.05k
    return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
1783
2.05k
}
1784
1785
#endif /* HUF_FORCE_DECOMPRESS_X1 */
1786
1787
1788
/* ***********************************/
1789
/* Universal decompression selectors */
1790
/* ***********************************/
1791
1792
1793
#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
1794
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
1795
static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] =
1796
{
1797
    /* single, double, quad */
1798
    {{0,0}, {1,1}},  /* Q==0 : impossible */
1799
    {{0,0}, {1,1}},  /* Q==1 : impossible */
1800
    {{ 150,216}, { 381,119}},   /* Q == 2 : 12-18% */
1801
    {{ 170,205}, { 514,112}},   /* Q == 3 : 18-25% */
1802
    {{ 177,199}, { 539,110}},   /* Q == 4 : 25-32% */
1803
    {{ 197,194}, { 644,107}},   /* Q == 5 : 32-38% */
1804
    {{ 221,192}, { 735,107}},   /* Q == 6 : 38-44% */
1805
    {{ 256,189}, { 881,106}},   /* Q == 7 : 44-50% */
1806
    {{ 359,188}, {1167,109}},   /* Q == 8 : 50-56% */
1807
    {{ 582,187}, {1570,114}},   /* Q == 9 : 56-62% */
1808
    {{ 688,187}, {1712,122}},   /* Q ==10 : 62-69% */
1809
    {{ 825,186}, {1965,136}},   /* Q ==11 : 69-75% */
1810
    {{ 976,185}, {2131,150}},   /* Q ==12 : 75-81% */
1811
    {{1180,186}, {2070,175}},   /* Q ==13 : 81-87% */
1812
    {{1377,185}, {1731,202}},   /* Q ==14 : 87-93% */
1813
    {{1412,185}, {1695,202}},   /* Q ==15 : 93-99% */
1814
};
1815
#endif
1816
1817
/** HUF_selectDecoder() :
1818
 *  Tells which decoder is likely to decode faster,
1819
 *  based on a set of pre-computed metrics.
1820
 * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .
1821
 *  Assumption : 0 < dstSize <= 128 KB */
1822
U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
1823
10.7k
{
1824
10.7k
    assert(dstSize > 0);
1825
10.7k
    assert(dstSize <= 128*1024);
1826
#if defined(HUF_FORCE_DECOMPRESS_X1)
1827
    (void)dstSize;
1828
    (void)cSrcSize;
1829
    return 0;
1830
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1831
    (void)dstSize;
1832
    (void)cSrcSize;
1833
    return 1;
1834
#else
1835
    /* decoder timing evaluation */
1836
10.7k
    {   U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 */
1837
10.7k
        U32 const D256 = (U32)(dstSize >> 8);
1838
10.7k
        U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
1839
10.7k
        U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
1840
10.7k
        DTime1 += DTime1 >> 5;  /* small advantage to algorithm using less memory, to reduce cache eviction */
1841
10.7k
        return DTime1 < DTime0;
1842
10.7k
    }
1843
10.7k
#endif
1844
10.7k
}
1845
1846
size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
1847
                                  const void* cSrc, size_t cSrcSize,
1848
                                  void* workSpace, size_t wkspSize, int flags)
1849
0
{
1850
    /* validation checks */
1851
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1852
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
1853
0
    if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
1854
0
    if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
1855
1856
0
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1857
#if defined(HUF_FORCE_DECOMPRESS_X1)
1858
        (void)algoNb;
1859
        assert(algoNb == 0);
1860
        return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1861
                                cSrcSize, workSpace, wkspSize, flags);
1862
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1863
        (void)algoNb;
1864
        assert(algoNb == 1);
1865
        return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1866
                                cSrcSize, workSpace, wkspSize, flags);
1867
#else
1868
0
        return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1869
0
                                cSrcSize, workSpace, wkspSize, flags):
1870
0
                        HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1871
0
                                cSrcSize, workSpace, wkspSize, flags);
1872
0
#endif
1873
0
    }
1874
0
}
1875
1876
1877
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags)
1878
124
{
1879
124
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
1880
#if defined(HUF_FORCE_DECOMPRESS_X1)
1881
    (void)dtd;
1882
    assert(dtd.tableType == 0);
1883
    return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1884
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1885
    (void)dtd;
1886
    assert(dtd.tableType == 1);
1887
    return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1888
#else
1889
124
    return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) :
1890
124
                           HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1891
124
#endif
1892
124
}
1893
1894
#ifndef HUF_FORCE_DECOMPRESS_X2
1895
size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags)
1896
316
{
1897
316
    const BYTE* ip = (const BYTE*) cSrc;
1898
1899
316
    size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags);
1900
316
    if (HUF_isError(hSize)) return hSize;
1901
145
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1902
110
    ip += hSize; cSrcSize -= hSize;
1903
1904
110
    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
1905
145
}
1906
#endif
1907
1908
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags)
1909
24
{
1910
24
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
1911
#if defined(HUF_FORCE_DECOMPRESS_X1)
1912
    (void)dtd;
1913
    assert(dtd.tableType == 0);
1914
    return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1915
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1916
    (void)dtd;
1917
    assert(dtd.tableType == 1);
1918
    return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1919
#else
1920
24
    return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) :
1921
24
                           HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1922
24
#endif
1923
24
}
1924
1925
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags)
1926
10.8k
{
1927
    /* validation checks */
1928
10.8k
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1929
10.8k
    if (cSrcSize == 0) return ERROR(corruption_detected);
1930
1931
10.7k
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1932
#if defined(HUF_FORCE_DECOMPRESS_X1)
1933
        (void)algoNb;
1934
        assert(algoNb == 0);
1935
        return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
1936
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1937
        (void)algoNb;
1938
        assert(algoNb == 1);
1939
        return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
1940
#else
1941
10.7k
        return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags) :
1942
10.7k
                        HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
1943
10.8k
#endif
1944
10.8k
    }
1945
10.8k
}