Coverage Report

Created: 2025-11-16 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zstd/lib/decompress/huf_decompress.c
Line
Count
Source
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
3.95k
#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
1.84k
# 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
2.54k
#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
70
    {                                                                       \
114
70
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
115
70
    }                                                                       \
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X2_usingDTable_internal_bmi2
huf_decompress.c:HUF_decompress1X1_usingDTable_internal_bmi2
Line
Count
Source
113
70
    {                                                                       \
114
70
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
115
70
    }                                                                       \
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
70
    {                                                                       \
120
70
        if (flags & HUF_flags_bmi2) {                                       \
121
70
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
122
70
        }                                                                   \
123
70
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
124
70
    }
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X2_usingDTable_internal
huf_decompress.c:HUF_decompress1X1_usingDTable_internal
Line
Count
Source
119
70
    {                                                                       \
120
70
        if (flags & HUF_flags_bmi2) {                                       \
121
70
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
122
70
        }                                                                   \
123
70
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
124
70
    }
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
2.63k
{
146
2.63k
    DTableDesc dtd;
147
2.63k
    ZSTD_memcpy(&dtd, table, sizeof(dtd));
148
2.63k
    return dtd;
149
2.63k
}
150
151
1.04k
static size_t HUF_initFastDStream(BYTE const* ip) {
152
1.04k
    BYTE const lastByte = ip[7];
153
1.04k
    size_t const bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
154
1.04k
    size_t const value = MEM_readLEST(ip) | 1;
155
1.04k
    assert(bitsConsumed <= 8);
156
1.04k
    assert(sizeof(size_t) == 8);
157
1.04k
    return value << bitsConsumed;
158
1.04k
}
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
923
{
194
923
    void const* dt = DTable + 1;
195
923
    U32 const dtLog = HUF_getDTableDesc(DTable).tableLog;
196
197
923
    const BYTE* const istart = (const BYTE*)src;
198
199
923
    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
923
    if (!MEM_isLittleEndian() || MEM_32bits())
205
0
        return 0;
206
207
    /* Avoid nullptr addition */
208
923
    if (dstSize == 0)
209
0
        return 0;
210
923
    assert(dst != NULL);
211
212
    /* strict minimum : jump table + 1 byte per stream */
213
923
    if (srcSize < 10)
214
3
        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
920
    if (dtLog != HUF_DECODER_FAST_TABLELOG)
221
118
        return 0;
222
223
    /* Read the jump table. */
224
802
    {
225
802
        size_t const length1 = MEM_readLE16(istart);
226
802
        size_t const length2 = MEM_readLE16(istart+2);
227
802
        size_t const length3 = MEM_readLE16(istart+4);
228
802
        size_t const length4 = srcSize - (length1 + length2 + length3 + 6);
229
802
        args->iend[0] = istart + 6;  /* jumpTable */
230
802
        args->iend[1] = args->iend[0] + length1;
231
802
        args->iend[2] = args->iend[1] + length2;
232
802
        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
802
        if (length1 < 8 || length2 < 8 || length3 < 8 || length4 < 8)
238
428
            return 0;
239
374
        if (length4 > srcSize) return ERROR(corruption_detected);   /* overflow */
240
374
    }
241
    /* ip[] contains the position that is currently loaded into bits[]. */
242
262
    args->ip[0] = args->iend[1] - sizeof(U64);
243
262
    args->ip[1] = args->iend[2] - sizeof(U64);
244
262
    args->ip[2] = args->iend[3] - sizeof(U64);
245
262
    args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64);
246
247
    /* op[] contains the output pointers. */
248
262
    args->op[0] = (BYTE*)dst;
249
262
    args->op[1] = args->op[0] + (dstSize+3)/4;
250
262
    args->op[2] = args->op[1] + (dstSize+3)/4;
251
262
    args->op[3] = args->op[2] + (dstSize+3)/4;
252
253
    /* No point to call the ASM loop for tiny outputs. */
254
262
    if (args->op[3] >= oend)
255
2
        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
260
    args->bits[0] = HUF_initFastDStream(args->ip[0]);
265
260
    args->bits[1] = HUF_initFastDStream(args->ip[1]);
266
260
    args->bits[2] = HUF_initFastDStream(args->ip[2]);
267
260
    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
260
    args->ilowest = istart;
275
276
260
    args->oend = oend;
277
260
    args->dt = dt;
278
279
260
    return 1;
280
262
}
281
282
static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArgs const* args, int stream, BYTE* segmentEnd)
283
890
{
284
    /* Validate that we haven't overwritten. */
285
890
    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
890
    if (args->ip[stream] < args->iend[stream] - 8)
293
114
        return ERROR(corruption_detected);
294
295
    /* Construct the BIT_DStream_t. */
296
776
    assert(sizeof(size_t) == 8);
297
776
    bit->bitContainer = MEM_readLEST(args->ip[stream]);
298
776
    bit->bitsConsumed = ZSTD_countTrailingZeros64(args->bits[stream]);
299
776
    bit->start = (const char*)args->ilowest;
300
776
    bit->limitPtr = bit->start + sizeof(size_t);
301
776
    bit->ptr = (const char*)args->ip[stream];
302
303
776
    return 0;
304
890
}
305
306
/* Calls X(N) for each stream 0, 1, 2, 3. */
307
#define HUF_4X_FOR_EACH_STREAM(X) \
308
1.68k
    do {                          \
309
1.68k
        X(0);                     \
310
1.68k
        X(1);                     \
311
1.68k
        X(2);                     \
312
1.68k
        X(3);                     \
313
1.68k
    } 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
25.2k
    do {                                        \
318
25.2k
        X(0, (var));                            \
319
25.2k
        X(1, (var));                            \
320
25.2k
        X(2, (var));                            \
321
25.2k
        X(3, (var));                            \
322
25.2k
    } 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
12.3k
static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
337
12.3k
    U64 D4;
338
12.3k
    if (MEM_isLittleEndian()) {
339
12.3k
        D4 = (U64)((symbol << 8) + nbBits);
340
12.3k
    } else {
341
0
        D4 = (U64)(symbol + (nbBits << 8));
342
0
    }
343
12.3k
    assert(D4 < (1U << 16));
344
12.3k
    D4 *= 0x0001000100010001ULL;
345
12.3k
    return D4;
346
12.3k
}
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
398
{
355
398
    if (tableLog > targetTableLog)
356
61
        return tableLog;
357
337
    if (tableLog < targetTableLog) {
358
292
        U32 const scale = targetTableLog - tableLog;
359
292
        U32 s;
360
        /* Increase the weight for all non-zero probability symbols by scale. */
361
38.5k
        for (s = 0; s < nbSymbols; ++s) {
362
38.3k
            huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale);
363
38.3k
        }
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
2.33k
        for (s = targetTableLog; s > scale; --s) {
369
2.04k
            rankVal[s] = rankVal[s - scale];
370
2.04k
        }
371
1.46k
        for (s = scale; s > 0; --s) {
372
1.16k
            rankVal[s] = 0;
373
1.16k
        }
374
292
    }
375
337
    return targetTableLog;
