Coverage Report

Created: 2019-04-17 13:10

/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) 2013-present, Yann Collet.
5
6
   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7
8
   Redistribution and use in source and binary forms, with or without
9
   modification, are permitted provided that the following conditions are
10
   met:
11
12
       * Redistributions of source code must retain the above copyright
13
   notice, this list of conditions and the following disclaimer.
14
       * Redistributions in binary form must reproduce the above
15
   copyright notice, this list of conditions and the following disclaimer
16
   in the documentation and/or other materials provided with the
17
   distribution.
18
19
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31
    You can contact the author at :
32
    - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
33
****************************************************************** */
34
35
/* **************************************************************
36
*  Dependencies
37
****************************************************************/
38
#include <string.h>     /* memcpy, memset */
39
#include "compiler.h"
40
#include "bitstream.h"  /* BIT_* */
41
#include "fse.h"        /* to compress headers */
42
#define HUF_STATIC_LINKING_ONLY
43
#include "huf.h"
44
#include "error_private.h"
45
46
/* **************************************************************
47
*  Macros
48
****************************************************************/
49
50
/* These two optional macros force the use one way or another of the two
51
 * Huffman decompression implementations. You can't force in both directions
52
 * at the same time.
53
 */
54
#if defined(HUF_FORCE_DECOMPRESS_X1) && \
55
    defined(HUF_FORCE_DECOMPRESS_X2)
56
#error "Cannot force the use of the X1 and X2 decoders at the same time!"
57
#endif
58
59
60
/* **************************************************************
61
*  Error Management
62
****************************************************************/
63
104k
#define HUF_isError ERR_isError
64
80.2k
#define CHECK_F(f) { size_t const err_ = (f); if (HUF_isError(err_)) return err_; }
65
66
67
/* **************************************************************
68
*  Byte alignment for workSpace management
69
****************************************************************/
70
34.3k
#define HUF_ALIGN(x, a)         HUF_ALIGN_MASK((x), (a) - 1)
71
34.3k
#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
72
73
74
/* **************************************************************
75
*  BMI2 Variant Wrappers
76
****************************************************************/
77
#if DYNAMIC_BMI2
78
79
#define HUF_DGEN(fn)                                                        \
80
                                                                            \
81
    static size_t fn##_default(                                             \
82
                  void* dst,  size_t dstSize,                               \
83
            const void* cSrc, size_t cSrcSize,                              \
84
            const HUF_DTable* DTable)                                       \
85
0
    {                                                                       \
86
0
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
87
0
    }                                                                       \
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X1_usingDTable_internal_default
Unexecuted instantiation: huf_decompress.c:HUF_decompress4X1_usingDTable_internal_default
Unexecuted instantiation: huf_decompress.c:HUF_decompress1X2_usingDTable_internal_default
Unexecuted instantiation: huf_decompress.c:HUF_decompress4X2_usingDTable_internal_default
88
                                                                            \
89
    static TARGET_ATTRIBUTE("bmi2") size_t fn##_bmi2(                       \
90
                  void* dst,  size_t dstSize,                               \
91
            const void* cSrc, size_t cSrcSize,                              \
92
            const HUF_DTable* DTable)                                       \
93
19.5k
    {                                                                       \
94
19.5k
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
95
19.5k
    }                                                                       \
huf_decompress.c:HUF_decompress1X1_usingDTable_internal_bmi2
Line
Count
Source
93
1.54k
    {                                                                       \
94
1.54k
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
95
1.54k
    }                                                                       \
huf_decompress.c:HUF_decompress4X1_usingDTable_internal_bmi2
Line
Count
Source
93
11.4k
    {                                                                       \
94
11.4k
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
95
11.4k
    }                                                                       \
huf_decompress.c:HUF_decompress1X2_usingDTable_internal_bmi2
Line
Count
Source
93
1.99k
    {                                                                       \
94
1.99k
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
95
1.99k
    }                                                                       \
huf_decompress.c:HUF_decompress4X2_usingDTable_internal_bmi2
Line
Count
Source
93
4.54k
    {                                                                       \
94
4.54k
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
95
4.54k
    }                                                                       \
96
                                                                            \
97
    static size_t fn(void* dst, size_t dstSize, void const* cSrc,           \
98
                     size_t cSrcSize, HUF_DTable const* DTable, int bmi2)   \
99
19.5k
    {                                                                       \
100
19.5k
        if (bmi2) {                                                         \
101
19.5k
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
102
19.5k
        }                                                                   \
103
19.5k
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
104
19.5k
    }
huf_decompress.c:HUF_decompress1X1_usingDTable_internal
Line
Count
Source
99
1.54k
    {                                                                       \
100
1.54k
        if (bmi2) {                                                         \
101
1.54k
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
102
1.54k
        }                                                                   \
103
1.54k
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
104
1.54k
    }
huf_decompress.c:HUF_decompress4X1_usingDTable_internal
Line
Count
Source
99
11.4k
    {                                                                       \
100
11.4k
        if (bmi2) {                                                         \
101
11.4k
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
102
11.4k
        }                                                                   \
103
11.4k
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
104
11.4k
    }
huf_decompress.c:HUF_decompress1X2_usingDTable_internal
Line
Count
Source
99
1.99k
    {                                                                       \
100
1.99k
        if (bmi2) {                                                         \
101
1.99k
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
102
1.99k
        }                                                                   \
103
1.99k
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
104
1.99k
    }
huf_decompress.c:HUF_decompress4X2_usingDTable_internal
Line
Count
Source
99
4.54k
    {                                                                       \
100
4.54k
        if (bmi2) {                                                         \
101
4.54k
            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \
102
4.54k
        }                                                                   \
103
4.54k
        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \
104
4.54k
    }
105
106
#else
107
108
#define HUF_DGEN(fn)                                                        \
109
    static size_t fn(void* dst, size_t dstSize, void const* cSrc,           \
110
                     size_t cSrcSize, HUF_DTable const* DTable, int bmi2)   \
111
    {                                                                       \
112
        (void)bmi2;                                                         \
113
        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \
114
    }