376
398
}
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
578
{
388
578
    U32 tableLog = 0;
389
578
    U32 nbSymbols = 0;
390
578
    size_t iSize;
391
578
    void* const dtPtr = DTable + 1;
392
578
    HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;
393
578
    HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace;
394
395
578
    DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp));
396
578
    if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge);
397
398
578
    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
578
    iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), flags);
402
578
    if (HUF_isError(iSize)) return iSize;
403
404
405
    /* Table header */
406
398
    {   DTableDesc dtd = HUF_getDTableDesc(DTable);
407
398
        U32 const maxTableLog = dtd.maxTableLog + 1;
408
398
        U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG);
409
398
        tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog);
410
398
        if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */
411
398
        dtd.tableType = 0;
412
398
        dtd.tableLog = (BYTE)tableLog;
413
398
        ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
414
398
    }
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
398
        U32 nextRankStart = 0;
430
398
        int const unroll = 4;
431
398
        int const nLimit = (int)nbSymbols - unroll + 1;
432
5.23k
        for (n=0; n<(int)tableLog+1; n++) {
433
4.83k
            U32 const curr = nextRankStart;
434
4.83k
            nextRankStart += wksp->rankVal[n];
435
4.83k
            wksp->rankStart[n] = curr;
436
4.83k
        }
437
10.9k
        for (n=0; n < nLimit; n += unroll) {
438
10.5k
            int u;
439
52.9k
            for (u=0; u < unroll; ++u) {
440
42.3k
                size_t const w = wksp->huffWeight[n+u];
441
42.3k
                wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u);
442
42.3k
            }
443
10.5k
        }
444
826
        for (; n < (int)nbSymbols; ++n) {
445
428
            size_t const w = wksp->huffWeight[n];
446
428
            wksp->symbols[wksp->rankStart[w]++] = (BYTE)n;
447
428
        }
448
398
    }
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
398
    {   U32 w;
457
398
        int symbol = wksp->rankVal[0];
458
398
        int rankStart = 0;
459
4.83k
        for (w=1; w<tableLog+1; ++w) {
460
4.43k
            int const symbolCount = wksp->rankVal[w];
461
4.43k
            int const length = (1 << w) >> 1;
462
4.43k
            int uStart = rankStart;
463
4.43k
            BYTE const nbBits = (BYTE)(tableLog + 1 - w);
464
4.43k
            int s;
465
4.43k
            int u;
466
4.43k
            switch (length) {
467
398
            case 1:
468
770
                for (s=0; s<symbolCount; ++s) {
469
372
                    HUF_DEltX1 D;
470
372
                    D.byte = wksp->symbols[symbol + s];
471
372
                    D.nbBits = nbBits;
472
372
                    dt[uStart] = D;
473
372
                    uStart += 1;
474
372
                }
475
398
                break;
476
398
            case 2:
477
1.13k
                for (s=0; s<symbolCount; ++s) {
478
736
                    HUF_DEltX1 D;
479
736
                    D.byte = wksp->symbols[symbol + s];
480
736
                    D.nbBits = nbBits;
481
736
                    dt[uStart+0] = D;
482
736
                    dt[uStart+1] = D;
483
736
                    uStart += 2;
484
736
                }
485
398
                break;
486
398
            case 4:
487
1.16k
                for (s=0; s<symbolCount; ++s) {
488
771
                    U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
489
771
                    MEM_write64(dt + uStart, D4);
490
771
                    uStart += 4;
491
771
                }
492
398
                break;
493
398
            case 8:
494
2.97k
                for (s=0; s<symbolCount; ++s) {
495
2.57k
                    U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
496
2.57k
                    MEM_write64(dt + uStart, D4);
497
2.57k
                    MEM_write64(dt + uStart + 4, D4);
498
2.57k
                    uStart += 8;
499
2.57k
                }
500
398
                break;
501
2.84k
            default:
502
11.8k
                for (s=0; s<symbolCount; ++s) {
503
9.00k
                    U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
504
66.1k
                    for (u=0; u < length; u += 16) {
505
57.1k
                        MEM_write64(dt + uStart + u + 0, D4);
506
57.1k
                        MEM_write64(dt + uStart + u + 4, D4);
507
57.1k
                        MEM_write64(dt + uStart + u + 8, D4);
508
57.1k
                        MEM_write64(dt + uStart + u + 12, D4);
509
57.1k
                    }
510
9.00k
                    assert(u == length);
511
9.00k
                    uStart += length;
512
9.00k
                }
513
2.84k
                break;
514
4.43k
            }
515
4.43k
            symbol += symbolCount;
516
4.43k
            rankStart += symbolCount * length;
517
4.43k
        }
518
398
    }
519
398
    return iSize;
520
398
}
521
522
FORCE_INLINE_TEMPLATE BYTE
523
HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)
524
108k
{
525
108k
    size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
526
108k
    BYTE const c = dt[val].byte;
527
108k
    BIT_skipBits(Dstream, dt[val].nbBits);
528
108k
    return c;
529
108k
}
530
531
#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \
532
108k
    do { *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog); } while (0)
533
534
#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr)      \
535
12.7k
    do {                                            \
536
12.7k
        if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
537
12.7k
            HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \
538
12.7k
    } while (0)
539
540
#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr)      \
541
25.5k
    do {                                            \
542
25.5k
        if (MEM_64bits())                           \
543
25.5k
            HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \
544
25.5k
    } 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
886
{
549
886
    BYTE* const pStart = p;
550
551
    /* up to 4 symbols at a time */
552
886
    if ((pEnd - p) > 3) {
553
12.5k
        while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {
554
11.7k
            HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
555
11.7k
            HUF_DECODE_SYMBOLX1_1(p, bitDPtr);
556
11.7k
            HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
557
11.7k
            HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
558
11.7k
        }
559
761
    } else {
560
125
        BIT_reloadDStream(bitDPtr);
561
125
    }
562
563
    /* [0-3] symbols remaining */
564
886
    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
57.7k
    while (p < pEnd)
570
56.8k
        HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
571
572
886
    return (size_t)(pEnd-pStart);
573
886
}
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
70
{
581
70
    BYTE* op = (BYTE*)dst;
582
70
    BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(op, (ptrdiff_t)dstSize);
583
70
    const void* dtPtr = DTable + 1;
584
70
    const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
585
70
    BIT_DStream_t bitD;
586
70
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
587
70
    U32 const dtLog = dtd.tableLog;
588
589
70
    CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
590
591
61
    HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog);
592
593
61
    if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
594
595
4
    return dstSize;
596
61
}
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
178
{
608
    /* Check */
609
178
    if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
610
178
    if (dstSize < 6) return ERROR(corruption_detected);         /* stream 4-split doesn't work */
611
612
178
    {   const BYTE* const istart = (const BYTE*) cSrc;
613
178
        BYTE* const ostart = (BYTE*) dst;
614
178
        BYTE* const oend = ostart + dstSize;
615
178
        BYTE* const olimit = oend - 3;
616
178
        const void* const dtPtr = DTable + 1;
617
178
        const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
618
619
        /* Init */
620
178
        BIT_DStream_t bitD1;
621
178
        BIT_DStream_t bitD2;
622
178
        BIT_DStream_t bitD3;
623
178
        BIT_DStream_t bitD4;
624
178
        size_t const length1 = MEM_readLE16(istart);
625
178
        size_t const length2 = MEM_readLE16(istart+2);
626
178
        size_t const length3 = MEM_readLE16(istart+4);
627
178
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
628
178
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
629
178
        const BYTE* const istart2 = istart1 + length1;
630
178
        const BYTE* const istart3 = istart2 + length2;
631
178
        const BYTE* const istart4 = istart3 + length3;
632
178
        const size_t segmentSize = (dstSize+3) / 4;
633
178
        BYTE* const opStart2 = ostart + segmentSize;
634
178
        BYTE* const opStart3 = opStart2 + segmentSize;
635
178
        BYTE* const opStart4 = opStart3 + segmentSize;
636
178
        BYTE* op1 = ostart;
637
178
        BYTE* op2 = opStart2;
638
178
        BYTE* op3 = opStart3;
639
178
        BYTE* op4 = opStart4;
640
178
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
641
178
        U32 const dtLog = dtd.tableLog;
642
178
        U32 endSignal = 1;
643
644
178
        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
645
156
        if (opStart4 > oend) return ERROR(corruption_detected);      /* overflow */
646
156
        assert(dstSize >= 6); /* validated above */
647
156
        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
648
142
        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
649
131
        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
650
121
        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
651
652
        /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
653
116
        if ((size_t)(oend - op4) >= sizeof(size_t)) {
654
354
            for ( ; (endSignal) & (op4 < olimit) ; ) {
655
257
                HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
656
257
                HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
657
257
                HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
658
257
                HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
659
257
                HUF_DECODE_SYMBOLX1_1(op1, &bitD1);
660
257
                HUF_DECODE_SYMBOLX1_1(op2, &bitD2);
661
257
                HUF_DECODE_SYMBOLX1_1(op3, &bitD3);
662
257
                HUF_DECODE_SYMBOLX1_1(op4, &bitD4);
663
257
                HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
664
257
                HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
665
257
                HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
666
257
                HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
667
257
                HUF_DECODE_SYMBOLX1_0(op1, &bitD1);
668
257
                HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
669
257
                HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
670
257
                HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
671
257
                endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
672
257
                endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
673
257
                endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
674
257
                endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
675
257
            }
676
97
        }
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
116
        if (op1 > opStart2) return ERROR(corruption_detected);
682
116
        if (op2 > opStart3) return ERROR(corruption_detected);
683
116
        if (op3 > opStart4) return ERROR(corruption_detected);
684
        /* note : op4 supposed already verified within main loop */
685
686
        /* finish bitStreams one by one */
687
116
        HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog);
688
116
        HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog);
689
116
        HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog);
690
116
        HUF_decodeStreamX1(op4, &bitD4, oend,     dt, dtLog);
691
692
        /* check */
693
116
        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
694
116
          if (!endCheck) return ERROR(corruption_detected); }
695
696
        /* decoded size */
697
0
        return dstSize;
698
116
    }
699
116
}
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
178
                    size_t cSrcSize, HUF_DTable const* DTable) {
705
178
    return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
706
178
}
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
115
{
724
115
    U64 bits[4];
725
115
    BYTE const* ip[4];
726
115
    BYTE* op[4];
727
115
    U16 const* const dtable = (U16 const*)args->dt;
728
115
    BYTE* const oend = args->oend;
729
115
    BYTE const* const ilowest = args->ilowest;
730
731
    /* Copy the arguments to local variables */
732
115
    ZSTD_memcpy(&bits, &args->bits, sizeof(bits));
733
115
    ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip));
734
115
    ZSTD_memcpy(&op, &args->op, sizeof(op));
735
736
115
    assert(MEM_isLittleEndian());
737
115
    assert(!MEM_32bits());
738
739
744
    for (;;) {
740
744
        BYTE* olimit;
741
744
        int stream;
742
743
        /* Assert loop preconditions */
744
744
#ifndef NDEBUG
745
3.72k
        for (stream = 0; stream < 4; ++stream) {
746
2.97k
            assert(op[stream] <= (stream == 3 ? oend : op[stream + 1]));
747
2.97k
            assert(ip[stream] >= ilowest);
748
2.97k
        }
749
744
#endif
750
        /* Compute olimit */
751
744
        {
752
            /* Each iteration produces 5 output symbols per stream */
753
744
            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
744
            size_t const iiters = (size_t)(ip[0] - ilowest) / 7;
758
            /* We can safely run iters iterations before running bounds checks */
759
744
            size_t const iters = MIN(oiters, iiters);
760
744
            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
744
            olimit = op[3] + symbols;
767
768
            /* Exit fast decoding loop once we reach the end. */
769
744
            if (op[3] == olimit)
770
115
                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
2.51k
            for (stream = 1; stream < 4; ++stream) {
777
1.88k
                if (ip[stream] < ip[stream - 1])
778
0
                    goto _out;
779
1.88k
            }
780
629
        }
781
782
629
#ifndef NDEBUG
783
2.51k
        for (stream = 1; stream < 4; ++stream) {
784
1.88k
            assert(ip[stream] >= ip[stream - 1]);
785
1.88k
        }
786
629
#endif
787
788
629
#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol)        \
789
33.7k
    do {                                               \
790
33.7k
        U64 const index = bits[(_stream)] >> 53;       \
791
33.7k
        U16 const entry = dtable[index];               \
792
33.7k
        bits[(_stream)] <<= entry & 0x3F;              \
793
33.7k
        op[(_stream)][(_symbol)] = (BYTE)(entry >> 8); \
794
33.7k
    } while (0)
795
796
629
#define HUF_5X1_RELOAD_STREAM(_stream)                              \
797
6.74k
    do {                                                            \
798
6.74k
        U64 const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
799
6.74k
        U64 const nbBits = ctz & 7;                                 \
800
6.74k
        U64 const nbBytes = ctz >> 3;                               \
801
6.74k
        op[(_stream)] += 5;                                         \
802
6.74k
        ip[(_stream)] -= nbBytes;                                   \
803
6.74k
        bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1;            \
804
6.74k
        bits[(_stream)] <<= nbBits;                                 \
805
6.74k
    } while (0)
806
807
        /* Manually unroll the loop because compilers don't consistently
808
         * unroll the inner loops, which destroys performance.
809
         */
810
1.68k
        do {
811
            /* Decode 5 symbols in each of the 4 streams */
812
6.74k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 0);
813
6.74k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 1);
814
6.74k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 2);
815
6.74k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 3);
816
6.74k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4);
817
818
            /* Reload each of the 4 the bitstreams */
819
6.74k
            HUF_4X_FOR_EACH_STREAM(HUF_5X1_RELOAD_STREAM);
820
1.68k
        } while (op[3] < olimit);
821
822
629
#undef HUF_4X1_DECODE_SYMBOL
823
629
#undef HUF_5X1_RELOAD_STREAM
824
629
    }
825
826
115
_out:
827
828
    /* Save the final values of each of the state variables back to args. */
829
115
    ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
830
115
    ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip));
831
115
    ZSTD_memcpy(&args->op, &op, sizeof(op));