115
116
#endif
117
118
119
/*-***************************/
120
/*  generic DTableDesc       */
121
/*-***************************/
122
typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
123
124
static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
125
48.1k
{
126
48.1k
    DTableDesc dtd;
127
48.1k
    memcpy(&dtd, table, sizeof(dtd));
128
48.1k
    return dtd;
129
48.1k
}
130
131
132
#ifndef HUF_FORCE_DECOMPRESS_X2
133
134
/*-***************************/
135
/*  single-symbol decoding   */
136
/*-***************************/
137
typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1;   /* single-symbol decoding */
138
139
size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize)
140
13.8k
{
141
13.8k
    U32 tableLog = 0;
142
13.8k
    U32 nbSymbols = 0;
143
13.8k
    size_t iSize;
144
13.8k
    void* const dtPtr = DTable + 1;
145
13.8k
    HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;
146
13.8k
147
13.8k
    U32* rankVal;
148
13.8k
    BYTE* huffWeight;
149
13.8k
    size_t spaceUsed32 = 0;
150
13.8k
151
13.8k
    rankVal = (U32 *)workSpace + spaceUsed32;
152
13.8k
    spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1;
153
13.8k
    huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32);
154
13.8k
    spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
155
13.8k
156
13.8k
    if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
157
13.8k
158
13.8k
    DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
159
13.8k
    /* memset(huffWeight, 0, sizeof(huffWeight)); */   /* is not necessary, even though some analyzer complain ... */
160
13.8k
161
13.8k
    iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
162
13.8k
    if (HUF_isError(iSize)) return iSize;
163
12.7k
164
12.7k
    /* Table header */
165
12.7k
    {   DTableDesc dtd = HUF_getDTableDesc(DTable);
166
12.7k
        if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */
167
12.7k
        dtd.tableType = 0;
168
12.7k
        dtd.tableLog = (BYTE)tableLog;
169
12.7k
        memcpy(DTable, &dtd, sizeof(dtd));
170
12.7k
    }
171
12.7k
172
12.7k
    /* Calculate starting value for each rank */
173
12.7k
    {   U32 n, nextRankStart = 0;
174
54.6k
        for (n=1; n<tableLog+1; n++) {
175
41.8k
            U32 const current = nextRankStart;
176
41.8k
            nextRankStart += (rankVal[n] << (n-1));
177
41.8k
            rankVal[n] = current;
178
41.8k
    }   }
179
12.7k
180
12.7k
    /* fill DTable */
181
12.7k
    {   U32 n;
182
1.76M
        for (n=0; n<nbSymbols; n++) {
183
1.75M
            U32 const w = huffWeight[n];
184
1.75M
            U32 const length = (1 << w) >> 1;
185
1.75M
            U32 u;
186
1.75M
            HUF_DEltX1 D;
187
1.75M
            D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
188
3.46M
            for (u = rankVal[w]; u < rankVal[w] + length; u++)
189
1.70M
                dt[u] = D;
190
1.75M
            rankVal[w] += length;
191
1.75M
    }   }
192
12.7k
193
12.7k
    return iSize;
194
12.7k
}
195
196
size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize)
197
0
{
198
0
    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
199
0
    return HUF_readDTableX1_wksp(DTable, src, srcSize,
200
0
                                 workSpace, sizeof(workSpace));
201
0
}
202
203
FORCE_INLINE_TEMPLATE BYTE
204
HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)
205
6.80M
{
206
6.80M
    size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
207
6.80M
    BYTE const c = dt[val].byte;
208
6.80M
    BIT_skipBits(Dstream, dt[val].nbBits);
209
6.80M
    return c;
210
6.80M
}
211
212
#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \
213
6.80M
    *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog)
214
215
#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr)  \
216
744k
    if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
217
744k
        HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)
218
219
#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \
220
1.48M
    if (MEM_64bits()) \
221
1.48M
        HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)
222
223
HINT_INLINE size_t
224
HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog)
225
45.8k
{
226
45.8k
    BYTE* const pStart = p;
227
45.8k
228
45.8k
    /* up to 4 symbols at a time */
229
70.4k
    while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {
230
24.6k
        HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
231
24.6k
        HUF_DECODE_SYMBOLX1_1(p, bitDPtr);
232
24.6k
        HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
233
24.6k
        HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
234
24.6k
    }
235
45.8k
236
45.8k
    /* [0-3] symbols remaining */
237
45.8k
    if (MEM_32bits())
238
0
        while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd))
239
0
            HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
240
45.8k
241
45.8k
    /* no more data to retrieve from bitstream, no need to reload */
242
3.86M
    while (p < pEnd)
243
3.82M
        HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
244
45.8k
245
45.8k
    return pEnd-pStart;
246
45.8k
}
247
248
FORCE_INLINE_TEMPLATE size_t
249
HUF_decompress1X1_usingDTable_internal_body(
250
          void* dst,  size_t dstSize,
251
    const void* cSrc, size_t cSrcSize,
252
    const HUF_DTable* DTable)
253
1.54k
{
254
1.54k
    BYTE* op = (BYTE*)dst;
255
1.54k
    BYTE* const oend = op + dstSize;
256
1.54k
    const void* dtPtr = DTable + 1;
257
1.54k
    const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
258
1.54k
    BIT_DStream_t bitD;
259
1.54k
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
260
1.54k
    U32 const dtLog = dtd.tableLog;
261
1.54k
262
1.54k
    CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
263
1.50k
264
1.50k
    HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog);
265
1.50k
266
1.50k
    if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
267
1.22k
268
1.22k
    return dstSize;
269
1.22k
}
270
271
FORCE_INLINE_TEMPLATE size_t
272
HUF_decompress4X1_usingDTable_internal_body(
273
          void* dst,  size_t dstSize,
274
    const void* cSrc, size_t cSrcSize,
275
    const HUF_DTable* DTable)
276
11.4k
{
277
11.4k
    /* Check */
278
11.4k
    if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
279
11.3k
280
11.3k
    {   const BYTE* const istart = (const BYTE*) cSrc;
281
11.3k
        BYTE* const ostart = (BYTE*) dst;
282
11.3k
        BYTE* const oend = ostart + dstSize;
283
11.3k
        const void* const dtPtr = DTable + 1;
284
11.3k
        const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
285
11.3k
286
11.3k
        /* Init */
287
11.3k
        BIT_DStream_t bitD1;
288
11.3k
        BIT_DStream_t bitD2;
289
11.3k
        BIT_DStream_t bitD3;
290
11.3k
        BIT_DStream_t bitD4;
291
11.3k
        size_t const length1 = MEM_readLE16(istart);
292
11.3k
        size_t const length2 = MEM_readLE16(istart+2);
293
11.3k
        size_t const length3 = MEM_readLE16(istart+4);
294
11.3k
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
295
11.3k
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
296
11.3k
        const BYTE* const istart2 = istart1 + length1;
297
11.3k
        const BYTE* const istart3 = istart2 + length2;
298
11.3k
        const BYTE* const istart4 = istart3 + length3;
299
11.3k
        const size_t segmentSize = (dstSize+3) / 4;
300
11.3k
        BYTE* const opStart2 = ostart + segmentSize;
301
11.3k
        BYTE* const opStart3 = opStart2 + segmentSize;
302
11.3k
        BYTE* const opStart4 = opStart3 + segmentSize;
303
11.3k
        BYTE* op1 = ostart;
304
11.3k
        BYTE* op2 = opStart2;
305
11.3k
        BYTE* op3 = opStart3;
306
11.3k
        BYTE* op4 = opStart4;
307
11.3k
        U32 endSignal = BIT_DStream_unfinished;
308
11.3k
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
309
11.3k
        U32 const dtLog = dtd.tableLog;
310
11.3k
311
11.3k
        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
312
11.1k
        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
313
11.1k
        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
314
11.1k
        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
315
11.1k
        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
316
11.0k
317
11.0k
        /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
318
11.0k
        endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
319
191k
        while ( (endSignal==BIT_DStream_unfinished) && (op4<(oend-3)) ) {
320
179k
            HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
321
179k
            HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
322
179k
            HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
323
179k
            HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
324
179k
            HUF_DECODE_SYMBOLX1_1(op1, &bitD1);
325
179k
            HUF_DECODE_SYMBOLX1_1(op2, &bitD2);
326
179k
            HUF_DECODE_SYMBOLX1_1(op3, &bitD3);
327
179k
            HUF_DECODE_SYMBOLX1_1(op4, &bitD4);
328
179k
            HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
329
179k
            HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
330
179k
            HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
331
179k
            HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
332
179k
            HUF_DECODE_SYMBOLX1_0(op1, &bitD1);
333
179k
            HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
334
179k
            HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
335
179k
            HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
336
179k
            BIT_reloadDStream(&bitD1);
337
179k
            BIT_reloadDStream(&bitD2);
338
179k
            BIT_reloadDStream(&bitD3);
339
179k
            BIT_reloadDStream(&bitD4);
340
179k
        }
341
11.0k
342
11.0k
        /* check corruption */
343
11.0k
        /* note : should not be necessary : op# advance in lock step, and we control op4.
344
11.0k
         *        but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */
345
11.0k
        if (op1 > opStart2) return ERROR(corruption_detected);
346
11.0k
        if (op2 > opStart3) return ERROR(corruption_detected);
347
11.0k
        if (op3 > opStart4) return ERROR(corruption_detected);
348
11.0k
        /* note : op4 supposed already verified within main loop */
349
11.0k
350
11.0k
        /* finish bitStreams one by one */
351
11.0k
        HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog);
352
11.0k
        HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog);
353
11.0k
        HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog);
354
11.0k
        HUF_decodeStreamX1(op4, &bitD4, oend,     dt, dtLog);
355
11.0k
356
11.0k
        /* check */
357
11.0k
        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
358
11.0k
          if (!endCheck) return ERROR(corruption_detected); }
359
10.5k
360
10.5k
        /* decoded size */
361
10.5k
        return dstSize;
362
10.5k
    }
363
10.5k
}
364
365
366
typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize,
367
                                               const void *cSrc,
368
                                               size_t cSrcSize,
369
                                               const HUF_DTable *DTable);
370
371
HUF_DGEN(HUF_decompress1X1_usingDTable_internal)
372
HUF_DGEN(HUF_decompress4X1_usingDTable_internal)
373
374
375
376
size_t HUF_decompress1X1_usingDTable(
377
          void* dst,  size_t dstSize,
378
    const void* cSrc, size_t cSrcSize,
379
    const HUF_DTable* DTable)
380
0
{
381
0
    DTableDesc dtd = HUF_getDTableDesc(DTable);
382
0
    if (dtd.tableType != 0) return ERROR(GENERIC);
383
0
    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
384
0
}
385
386
size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
387
                                   const void* cSrc, size_t cSrcSize,
388
                                   void* workSpace, size_t wkspSize)
389
0
{
390
0
    const BYTE* ip = (const BYTE*) cSrc;
391
0
392
0
    size_t const hSize = HUF_readDTableX1_wksp(DCtx, cSrc, cSrcSize, workSpace, wkspSize);
393
0
    if (HUF_isError(hSize)) return hSize;
394
0
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
395
0
    ip += hSize; cSrcSize -= hSize;
396
0
397
0
    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0);
398
0
}
399
400
401
size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
402
                              const void* cSrc, size_t cSrcSize)
403
0
{
404
0
    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
405
0
    return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
406
0
                                       workSpace, sizeof(workSpace));
407
0
}
408
409
size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
410
0
{
411
0
    HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
412
0
    return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
413
0
}
414
415
size_t HUF_decompress4X1_usingDTable(
416
          void* dst,  size_t dstSize,
417
    const void* cSrc, size_t cSrcSize,
418
    const HUF_DTable* DTable)
419
0
{
420
0
    DTableDesc dtd = HUF_getDTableDesc(DTable);
421
0
    if (dtd.tableType != 0) return ERROR(GENERIC);
422
0
    return HUF_decompress4X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
423
0
}
424
425
static size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,
426
                                   const void* cSrc, size_t cSrcSize,