832
115
}
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
325
{
847
325
    void const* dt = DTable + 1;
848
325
    BYTE const* const ilowest = (BYTE const*)cSrc;
849
325
    BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
850
325
    HUF_DecompressFastArgs args;
851
325
    {   size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
852
325
        FORWARD_IF_ERROR(ret, "Failed to init fast loop args");
853
293
        if (ret == 0)
854
178
            return 0;
855
293
    }
856
857
115
    assert(args.ip[0] >= args.ilowest);
858
115
    loopFn(&args);
859
860
    /* Our loop guarantees that ip[] >= ilowest and that we haven't
861
    * overwritten any op[].
862
    */
863
115
    assert(args.ip[0] >= ilowest);
864
115
    assert(args.ip[0] >= ilowest);
865
115
    assert(args.ip[1] >= ilowest);
866
115
    assert(args.ip[2] >= ilowest);
867
115
    assert(args.ip[3] >= ilowest);
868
115
    assert(args.op[3] <= oend);
869
870
115
    assert(ilowest == args.ilowest);
871
115
    assert(ilowest + 6 == args.iend[0]);
872
115
    (void)ilowest;
873
874
    /* finish bit streams one by one. */
875
115
    {   size_t const segmentSize = (dstSize+3) / 4;
876
115
        BYTE* segmentEnd = (BYTE*)dst;
877
115
        int i;
878
476
        for (i = 0; i < 4; ++i) {
879
405
            BIT_DStream_t bit;
880
405
            if (segmentSize <= (size_t)(oend - segmentEnd))
881
332
                segmentEnd += segmentSize;
882
73
            else
883
73
                segmentEnd = oend;
884
405
            FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
885
            /* Decompress and validate that we've produced exactly the expected length. */
886
361
            args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG);
887
361
            if (args.op[i] != segmentEnd) return ERROR(corruption_detected);
888
361
        }
889
115
    }
890
891
    /* decoded size */
892
71
    assert(dstSize != 0);
893
71
    return dstSize;
894
115
}
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
325
{
901
325
    HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X1_usingDTable_internal_default;
902
325
    HUF_DecompressFastLoopFn loopFn = HUF_decompress4X1_usingDTable_internal_fast_c_loop;
903
904
325
#if DYNAMIC_BMI2
905
325
    if (flags & HUF_flags_bmi2) {
906
325
        fallbackFn = HUF_decompress4X1_usingDTable_internal_bmi2;
907
# if ZSTD_ENABLE_ASM_X86_64_BMI2
908
        if (!(flags & HUF_flags_disableAsm)) {
909
            loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop;
910
        }
911
# endif
912
325
    } else {
913
0
        return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
914
0
    }
915
325
#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
325
    if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) {
924
325
        size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
925
325
        if (ret != 0)
926
147
            return ret;
927
325
    }
928
178
    return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
929
325
}
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
470
{
935
470
    const BYTE* ip = (const BYTE*) cSrc;
936
937
470
    size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags);
938
470
    if (HUF_isError(hSize)) return hSize;
939
327
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
940
325
    ip += hSize; cSrcSize -= hSize;
941
942
325
    return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
943
327
}
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
140k
{
964
140k
    U32 seq;
965
140k
    DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0);
966
140k
    DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2);
967
140k
    DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3);
968
140k
    DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32));
969
140k
    if (MEM_isLittleEndian()) {
970
140k
        seq = level == 1 ? symbol : (baseSeq + (symbol << 8));
971
140k
        return seq + (nbBits << 16) + ((U32)level << 24);
972
140k
    } else {
973
0
        seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol);
974
0
        return (seq << 16) + (nbBits << 8) + (U32)level;
975
0
    }
976
140k
}
977
978
/**
979
 * Constructs a HUF_DEltX2.
980
 */
981
static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level)
982
83.1k
{
983
83.1k
    HUF_DEltX2 DElt;
984
83.1k
    U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
985
83.1k
    DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val));
986
83.1k
    ZSTD_memcpy(&DElt, &val, sizeof(val));
987
83.1k
    return DElt;
988
83.1k
}
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
57.1k
{
995
57.1k
    U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
996
57.1k
    return (U64)DElt + ((U64)DElt << 32);
997
57.1k
}
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
54.4k
{
1017
54.4k
    U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */);
1018
54.4k
    const sortedSymbol_t* ptr;
1019
54.4k
    assert(level >= 1 && level <= 2);
1020
54.4k
    switch (length) {
1021
13.1k
    case 1:
1022
58.3k
        for (ptr = begin; ptr != end; ++ptr) {
1023
45.1k
            HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
1024
45.1k
            *DTableRank++ = DElt;
1025
45.1k
        }
1026
13.1k
        break;
1027
11.5k
    case 2:
1028
49.5k
        for (ptr = begin; ptr != end; ++ptr) {
1029
37.9k
            HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
1030
37.9k
            DTableRank[0] = DElt;
1031
37.9k
            DTableRank[1] = DElt;
1032
37.9k
            DTableRank += 2;
1033
37.9k
        }
1034
11.5k
        break;
1035
9.92k
    case 4:
1036
23.6k
        for (ptr = begin; ptr != end; ++ptr) {
1037
13.6k
            U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
1038
13.6k
            ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
1039
13.6k
            ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
1040
13.6k
            DTableRank += 4;
1041
13.6k
        }
1042
9.92k
        break;
1043
7.79k
    case 8:
1044
22.7k
        for (ptr = begin; ptr != end; ++ptr) {
1045
14.9k
            U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
1046
14.9k
            ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
1047
14.9k
            ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
1048
14.9k
            ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
1049
14.9k
            ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
1050
14.9k
            DTableRank += 8;
1051
14.9k
        }
1052
7.79k
        break;
1053
12.0k
    default:
1054
28.1k
        for (ptr = begin; ptr != end; ++ptr) {
1055
16.1k
            U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
1056
16.1k
            HUF_DEltX2* const DTableRankEnd = DTableRank + length;
1057
138k
            for (; DTableRank != DTableRankEnd; DTableRank += 8) {
1058
122k
                ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
1059
122k
                ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
1060
122k
                ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
1061
122k
                ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
1062
122k
            }
1063
16.1k
        }
1064
12.0k
        break;
1065
54.4k
    }
1066
54.4k
}
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
14.1k
{
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
14.1k
    if (minWeight>1) {
1080
12.4k
        U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */);
1081
12.4k
        U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1);
1082
12.4k
        int const skipSize = rankVal[minWeight];
1083
12.4k
        assert(length > 1);
1084
12.4k
        assert((U32)skipSize < length);
1085
12.4k
        switch (length) {
1086
724
        case 2:
1087
724
            assert(skipSize == 1);
1088
724
            ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2));
1089
724
            break;
1090
860
        case 4:
1091
860
            assert(skipSize <= 4);
1092
860
            ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2));
1093
860
            ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2));
1094
860
            break;
1095
10.8k
        default:
1096
10.8k
            {
1097
10.8k
                int i;
1098
26.8k
                for (i = 0; i < skipSize; i += 8) {
1099
16.0k
                    ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2));
1100
16.0k
                    ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2));
1101
16.0k
                    ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2));
1102
16.0k
                    ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2));
1103
16.0k
                }
1104
10.8k
            }