427
                                   void* workSpace, size_t wkspSize, int bmi2)
428
12.0k
{
429
12.0k
    const BYTE* ip = (const BYTE*) cSrc;
430
12.0k
431
12.0k
    size_t const hSize = HUF_readDTableX1_wksp (dctx, cSrc, cSrcSize,
432
12.0k
                                                workSpace, wkspSize);
433
12.0k
    if (HUF_isError(hSize)) return hSize;
434
11.3k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
435
11.3k
    ip += hSize; cSrcSize -= hSize;
436
11.3k
437
11.3k
    return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);
438
11.3k
}
439
440
size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
441
                                   const void* cSrc, size_t cSrcSize,
442
                                   void* workSpace, size_t wkspSize)
443
0
{
444
0
    return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, 0);
445
0
}
446
447
448
size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
449
0
{
450
0
    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
451
0
    return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
452
0
                                       workSpace, sizeof(workSpace));
453
0
}
454
size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
455
0
{
456
0
    HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
457
0
    return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
458
0
}
459
460
#endif /* HUF_FORCE_DECOMPRESS_X2 */
461
462
463
#ifndef HUF_FORCE_DECOMPRESS_X1
464
465
/* *************************/
466
/* double-symbols decoding */
467
/* *************************/
468
469
typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2;  /* double-symbols decoding */
470
typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
471
typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1];
472
typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];
473
474
475
/* HUF_fillDTableX2Level2() :
476
 * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
477
static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed,
478
                           const U32* rankValOrigin, const int minWeight,
479
                           const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
480
                           U32 nbBitsBaseline, U16 baseSeq)
481
787k
{
482
787k
    HUF_DEltX2 DElt;
483
787k
    U32 rankVal[HUF_TABLELOG_MAX + 1];
484
787k
485
787k
    /* get pre-calculated rankVal */
486
787k
    memcpy(rankVal, rankValOrigin, sizeof(rankVal));
487
787k
488
787k
    /* fill skipped values */
489
787k
    if (minWeight>1) {
490
779k
        U32 i, skipSize = rankVal[minWeight];
491
779k
        MEM_writeLE16(&(DElt.sequence), baseSeq);
492
779k
        DElt.nbBits   = (BYTE)(consumed);
493
779k
        DElt.length   = 1;
494
11.7M
        for (i = 0; i < skipSize; i++)
495
10.9M
            DTable[i] = DElt;
496
779k
    }
497
787k
498
787k
    /* fill DTable */
499
3.72M
    {   U32 s; for (s=0; s<sortedListSize; s++) {   /* note : sortedSymbols already skipped */
500
2.93M
            const U32 symbol = sortedSymbols[s].symbol;
501
2.93M
            const U32 weight = sortedSymbols[s].weight;
502
2.93M
            const U32 nbBits = nbBitsBaseline - weight;
503
2.93M
            const U32 length = 1 << (sizeLog-nbBits);
504
2.93M
            const U32 start = rankVal[weight];
505
2.93M
            U32 i = start;
506
2.93M
            const U32 end = start + length;
507
2.93M
508
2.93M
            MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
509
2.93M
            DElt.nbBits = (BYTE)(nbBits + consumed);
510
2.93M
            DElt.length = 2;
511
9.51M
            do { DTable[i++] = DElt; } while (i<end);   /* since length >= 1 */
512
2.93M
513
2.93M
            rankVal[weight] += length;
514
2.93M
    }   }
515
787k
}
516
517
518
static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
519
                           const sortedSymbol_t* sortedList, const U32 sortedListSize,
520
                           const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
521
                           const U32 nbBitsBaseline)
522
10.2k
{
523
10.2k
    U32 rankVal[HUF_TABLELOG_MAX + 1];
524
10.2k
    const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */
525
10.2k
    const U32 minBits  = nbBitsBaseline - maxWeight;
526
10.2k
    U32 s;
527
10.2k
528
10.2k
    memcpy(rankVal, rankValOrigin, sizeof(rankVal));
529
10.2k
530
10.2k
    /* fill DTable */
531
2.35M
    for (s=0; s<sortedListSize; s++) {
532
2.34M
        const U16 symbol = sortedList[s].symbol;
533
2.34M
        const U32 weight = sortedList[s].weight;
534
2.34M
        const U32 nbBits = nbBitsBaseline - weight;
535
2.34M
        const U32 start = rankVal[weight];
536
2.34M
        const U32 length = 1 << (targetLog-nbBits);
537
2.34M
538
2.34M
        if (targetLog-nbBits >= minBits) {   /* enough room for a second symbol */
539
787k
            U32 sortedRank;
540
787k
            int minWeight = nbBits + scaleLog;
541
787k
            if (minWeight < 1) minWeight = 1;
542
787k
            sortedRank = rankStart[minWeight];
543
787k
            HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits,
544
787k
                           rankValOrigin[nbBits], minWeight,
545
787k
                           sortedList+sortedRank, sortedListSize-sortedRank,
546
787k
                           nbBitsBaseline, symbol);
547
1.55M
        } else {
548
1.55M
            HUF_DEltX2 DElt;
549
1.55M
            MEM_writeLE16(&(DElt.sequence), symbol);
550
1.55M
            DElt.nbBits = (BYTE)(nbBits);
551
1.55M
            DElt.length = 1;
552
1.55M
            {   U32 const end = start + length;
553
1.55M
                U32 u;
554
22.9M
                for (u = start; u < end; u++) DTable[u] = DElt;
555
1.55M
        }   }
556
2.34M
        rankVal[weight] += length;
557
2.34M
    }
558
10.2k
}
559
560
size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
561
                       const void* src, size_t srcSize,
562
                             void* workSpace, size_t wkspSize)