1105
12.4k
        }
1106
12.4k
    }
1107
1108
    /* Fill each of the second level symbols by weight. */
1109
14.1k
    {
1110
14.1k
        int w;
1111
68.2k
        for (w = minWeight; w < maxWeight1; ++w) {
1112
54.1k
            int const begin = rankStart[w];
1113
54.1k
            int const end = rankStart[w+1];
1114
54.1k
            U32 const nbBits = nbBitsBaseline - w;
1115
54.1k
            U32 const totalBits = nbBits + consumedBits;
1116
54.1k
            HUF_fillDTableX2ForWeight(
1117
54.1k
                DTable + rankVal[w],
1118
54.1k
                sortedSymbols + begin, sortedSymbols + end,
1119
54.1k
                totalBits, targetLog,
1120
54.1k
                baseSeq, /* level */ 2);
1121
54.1k
        }
1122
14.1k
    }
1123
14.1k
}
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
598
{
1130
598
    U32* const rankVal = rankValOrigin[0];
1131
598
    const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */
1132
598
    const U32 minBits  = nbBitsBaseline - maxWeight;
1133
598
    int w;
1134
598
    int const wEnd = (int)maxWeight + 1;
1135
1136
    /* Fill DTable in order of weight. */
1137
5.24k
    for (w = 1; w < wEnd; ++w) {
1138
4.64k
        int const begin = (int)rankStart[w];
1139
4.64k
        int const end = (int)rankStart[w+1];
1140
4.64k
        U32 const nbBits = nbBitsBaseline - w;
1141
1142
4.64k
        if (targetLog-nbBits >= minBits) {
1143
            /* Enough room for a second symbol. */
1144
4.35k
            int start = rankVal[w];
1145
4.35k
            U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */);
1146
4.35k
            int minWeight = nbBits + scaleLog;
1147
4.35k
            int s;
1148
4.35k
            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
18.4k
            for (s = begin; s != end; ++s) {
1153
14.1k
                HUF_fillDTableX2Level2(
1154
14.1k
                    DTable + start, targetLog, nbBits,
1155
14.1k
                    rankValOrigin[nbBits], minWeight, wEnd,
1156
14.1k
                    sortedList, rankStart,
1157
14.1k
                    nbBitsBaseline, sortedList[s].symbol);
1158
14.1k
                start += length;
1159
14.1k
            }
1160
4.35k
        } else {
1161
            /* Only a single symbol. */
1162
292
            HUF_fillDTableX2ForWeight(
1163
292
                DTable + rankVal[w],
1164
292
                sortedList + begin, sortedList + end,
1165
292
                nbBits, targetLog,
1166
292
                /* baseSeq */ 0, /* level */ 1);
1167
292
        }
1168
4.64k
    }
1169
598
}
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
695
{
1184
695
    U32 tableLog, maxW, nbSymbols;
1185
695
    DTableDesc dtd = HUF_getDTableDesc(DTable);
1186
695
    U32 maxTableLog = dtd.maxTableLog;
1187
695
    size_t iSize;
1188
695
    void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */
1189
695
    HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
1190
695
    U32 *rankStart;
1191
1192
695
    HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace;
1193
1194
695
    if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC);
1195
1196
695
    rankStart = wksp->rankStart0 + 1;
1197
695
    ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats));
1198
695
    ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0));
1199
1200
695
    DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable));   /* if compiler fails here, assertion is wrong */
1201
695
    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
695
    iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), flags);
1205
695
    if (HUF_isError(iSize)) return iSize;
1206
1207
    /* check result */
1208
598
    if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */
1209
598
    if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG;
1210
1211
    /* find maxWeight */
1212
979
    for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */
1213
1214
    /* Get start index of each weight */
1215
598
    {   U32 w, nextRankStart = 0;
1216
5.24k
        for (w=1; w<maxW+1; w++) {
1217
4.64k
            U32 curr = nextRankStart;
1218
4.64k
            nextRankStart += wksp->rankStats[w];
1219
4.64k
            rankStart[w] = curr;
1220
4.64k
        }
1221
598
        rankStart[0] = nextRankStart;   /* put all 0w symbols at the end of sorted list*/
1222
598
        rankStart[maxW+1] = nextRankStart;
1223
598
    }
1224
1225
    /* sort symbols by weight */
1226
598
    {   U32 s;
1227
54.6k
        for (s=0; s<nbSymbols; s++) {
1228
54.0k
            U32 const w = wksp->weightList[s];
1229
54.0k
            U32 const r = rankStart[w]++;
1230
54.0k
            wksp->sortedSymbol[r].symbol = (BYTE)s;
1231
54.0k
        }
1232
598
        rankStart[0] = 0;   /* forget 0w symbols; this is beginning of weight(1) */
1233
598
    }
1234
1235
    /* Build rankVal */
1236
598
    {   U32* const rankVal0 = wksp->rankVal[0];
1237
598
        {   int const rescale = (maxTableLog-tableLog) - 1;   /* tableLog <= maxTableLog */
1238
598
            U32 nextRankVal = 0;
1239
598
            U32 w;
1240
5.24k
            for (w=1; w<maxW+1; w++) {
1241
4.64k
                U32 curr = nextRankVal;
1242
4.64k
                nextRankVal += wksp->rankStats[w] << (w+rescale);
1243
4.64k
                rankVal0[w] = curr;
1244
4.64k
        }   }
1245
598
        {   U32 const minBits = tableLog+1 - maxW;
1246
598
            U32 consumed;
1247
5.89k
            for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
1248
5.29k
                U32* const rankValPtr = wksp->rankVal[consumed];
1249
5.29k
                U32 w;
1250
49.1k
                for (w = 1; w < maxW+1; w++) {
1251
43.8k
                    rankValPtr[w] = rankVal0[w] >> consumed;
1252
43.8k
    }   }   }   }
1253
1254
598
    HUF_fillDTableX2(dt, maxTableLog,
1255
598
                   wksp->sortedSymbol,
1256
598
                   wksp->rankStart0, wksp->rankVal, maxW,
1257
598
                   tableLog+1);
1258
1259
598
    dtd.tableLog = (BYTE)maxTableLog;
1260
598
    dtd.tableType = 1;
1261
598
    ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
1262
598
    return iSize;
1263
598
}
1264
1265
1266
FORCE_INLINE_TEMPLATE U32
1267
HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
1268
283k
{
1269
283k
    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
1270
283k
    ZSTD_memcpy(op, &dt[val].sequence, 2);
1271
283k
    BIT_skipBits(DStream, dt[val].nbBits);
1272
283k
    return dt[val].length;
1273
283k
}
1274
1275
FORCE_INLINE_TEMPLATE U32
1276
HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
1277
965
{
1278
965
    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
1279
965
    ZSTD_memcpy(op, &dt[val].sequence, 1);
1280
965
    if (dt[val].length==1) {
1281
347
        BIT_skipBits(DStream, dt[val].nbBits);
1282
618
    } else {
1283
618
        if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
1284
223
            BIT_skipBits(DStream, dt[val].nbBits);
1285
223
            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
11
                DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);
1288
223
        }
1289
618
    }
1290
965
    return 1;
1291
965
}
1292
1293
#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
1294
271k
    do { ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); } while (0)
1295
1296
#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr)                     \
1297
3.78k
    do {                                                           \
1298
3.78k
        if (MEM_64bits() || (HUF_TABLELOG_MAX<=12))                \
1299
3.78k
            ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \
1300
3.78k
    } while (0)
1301
1302
#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr)                     \
1303
7.57k
    do {                                                           \
1304
7.57k
        if (MEM_64bits())                                          \
1305
7.57k
            ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \
1306
7.57k
    } 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
1.53k
{
1312
1.53k
    BYTE* const pStart = p;
1313
1314
    /* up to 8 symbols at a time */
1315
1.53k
    if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) {
1316
1.50k
        if (dtLog <= 11 && MEM_64bits()) {
1317
            /* up to 10 symbols at a time */
1318
20.2k
            while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) {
1319
19.0k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1320
19.0k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1321
19.0k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1322
19.0k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1323
19.0k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1324
19.0k
            }
1325
1.27k
        } else {
1326
            /* up to 8 symbols at a time */
1327
2.37k
            while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
1328
2.14k
                HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
1329
2.14k
                HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
1330
2.14k
                HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
1331
2.14k
                HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1332
2.14k
            }
1333
224
        }
1334
1.50k
    } else {
1335
38
        BIT_reloadDStream(bitDPtr);
1336
38
    }
1337
1338
    /* closer to end : up to 2 symbols at a time */
1339
1.53k
    if ((size_t)(pEnd - p) >= 2) {
1340
2.38k
        while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
1341
912
            HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1342
1343
173k
        while (p <= pEnd-2)
1344
172k
            HUF_DECODE_SYMBOLX2_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */
1345
1.46k
    }
1346
1347
1.53k
    if (p < pEnd)
1348
965
        p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog);
1349
1350
1.53k
    return p-pStart;
1351
1.53k
}
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
370
{
1390
370
    if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */
1391
370
    if (dstSize < 6) return ERROR(corruption_detected);         /* stream 4-split doesn't work */
1392
1393
370
    {   const BYTE* const istart = (const BYTE*) cSrc;
1394
370
        BYTE* const ostart = (BYTE*) dst;
1395
370
        BYTE* const oend = ostart + dstSize;
1396
370
        BYTE* const olimit = oend - (sizeof(size_t)-1);
1397
370
        const void* const dtPtr = DTable+1;
1398
370
        const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
1399
1400
        /* Init */
1401
370
        BIT_DStream_t bitD1;
1402
370
        BIT_DStream_t bitD2;
1403
370
        BIT_DStream_t bitD3;
1404
370
        BIT_DStream_t bitD4;
1405
370
        size_t const length1 = MEM_readLE16(istart);
1406
370
        size_t const length2 = MEM_readLE16(istart+2);
1407
370
        size_t const length3 = MEM_readLE16(istart+4);
1408
370
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
1409
370
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
1410
370
        const BYTE* const istart2 = istart1 + length1;
1411
370
        const BYTE* const istart3 = istart2 + length2;
1412
370
        const BYTE* const istart4 = istart3 + length3;
1413
370
        size_t const segmentSize = (dstSize+3) / 4;
1414
370
        BYTE* const opStart2 = ostart + segmentSize;
1415
370
        BYTE* const opStart3 = opStart2 + segmentSize;
1416
370
        BYTE* const opStart4 = opStart3 + segmentSize;
1417
370
        BYTE* op1 = ostart;
1418
370
        BYTE* op2 = opStart2;
1419
370
        BYTE* op3 = opStart3;
1420
370
        BYTE* op4 = opStart4;
1421
370
        U32 endSignal = 1;
1422
370
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
1423
370
        U32 const dtLog = dtd.tableLog;
1424
1425
370
        if (length4 > cSrcSize) return ERROR(corruption_detected);  /* overflow */
1426
335
        if (opStart4 > oend) return ERROR(corruption_detected);     /* overflow */
1427
335
        assert(dstSize >= 6 /* validated above */);
1428
335
        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
1429
315
        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
1430
303
        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
1431
287
        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
1432
1433
        /* 16-32 symbols per loop (4-8 symbols per stream) */
1434
281
        if ((size_t)(oend - op4) >= sizeof(size_t)) {
1435
691
            for ( ; (endSignal) & (op4 < olimit); ) {
1436
410
#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
1437
410
                HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1438
410
                HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
1439
410
                HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1440
410
                HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
1441
410
                HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1442
410
                HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
1443
410
                HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1444
410
                HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
1445
410
                endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
1446
410
                endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
1447
410
                HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1448
410
                HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
1449
410
                HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1450
410
                HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
1451
410
                HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1452
410
                HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
1453
410
                HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1454
410
                HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
1455
410
                endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
1456
410
                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
410
            }
1481
281
        }
1482
1483
        /* check corruption */
1484
281
        if (op1 > opStart2) return ERROR(corruption_detected);
1485
281
        if (op2 > opStart3) return ERROR(corruption_detected);
1486
281
        if (op3 > opStart4) return ERROR(corruption_detected);
1487
        /* note : op4 already verified within main loop */
1488
1489
        /* finish bitStreams one by one */
1490
281
        HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
1491
281
        HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
1492
281
        HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
1493
281
        HUF_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);
1494
1495
        /* check */
1496
281
        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
1497
281
          if (!endCheck) return ERROR(corruption_detected); }
1498
1499
        /* decoded size */
1500
0
        return dstSize;
1501
281
    }
1502
281
}
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
370
                    size_t cSrcSize, HUF_DTable const* DTable) {
1508
370
    return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
1509
370
}
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
145
{
1527
145
    U64 bits[4];
1528
145
    BYTE const* ip[4];
1529
145
    BYTE* op[4];
1530
145
    BYTE* oend[4];
1531
145
    HUF_DEltX2 const* const dtable = (HUF_DEltX2 const*)args->dt;
1532
145
    BYTE const* const ilowest = args->ilowest;
1533
1534
    /* Copy the arguments to local registers. */
1535
145
    ZSTD_memcpy(&bits, &args->bits, sizeof(bits));
1536
145
    ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip));
1537
145
    ZSTD_memcpy(&op, &args->op, sizeof(op));
1538
1539
145
    oend[0] = op[1];
1540
145
    oend[1] = op[2];
1541
145
    oend[2] = op[3];
1542
145
    oend[3] = args->oend;
1543
1544
145
    assert(MEM_isLittleEndian());
1545
145
    assert(!MEM_32bits());