563
10.2k
{
564
10.2k
    U32 tableLog, maxW, sizeOfSort, nbSymbols;
565
10.2k
    DTableDesc dtd = HUF_getDTableDesc(DTable);
566
10.2k
    U32 const maxTableLog = dtd.maxTableLog;
567
10.2k
    size_t iSize;
568
10.2k
    void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */
569
10.2k
    HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
570
10.2k
    U32 *rankStart;
571
10.2k
572
10.2k
    rankValCol_t* rankVal;
573
10.2k
    U32* rankStats;
574
10.2k
    U32* rankStart0;
575
10.2k
    sortedSymbol_t* sortedSymbol;
576
10.2k
    BYTE* weightList;
577
10.2k
    size_t spaceUsed32 = 0;
578
10.2k
579
10.2k
    rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32);
580
10.2k
    spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2;
581
10.2k
    rankStats = (U32 *)workSpace + spaceUsed32;
582
10.2k
    spaceUsed32 += HUF_TABLELOG_MAX + 1;
583
10.2k
    rankStart0 = (U32 *)workSpace + spaceUsed32;
584
10.2k
    spaceUsed32 += HUF_TABLELOG_MAX + 2;
585
10.2k
    sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t);
586
10.2k
    spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2;
587
10.2k
    weightList = (BYTE *)((U32 *)workSpace + spaceUsed32);
588
10.2k
    spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
589
10.2k
590
10.2k
    if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
591
10.2k
592
10.2k
    rankStart = rankStart0 + 1;
593
10.2k
    memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));
594
10.2k
595
10.2k
    DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable));   /* if compiler fails here, assertion is wrong */
596
10.2k
    if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
597
10.2k
    /* memset(weightList, 0, sizeof(weightList)); */  /* is not necessary, even though some analyzer complain ... */
598
10.2k
599
10.2k
    iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
600
10.2k
    if (HUF_isError(iSize)) return iSize;
601
10.2k
602
10.2k
    /* check result */
603
10.2k
    if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */
604
10.2k
605
10.2k
    /* find maxWeight */
606
46.7k
    for (maxW = tableLog; rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */
607
10.2k
608
10.2k
    /* Get start index of each weight */
609
10.2k
    {   U32 w, nextRankStart = 0;
610
67.5k
        for (w=1; w<maxW+1; w++) {
611
57.3k
            U32 current = nextRankStart;
612
57.3k
            nextRankStart += rankStats[w];
613
57.3k
            rankStart[w] = current;
614
57.3k
        }
615
10.2k
        rankStart[0] = nextRankStart;   /* put all 0w symbols at the end of sorted list*/
616
10.2k
        sizeOfSort = nextRankStart;
617
10.2k
    }
618
10.2k
619
10.2k
    /* sort symbols by weight */
620
10.2k
    {   U32 s;
621
2.54M
        for (s=0; s<nbSymbols; s++) {
622
2.53M
            U32 const w = weightList[s];
623
2.53M
            U32 const r = rankStart[w]++;
624
2.53M
            sortedSymbol[r].symbol = (BYTE)s;
625
2.53M
            sortedSymbol[r].weight = (BYTE)w;
626
2.53M
        }
627
10.2k
        rankStart[0] = 0;   /* forget 0w symbols; this is beginning of weight(1) */
628
10.2k
    }
629
10.2k
630
10.2k
    /* Build rankVal */
631
10.2k
    {   U32* const rankVal0 = rankVal[0];
632
10.2k
        {   int const rescale = (maxTableLog-tableLog) - 1;   /* tableLog <= maxTableLog */
633
10.2k
            U32 nextRankVal = 0;
634
10.2k
            U32 w;
635
67.5k
            for (w=1; w<maxW+1; w++) {
636
57.3k
                U32 current = nextRankVal;
637
57.3k
                nextRankVal += rankStats[w] << (w+rescale);
638
57.3k
                rankVal0[w] = current;
639
57.3k
        }   }
640
10.2k
        {   U32 const minBits = tableLog+1 - maxW;
641
10.2k
            U32 consumed;
642
51.9k
            for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
643
41.7k
                U32* const rankValPtr = rankVal[consumed];
644
41.7k
                U32 w;
645
339k
                for (w = 1; w < maxW+1; w++) {
646
297k
                    rankValPtr[w] = rankVal0[w] >> consumed;
647
297k
    }   }   }   }
648
10.2k
649
10.2k
    HUF_fillDTableX2(dt, maxTableLog,
650
10.2k
                   sortedSymbol, sizeOfSort,
651
10.2k
                   rankStart0, rankVal, maxW,
652
10.2k
                   tableLog+1);
653
10.2k
654
10.2k
    dtd.tableLog = (BYTE)maxTableLog;
655
10.2k
    dtd.tableType = 1;
656
10.2k
    memcpy(DTable, &dtd, sizeof(dtd));
657
10.2k
    return iSize;
658
10.2k
}
659
660
size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)
661
0
{
662
0
  U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
663
0
  return HUF_readDTableX2_wksp(DTable, src, srcSize,
664
0
                               workSpace, sizeof(workSpace));
665
0
}
666
667
668
FORCE_INLINE_TEMPLATE U32
669
HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
670
6.85M
{
671
6.85M
    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
672
6.85M
    memcpy(op, dt+val, 2);
673
6.85M
    BIT_skipBits(DStream, dt[val].nbBits);
674
6.85M
    return dt[val].length;
675
6.85M
}
676
677
FORCE_INLINE_TEMPLATE U32
678
HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
679
16.9k
{
680
16.9k
    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
681
16.9k
    memcpy(op, dt+val, 1);
682
16.9k
    if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
683
10.7k
    else {
684
10.7k
        if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
685
8.97k
            BIT_skipBits(DStream, dt[val].nbBits);
686
8.97k
            if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
687
4.03k
                /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
688
4.03k
                DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);
689
8.97k
    }   }
690
16.9k
    return 1;
691
16.9k
}
692
693
#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
694
5.09M
    ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
695
696
#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
697
585k
    if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
698
585k
        ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
699
700
#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
701
1.17M
    if (MEM_64bits()) \
702
1.17M
        ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
703
704
HINT_INLINE size_t
705
HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd,
706
                const HUF_DEltX2* const dt, const U32 dtLog)
707
18.5k
{
708
18.5k
    BYTE* const pStart = p;
709
18.5k
710
18.5k
    /* up to 8 symbols at a time */
711
198k
    while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
712
180k
        HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
713
180k
        HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
714
180k
        HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
715
180k
        HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
716
180k
    }
717
18.5k
718
18.5k
    /* closer to end : up to 2 symbols at a time */
719
19.3k
    while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
720
18.5k
        HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
721
18.5k
722
4.52M
    while (p <= pEnd-2)
723
4.51M
        HUF_DECODE_SYMBOLX2_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */
724
18.5k
725
18.5k
    if (p < pEnd)
726
16.9k
        p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog);
727
18.5k
728
18.5k
    return p-pStart;
729
18.5k
}
730
731
FORCE_INLINE_TEMPLATE size_t
732
HUF_decompress1X2_usingDTable_internal_body(
733
          void* dst,  size_t dstSize,
734
    const void* cSrc, size_t cSrcSize,
735
    const HUF_DTable* DTable)
736
1.99k
{
737
1.99k
    BIT_DStream_t bitD;
738
1.99k
739
1.99k
    /* Init */
740
1.99k
    CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
741
1.99k
742
1.99k
    /* decode */
743
1.99k
    {   BYTE* const ostart = (BYTE*) dst;
744
1.99k
        BYTE* const oend = ostart + dstSize;
745
1.99k
        const void* const dtPtr = DTable+1;   /* force compiler to not use strict-aliasing */
746
1.99k
        const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
747
1.99k
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
748
1.99k
        HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog);
749
1.99k
    }
750
1.99k
751
1.99k
    /* check */
752
1.99k
    if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
753
1.82k
754
1.82k
    /* decoded size */
755
1.82k
    return dstSize;
756
1.82k
}
757
758
759
FORCE_INLINE_TEMPLATE size_t
760
HUF_decompress4X2_usingDTable_internal_body(
761
          void* dst,  size_t dstSize,
762
    const void* cSrc, size_t cSrcSize,
763
    const HUF_DTable* DTable)
764
4.54k
{
765
4.54k
    if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */
766
4.52k
767
4.52k
    {   const BYTE* const istart = (const BYTE*) cSrc;
768
4.52k
        BYTE* const ostart = (BYTE*) dst;
769
4.52k
        BYTE* const oend = ostart + dstSize;
770
4.52k
        const void* const dtPtr = DTable+1;
771
4.52k
        const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
772
4.52k
773
4.52k
        /* Init */
774
4.52k
        BIT_DStream_t bitD1;
775
4.52k
        BIT_DStream_t bitD2;
776
4.52k
        BIT_DStream_t bitD3;
777
4.52k
        BIT_DStream_t bitD4;
778
4.52k
        size_t const length1 = MEM_readLE16(istart);
779
4.52k
        size_t const length2 = MEM_readLE16(istart+2);
780
4.52k
        size_t const length3 = MEM_readLE16(istart+4);
781
4.52k
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
782
4.52k
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
783
4.52k
        const BYTE* const istart2 = istart1 + length1;
784
4.52k
        const BYTE* const istart3 = istart2 + length2;
785
4.52k
        const BYTE* const istart4 = istart3 + length3;
786
4.52k
        size_t const segmentSize = (dstSize+3) / 4;
787
4.52k
        BYTE* const opStart2 = ostart + segmentSize;
788
4.52k
        BYTE* const opStart3 = opStart2 + segmentSize;
789
4.52k
        BYTE* const opStart4 = opStart3 + segmentSize;
790
4.52k
        BYTE* op1 = ostart;
791
4.52k
        BYTE* op2 = opStart2;
792
4.52k
        BYTE* op3 = opStart3;
793
4.52k
        BYTE* op4 = opStart4;
794
4.52k
        U32 endSignal;
795
4.52k
        DTableDesc const dtd = HUF_getDTableDesc(DTable);
796
4.52k
        U32 const dtLog = dtd.tableLog;
797
4.52k
798
4.52k
        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
799
4.24k
        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
800
4.23k
        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
801
4.17k
        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
802
4.16k
        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
803
4.15k
804
4.15k
        /* 16-32 symbols per loop (4-8 symbols per stream) */
805
4.15k
        endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
806
105k
        for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {
807
101k
            HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
808
101k
            HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
809
101k
            HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
810
101k
            HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
811
101k
            HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
812
101k
            HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
813
101k
            HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
814
101k
            HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
815
101k
            HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
816
101k
            HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
817
101k
            HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
818
101k
            HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
819
101k
            HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
820
101k
            HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
821
101k
            HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
822
101k
            HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
823
101k
824
101k
            endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
825
101k
        }
826
4.15k
827
4.15k
        /* check corruption */
828
4.15k
        if (op1 > opStart2) return ERROR(corruption_detected);
829
4.14k
        if (op2 > opStart3) return ERROR(corruption_detected);
830
4.14k
        if (op3 > opStart4) return ERROR(corruption_detected);
831
4.13k
        /* note : op4 already verified within main loop */
832
4.13k
833
4.13k
        /* finish bitStreams one by one */
834
4.13k
        HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
835
4.13k
        HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
836
4.13k
        HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
837
4.13k
        HUF_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);
838
4.13k
839
4.13k
        /* check */
840
4.13k
        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
841
4.13k
          if (!endCheck) return ERROR(corruption_detected); }
842
3.43k
843
3.43k
        /* decoded size */
844
3.43k
        return dstSize;
845
3.43k
    }
846
3.43k
}
847
848
HUF_DGEN(HUF_decompress1X2_usingDTable_internal)
849
HUF_DGEN(HUF_decompress4X2_usingDTable_internal)
850
851
size_t HUF_decompress1X2_usingDTable(
852
          void* dst,  size_t dstSize,
853
    const void* cSrc, size_t cSrcSize,
854
    const HUF_DTable* DTable)
855
0
{
856
0
    DTableDesc dtd = HUF_getDTableDesc(DTable);
857
0
    if (dtd.tableType != 1) return ERROR(GENERIC);
858
0
    return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
859
0
}
860
861
size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
862
                                   const void* cSrc, size_t cSrcSize,