1546
1547
956
    for (;;) {
1548
956
        BYTE* olimit;
1549
956
        int stream;
1550
1551
        /* Assert loop preconditions */
1552
956
#ifndef NDEBUG
1553
4.78k
        for (stream = 0; stream < 4; ++stream) {
1554
3.82k
            assert(op[stream] <= oend[stream]);
1555
3.82k
            assert(ip[stream] >= ilowest);
1556
3.82k
        }
1557
956
#endif
1558
        /* Compute olimit */
1559
956
        {
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
956
            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
4.78k
            for (stream = 0; stream < 4; ++stream) {
1574
3.82k
                size_t const oiters = (size_t)(oend[stream] - op[stream]) / 10;
1575
3.82k
                iters = MIN(iters, oiters);
1576
3.82k
            }
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
956
            olimit = op[3] + (iters * 5);
1585
1586
            /* Exit the fast decoding loop once we reach the end. */
1587
956
            if (op[3] == olimit)
1588
145
                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
3.24k
            for (stream = 1; stream < 4; ++stream) {
1595
2.43k
                if (ip[stream] < ip[stream - 1])
1596
0
                    goto _out;
1597
2.43k
            }
1598
811
        }
1599
1600
811
#ifndef NDEBUG
1601
3.24k
        for (stream = 1; stream < 4; ++stream) {
1602
2.43k
            assert(ip[stream] >= ip[stream - 1]);
1603
2.43k
        }
1604
811
#endif
1605
1606
811
#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3)               \
1607
70.1k
    do {                                                       \
1608
70.1k
        if ((_decode3) || (_stream) != 3) {                    \
1609
56.1k
            U64 const index = bits[(_stream)] >> 53;           \
1610
56.1k
            size_t const entry = MEM_readLE32(&dtable[index]); \
1611
56.1k
            MEM_write16(op[(_stream)], (U16)entry);            \
1612
56.1k
            bits[(_stream)] <<= (entry >> 16) & 0x3F;          \
1613
56.1k
            op[(_stream)] += entry >> 24;                      \
1614
56.1k
        }                                                      \
1615
70.1k
    } while (0)
1616
1617
811
#define HUF_5X2_RELOAD_STREAM(_stream, _decode3)                        \
1618
11.2k
    do {                                                                \
1619
11.2k
        if (_decode3) HUF_4X2_DECODE_SYMBOL(3, 1);                      \
1620
11.2k
        {                                                               \
1621
11.2k
            U64 const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
1622
11.2k
            U64 const nbBits = ctz & 7;                                 \
1623
11.2k
            U64 const nbBytes = ctz >> 3;                               \
1624
11.2k
            ip[(_stream)] -= nbBytes;                                   \
1625
11.2k
            bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1;            \
1626
11.2k
            bits[(_stream)] <<= nbBits;                                 \
1627
11.2k
        }                                                               \
1628
11.2k
    } while (0)
1629
1630
#if defined(__aarch64__)
1631
#  define HUF_4X2_4WAY 1
1632
#else
1633
811
#  define HUF_4X2_4WAY 0
1634
811
#endif
1635
811
#define HUF_4X2_3WAY !HUF_4X2_4WAY
1636
1637
        /* Manually unroll the loop because compilers don't consistently
1638
         * unroll the inner loops, which destroys performance.
1639
         */
1640
2.80k
        do {
1641
            /* Decode 5 symbols from each of the first 3 or 4 streams.
1642
             * In the 3-way case the final stream will be decoded during
1643
             * the reload phase to reduce register pressure.
1644
             */
1645
11.2k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
1646
11.2k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
1647
11.2k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
1648
11.2k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
1649
11.2k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
1650
1651
            /* In the 3-way case decode one symbol from the final stream. */
1652
2.80k
            HUF_4X2_DECODE_SYMBOL(3, HUF_4X2_3WAY);
1653
1654
            /* In the 3-way case decode 4 symbols from the final stream &
1655
             * reload bitstreams. The final stream is reloaded last, meaning
1656
             * that all 5 symbols are decoded from the final stream before
1657
             * it is reloaded.
1658
             */
1659
11.2k
            HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_5X2_RELOAD_STREAM, HUF_4X2_3WAY);
1660
2.80k
        } while (op[3] < olimit);
1661
811
    }
1662
1663
145
#undef HUF_4X2_DECODE_SYMBOL
1664
145
#undef HUF_5X2_RELOAD_STREAM
1665
1666
145
_out:
1667
1668
    /* Save the final values of each of the state variables back to args. */
1669
145
    ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
1670
145
    ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip));
1671
145
    ZSTD_memcpy(&args->op, &op, sizeof(op));
1672
145
}
1673
1674
1675
static HUF_FAST_BMI2_ATTRS size_t
1676
HUF_decompress4X2_usingDTable_internal_fast(
1677
          void* dst,  size_t dstSize,
1678
    const void* cSrc, size_t cSrcSize,
1679
    const HUF_DTable* DTable,
1680
598
    HUF_DecompressFastLoopFn loopFn) {
1681
598
    void const* dt = DTable + 1;
1682
598
    const BYTE* const ilowest = (const BYTE*)cSrc;
1683
598
    BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
1684
598
    HUF_DecompressFastArgs args;
1685
598
    {
1686
598
        size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
1687
598
        FORWARD_IF_ERROR(ret, "Failed to init asm args");
1688
515
        if (ret == 0)
1689
370
            return 0;
1690
515
    }
1691
1692
145
    assert(args.ip[0] >= args.ilowest);
1693
145
    loopFn(&args);
1694
1695
    /* note : op4 already verified within main loop */
1696
145
    assert(args.ip[0] >= ilowest);
1697
145
    assert(args.ip[1] >= ilowest);
1698
145
    assert(args.ip[2] >= ilowest);
1699
145
    assert(args.ip[3] >= ilowest);
1700
145
    assert(args.op[3] <= oend);
1701
1702
145
    assert(ilowest == args.ilowest);
1703
145
    assert(ilowest + 6 == args.iend[0]);
1704
145
    (void)ilowest;
1705
1706
    /* finish bitStreams one by one */
1707
145
    {
1708
145
        size_t const segmentSize = (dstSize+3) / 4;
1709
145
        BYTE* segmentEnd = (BYTE*)dst;
1710
145
        int i;
1711
560
        for (i = 0; i < 4; ++i) {
1712
485
            BIT_DStream_t bit;
1713
485
            if (segmentSize <= (size_t)(oend - segmentEnd))
1714
407
                segmentEnd += segmentSize;
1715
78
            else
1716
78
                segmentEnd = oend;
1717
485
            FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
1718
415
            args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG);
1719
415
            if (args.op[i] != segmentEnd)
1720
0
                return ERROR(corruption_detected);
1721
415
        }
1722
145
    }
1723
1724
    /* decoded size */
1725
75
    return dstSize;
1726
145
}
1727
1728
static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
1729
                    size_t cSrcSize, HUF_DTable const* DTable, int flags)
1730
598
{
1731
598
    HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X2_usingDTable_internal_default;
1732
598
    HUF_DecompressFastLoopFn loopFn = HUF_decompress4X2_usingDTable_internal_fast_c_loop;
1733
1734
598
#if DYNAMIC_BMI2
1735
598
    if (flags & HUF_flags_bmi2) {
1736
598
        fallbackFn = HUF_decompress4X2_usingDTable_internal_bmi2;
1737
# if ZSTD_ENABLE_ASM_X86_64_BMI2
1738
        if (!(flags & HUF_flags_disableAsm)) {
1739
            loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop;
1740
        }
1741
# endif
1742
598
    } else {
1743
0
        return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
1744
0
    }
1745
598
#endif
1746
1747
#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
1748
    if (!(flags & HUF_flags_disableAsm)) {
1749
        loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop;
1750
    }
1751
#endif
1752
1753
598
    if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) {
1754
598
        size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
1755
598
        if (ret != 0)
1756
228
            return ret;
1757
598
    }