863
                                   void* workSpace, size_t wkspSize)
864
0
{
865
0
    const BYTE* ip = (const BYTE*) cSrc;
866
0
867
0
    size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize,
868
0
                                               workSpace, wkspSize);
869
0
    if (HUF_isError(hSize)) return hSize;
870
0
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
871
0
    ip += hSize; cSrcSize -= hSize;
872
0
873
0
    return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0);
874
0
}
875
876
877
size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
878
                              const void* cSrc, size_t cSrcSize)
879
0
{
880
0
    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
881
0
    return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
882
0
                                       workSpace, sizeof(workSpace));
883
0
}
884
885
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
886
0
{
887
0
    HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
888
0
    return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
889
0
}
890
891
size_t HUF_decompress4X2_usingDTable(
892
          void* dst,  size_t dstSize,
893
    const void* cSrc, size_t cSrcSize,
894
    const HUF_DTable* DTable)
895
0
{
896
0
    DTableDesc dtd = HUF_getDTableDesc(DTable);
897
0
    if (dtd.tableType != 1) return ERROR(GENERIC);
898
0
    return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
899
0
}
900
901
static size_t HUF_decompress4X2_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,
902
                                   const void* cSrc, size_t cSrcSize,
903
                                   void* workSpace, size_t wkspSize, int bmi2)
904
1.25k
{
905
1.25k
    const BYTE* ip = (const BYTE*) cSrc;
906
1.25k
907
1.25k
    size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize,
908
1.25k
                                         workSpace, wkspSize);
909
1.25k
    if (HUF_isError(hSize)) return hSize;
910
1.23k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
911
1.23k
    ip += hSize; cSrcSize -= hSize;
912
1.23k
913
1.23k
    return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);
914
1.23k
}
915
916
size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
917
                                   const void* cSrc, size_t cSrcSize,
918
                                   void* workSpace, size_t wkspSize)
919
0
{
920
0
    return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, /* bmi2 */ 0);
921
0
}
922
923
924
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
925
                              const void* cSrc, size_t cSrcSize)
926
0
{
927
0
    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
928
0
    return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
929
0
                                       workSpace, sizeof(workSpace));
930
0
}
931
932
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
933
0
{
934
0
    HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
935
0
    return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
936
0
}
937
938
#endif /* HUF_FORCE_DECOMPRESS_X1 */
939
940
941
/* ***********************************/
942
/* Universal decompression selectors */
943
/* ***********************************/
944
945
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,
946
                                    const void* cSrc, size_t cSrcSize,
947
                                    const HUF_DTable* DTable)
948
0
{
949
0
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
950
#if defined(HUF_FORCE_DECOMPRESS_X1)
951
    (void)dtd;
952
    assert(dtd.tableType == 0);
953
    return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
954
#elif defined(HUF_FORCE_DECOMPRESS_X2)
955
    (void)dtd;
956
    assert(dtd.tableType == 1);
957
    return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
958
#else
959
0
    return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) :
960
0
                           HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
961
0
#endif
962
0
}
963
964
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
965
                                    const void* cSrc, size_t cSrcSize,
966
                                    const HUF_DTable* DTable)
967
0
{
968
0
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
969
#if defined(HUF_FORCE_DECOMPRESS_X1)
970
    (void)dtd;
971
    assert(dtd.tableType == 0);
972
    return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
973
#elif defined(HUF_FORCE_DECOMPRESS_X2)
974
    (void)dtd;
975
    assert(dtd.tableType == 1);
976
    return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
977
#else
978
0
    return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) :
979
0
                           HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
980
0
#endif
981
0
}
982
983
984
#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
985
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
986
static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
987
{
988
    /* single, double, quad */
989
    {{0,0}, {1,1}, {2,2}},  /* Q==0 : impossible */
990
    {{0,0}, {1,1}, {2,2}},  /* Q==1 : impossible */
991
    {{  38,130}, {1313, 74}, {2151, 38}},   /* Q == 2 : 12-18% */
992
    {{ 448,128}, {1353, 74}, {2238, 41}},   /* Q == 3 : 18-25% */
993
    {{ 556,128}, {1353, 74}, {2238, 47}},   /* Q == 4 : 25-32% */
994
    {{ 714,128}, {1418, 74}, {2436, 53}},   /* Q == 5 : 32-38% */
995
    {{ 883,128}, {1437, 74}, {2464, 61}},   /* Q == 6 : 38-44% */
996
    {{ 897,128}, {1515, 75}, {2622, 68}},   /* Q == 7 : 44-50% */
997
    {{ 926,128}, {1613, 75}, {2730, 75}},   /* Q == 8 : 50-56% */
998
    {{ 947,128}, {1729, 77}, {3359, 77}},   /* Q == 9 : 56-62% */
999
    {{1107,128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */
1000
    {{1177,128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */
1001
    {{1242,128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */
1002
    {{1349,128}, {2644,106}, {5260,106}},   /* Q ==13 : 81-87% */
1003
    {{1455,128}, {2422,124}, {4174,124}},   /* Q ==14 : 87-93% */
1004
    {{ 722,128}, {1891,145}, {1936,146}},   /* Q ==15 : 93-99% */
1005
};
1006
#endif
1007
1008
/** HUF_selectDecoder() :
1009
 *  Tells which decoder is likely to decode faster,
1010
 *  based on a set of pre-computed metrics.
1011
 * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .
1012
 *  Assumption : 0 < dstSize <= 128 KB */
1013
U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
1014
13.3k
{
1015
13.3k
    assert(dstSize > 0);
1016
13.3k
    assert(dstSize <= 128*1024);
1017
#if defined(HUF_FORCE_DECOMPRESS_X1)
1018
    (void)dstSize;
1019
    (void)cSrcSize;
1020
    return 0;
1021
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1022
    (void)dstSize;
1023
    (void)cSrcSize;
1024
    return 1;
1025
#else
1026
    /* decoder timing evaluation */
1027
13.3k
    {   U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 */
1028
13.3k
        U32 const D256 = (U32)(dstSize >> 8);
1029
13.3k
        U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
1030
13.3k
        U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
1031
13.3k
        DTime1 += DTime1 >> 3;  /* advantage to algorithm using less memory, to reduce cache eviction */
1032
13.3k
        return DTime1 < DTime0;
1033
13.3k
    }
1034
13.3k
#endif
1035
13.3k
}
1036
1037
1038
typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
1039
1040
size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1041
0
{
1042
0
#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
1043
0
    static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 };
1044
0
#endif
1045
0
1046
0
    /* validation checks */
1047
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1048
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
1049
0
    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
1050
0
    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
1051
0
1052
0
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1053
#if defined(HUF_FORCE_DECOMPRESS_X1)
1054
        (void)algoNb;
1055
        assert(algoNb == 0);
1056
        return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize);
1057
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1058
        (void)algoNb;
1059
        assert(algoNb == 1);
1060
        return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize);
1061
#else
1062
        return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
1063
0
#endif
1064
0
    }
1065
0
}
1066
1067
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1068
0
{
1069
0
    /* validation checks */
1070
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1071
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
1072
0
    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
1073
0
    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
1074
0
1075
0
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1076
#if defined(HUF_FORCE_DECOMPRESS_X1)
1077
        (void)algoNb;
1078
        assert(algoNb == 0);
1079
        return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
1080
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1081
        (void)algoNb;
1082
        assert(algoNb == 1);
1083
        return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
1084
#else
1085
0
        return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
1086
0
                        HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
1087
0
#endif
1088
0
    }
1089
0
}
1090
1091
size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1092
0
{
1093
0
    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1094
0
    return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
1095
0
                                         workSpace, sizeof(workSpace));
1096
0
}
1097
1098
1099
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst,
1100
                                     size_t dstSize, const void* cSrc,