1758
370
    return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
1759
598
}
1760
1761
HUF_DGEN(HUF_decompress1X2_usingDTable_internal)
1762
1763
size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
1764
                                   const void* cSrc, size_t cSrcSize,
1765
                                   void* workSpace, size_t wkspSize, int flags)
1766
0
{
1767
0
    const BYTE* ip = (const BYTE*) cSrc;
1768
1769
0
    size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize,
1770
0
                                               workSpace, wkspSize, flags);
1771
0
    if (HUF_isError(hSize)) return hSize;
1772
0
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1773
0
    ip += hSize; cSrcSize -= hSize;
1774
1775
0
    return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, flags);
1776
0
}
1777
1778
static size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
1779
                                   const void* cSrc, size_t cSrcSize,
1780
                                   void* workSpace, size_t wkspSize, int flags)
1781
695
{
1782
695
    const BYTE* ip = (const BYTE*) cSrc;
1783
1784
695
    size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize,
1785
695
                                         workSpace, wkspSize, flags);
1786
695
    if (HUF_isError(hSize)) return hSize;
1787
598
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1788
598
    ip += hSize; cSrcSize -= hSize;
1789
1790
598
    return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
1791
598
}
1792
1793
#endif /* HUF_FORCE_DECOMPRESS_X1 */
1794
1795
1796
/* ***********************************/
1797
/* Universal decompression selectors */
1798
/* ***********************************/
1799
1800
1801
#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
1802
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
1803
static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] =
1804
{
1805
    /* single, double, quad */
1806
    {{0,0}, {1,1}},  /* Q==0 : impossible */
1807
    {{0,0}, {1,1}},  /* Q==1 : impossible */
1808
    {{ 150,216}, { 381,119}},   /* Q == 2 : 12-18% */
1809
    {{ 170,205}, { 514,112}},   /* Q == 3 : 18-25% */
1810
    {{ 177,199}, { 539,110}},   /* Q == 4 : 25-32% */
1811
    {{ 197,194}, { 644,107}},   /* Q == 5 : 32-38% */
1812
    {{ 221,192}, { 735,107}},   /* Q == 6 : 38-44% */
1813
    {{ 256,189}, { 881,106}},   /* Q == 7 : 44-50% */
1814
    {{ 359,188}, {1167,109}},   /* Q == 8 : 50-56% */
1815
    {{ 582,187}, {1570,114}},   /* Q == 9 : 56-62% */
1816
    {{ 688,187}, {1712,122}},   /* Q ==10 : 62-69% */
1817
    {{ 825,186}, {1965,136}},   /* Q ==11 : 69-75% */
1818
    {{ 976,185}, {2131,150}},   /* Q ==12 : 75-81% */
1819
    {{1180,186}, {2070,175}},   /* Q ==13 : 81-87% */
1820
    {{1377,185}, {1731,202}},   /* Q ==14 : 87-93% */
1821
    {{1412,185}, {1695,202}},   /* Q ==15 : 93-99% */
1822
};
1823
#endif
1824
1825
/** HUF_selectDecoder() :
1826
 *  Tells which decoder is likely to decode faster,
1827
 *  based on a set of pre-computed metrics.
1828
 * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .
1829
 *  Assumption : 0 < dstSize <= 128 KB */
1830
U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
1831
1.16k
{
1832
1.16k
    assert(dstSize > 0);
1833
1.16k
    assert(dstSize <= 128*1024);
1834
#if defined(HUF_FORCE_DECOMPRESS_X1)
1835
    (void)dstSize;
1836
    (void)cSrcSize;
1837
    return 0;
1838
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1839
    (void)dstSize;
1840
    (void)cSrcSize;
1841
    return 1;
1842
#else
1843
    /* decoder timing evaluation */
1844
1.16k
    {   U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 */
1845
1.16k
        U32 const D256 = (U32)(dstSize >> 8);
1846
1.16k
        U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
1847
1.16k
        U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
1848
1.16k
        DTime1 += DTime1 >> 5;  /* small advantage to algorithm using less memory, to reduce cache eviction */
1849
1.16k
        return DTime1 < DTime0;
1850
1.16k
    }
1851
1.16k
#endif
1852
1.16k
}
1853
1854
size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
1855
                                  const void* cSrc, size_t cSrcSize,
1856
                                  void* workSpace, size_t wkspSize, int flags)
1857
0
{
1858
    /* validation checks */
1859
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1860
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
1861
0
    if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
1862
0
    if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
1863
1864
0
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1865
#if defined(HUF_FORCE_DECOMPRESS_X1)
1866
        (void)algoNb;
1867
        assert(algoNb == 0);
1868
        return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1869
                                cSrcSize, workSpace, wkspSize, flags);
1870
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1871
        (void)algoNb;
1872
        assert(algoNb == 1);
1873
        return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1874
                                cSrcSize, workSpace, wkspSize, flags);
1875
#else
1876
0
        return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1877
0
                                cSrcSize, workSpace, wkspSize, flags):
1878
0
                        HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1879
0
                                cSrcSize, workSpace, wkspSize, flags);
1880
0
#endif
1881
0
    }
1882
0
}
1883
1884
1885
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags)
1886
0
{
1887
0
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
1888
#if defined(HUF_FORCE_DECOMPRESS_X1)
1889
    (void)dtd;
1890
    assert(dtd.tableType == 0);
1891
    return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1892
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1893
    (void)dtd;
1894
    assert(dtd.tableType == 1);
1895
    return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1896
#else
1897
0
    return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) :
1898
0
                           HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1899
0
#endif
1900
0
}
1901
1902
#ifndef HUF_FORCE_DECOMPRESS_X2
1903
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)
1904
108
{
1905
108
    const BYTE* ip = (const BYTE*) cSrc;
1906
1907
108
    size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags);
1908
108
    if (HUF_isError(hSize)) return hSize;
1909
71
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1910
70
    ip += hSize; cSrcSize -= hSize;
1911
1912
70
    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
1913
71
}
1914
#endif
1915
1916
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags)
1917
0
{
1918
0
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
1919
#if defined(HUF_FORCE_DECOMPRESS_X1)
1920
    (void)dtd;
1921
    assert(dtd.tableType == 0);
1922
    return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1923
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1924
    (void)dtd;
1925
    assert(dtd.tableType == 1);
1926
    return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1927
#else
1928
0
    return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) :
1929
0
                           HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
1930
0
#endif
1931
0
}
1932
1933
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)
1934
1.16k
{
1935
    /* validation checks */
1936
1.16k
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1937
1.16k
    if (cSrcSize == 0) return ERROR(corruption_detected);
1938
1939
1.16k
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1940
#if defined(HUF_FORCE_DECOMPRESS_X1)
1941
        (void)algoNb;
1942
        assert(algoNb == 0);
1943
        return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
1944
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1945
        (void)algoNb;
1946
        assert(algoNb == 1);
1947
        return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
1948
#else
1949
1.16k
        return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags) :
1950
1.16k
                        HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
1951
1.16k
#endif
1952
1.16k
    }
1953
1.16k
}