1101
                                     size_t cSrcSize, void* workSpace,
1102
                                     size_t wkspSize)
1103
0
{
1104
0
    /* validation checks */
1105
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1106
0
    if (cSrcSize == 0) return ERROR(corruption_detected);
1107
0
1108
0
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1109
#if defined(HUF_FORCE_DECOMPRESS_X1)
1110
        (void)algoNb;
1111
        assert(algoNb == 0);
1112
        return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);
1113
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1114
        (void)algoNb;
1115
        assert(algoNb == 1);
1116
        return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);
1117
#else
1118
0
        return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1119
0
                            cSrcSize, workSpace, wkspSize):
1120
0
                        HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);
1121
0
#endif
1122
0
    }
1123
0
}
1124
1125
size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
1126
                                  const void* cSrc, size_t cSrcSize,
1127
                                  void* workSpace, size_t wkspSize)
1128
0
{
1129
0
    /* validation checks */
1130
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1131
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
1132
0
    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
1133
0
    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
1134
0
1135
0
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1136
#if defined(HUF_FORCE_DECOMPRESS_X1)
1137
        (void)algoNb;
1138
        assert(algoNb == 0);
1139
        return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1140
                                cSrcSize, workSpace, wkspSize);
1141
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1142
        (void)algoNb;
1143
        assert(algoNb == 1);
1144
        return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1145
                                cSrcSize, workSpace, wkspSize);
1146
#else
1147
0
        return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1148
0
                                cSrcSize, workSpace, wkspSize):
1149
0
                        HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1150
0
                                cSrcSize, workSpace, wkspSize);
1151
0
#endif
1152
0
    }
1153
0
}
1154
1155
size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
1156
                             const void* cSrc, size_t cSrcSize)
1157
0
{
1158
0
    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1159
0
    return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
1160
0
                                      workSpace, sizeof(workSpace));
1161
0
}
1162
1163
1164
size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)
1165
2.23k
{
1166
2.23k
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
1167
#if defined(HUF_FORCE_DECOMPRESS_X1)
1168
    (void)dtd;
1169
    assert(dtd.tableType == 0);
1170
    return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1171
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1172
    (void)dtd;
1173
    assert(dtd.tableType == 1);
1174
    return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1175
#else
1176
1.99k
    return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) :
1177
2.23k
                           HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1178
2.23k
#endif
1179
2.23k
}
1180
1181
#ifndef HUF_FORCE_DECOMPRESS_X2
1182
size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2)
1183
1.78k
{
1184
1.78k
    const BYTE* ip = (const BYTE*) cSrc;
1185
1.78k
1186
1.78k
    size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize);
1187
1.78k
    if (HUF_isError(hSize)) return hSize;
1188
1.40k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1189
1.30k
    ip += hSize; cSrcSize -= hSize;
1190
1.30k
1191
1.30k
    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);
1192
1.30k
}
1193
#endif
1194
1195
size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)
1196
3.45k
{
1197
3.45k
    DTableDesc const dtd = HUF_getDTableDesc(DTable);
1198
#if defined(HUF_FORCE_DECOMPRESS_X1)
1199
    (void)dtd;
1200
    assert(dtd.tableType == 0);
1201
    return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1202
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1203
    (void)dtd;
1204
    assert(dtd.tableType == 1);
1205
    return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1206
#else
1207
3.31k
    return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) :
1208
3.45k
                           HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1209
3.45k
#endif
1210
3.45k
}
1211
1212
size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2)
1213
13.3k
{
1214
13.3k
    /* validation checks */
1215
13.3k
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
1216
13.3k
    if (cSrcSize == 0) return ERROR(corruption_detected);
1217
13.3k
1218
13.3k
    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1219
#if defined(HUF_FORCE_DECOMPRESS_X1)
1220
        (void)algoNb;
1221
        assert(algoNb == 0);
1222
        return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
1223
#elif defined(HUF_FORCE_DECOMPRESS_X2)
1224
        (void)algoNb;
1225
        assert(algoNb == 1);
1226
        return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
1227
#else
1228
1.25k
        return algoNb ? HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2) :
1229
13.3k
                        HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
1230
13.3k
#endif
1231
13.3k
    }
1232
13.3k
}