Coverage Report

Created: 2025-11-26 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zstd/lib/legacy/zstd_v07.c
Line
Count
Source
1
/*
2
 * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under both the BSD-style license (found in the
6
 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
 * in the COPYING file in the root directory of this source tree).
8
 * You may select, at your option, one of the above-listed licenses.
9
 */
10
11
12
/*- Dependencies -*/
13
#include <stddef.h>     /* size_t, ptrdiff_t */
14
#include <string.h>     /* memcpy */
15
#include <stdlib.h>     /* malloc, free, qsort */
16
17
#ifndef XXH_STATIC_LINKING_ONLY
18
#  define XXH_STATIC_LINKING_ONLY    /* XXH64_state_t */
19
#endif
20
#include "../common/xxhash.h"                  /* XXH64_* */
21
#include "zstd_v07.h"
22
23
#define FSEv07_STATIC_LINKING_ONLY   /* FSEv07_MIN_TABLELOG */
24
#define HUFv07_STATIC_LINKING_ONLY   /* HUFv07_TABLELOG_ABSOLUTEMAX */
25
#define ZSTDv07_STATIC_LINKING_ONLY
26
27
#include "../common/compiler.h"
28
#include "../common/error_private.h"
29
30
31
#ifdef ZSTDv07_STATIC_LINKING_ONLY
32
33
/* ====================================================================================
34
 * The definitions in this section are considered experimental.
35
 * They should never be used with a dynamic library, as they may change in the future.
36
 * They are provided for advanced usages.
37
 * Use them only in association with static linking.
38
 * ==================================================================================== */
39
40
/*--- Constants ---*/
41
4.92k
#define ZSTDv07_MAGIC_SKIPPABLE_START  0x184D2A50U
42
43
0
#define ZSTDv07_WINDOWLOG_MAX_32  25
44
59.5k
#define ZSTDv07_WINDOWLOG_MAX_64  27
45
59.5k
#define ZSTDv07_WINDOWLOG_MAX    ((U32)(MEM_32bits() ? ZSTDv07_WINDOWLOG_MAX_32 : ZSTDv07_WINDOWLOG_MAX_64))
46
#define ZSTDv07_WINDOWLOG_MIN     18
47
#define ZSTDv07_CHAINLOG_MAX     (ZSTDv07_WINDOWLOG_MAX+1)
48
#define ZSTDv07_CHAINLOG_MIN       4
49
#define ZSTDv07_HASHLOG_MAX       ZSTDv07_WINDOWLOG_MAX
50
#define ZSTDv07_HASHLOG_MIN       12
51
#define ZSTDv07_HASHLOG3_MAX      17
52
#define ZSTDv07_SEARCHLOG_MAX    (ZSTDv07_WINDOWLOG_MAX-1)
53
#define ZSTDv07_SEARCHLOG_MIN      1
54
#define ZSTDv07_SEARCHLENGTH_MAX   7
55
#define ZSTDv07_SEARCHLENGTH_MIN   3
56
#define ZSTDv07_TARGETLENGTH_MIN   4
57
#define ZSTDv07_TARGETLENGTH_MAX 999
58
59
#define ZSTDv07_FRAMEHEADERSIZE_MAX 18    /* for static allocation */
60
static const size_t ZSTDv07_frameHeaderSize_min = 5;
61
static const size_t ZSTDv07_frameHeaderSize_max = ZSTDv07_FRAMEHEADERSIZE_MAX;
62
static const size_t ZSTDv07_skippableHeaderSize = 8;  /* magic number + skippable frame length */
63
64
65
/* custom memory allocation functions */
66
typedef void* (*ZSTDv07_allocFunction) (void* opaque, size_t size);
67
typedef void  (*ZSTDv07_freeFunction) (void* opaque, void* address);
68
typedef struct { ZSTDv07_allocFunction customAlloc; ZSTDv07_freeFunction customFree; void* opaque; } ZSTDv07_customMem;
69
70
71
/*--- Advanced Decompression functions ---*/
72
73
/*! ZSTDv07_estimateDCtxSize() :
74
 *  Gives the potential amount of memory allocated to create a ZSTDv07_DCtx */
75
ZSTDLIBv07_API size_t ZSTDv07_estimateDCtxSize(void);
76
77
/*! ZSTDv07_createDCtx_advanced() :
78
 *  Create a ZSTD decompression context using external alloc and free functions */
79
ZSTDLIBv07_API ZSTDv07_DCtx* ZSTDv07_createDCtx_advanced(ZSTDv07_customMem customMem);
80
81
/*! ZSTDv07_sizeofDCtx() :
82
 *  Gives the amount of memory used by a given ZSTDv07_DCtx */
83
ZSTDLIBv07_API size_t ZSTDv07_sizeofDCtx(const ZSTDv07_DCtx* dctx);
84
85
86
/* ******************************************************************
87
*  Buffer-less streaming functions (synchronous mode)
88
********************************************************************/
89
90
ZSTDLIBv07_API size_t ZSTDv07_decompressBegin(ZSTDv07_DCtx* dctx);
91
ZSTDLIBv07_API size_t ZSTDv07_decompressBegin_usingDict(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize);
92
ZSTDLIBv07_API void   ZSTDv07_copyDCtx(ZSTDv07_DCtx* dctx, const ZSTDv07_DCtx* preparedDCtx);
93
94
ZSTDLIBv07_API size_t ZSTDv07_nextSrcSizeToDecompress(ZSTDv07_DCtx* dctx);
95
ZSTDLIBv07_API size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
96
97
/*
98
  Buffer-less streaming decompression (synchronous mode)
99
100
  A ZSTDv07_DCtx object is required to track streaming operations.
101
  Use ZSTDv07_createDCtx() / ZSTDv07_freeDCtx() to manage it.
102
  A ZSTDv07_DCtx object can be re-used multiple times.
103
104
  First optional operation is to retrieve frame parameters, using ZSTDv07_getFrameParams(), which doesn't consume the input.
105
  It can provide the minimum size of rolling buffer required to properly decompress data (`windowSize`),
106
  and optionally the final size of uncompressed content.
107
  (Note : content size is an optional info that may not be present. 0 means : content size unknown)
108
  Frame parameters are extracted from the beginning of compressed frame.
109
  The amount of data to read is variable, from ZSTDv07_frameHeaderSize_min to ZSTDv07_frameHeaderSize_max (so if `srcSize` >= ZSTDv07_frameHeaderSize_max, it will always work)
110
  If `srcSize` is too small for operation to succeed, function will return the minimum size it requires to produce a result.
111
  Result : 0 when successful, it means the ZSTDv07_frameParams structure has been filled.
112
          >0 : means there is not enough data into `src`. Provides the expected size to successfully decode header.
113
           errorCode, which can be tested using ZSTDv07_isError()
114
115
  Start decompression, with ZSTDv07_decompressBegin() or ZSTDv07_decompressBegin_usingDict().
116
  Alternatively, you can copy a prepared context, using ZSTDv07_copyDCtx().
117
118
  Then use ZSTDv07_nextSrcSizeToDecompress() and ZSTDv07_decompressContinue() alternatively.
119
  ZSTDv07_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTDv07_decompressContinue().
120
  ZSTDv07_decompressContinue() requires this exact amount of bytes, or it will fail.
121
122
  @result of ZSTDv07_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
123
  It can be zero, which is not an error; it just means ZSTDv07_decompressContinue() has decoded some header.
124
125
  ZSTDv07_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
126
  They should preferably be located contiguously, prior to current block.
127
  Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
128
  ZSTDv07_decompressContinue() is very sensitive to contiguity,
129
  if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
130
    or that previous contiguous segment is large enough to properly handle maximum back-reference.
131
132
  A frame is fully decoded when ZSTDv07_nextSrcSizeToDecompress() returns zero.
133
  Context can then be reset to start a new decompression.
134
135
136
  == Special case : skippable frames ==
137
138
  Skippable frames allow the integration of user-defined data into a flow of concatenated frames.
139
  Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frame is following:
140
  a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
141
  b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
142
  c) Frame Content - any content (User Data) of length equal to Frame Size
143
  For skippable frames ZSTDv07_decompressContinue() always returns 0.
144
  For skippable frames ZSTDv07_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
145
  It also returns Frame Size as fparamsPtr->frameContentSize.
146
*/
147
148
149
/* **************************************
150
*  Block functions
151
****************************************/
152
/*! Block functions produce and decode raw zstd blocks, without frame metadata.
153
    Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
154
    User will have to take in charge required information to regenerate data, such as compressed and content sizes.
155
156
    A few rules to respect :
157
    - Compressing and decompressing require a context structure
158
      + Use ZSTDv07_createCCtx() and ZSTDv07_createDCtx()
159
    - It is necessary to init context before starting
160
      + compression : ZSTDv07_compressBegin()
161
      + decompression : ZSTDv07_decompressBegin()
162
      + variants _usingDict() are also allowed
163
      + copyCCtx() and copyDCtx() work too
164
    - Block size is limited, it must be <= ZSTDv07_getBlockSizeMax()
165
      + If you need to compress more, cut data into multiple blocks
166
      + Consider using the regular ZSTDv07_compress() instead, as frame metadata costs become negligible when source size is large.
167
    - When a block is considered not compressible enough, ZSTDv07_compressBlock() result will be zero.
168
      In which case, nothing is produced into `dst`.
169
      + User must test for such outcome and deal directly with uncompressed data
170
      + ZSTDv07_decompressBlock() doesn't accept uncompressed data as input !!!
171
      + In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
172
        Use ZSTDv07_insertBlock() in such a case.
173
*/
174
175
95.6k
#define ZSTDv07_BLOCKSIZE_ABSOLUTEMAX (128 * 1024)   /* define, for static allocation */
176
ZSTDLIBv07_API size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
177
ZSTDLIBv07_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
178
179
180
#endif   /* ZSTDv07_STATIC_LINKING_ONLY */
181
182
183
/* ******************************************************************
184
   mem.h
185
   low-level memory access routines
186
   Copyright (C) 2013-2015, Yann Collet.
187
188
   BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
189
190
   Redistribution and use in source and binary forms, with or without
191
   modification, are permitted provided that the following conditions are
192
   met:
193
194
       * Redistributions of source code must retain the above copyright
195
   notice, this list of conditions and the following disclaimer.
196
       * Redistributions in binary form must reproduce the above
197
   copyright notice, this list of conditions and the following disclaimer
198
   in the documentation and/or other materials provided with the
199
   distribution.
200
201
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
202
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
203
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
204
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
207
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
208
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
209
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
210
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
211
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
212
213
    You can contact the author at :
214
    - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
215
    - Public forum : https://groups.google.com/forum/#!forum/lz4c
216
****************************************************************** */
217
#ifndef MEM_H_MODULE
218
#define MEM_H_MODULE
219
220
#if defined (__cplusplus)
221
extern "C" {
222
#endif
223
224
/*-****************************************
225
*  Compiler specifics
226
******************************************/
227
#if defined(_MSC_VER)   /* Visual Studio */
228
#   include <stdlib.h>  /* _byteswap_ulong */
229
#   include <intrin.h>  /* _byteswap_* */
230
#endif
231
232
233
/*-**************************************************************
234
*  Basic Types
235
*****************************************************************/
236
#if  !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
237
# if defined(_AIX)
238
#  include <inttypes.h>
239
# else
240
#  include <stdint.h> /* intptr_t */
241
# endif
242
  typedef  uint8_t BYTE;
243
  typedef uint16_t U16;
244
  typedef  int16_t S16;
245
  typedef uint32_t U32;
246
  typedef  int32_t S32;
247
  typedef uint64_t U64;
248
  typedef  int64_t S64;
249
#else
250
  typedef unsigned char       BYTE;
251
  typedef unsigned short      U16;
252
  typedef   signed short      S16;
253
  typedef unsigned int        U32;
254
  typedef   signed int        S32;
255
  typedef unsigned long long  U64;
256
  typedef   signed long long  S64;
257
#endif
258
259
260
/*-**************************************************************
261
*  Memory I/O
262
*****************************************************************/
263
264
32.5M
MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
265
5.88M
MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
266
267
MEM_STATIC unsigned MEM_isLittleEndian(void)
268
13.0M
{
269
13.0M
    const union { U32 u; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental  */
270
13.0M
    return one.c[0];
271
13.0M
}
272
273
MEM_STATIC U16 MEM_read16(const void* memPtr)
274
21.6k
{
275
21.6k
    U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
276
21.6k
}
277
278
MEM_STATIC U32 MEM_read32(const void* memPtr)
279
1.46M
{
280
1.46M
    U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
281
1.46M
}
282
283
MEM_STATIC U64 MEM_read64(const void* memPtr)
284
5.81M
{
285
5.81M
    U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
286
5.81M
}
287
288
MEM_STATIC void MEM_write16(void* memPtr, U16 value)
289
5.74M
{
290
5.74M
    memcpy(memPtr, &value, sizeof(value));
291
5.74M
}
292
293
MEM_STATIC U32 MEM_swap32(U32 in)
294
0
{
295
#if defined(_MSC_VER)     /* Visual Studio */
296
    return _byteswap_ulong(in);
297
#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
298
    return __builtin_bswap32(in);
299
#else
300
0
    return  ((in << 24) & 0xff000000 ) |
301
0
            ((in <<  8) & 0x00ff0000 ) |
302
0
            ((in >>  8) & 0x0000ff00 ) |
303
0
            ((in >> 24) & 0x000000ff );
304
0
#endif
305
0
}
306
307
MEM_STATIC U64 MEM_swap64(U64 in)
308
0
{
309
#if defined(_MSC_VER)     /* Visual Studio */
310
    return _byteswap_uint64(in);
311
#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
312
    return __builtin_bswap64(in);
313
#else
314
0
    return  ((in << 56) & 0xff00000000000000ULL) |
315
0
            ((in << 40) & 0x00ff000000000000ULL) |
316
0
            ((in << 24) & 0x0000ff0000000000ULL) |
317
0
            ((in << 8)  & 0x000000ff00000000ULL) |
318
0
            ((in >> 8)  & 0x00000000ff000000ULL) |
319
0
            ((in >> 24) & 0x0000000000ff0000ULL) |
320
0
            ((in >> 40) & 0x000000000000ff00ULL) |
321
0
            ((in >> 56) & 0x00000000000000ffULL);
322
0
#endif
323
0
}
324
325
326
/*=== Little endian r/w ===*/
327
328
MEM_STATIC U16 MEM_readLE16(const void* memPtr)
329
21.6k
{
330
21.6k
    if (MEM_isLittleEndian())
331
21.6k
        return MEM_read16(memPtr);
332
0
    else {
333
0
        const BYTE* p = (const BYTE*)memPtr;
334
0
        return (U16)(p[0] + (p[1]<<8));
335
0
    }
336
21.6k
}
337
338
MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
339
5.74M
{
340
5.74M
    if (MEM_isLittleEndian()) {
341
5.74M
        MEM_write16(memPtr, val);
342
5.74M
    } else {
343
0
        BYTE* p = (BYTE*)memPtr;
344
0
        p[0] = (BYTE)val;
345
0
        p[1] = (BYTE)(val>>8);
346
0
    }
347
5.74M
}
348
349
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
350
1.46M
{
351
1.46M
    if (MEM_isLittleEndian())
352
1.46M
        return MEM_read32(memPtr);
353
0
    else
354
0
        return MEM_swap32(MEM_read32(memPtr));
355
1.46M
}
356
357
358
MEM_STATIC U64 MEM_readLE64(const void* memPtr)
359
5.81M
{
360
5.81M
    if (MEM_isLittleEndian())
361
5.81M
        return MEM_read64(memPtr);
362
0
    else
363
0
        return MEM_swap64(MEM_read64(memPtr));
364
5.81M
}
365
366
MEM_STATIC size_t MEM_readLEST(const void* memPtr)
367
5.81M
{
368
5.81M
    if (MEM_32bits())
369
0
        return (size_t)MEM_readLE32(memPtr);
370
5.81M
    else
371
5.81M
        return (size_t)MEM_readLE64(memPtr);
372
5.81M
}
373
374
375
376
#if defined (__cplusplus)
377
}
378
#endif
379
380
#endif /* MEM_H_MODULE */
381
/* ******************************************************************
382
   bitstream
383
   Part of FSE library
384
   header file (to include)
385
   Copyright (C) 2013-2016, Yann Collet.
386
387
   BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
388
389
   Redistribution and use in source and binary forms, with or without
390
   modification, are permitted provided that the following conditions are
391
   met:
392
393
       * Redistributions of source code must retain the above copyright
394
   notice, this list of conditions and the following disclaimer.
395
       * Redistributions in binary form must reproduce the above
396
   copyright notice, this list of conditions and the following disclaimer
397
   in the documentation and/or other materials provided with the
398
   distribution.
399
400
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
401
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
402
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
403
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
404
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
405
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
406
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
407
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
408
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
409
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
410
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
411
412
   You can contact the author at :
413
   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
414
****************************************************************** */
415
#ifndef BITSTREAM_H_MODULE
416
#define BITSTREAM_H_MODULE
417
418
#if defined (__cplusplus)
419
extern "C" {
420
#endif
421
422
423
/*
424
*  This API consists of small unitary functions, which must be inlined for best performance.
425
*  Since link-time-optimization is not available for all compilers,
426
*  these functions are defined into a .h to be included.
427
*/
428
429
430
/*=========================================
431
*  Target specific
432
=========================================*/
433
#if defined(__BMI__) && defined(__GNUC__)
434
#  include <immintrin.h>   /* support for bextr (experimental) */
435
#endif
436
437
/*-********************************************
438
*  bitStream decoding API (read backward)
439
**********************************************/
440
typedef struct
441
{
442
    size_t   bitContainer;
443
    unsigned bitsConsumed;
444
    const char* ptr;
445
    const char* start;
446
} BITv07_DStream_t;
447
448
typedef enum { BITv07_DStream_unfinished = 0,
449
               BITv07_DStream_endOfBuffer = 1,
450
               BITv07_DStream_completed = 2,
451
               BITv07_DStream_overflow = 3 } BITv07_DStream_status;  /* result of BITv07_reloadDStream() */
452
               /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
453
454
MEM_STATIC size_t   BITv07_initDStream(BITv07_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
455
MEM_STATIC size_t   BITv07_readBits(BITv07_DStream_t* bitD, unsigned nbBits);
456
MEM_STATIC BITv07_DStream_status BITv07_reloadDStream(BITv07_DStream_t* bitD);
457
MEM_STATIC unsigned BITv07_endOfDStream(const BITv07_DStream_t* bitD);
458
459
460
461
/*-****************************************
462
*  unsafe API
463
******************************************/
464
MEM_STATIC size_t BITv07_readBitsFast(BITv07_DStream_t* bitD, unsigned nbBits);
465
/* faster, but works only if nbBits >= 1 */
466
467
468
469
/*-**************************************************************
470
*  Internal functions
471
****************************************************************/
472
MEM_STATIC unsigned BITv07_highbit32 (U32 val)
473
32.6M
{
474
#   if defined(_MSC_VER)   /* Visual */
475
    unsigned long r;
476
    return _BitScanReverse(&r, val) ? (unsigned)r : 0;
477
#   elif defined(__GNUC__) && (__GNUC__ >= 3)   /* Use GCC Intrinsic */
478
    return __builtin_clz (val) ^ 31;
479
#   else   /* Software version */
480
    static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
481
    U32 v = val;
482
    v |= v >> 1;
483
    v |= v >> 2;
484
    v |= v >> 4;
485
    v |= v >> 8;
486
    v |= v >> 16;
487
    return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
488
#   endif
489
32.6M
}
490
491
492
493
/*-********************************************************
494
* bitStream decoding
495
**********************************************************/
496
/*! BITv07_initDStream() :
497
*   Initialize a BITv07_DStream_t.
498
*   `bitD` : a pointer to an already allocated BITv07_DStream_t structure.
499
*   `srcSize` must be the *exact* size of the bitStream, in bytes.
500
*   @return : size of stream (== srcSize) or an errorCode if a problem is detected
501
*/
502
MEM_STATIC size_t BITv07_initDStream(BITv07_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
503
75.8k
{
504
75.8k
    if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
505
506
75.7k
    if (srcSize >=  sizeof(bitD->bitContainer)) {  /* normal case */
507
22.6k
        bitD->start = (const char*)srcBuffer;
508
22.6k
        bitD->ptr   = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
509
22.6k
        bitD->bitContainer = MEM_readLEST(bitD->ptr);
510
22.6k
        { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
511
22.6k
          bitD->bitsConsumed = lastByte ? 8 - BITv07_highbit32(lastByte) : 0;
512
22.6k
          if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
513
53.0k
    } else {
514
53.0k
        bitD->start = (const char*)srcBuffer;
515
53.0k
        bitD->ptr   = bitD->start;
516
53.0k
        bitD->bitContainer = *(const BYTE*)(bitD->start);
517
53.0k
        switch(srcSize)
518
53.0k
        {
519
3.05k
            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);/* fall-through */
520
5.81k
            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);/* fall-through */
521
9.97k
            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);/* fall-through */
522
13.5k
            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; /* fall-through */
523
17.8k
            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; /* fall-through */
524
36.5k
            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8; /* fall-through */
525
53.0k
            default: break;
526
53.0k
        }
527
53.0k
        { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
528
53.0k
          bitD->bitsConsumed = lastByte ? 8 - BITv07_highbit32(lastByte) : 0;
529
53.0k
          if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
530
52.9k
        bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
531
52.9k
    }
532
533
75.5k
    return srcSize;
534
75.7k
}
535
536
537
 MEM_STATIC size_t BITv07_lookBits(const BITv07_DStream_t* bitD, U32 nbBits)
538
28.8M
{
539
28.8M
    U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
540
28.8M
    return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
541
28.8M
}
542
543
/*! BITv07_lookBitsFast() :
544
*   unsafe version; only works if nbBits >= 1 */
545
MEM_STATIC size_t BITv07_lookBitsFast(const BITv07_DStream_t* bitD, U32 nbBits)
546
14.2M
{
547
14.2M
    U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
548
14.2M
    return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
549
14.2M
}
550
551
MEM_STATIC void BITv07_skipBits(BITv07_DStream_t* bitD, U32 nbBits)
552
43.1M
{
553
43.1M
    bitD->bitsConsumed += nbBits;
554
43.1M
}
555
556
MEM_STATIC size_t BITv07_readBits(BITv07_DStream_t* bitD, U32 nbBits)
557
28.8M
{
558
28.8M
    size_t const value = BITv07_lookBits(bitD, nbBits);
559
28.8M
    BITv07_skipBits(bitD, nbBits);
560
28.8M
    return value;
561
28.8M
}
562
563
/*! BITv07_readBitsFast() :
564
*   unsafe version; only works if nbBits >= 1 */
565
MEM_STATIC size_t BITv07_readBitsFast(BITv07_DStream_t* bitD, U32 nbBits)
566
708k
{
567
708k
    size_t const value = BITv07_lookBitsFast(bitD, nbBits);
568
708k
    BITv07_skipBits(bitD, nbBits);
569
708k
    return value;
570
708k
}
571
572
MEM_STATIC BITv07_DStream_status BITv07_reloadDStream(BITv07_DStream_t* bitD)
573
12.6M
{
574
12.6M
    if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* should not happen => corruption detected */
575
37.5k
        return BITv07_DStream_overflow;
576
577
12.6M
    if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
578
3.40M
        bitD->ptr -= bitD->bitsConsumed >> 3;
579
3.40M
        bitD->bitsConsumed &= 7;
580
3.40M
        bitD->bitContainer = MEM_readLEST(bitD->ptr);
581
3.40M
        return BITv07_DStream_unfinished;
582
3.40M
    }
583
9.22M
    if (bitD->ptr == bitD->start) {
584
6.83M
        if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BITv07_DStream_endOfBuffer;
585
90.9k
        return BITv07_DStream_completed;
586
6.83M
    }
587
2.38M
    {   U32 nbBytes = bitD->bitsConsumed >> 3;
588
2.38M
        BITv07_DStream_status result = BITv07_DStream_unfinished;
589
2.38M
        if (bitD->ptr - nbBytes < bitD->start) {
590
8.09k
            nbBytes = (U32)(bitD->ptr - bitD->start);  /* ptr > start */
591
8.09k
            result = BITv07_DStream_endOfBuffer;
592
8.09k
        }
593
2.38M
        bitD->ptr -= nbBytes;
594
2.38M
        bitD->bitsConsumed -= nbBytes*8;
595
2.38M
        bitD->bitContainer = MEM_readLEST(bitD->ptr);   /* reminder : srcSize > sizeof(bitD) */
596
2.38M
        return result;
597
9.22M
    }
598
9.22M
}
599
600
/*! BITv07_endOfDStream() :
601
*   @return Tells if DStream has exactly reached its end (all bits consumed).
602
*/
603
MEM_STATIC unsigned BITv07_endOfDStream(const BITv07_DStream_t* DStream)
604
41.1k
{
605
41.1k
    return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
606
41.1k
}
607
608
#if defined (__cplusplus)
609
}
610
#endif
611
612
#endif /* BITSTREAM_H_MODULE */
613
/* ******************************************************************
614
   FSE : Finite State Entropy codec
615
   Public Prototypes declaration
616
   Copyright (C) 2013-2016, Yann Collet.
617
618
   BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
619
620
   Redistribution and use in source and binary forms, with or without
621
   modification, are permitted provided that the following conditions are
622
   met:
623
624
       * Redistributions of source code must retain the above copyright
625
   notice, this list of conditions and the following disclaimer.
626
       * Redistributions in binary form must reproduce the above
627
   copyright notice, this list of conditions and the following disclaimer
628
   in the documentation and/or other materials provided with the
629
   distribution.
630
631
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
632
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
633
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
634
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
635
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
636
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
637
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
638
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
639
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
640
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
641
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
642
643
   You can contact the author at :
644
   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
645
****************************************************************** */
646
#ifndef FSEv07_H
647
#define FSEv07_H
648
649
#if defined (__cplusplus)
650
extern "C" {
651
#endif
652
653
654
655
/*-****************************************
656
*  FSE simple functions
657
******************************************/
658
659
/*! FSEv07_decompress():
660
    Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',
661
    into already allocated destination buffer 'dst', of size 'dstCapacity'.
662
    @return : size of regenerated data (<= maxDstSize),
663
              or an error code, which can be tested using FSEv07_isError() .
664
665
    ** Important ** : FSEv07_decompress() does not decompress non-compressible nor RLE data !!!
666
    Why ? : making this distinction requires a header.
667
    Header management is intentionally delegated to the user layer, which can better manage special cases.
668
*/
669
size_t FSEv07_decompress(void* dst,  size_t dstCapacity,
670
                const void* cSrc, size_t cSrcSize);
671
672
673
/* Error Management */
674
unsigned    FSEv07_isError(size_t code);        /* tells if a return value is an error code */
675
const char* FSEv07_getErrorName(size_t code);   /* provides error code string (useful for debugging) */
676
677
678
/*-*****************************************
679
*  FSE detailed API
680
******************************************/
681
/*!
682
FSEv07_decompress() does the following:
683
1. read normalized counters with readNCount()
684
2. build decoding table 'DTable' from normalized counters
685
3. decode the data stream using decoding table 'DTable'
686
687
The following API allows targeting specific sub-functions for advanced tasks.
688
For example, it's possible to compress several blocks using the same 'CTable',
689
or to save and provide normalized distribution using external method.
690
*/
691
692
693
/* *** DECOMPRESSION *** */
694
695
/*! FSEv07_readNCount():
696
    Read compactly saved 'normalizedCounter' from 'rBuffer'.
697
    @return : size read from 'rBuffer',
698
              or an errorCode, which can be tested using FSEv07_isError().
699
              maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
700
size_t FSEv07_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
701
702
/*! Constructor and Destructor of FSEv07_DTable.
703
    Note that its size depends on 'tableLog' */
704
typedef unsigned FSEv07_DTable;   /* don't allocate that. It's just a way to be more restrictive than void* */
705
FSEv07_DTable* FSEv07_createDTable(unsigned tableLog);
706
void        FSEv07_freeDTable(FSEv07_DTable* dt);
707
708
/*! FSEv07_buildDTable():
709
    Builds 'dt', which must be already allocated, using FSEv07_createDTable().
710
    return : 0, or an errorCode, which can be tested using FSEv07_isError() */
711
size_t FSEv07_buildDTable (FSEv07_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
712
713
/*! FSEv07_decompress_usingDTable():
714
    Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
715
    into `dst` which must be already allocated.
716
    @return : size of regenerated data (necessarily <= `dstCapacity`),
717
              or an errorCode, which can be tested using FSEv07_isError() */
718
size_t FSEv07_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSEv07_DTable* dt);
719
720
/*!
721
Tutorial :
722
----------
723
(Note : these functions only decompress FSE-compressed blocks.
724
 If block is uncompressed, use memcpy() instead
725
 If block is a single repeated byte, use memset() instead )
726
727
The first step is to obtain the normalized frequencies of symbols.
728
This can be performed by FSEv07_readNCount() if it was saved using FSEv07_writeNCount().
729
'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short.
730
In practice, that means it's necessary to know 'maxSymbolValue' beforehand,
731
or size the table to handle worst case situations (typically 256).
732
FSEv07_readNCount() will provide 'tableLog' and 'maxSymbolValue'.
733
The result of FSEv07_readNCount() is the number of bytes read from 'rBuffer'.
734
Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that.
735
If there is an error, the function will return an error code, which can be tested using FSEv07_isError().
736
737
The next step is to build the decompression tables 'FSEv07_DTable' from 'normalizedCounter'.
738
This is performed by the function FSEv07_buildDTable().
739
The space required by 'FSEv07_DTable' must be already allocated using FSEv07_createDTable().
740
If there is an error, the function will return an error code, which can be tested using FSEv07_isError().
741
742
`FSEv07_DTable` can then be used to decompress `cSrc`, with FSEv07_decompress_usingDTable().
743
`cSrcSize` must be strictly correct, otherwise decompression will fail.
744
FSEv07_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`).
745
If there is an error, the function will return an error code, which can be tested using FSEv07_isError(). (ex: dst buffer too small)
746
*/
747
748
749
#ifdef FSEv07_STATIC_LINKING_ONLY
750
751
752
/* *****************************************
753
*  Static allocation
754
*******************************************/
755
/* FSE buffer bounds */
756
#define FSEv07_NCOUNTBOUND 512
757
#define FSEv07_BLOCKBOUND(size) (size + (size>>7))
758
759
/* It is possible to statically allocate FSE CTable/DTable as a table of unsigned using below macros */
760
0
#define FSEv07_DTABLE_SIZE_U32(maxTableLog)                   (1 + (1<<maxTableLog))
761
762
763
/* *****************************************
764
*  FSE advanced API
765
*******************************************/
766
size_t FSEv07_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
767
/**< same as FSEv07_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr  */
768
769
unsigned FSEv07_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
770
/**< same as FSEv07_optimalTableLog(), which used `minus==2` */
771
772
size_t FSEv07_buildDTable_raw (FSEv07_DTable* dt, unsigned nbBits);
773
/**< build a fake FSEv07_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */
774
775
size_t FSEv07_buildDTable_rle (FSEv07_DTable* dt, unsigned char symbolValue);
776
/**< build a fake FSEv07_DTable, designed to always generate the same symbolValue */
777
778
779
780
/* *****************************************
781
*  FSE symbol decompression API
782
*******************************************/
783
typedef struct
784
{
785
    size_t      state;
786
    const void* table;   /* precise table may vary, depending on U16 */
787
} FSEv07_DState_t;
788
789
790
static void     FSEv07_initDState(FSEv07_DState_t* DStatePtr, BITv07_DStream_t* bitD, const FSEv07_DTable* dt);
791
792
static unsigned char FSEv07_decodeSymbol(FSEv07_DState_t* DStatePtr, BITv07_DStream_t* bitD);
793
794
795
796
/* *****************************************
797
*  FSE unsafe API
798
*******************************************/
799
static unsigned char FSEv07_decodeSymbolFast(FSEv07_DState_t* DStatePtr, BITv07_DStream_t* bitD);
800
/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
801
802
803
/* ======    Decompression    ====== */
804
805
typedef struct {
806
    U16 tableLog;
807
    U16 fastMode;
808
} FSEv07_DTableHeader;   /* sizeof U32 */
809
810
typedef struct
811
{
812
    unsigned short newState;
813
    unsigned char  symbol;
814
    unsigned char  nbBits;
815
} FSEv07_decode_t;   /* size == U32 */
816
817
MEM_STATIC void FSEv07_initDState(FSEv07_DState_t* DStatePtr, BITv07_DStream_t* bitD, const FSEv07_DTable* dt)
818
78.8k
{
819
78.8k
    const void* ptr = dt;
820
78.8k
    const FSEv07_DTableHeader* const DTableH = (const FSEv07_DTableHeader*)ptr;
821
78.8k
    DStatePtr->state = BITv07_readBits(bitD, DTableH->tableLog);
822
78.8k
    BITv07_reloadDStream(bitD);
823
78.8k
    DStatePtr->table = dt + 1;
824
78.8k
}
825
826
MEM_STATIC BYTE FSEv07_peekSymbol(const FSEv07_DState_t* DStatePtr)
827
26.4M
{
828
26.4M
    FSEv07_decode_t const DInfo = ((const FSEv07_decode_t*)(DStatePtr->table))[DStatePtr->state];
829
26.4M
    return DInfo.symbol;
830
26.4M
}
831
832
MEM_STATIC void FSEv07_updateState(FSEv07_DState_t* DStatePtr, BITv07_DStream_t* bitD)
833
26.4M
{
834
26.4M
    FSEv07_decode_t const DInfo = ((const FSEv07_decode_t*)(DStatePtr->table))[DStatePtr->state];
835
26.4M
    U32 const nbBits = DInfo.nbBits;
836
26.4M
    size_t const lowBits = BITv07_readBits(bitD, nbBits);
837
26.4M
    DStatePtr->state = DInfo.newState + lowBits;
838
26.4M
}
839
840
MEM_STATIC BYTE FSEv07_decodeSymbol(FSEv07_DState_t* DStatePtr, BITv07_DStream_t* bitD)
841
1.94M
{
842
1.94M
    FSEv07_decode_t const DInfo = ((const FSEv07_decode_t*)(DStatePtr->table))[DStatePtr->state];
843
1.94M
    U32 const nbBits = DInfo.nbBits;
844
1.94M
    BYTE const symbol = DInfo.symbol;
845
1.94M
    size_t const lowBits = BITv07_readBits(bitD, nbBits);
846
847
1.94M
    DStatePtr->state = DInfo.newState + lowBits;
848
1.94M
    return symbol;
849
1.94M
}
850
851
/*! FSEv07_decodeSymbolFast() :
852
    unsafe, only works if no symbol has a probability > 50% */
853
MEM_STATIC BYTE FSEv07_decodeSymbolFast(FSEv07_DState_t* DStatePtr, BITv07_DStream_t* bitD)
854
708k
{
855
708k
    FSEv07_decode_t const DInfo = ((const FSEv07_decode_t*)(DStatePtr->table))[DStatePtr->state];
856
708k
    U32 const nbBits = DInfo.nbBits;
857
708k
    BYTE const symbol = DInfo.symbol;
858
708k
    size_t const lowBits = BITv07_readBitsFast(bitD, nbBits);
859
860
708k
    DStatePtr->state = DInfo.newState + lowBits;
861
708k
    return symbol;
862
708k
}
863
864
865
866
#ifndef FSEv07_COMMONDEFS_ONLY
867
868
/* **************************************************************
869
*  Tuning parameters
870
****************************************************************/
871
/*!MEMORY_USAGE :
872
*  Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
873
*  Increasing memory usage improves compression ratio
874
*  Reduced memory usage can improve speed, due to cache effect
875
*  Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
876
1.04M
#define FSEv07_MAX_MEMORY_USAGE 14
877
#define FSEv07_DEFAULT_MEMORY_USAGE 13
878
879
/*!FSEv07_MAX_SYMBOL_VALUE :
880
*  Maximum symbol value authorized.
881
*  Required for proper stack allocation */
882
96.6k
#define FSEv07_MAX_SYMBOL_VALUE 255
883
884
885
/* **************************************************************
886
*  template functions type & suffix
887
****************************************************************/
888
32.4M
#define FSEv07_FUNCTION_TYPE BYTE
889
#define FSEv07_FUNCTION_EXTENSION
890
72.9k
#define FSEv07_DECODE_TYPE FSEv07_decode_t
891
892
893
#endif   /* !FSEv07_COMMONDEFS_ONLY */
894
895
896
/* ***************************************************************
897
*  Constants
898
*****************************************************************/
899
1.04M
#define FSEv07_MAX_TABLELOG  (FSEv07_MAX_MEMORY_USAGE-2)
900
#define FSEv07_MAX_TABLESIZE (1U<<FSEv07_MAX_TABLELOG)
901
#define FSEv07_MAXTABLESIZE_MASK (FSEv07_MAX_TABLESIZE-1)
902
#define FSEv07_DEFAULT_TABLELOG (FSEv07_DEFAULT_MEMORY_USAGE-2)
903
54.4k
#define FSEv07_MIN_TABLELOG 5
904
905
54.4k
#define FSEv07_TABLELOG_ABSOLUTE_MAX 15
906
#if FSEv07_MAX_TABLELOG > FSEv07_TABLELOG_ABSOLUTE_MAX
907
#  error "FSEv07_MAX_TABLELOG > FSEv07_TABLELOG_ABSOLUTE_MAX is not supported"
908
#endif
909
910
72.9k
#define FSEv07_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
911
912
913
#endif /* FSEv07_STATIC_LINKING_ONLY */
914
915
916
#if defined (__cplusplus)
917
}
918
#endif
919
920
#endif  /* FSEv07_H */
921
/* ******************************************************************
922
   Huffman coder, part of New Generation Entropy library
923
   header file
924
   Copyright (C) 2013-2016, Yann Collet.
925
926
   BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
927
928
   Redistribution and use in source and binary forms, with or without
929
   modification, are permitted provided that the following conditions are
930
   met:
931
932
       * Redistributions of source code must retain the above copyright
933
   notice, this list of conditions and the following disclaimer.
934
       * Redistributions in binary form must reproduce the above
935
   copyright notice, this list of conditions and the following disclaimer
936
   in the documentation and/or other materials provided with the
937
   distribution.
938
939
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
940
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
941
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
942
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
943
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
944
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
945
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
946
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
947
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
948
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
949
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
950
951
   You can contact the author at :
952
   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
953
****************************************************************** */
954
#ifndef HUFv07_H_298734234
955
#define HUFv07_H_298734234
956
957
#if defined (__cplusplus)
958
extern "C" {
959
#endif
960
961
962
963
/* *** simple functions *** */
964
/**
965
HUFv07_decompress() :
966
    Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
967
    into already allocated buffer 'dst', of minimum size 'dstSize'.
968
    `dstSize` : **must** be the ***exact*** size of original (uncompressed) data.
969
    Note : in contrast with FSE, HUFv07_decompress can regenerate
970
           RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
971
           because it knows size to regenerate.
972
    @return : size of regenerated data (== dstSize),
973
              or an error code, which can be tested using HUFv07_isError()
974
*/
975
size_t HUFv07_decompress(void* dst,  size_t dstSize,
976
                const void* cSrc, size_t cSrcSize);
977
978
979
/* ****************************************
980
*  Tool functions
981
******************************************/
982
#define HUFv07_BLOCKSIZE_MAX (128 * 1024)
983
984
/* Error Management */
985
unsigned    HUFv07_isError(size_t code);        /**< tells if a return value is an error code */
986
const char* HUFv07_getErrorName(size_t code);   /**< provides error code string (useful for debugging) */
987
988
989
/* *** Advanced function *** */
990
991
992
#ifdef HUFv07_STATIC_LINKING_ONLY
993
994
995
/* *** Constants *** */
996
2.90M
#define HUFv07_TABLELOG_ABSOLUTEMAX  16   /* absolute limit of HUFv07_MAX_TABLELOG. Beyond that value, code does not work */
997
0
#define HUFv07_TABLELOG_MAX  12           /* max configured tableLog (for static allocation); can be modified up to HUFv07_ABSOLUTEMAX_TABLELOG */
998
#define HUFv07_TABLELOG_DEFAULT  11       /* tableLog by default, when not specified */
999
32.2k
#define HUFv07_SYMBOLVALUE_MAX 255
1000
#if (HUFv07_TABLELOG_MAX > HUFv07_TABLELOG_ABSOLUTEMAX)
1001
#  error "HUFv07_TABLELOG_MAX is too large !"
1002
#endif
1003
1004
1005
/* ****************************************
1006
*  Static allocation
1007
******************************************/
1008
/* HUF buffer bounds */
1009
#define HUFv07_BLOCKBOUND(size) (size + (size>>8) + 8)   /* only true if incompressible pre-filtered with fast heuristic */
1010
1011
/* static allocation of HUF's DTable */
1012
typedef U32 HUFv07_DTable;
1013
#define HUFv07_DTABLE_SIZE(maxTableLog)   (1 + (1<<(maxTableLog)))
1014
#define HUFv07_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
1015
0
        HUFv07_DTable DTable[HUFv07_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1)*0x1000001) }
1016
#define HUFv07_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
1017
0
        HUFv07_DTable DTable[HUFv07_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog)*0x1000001) }
1018
1019
1020
/* ****************************************
1021
*  Advanced decompression functions
1022
******************************************/
1023
size_t HUFv07_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */
1024
size_t HUFv07_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */
1025
1026
size_t HUFv07_decompress4X_DCtx (HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< decodes RLE and uncompressed */
1027
size_t HUFv07_decompress4X_hufOnly(HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
1028
size_t HUFv07_decompress4X2_DCtx(HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */
1029
size_t HUFv07_decompress4X4_DCtx(HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */
1030
1031
size_t HUFv07_decompress1X_DCtx (HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
1032
size_t HUFv07_decompress1X2_DCtx(HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */
1033
size_t HUFv07_decompress1X4_DCtx(HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */
1034
1035
1036
/* ****************************************
1037
*  HUF detailed API
1038
******************************************/
1039
/*!
1040
The following API allows targeting specific sub-functions for advanced tasks.
1041
For example, it's possible to compress several blocks using the same 'CTable',
1042
or to save and regenerate 'CTable' using external methods.
1043
*/
1044
/* FSEv07_count() : find it within "fse.h" */
1045
1046
/*! HUFv07_readStats() :
1047
    Read compact Huffman tree, saved by HUFv07_writeCTable().
1048
    `huffWeight` is destination buffer.
1049
    @return : size read from `src` , or an error Code .
1050
    Note : Needed by HUFv07_readCTable() and HUFv07_readDTableXn() . */
1051
size_t HUFv07_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
1052
                     U32* nbSymbolsPtr, U32* tableLogPtr,
1053
                     const void* src, size_t srcSize);
1054
1055
1056
/*
1057
HUFv07_decompress() does the following:
1058
1. select the decompression algorithm (X2, X4) based on pre-computed heuristics
1059
2. build Huffman table from save, using HUFv07_readDTableXn()
1060
3. decode 1 or 4 segments in parallel using HUFv07_decompressSXn_usingDTable
1061
*/
1062
1063
/** HUFv07_selectDecoder() :
1064
*   Tells which decoder is likely to decode faster,
1065
*   based on a set of pre-determined metrics.
1066
*   @return : 0==HUFv07_decompress4X2, 1==HUFv07_decompress4X4 .
1067
*   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
1068
U32 HUFv07_selectDecoder (size_t dstSize, size_t cSrcSize);
1069
1070
size_t HUFv07_readDTableX2 (HUFv07_DTable* DTable, const void* src, size_t srcSize);
1071
size_t HUFv07_readDTableX4 (HUFv07_DTable* DTable, const void* src, size_t srcSize);
1072
1073
size_t HUFv07_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUFv07_DTable* DTable);
1074
size_t HUFv07_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUFv07_DTable* DTable);
1075
size_t HUFv07_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUFv07_DTable* DTable);
1076
1077
1078
/* single stream variants */
1079
size_t HUFv07_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /* single-symbol decoder */
1080
size_t HUFv07_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /* double-symbol decoder */
1081
1082
size_t HUFv07_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUFv07_DTable* DTable);
1083
size_t HUFv07_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUFv07_DTable* DTable);
1084
size_t HUFv07_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUFv07_DTable* DTable);
1085
1086
1087
#endif /* HUFv07_STATIC_LINKING_ONLY */
1088
1089
1090
#if defined (__cplusplus)
1091
}
1092
#endif
1093
1094
#endif   /* HUFv07_H_298734234 */
1095
/*
1096
   Common functions of New Generation Entropy library
1097
   Copyright (C) 2016, Yann Collet.
1098
1099
   BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
1100
1101
   Redistribution and use in source and binary forms, with or without
1102
   modification, are permitted provided that the following conditions are
1103
   met:
1104
1105
       * Redistributions of source code must retain the above copyright
1106
   notice, this list of conditions and the following disclaimer.
1107
       * Redistributions in binary form must reproduce the above
1108
   copyright notice, this list of conditions and the following disclaimer
1109
   in the documentation and/or other materials provided with the
1110
   distribution.
1111
1112
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1113
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1114
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1115
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1116
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1117
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1118
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1119
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1120
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1121
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1122
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1123
1124
    You can contact the author at :
1125
    - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
1126
    - Public forum : https://groups.google.com/forum/#!forum/lz4c
1127
*************************************************************************** */
1128
1129
1130
1131
/*-****************************************
1132
*  FSE Error Management
1133
******************************************/
1134
23.7k
unsigned FSEv07_isError(size_t code) { return ERR_isError(code); }
1135
1136
0
const char* FSEv07_getErrorName(size_t code) { return ERR_getErrorName(code); }
1137
1138
1139
/* **************************************************************
1140
*  HUF Error Management
1141
****************************************************************/
1142
97.8k
unsigned HUFv07_isError(size_t code) { return ERR_isError(code); }
1143
1144
0
const char* HUFv07_getErrorName(size_t code) { return ERR_getErrorName(code); }
1145
1146
1147
/*-**************************************************************
1148
*  FSE NCount encoding-decoding
1149
****************************************************************/
1150
1.10M
static short FSEv07_abs(short a) { return (short)(a<0 ? -a : a); }
1151
1152
size_t FSEv07_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
1153
                 const void* headerBuffer, size_t hbSize)
1154
54.4k
{
1155
54.4k
    const BYTE* const istart = (const BYTE*) headerBuffer;
1156
54.4k
    const BYTE* const iend = istart + hbSize;
1157
54.4k
    const BYTE* ip = istart;
1158
54.4k
    int nbBits;
1159
54.4k
    int remaining;
1160
54.4k
    int threshold;
1161
54.4k
    U32 bitStream;
1162
54.4k
    int bitCount;
1163
54.4k
    unsigned charnum = 0;
1164
54.4k
    int previous0 = 0;
1165
1166
54.4k
    if (hbSize < 4) return ERROR(srcSize_wrong);
1167
54.4k
    bitStream = MEM_readLE32(ip);
1168
54.4k
    nbBits = (bitStream & 0xF) + FSEv07_MIN_TABLELOG;   /* extract tableLog */
1169
54.4k
    if (nbBits > FSEv07_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
1170
54.3k
    bitStream >>= 4;
1171
54.3k
    bitCount = 4;
1172
54.3k
    *tableLogPtr = nbBits;
1173
54.3k
    remaining = (1<<nbBits)+1;
1174
54.3k
    threshold = 1<<nbBits;
1175
54.3k
    nbBits++;
1176
1177
1.15M
    while ((remaining>1) && (charnum<=*maxSVPtr)) {
1178
1.10M
        if (previous0) {
1179
32.5k
            unsigned n0 = charnum;
1180
211k
            while ((bitStream & 0xFFFF) == 0xFFFF) {
1181
178k
                n0+=24;
1182
178k
                if (ip < iend-5) {
1183
177k
                    ip+=2;
1184
177k
                    bitStream = MEM_readLE32(ip) >> bitCount;
1185
177k
                } else {
1186
1.54k
                    bitStream >>= 16;
1187
1.54k
                    bitCount+=16;
1188
1.54k
            }   }
1189
49.1k
            while ((bitStream & 3) == 3) {
1190
16.5k
                n0+=3;
1191
16.5k
                bitStream>>=2;
1192
16.5k
                bitCount+=2;
1193
16.5k
            }
1194
32.5k
            n0 += bitStream & 3;
1195
32.5k
            bitCount += 2;
1196
32.5k
            if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
1197
183k
            while (charnum < n0) normalizedCounter[charnum++] = 0;
1198
32.5k
            if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
1199
23.2k
                ip += bitCount>>3;
1200
23.2k
                bitCount &= 7;
1201
23.2k
                bitStream = MEM_readLE32(ip) >> bitCount;
1202
23.2k
            }
1203
9.29k
            else
1204
9.29k
                bitStream >>= 2;
1205
32.5k
        }
1206
1.10M
        {   short const max = (short)((2*threshold-1)-remaining);
1207
1.10M
            short count;
1208
1209
1.10M
            if ((bitStream & (threshold-1)) < (U32)max) {
1210
806k
                count = (short)(bitStream & (threshold-1));
1211
806k
                bitCount   += nbBits-1;
1212
806k
            } else {
1213
296k
                count = (short)(bitStream & (2*threshold-1));
1214
296k
                if (count >= threshold) count -= max;
1215
296k
                bitCount   += nbBits;
1216
296k
            }
1217
1218
1.10M
            count--;   /* extra accuracy */
1219
1.10M
            remaining -= FSEv07_abs(count);
1220
1.10M
            normalizedCounter[charnum++] = count;
1221
1.10M
            previous0 = !count;
1222
1.51M
            while (remaining < threshold) {
1223
409k
                nbBits--;
1224
409k
                threshold >>= 1;
1225
409k
            }
1226
1227
1.10M
            if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
1228
1.07M
                ip += bitCount>>3;
1229
1.07M
                bitCount &= 7;
1230
1.07M
            } else {
1231
26.0k
                bitCount -= (int)(8 * (iend - 4 - ip));
1232
26.0k
                ip = iend - 4;
1233
26.0k
            }
1234
1.10M
            bitStream = MEM_readLE32(ip) >> (bitCount & 31);
1235
1.10M
    }   }   /* while ((remaining>1) && (charnum<=*maxSVPtr)) */
1236
54.2k
    if (remaining != 1) return ERROR(GENERIC);
1237
54.2k
    *maxSVPtr = charnum-1;
1238
1239
54.2k
    ip += (bitCount+7)>>3;
1240
54.2k
    if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);
1241
54.1k
    return ip-istart;
1242
54.2k
}
1243
1244
1245
/*! HUFv07_readStats() :
1246
    Read compact Huffman tree, saved by HUFv07_writeCTable().
1247
    `huffWeight` is destination buffer.
1248
    @return : size read from `src` , or an error Code .
1249
    Note : Needed by HUFv07_readCTable() and HUFv07_readDTableXn() .
1250
*/
1251
size_t HUFv07_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
1252
                     U32* nbSymbolsPtr, U32* tableLogPtr,
1253
                     const void* src, size_t srcSize)
1254
32.2k
{
1255
32.2k
    U32 weightTotal;
1256
32.2k
    const BYTE* ip = (const BYTE*) src;
1257
32.2k
    size_t iSize;
1258
32.2k
    size_t oSize;
1259
1260
32.2k
    if (!srcSize) return ERROR(srcSize_wrong);
1261
32.2k
    iSize = ip[0];
1262
    /* memset(huffWeight, 0, hwSize); */   /* is not necessary, even though some analyzer complain ... */
1263
1264
32.2k
    if (iSize >= 128)  { /* special header */
1265
8.50k
        if (iSize >= (242)) {  /* RLE */
1266
4.08k
            static U32 l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };
1267
4.08k
            oSize = l[iSize-242];
1268
4.08k
            memset(huffWeight, 1, hwSize);
1269
4.08k
            iSize = 0;
1270
4.08k
        }
1271
4.41k
        else {   /* Incompressible */
1272
4.41k
            oSize = iSize - 127;
1273
4.41k
            iSize = ((oSize+1)/2);
1274
4.41k
            if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
1275
4.38k
            if (oSize >= hwSize) return ERROR(corruption_detected);
1276
4.38k
            ip += 1;
1277
4.38k
            {   U32 n;
1278
10.1k
                for (n=0; n<oSize; n+=2) {
1279
5.77k
                    huffWeight[n]   = ip[n/2] >> 4;
1280
5.77k
                    huffWeight[n+1] = ip[n/2] & 15;
1281
5.77k
    }   }   }   }
1282
23.7k
    else  {   /* header compressed with FSE (normal case) */
1283
23.7k
        if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
1284
23.7k
        oSize = FSEv07_decompress(huffWeight, hwSize-1, ip+1, iSize);   /* max (hwSize-1) values decoded, as last one is implied */
1285
23.7k
        if (FSEv07_isError(oSize)) return oSize;
1286
23.7k
    }
1287
1288
    /* collect weight stats */
1289
31.9k
    memset(rankStats, 0, (HUFv07_TABLELOG_ABSOLUTEMAX + 1) * sizeof(U32));
1290
31.9k
    weightTotal = 0;
1291
2.86M
    {   U32 n; for (n=0; n<oSize; n++) {
1292
2.83M
            if (huffWeight[n] >= HUFv07_TABLELOG_ABSOLUTEMAX) return ERROR(corruption_detected);
1293
2.83M
            rankStats[huffWeight[n]]++;
1294
2.83M
            weightTotal += (1 << huffWeight[n]) >> 1;
1295
2.83M
    }   }
1296
31.9k
    if (weightTotal == 0) return ERROR(corruption_detected);
1297
1298
    /* get last non-null symbol weight (implied, total must be 2^n) */
1299
31.9k
    {   U32 const tableLog = BITv07_highbit32(weightTotal) + 1;
1300
31.9k
        if (tableLog > HUFv07_TABLELOG_ABSOLUTEMAX) return ERROR(corruption_detected);
1301
31.8k
        *tableLogPtr = tableLog;
1302
        /* determine last weight */
1303
31.8k
        {   U32 const total = 1 << tableLog;
1304
31.8k
            U32 const rest = total - weightTotal;
1305
31.8k
            U32 const verif = 1 << BITv07_highbit32(rest);
1306
31.8k
            U32 const lastWeight = BITv07_highbit32(rest) + 1;
1307
31.8k
            if (verif != rest) return ERROR(corruption_detected);    /* last value must be a clean power of 2 */
1308
31.6k
            huffWeight[oSize] = (BYTE)lastWeight;
1309
31.6k
            rankStats[lastWeight]++;
1310
31.6k
    }   }
1311
1312
    /* check tree construction validity */
1313
31.6k
    if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected);   /* by construction : at least 2 elts of rank 1, must be even */
1314
1315
    /* results */
1316
31.6k
    *nbSymbolsPtr = (U32)(oSize+1);
1317
31.6k
    return iSize+1;
1318
31.6k
}
1319
/* ******************************************************************
1320
   FSE : Finite State Entropy decoder
1321
   Copyright (C) 2013-2015, Yann Collet.
1322
1323
   BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
1324
1325
   Redistribution and use in source and binary forms, with or without
1326
   modification, are permitted provided that the following conditions are
1327
   met:
1328
1329
       * Redistributions of source code must retain the above copyright
1330
   notice, this list of conditions and the following disclaimer.
1331
       * Redistributions in binary form must reproduce the above
1332
   copyright notice, this list of conditions and the following disclaimer
1333
   in the documentation and/or other materials provided with the
1334
   distribution.
1335
1336
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1337
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1338
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1339
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1340
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1341
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1342
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1343
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1344
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1345
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1346
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1347
1348
    You can contact the author at :
1349
    - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
1350
    - Public forum : https://groups.google.com/forum/#!forum/lz4c
1351
****************************************************************** */
1352
1353
1354
/* **************************************************************
1355
*  Compiler specifics
1356
****************************************************************/
1357
#ifdef _MSC_VER    /* Visual Studio */
1358
#  define FORCE_INLINE static __forceinline
1359
#  include <intrin.h>                    /* For Visual 2005 */
1360
#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
1361
#  pragma warning(disable : 4214)        /* disable: C4214: non-int bitfields */
1362
#else
1363
#  if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
1364
#    ifdef __GNUC__
1365
#      define FORCE_INLINE static inline __attribute__((always_inline))
1366
#    else
1367
#      define FORCE_INLINE static inline
1368
#    endif
1369
#  else
1370
#    define FORCE_INLINE static
1371
#  endif /* __STDC_VERSION__ */
1372
#endif
1373
1374
1375
/* **************************************************************
1376
*  Error Management
1377
****************************************************************/
1378
70.9k
#define FSEv07_isError ERR_isError
1379
#define FSEv07_STATIC_ASSERT(c) { enum { FSEv07_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
1380
1381
1382
/* **************************************************************
1383
*  Complex types
1384
****************************************************************/
1385
typedef U32 DTable_max_t[FSEv07_DTABLE_SIZE_U32(FSEv07_MAX_TABLELOG)];
1386
1387
1388
/* **************************************************************
1389
*  Templates
1390
****************************************************************/
1391
/*
1392
  designed to be included
1393
  for type-specific functions (template emulation in C)
1394
  Objective is to write these functions only once, for improved maintenance
1395
*/
1396
1397
/* safety checks */
1398
#ifndef FSEv07_FUNCTION_EXTENSION
1399
#  error "FSEv07_FUNCTION_EXTENSION must be defined"
1400
#endif
1401
#ifndef FSEv07_FUNCTION_TYPE
1402
#  error "FSEv07_FUNCTION_TYPE must be defined"
1403
#endif
1404
1405
/* Function names */
1406
#define FSEv07_CAT(X,Y) X##Y
1407
#define FSEv07_FUNCTION_NAME(X,Y) FSEv07_CAT(X,Y)
1408
#define FSEv07_TYPE_NAME(X,Y) FSEv07_CAT(X,Y)
1409
1410
1411
/* Function templates */
1412
FSEv07_DTable* FSEv07_createDTable (unsigned tableLog)
1413
0
{
1414
0
    if (tableLog > FSEv07_TABLELOG_ABSOLUTE_MAX) tableLog = FSEv07_TABLELOG_ABSOLUTE_MAX;
1415
0
    return (FSEv07_DTable*)malloc( FSEv07_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
1416
0
}
1417
1418
void FSEv07_freeDTable (FSEv07_DTable* dt)
1419
0
{
1420
0
    free(dt);
1421
0
}
1422
1423
size_t FSEv07_buildDTable(FSEv07_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
1424
72.9k
{
1425
72.9k
    void* const tdPtr = dt+1;   /* because *dt is unsigned, 32-bits aligned on 32-bits */
1426
72.9k
    FSEv07_DECODE_TYPE* const tableDecode = (FSEv07_DECODE_TYPE*) (tdPtr);
1427
72.9k
    U16 symbolNext[FSEv07_MAX_SYMBOL_VALUE+1];
1428
1429
72.9k
    U32 const maxSV1 = maxSymbolValue + 1;
1430
72.9k
    U32 const tableSize = 1 << tableLog;
1431
72.9k
    U32 highThreshold = tableSize-1;
1432
1433
    /* Sanity Checks */
1434
72.9k
    if (maxSymbolValue > FSEv07_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
1435
72.9k
    if (tableLog > FSEv07_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
1436
1437
    /* Init, lay down lowprob symbols */
1438
72.9k
    {   FSEv07_DTableHeader DTableH;
1439
72.9k
        DTableH.tableLog = (U16)tableLog;
1440
72.9k
        DTableH.fastMode = 1;
1441
72.9k
        {   S16 const largeLimit= (S16)(1 << (tableLog-1));
1442
72.9k
            U32 s;
1443
2.05M
            for (s=0; s<maxSV1; s++) {
1444
1.98M
                if (normalizedCounter[s]==-1) {
1445
175k
                    tableDecode[highThreshold--].symbol = (FSEv07_FUNCTION_TYPE)s;
1446
175k
                    symbolNext[s] = 1;
1447
1.80M
                } else {
1448
1.80M
                    if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
1449
1.80M
                    symbolNext[s] = normalizedCounter[s];
1450
1.80M
        }   }   }
1451
72.9k
        memcpy(dt, &DTableH, sizeof(DTableH));
1452
72.9k
    }
1453
1454
    /* Spread symbols */
1455
72.9k
    {   U32 const tableMask = tableSize-1;
1456
72.9k
        U32 const step = FSEv07_TABLESTEP(tableSize);
1457
72.9k
        U32 s, position = 0;
1458
2.05M
        for (s=0; s<maxSV1; s++) {
1459
1.98M
            int i;
1460
34.2M
            for (i=0; i<normalizedCounter[s]; i++) {
1461
32.3M
                tableDecode[position].symbol = (FSEv07_FUNCTION_TYPE)s;
1462
32.3M
                position = (position + step) & tableMask;
1463
32.4M
                while (position > highThreshold) position = (position + step) & tableMask;   /* lowprob area */
1464
32.3M
        }   }
1465
1466
72.9k
        if (position!=0) return ERROR(GENERIC);   /* position must reach all cells once, otherwise normalizedCounter is incorrect */
1467
72.9k
    }
1468
1469
    /* Build Decoding table */
1470
72.9k
    {   U32 u;
1471
32.5M
        for (u=0; u<tableSize; u++) {
1472
32.4M
            FSEv07_FUNCTION_TYPE const symbol = (FSEv07_FUNCTION_TYPE)(tableDecode[u].symbol);
1473
32.4M
            U16 nextState = symbolNext[symbol]++;
1474
32.4M
            tableDecode[u].nbBits = (BYTE) (tableLog - BITv07_highbit32 ((U32)nextState) );
1475
32.4M
            tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
1476
32.4M
    }   }
1477
1478
72.9k
    return 0;
1479
72.9k
}
1480
1481
1482
1483
#ifndef FSEv07_COMMONDEFS_ONLY
1484
1485
/*-*******************************************************
1486
*  Decompression (Byte symbols)
1487
*********************************************************/
1488
size_t FSEv07_buildDTable_rle (FSEv07_DTable* dt, BYTE symbolValue)
1489
9.28k
{
1490
9.28k
    void* ptr = dt;
1491
9.28k
    FSEv07_DTableHeader* const DTableH = (FSEv07_DTableHeader*)ptr;
1492
9.28k
    void* dPtr = dt + 1;
1493
9.28k
    FSEv07_decode_t* const cell = (FSEv07_decode_t*)dPtr;
1494
1495
9.28k
    DTableH->tableLog = 0;
1496
9.28k
    DTableH->fastMode = 0;
1497
1498
9.28k
    cell->newState = 0;
1499
9.28k
    cell->symbol = symbolValue;
1500
9.28k
    cell->nbBits = 0;
1501
1502
9.28k
    return 0;
1503
9.28k
}
1504
1505
1506
size_t FSEv07_buildDTable_raw (FSEv07_DTable* dt, unsigned nbBits)
1507
0
{
1508
0
    void* ptr = dt;
1509
0
    FSEv07_DTableHeader* const DTableH = (FSEv07_DTableHeader*)ptr;
1510
0
    void* dPtr = dt + 1;
1511
0
    FSEv07_decode_t* const dinfo = (FSEv07_decode_t*)dPtr;
1512
0
    const unsigned tableSize = 1 << nbBits;
1513
0
    const unsigned tableMask = tableSize - 1;
1514
0
    const unsigned maxSV1 = tableMask+1;
1515
0
    unsigned s;
1516
1517
    /* Sanity checks */
1518
0
    if (nbBits < 1) return ERROR(GENERIC);         /* min size */
1519
1520
    /* Build Decoding Table */
1521
0
    DTableH->tableLog = (U16)nbBits;
1522
0
    DTableH->fastMode = 1;
1523
0
    for (s=0; s<maxSV1; s++) {
1524
0
        dinfo[s].newState = 0;
1525
0
        dinfo[s].symbol = (BYTE)s;
1526
0
        dinfo[s].nbBits = (BYTE)nbBits;
1527
0
    }
1528
1529
0
    return 0;
1530
0
}
1531
1532
FORCE_INLINE size_t FSEv07_decompress_usingDTable_generic(
1533
          void* dst, size_t maxDstSize,
1534
    const void* cSrc, size_t cSrcSize,
1535
    const FSEv07_DTable* dt, const unsigned fast)
1536
23.6k
{
1537
23.6k
    BYTE* const ostart = (BYTE*) dst;
1538
23.6k
    BYTE* op = ostart;
1539
23.6k
    BYTE* const omax = op + maxDstSize;
1540
23.6k
    BYTE* const olimit = omax-3;
1541
1542
23.6k
    BITv07_DStream_t bitD;
1543
23.6k
    FSEv07_DState_t state1;
1544
23.6k
    FSEv07_DState_t state2;
1545
1546
    /* Init */
1547
23.6k
    { size_t const errorCode = BITv07_initDStream(&bitD, cSrc, cSrcSize);   /* replaced last arg by maxCompressed Size */
1548
23.6k
      if (FSEv07_isError(errorCode)) return errorCode; }
1549
1550
23.5k
    FSEv07_initDState(&state1, &bitD, dt);
1551
23.5k
    FSEv07_initDState(&state2, &bitD, dt);
1552
1553
2.65M
#define FSEv07_GETSYMBOL(statePtr) fast ? FSEv07_decodeSymbolFast(statePtr, &bitD) : FSEv07_decodeSymbol(statePtr, &bitD)
1554
1555
    /* 4 symbols per loop */
1556
348k
    for ( ; (BITv07_reloadDStream(&bitD)==BITv07_DStream_unfinished) && (op<olimit) ; op+=4) {
1557
325k
        op[0] = FSEv07_GETSYMBOL(&state1);
1558
1559
325k
        if (FSEv07_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
1560
0
            BITv07_reloadDStream(&bitD);
1561
1562
325k
        op[1] = FSEv07_GETSYMBOL(&state2);
1563
1564
325k
        if (FSEv07_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
1565
0
            { if (BITv07_reloadDStream(&bitD) > BITv07_DStream_unfinished) { op+=2; break; } }
1566
1567
325k
        op[2] = FSEv07_GETSYMBOL(&state1);
1568
1569
325k
        if (FSEv07_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
1570
0
            BITv07_reloadDStream(&bitD);
1571
1572
325k
        op[3] = FSEv07_GETSYMBOL(&state2);
1573
325k
    }
1574
1575
    /* tail */
1576
    /* note : BITv07_reloadDStream(&bitD) >= FSEv07_DStream_partiallyFilled; Ends at exactly BITv07_DStream_completed */
1577
670k
    while (1) {
1578
670k
        if (op>(omax-2)) return ERROR(dstSize_tooSmall);
1579
1580
670k
        *op++ = FSEv07_GETSYMBOL(&state1);
1581
1582
670k
        if (BITv07_reloadDStream(&bitD)==BITv07_DStream_overflow) {
1583
8.56k
            *op++ = FSEv07_GETSYMBOL(&state2);
1584
8.56k
            break;
1585
8.56k
        }
1586
1587
662k
        if (op>(omax-2)) return ERROR(dstSize_tooSmall);
1588
1589
662k
        *op++ = FSEv07_GETSYMBOL(&state2);
1590
1591
662k
        if (BITv07_reloadDStream(&bitD)==BITv07_DStream_overflow) {
1592
14.9k
            *op++ = FSEv07_GETSYMBOL(&state1);
1593
14.9k
            break;
1594
14.9k
    }   }
1595
1596
23.4k
    return op-ostart;
1597
23.5k
}
1598
1599
1600
size_t FSEv07_decompress_usingDTable(void* dst, size_t originalSize,
1601
                            const void* cSrc, size_t cSrcSize,
1602
                            const FSEv07_DTable* dt)
1603
23.6k
{
1604
23.6k
    const void* ptr = dt;
1605
23.6k
    const FSEv07_DTableHeader* DTableH = (const FSEv07_DTableHeader*)ptr;
1606
23.6k
    const U32 fastMode = DTableH->fastMode;
1607
1608
    /* select fast mode (static) */
1609
23.6k
    if (fastMode) return FSEv07_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
1610
13.5k
    return FSEv07_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
1611
23.6k
}
1612
1613
1614
size_t FSEv07_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)
1615
23.7k
{
1616
23.7k
    const BYTE* const istart = (const BYTE*)cSrc;
1617
23.7k
    const BYTE* ip = istart;
1618
23.7k
    short counting[FSEv07_MAX_SYMBOL_VALUE+1];
1619
23.7k
    DTable_max_t dt;   /* Static analyzer seems unable to understand this table will be properly initialized later */
1620
23.7k
    unsigned tableLog;
1621
23.7k
    unsigned maxSymbolValue = FSEv07_MAX_SYMBOL_VALUE;
1622
1623
23.7k
    if (cSrcSize<2) return ERROR(srcSize_wrong);   /* too small input size */
1624
1625
    /* normal FSE decoding mode */
1626
23.7k
    {   size_t const NCountLength = FSEv07_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
1627
23.7k
        if (FSEv07_isError(NCountLength)) return NCountLength;
1628
23.6k
        if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong);   /* too small input size */
1629
23.6k
        ip += NCountLength;
1630
23.6k
        cSrcSize -= NCountLength;
1631
23.6k
    }
1632
1633
0
    { size_t const errorCode = FSEv07_buildDTable (dt, counting, maxSymbolValue, tableLog);
1634
23.6k
      if (FSEv07_isError(errorCode)) return errorCode; }
1635
1636
23.6k
    return FSEv07_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt);   /* always return, even if it is an error code */
1637
23.6k
}
1638
1639
1640
1641
#endif   /* FSEv07_COMMONDEFS_ONLY */
1642
1643
/* ******************************************************************
1644
   Huffman decoder, part of New Generation Entropy library
1645
   Copyright (C) 2013-2016, Yann Collet.
1646
1647
   BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
1648
1649
   Redistribution and use in source and binary forms, with or without
1650
   modification, are permitted provided that the following conditions are
1651
   met:
1652
1653
       * Redistributions of source code must retain the above copyright
1654
   notice, this list of conditions and the following disclaimer.
1655
       * Redistributions in binary form must reproduce the above
1656
   copyright notice, this list of conditions and the following disclaimer
1657
   in the documentation and/or other materials provided with the
1658
   distribution.
1659
1660
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1661
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1662
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1663
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1664
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1665
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1666
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1667
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1668
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1669
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1670
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1671
1672
    You can contact the author at :
1673
    - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
1674
    - Public forum : https://groups.google.com/forum/#!forum/lz4c
1675
****************************************************************** */
1676
1677
/* **************************************************************
1678
*  Compiler specifics
1679
****************************************************************/
1680
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
1681
/* inline is defined */
1682
#elif defined(_MSC_VER)
1683
#  define inline __inline
1684
#else
1685
#  define inline /* disable inline */
1686
#endif
1687
1688
1689
#ifdef _MSC_VER    /* Visual Studio */
1690
#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
1691
#endif
1692
1693
1694
1695
/* **************************************************************
1696
*  Error Management
1697
****************************************************************/
1698
32.2k
#define HUFv07_STATIC_ASSERT(c) { enum { HUFv07_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
1699
1700
1701
/*-***************************/
1702
/*  generic DTableDesc       */
1703
/*-***************************/
1704
1705
typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
1706
1707
static DTableDesc HUFv07_getDTableDesc(const HUFv07_DTable* table)
1708
55.1k
{
1709
55.1k
    DTableDesc dtd;
1710
55.1k
    memcpy(&dtd, table, sizeof(dtd));
1711
55.1k
    return dtd;
1712
55.1k
}
1713
1714
1715
/*-***************************/
1716
/*  single-symbol decoding   */
1717
/*-***************************/
1718
1719
typedef struct { BYTE byte; BYTE nbBits; } HUFv07_DEltX2;   /* single-symbol decoding */
1720
1721
size_t HUFv07_readDTableX2 (HUFv07_DTable* DTable, const void* src, size_t srcSize)
1722
21.9k
{
1723
21.9k
    BYTE huffWeight[HUFv07_SYMBOLVALUE_MAX + 1];
1724
21.9k
    U32 rankVal[HUFv07_TABLELOG_ABSOLUTEMAX + 1];   /* large enough for values from 0 to 16 */
1725
21.9k
    U32 tableLog = 0;
1726
21.9k
    U32 nbSymbols = 0;
1727
21.9k
    size_t iSize;
1728
21.9k
    void* const dtPtr = DTable + 1;
1729
21.9k
    HUFv07_DEltX2* const dt = (HUFv07_DEltX2*)dtPtr;
1730
1731
21.9k
    HUFv07_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUFv07_DTable));
1732
    /* memset(huffWeight, 0, sizeof(huffWeight)); */   /* is not necessary, even though some analyzer complain ... */
1733
1734
21.9k
    iSize = HUFv07_readStats(huffWeight, HUFv07_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
1735
21.9k
    if (HUFv07_isError(iSize)) return iSize;
1736
1737
    /* Table header */
1738
21.3k
    {   DTableDesc dtd = HUFv07_getDTableDesc(DTable);
1739
21.3k
        if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, huffman tree cannot fit in */
1740
21.3k
        dtd.tableType = 0;
1741
21.3k
        dtd.tableLog = (BYTE)tableLog;
1742
21.3k
        memcpy(DTable, &dtd, sizeof(dtd));
1743
21.3k
    }
1744
1745
    /* Prepare ranks */
1746
0
    {   U32 n, nextRankStart = 0;
1747
84.0k
        for (n=1; n<tableLog+1; n++) {
1748
62.7k
            U32 current = nextRankStart;
1749
62.7k
            nextRankStart += (rankVal[n] << (n-1));
1750
62.7k
            rankVal[n] = current;
1751
62.7k
    }   }
1752
1753
    /* fill DTable */
1754
21.3k
    {   U32 n;
1755
702k
        for (n=0; n<nbSymbols; n++) {
1756
681k
            U32 const w = huffWeight[n];
1757
681k
            U32 const length = (1 << w) >> 1;
1758
681k
            U32 i;
1759
681k
            HUFv07_DEltX2 D;
1760
681k
            D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
1761
1.38M
            for (i = rankVal[w]; i < rankVal[w] + length; i++)
1762
704k
                dt[i] = D;
1763
681k
            rankVal[w] += length;
1764
681k
    }   }
1765
1766
21.3k
    return iSize;
1767
21.3k
}
1768
1769
1770
static BYTE HUFv07_decodeSymbolX2(BITv07_DStream_t* Dstream, const HUFv07_DEltX2* dt, const U32 dtLog)
1771
4.94M
{
1772
4.94M
    size_t const val = BITv07_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
1773
4.94M
    BYTE const c = dt[val].byte;
1774
4.94M
    BITv07_skipBits(Dstream, dt[val].nbBits);
1775
4.94M
    return c;
1776
4.94M
}
1777
1778
#define HUFv07_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
1779
4.94M
    *ptr++ = HUFv07_decodeSymbolX2(DStreamPtr, dt, dtLog)
1780
1781
#define HUFv07_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
1782
305k
    if (MEM_64bits() || (HUFv07_TABLELOG_MAX<=12)) \
1783
305k
        HUFv07_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
1784
1785
#define HUFv07_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
1786
610k
    if (MEM_64bits()) \
1787
610k
        HUFv07_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
1788
1789
static inline size_t HUFv07_decodeStreamX2(BYTE* p, BITv07_DStream_t* const bitDPtr, BYTE* const pEnd, const HUFv07_DEltX2* const dt, const U32 dtLog)
1790
33.5k
{
1791
33.5k
    BYTE* const pStart = p;
1792
1793
    /* up to 4 symbols at a time */
1794
241k
    while ((BITv07_reloadDStream(bitDPtr) == BITv07_DStream_unfinished) && (p <= pEnd-4)) {
1795
208k
        HUFv07_DECODE_SYMBOLX2_2(p, bitDPtr);
1796
208k
        HUFv07_DECODE_SYMBOLX2_1(p, bitDPtr);
1797
208k
        HUFv07_DECODE_SYMBOLX2_2(p, bitDPtr);
1798
208k
        HUFv07_DECODE_SYMBOLX2_0(p, bitDPtr);
1799
208k
    }
1800
1801
    /* closer to the end */
1802
34.0k
    while ((BITv07_reloadDStream(bitDPtr) == BITv07_DStream_unfinished) && (p < pEnd))
1803
439
        HUFv07_DECODE_SYMBOLX2_0(p, bitDPtr);
1804
1805
    /* no more data to retrieve from bitstream, hence no need to reload */
1806
3.75M
    while (p < pEnd)
1807
3.72M
        HUFv07_DECODE_SYMBOLX2_0(p, bitDPtr);
1808
1809
33.5k
    return pEnd-pStart;
1810
33.5k
}
1811
1812
static size_t HUFv07_decompress1X2_usingDTable_internal(
1813
          void* dst,  size_t dstSize,
1814
    const void* cSrc, size_t cSrcSize,
1815
    const HUFv07_DTable* DTable)
1816
16.9k
{
1817
16.9k
    BYTE* op = (BYTE*)dst;
1818
16.9k
    BYTE* const oend = op + dstSize;
1819
16.9k
    const void* dtPtr = DTable + 1;
1820
16.9k
    const HUFv07_DEltX2* const dt = (const HUFv07_DEltX2*)dtPtr;
1821
16.9k
    BITv07_DStream_t bitD;
1822
16.9k
    DTableDesc const dtd = HUFv07_getDTableDesc(DTable);
1823
16.9k
    U32 const dtLog = dtd.tableLog;
1824
1825
16.9k
    { size_t const errorCode = BITv07_initDStream(&bitD, cSrc, cSrcSize);
1826
16.9k
      if (HUFv07_isError(errorCode)) return errorCode; }
1827
1828
16.8k
    HUFv07_decodeStreamX2(op, &bitD, oend, dt, dtLog);
1829
1830
    /* check */
1831
16.8k
    if (!BITv07_endOfDStream(&bitD)) return ERROR(corruption_detected);
1832
1833
16.5k
    return dstSize;
1834
16.8k
}
1835
1836
size_t HUFv07_decompress1X2_usingDTable(
1837
          void* dst,  size_t dstSize,
1838
    const void* cSrc, size_t cSrcSize,
1839
    const HUFv07_DTable* DTable)
1840
0
{
1841
0
    DTableDesc dtd = HUFv07_getDTableDesc(DTable);
1842
0
    if (dtd.tableType != 0) return ERROR(GENERIC);
1843
0
    return HUFv07_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
1844
0
}
1845
1846
size_t HUFv07_decompress1X2_DCtx (HUFv07_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1847
17.3k
{
1848
17.3k
    const BYTE* ip = (const BYTE*) cSrc;
1849
1850
17.3k
    size_t const hSize = HUFv07_readDTableX2 (DCtx, cSrc, cSrcSize);
1851
17.3k
    if (HUFv07_isError(hSize)) return hSize;
1852
16.9k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1853
16.9k
    ip += hSize; cSrcSize -= hSize;
1854
1855
16.9k
    return HUFv07_decompress1X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
1856
16.9k
}
1857
1858
size_t HUFv07_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1859
0
{
1860
0
    HUFv07_CREATE_STATIC_DTABLEX2(DTable, HUFv07_TABLELOG_MAX);
1861
0
    return HUFv07_decompress1X2_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
1862
0
}
1863
1864
1865
static size_t HUFv07_decompress4X2_usingDTable_internal(
1866
          void* dst,  size_t dstSize,
1867
    const void* cSrc, size_t cSrcSize,
1868
    const HUFv07_DTable* DTable)
1869
4.34k
{
1870
    /* Check */
1871
4.34k
    if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
1872
1873
4.31k
    {   const BYTE* const istart = (const BYTE*) cSrc;
1874
4.31k
        BYTE* const ostart = (BYTE*) dst;
1875
4.31k
        BYTE* const oend = ostart + dstSize;
1876
4.31k
        const void* const dtPtr = DTable + 1;
1877
4.31k
        const HUFv07_DEltX2* const dt = (const HUFv07_DEltX2*)dtPtr;
1878
1879
        /* Init */
1880
4.31k
        BITv07_DStream_t bitD1;
1881
4.31k
        BITv07_DStream_t bitD2;
1882
4.31k
        BITv07_DStream_t bitD3;
1883
4.31k
        BITv07_DStream_t bitD4;
1884
4.31k
        size_t const length1 = MEM_readLE16(istart);
1885
4.31k
        size_t const length2 = MEM_readLE16(istart+2);
1886
4.31k
        size_t const length3 = MEM_readLE16(istart+4);
1887
4.31k
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
1888
4.31k
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
1889
4.31k
        const BYTE* const istart2 = istart1 + length1;
1890
4.31k
        const BYTE* const istart3 = istart2 + length2;
1891
4.31k
        const BYTE* const istart4 = istart3 + length3;
1892
4.31k
        const size_t segmentSize = (dstSize+3) / 4;
1893
4.31k
        BYTE* const opStart2 = ostart + segmentSize;
1894
4.31k
        BYTE* const opStart3 = opStart2 + segmentSize;
1895
4.31k
        BYTE* const opStart4 = opStart3 + segmentSize;
1896
4.31k
        BYTE* op1 = ostart;
1897
4.31k
        BYTE* op2 = opStart2;
1898
4.31k
        BYTE* op3 = opStart3;
1899
4.31k
        BYTE* op4 = opStart4;
1900
4.31k
        U32 endSignal;
1901
4.31k
        DTableDesc const dtd = HUFv07_getDTableDesc(DTable);
1902
4.31k
        U32 const dtLog = dtd.tableLog;
1903
1904
4.31k
        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
1905
4.27k
        { size_t const errorCode = BITv07_initDStream(&bitD1, istart1, length1);
1906
4.27k
          if (HUFv07_isError(errorCode)) return errorCode; }
1907
4.26k
        { size_t const errorCode = BITv07_initDStream(&bitD2, istart2, length2);
1908
4.26k
          if (HUFv07_isError(errorCode)) return errorCode; }
1909
4.23k
        { size_t const errorCode = BITv07_initDStream(&bitD3, istart3, length3);
1910
4.23k
          if (HUFv07_isError(errorCode)) return errorCode; }
1911
4.20k
        { size_t const errorCode = BITv07_initDStream(&bitD4, istart4, length4);
1912
4.20k
          if (HUFv07_isError(errorCode)) return errorCode; }
1913
1914
        /* 16-32 symbols per loop (4-8 symbols per stream) */
1915
4.18k
        endSignal = BITv07_reloadDStream(&bitD1) | BITv07_reloadDStream(&bitD2) | BITv07_reloadDStream(&bitD3) | BITv07_reloadDStream(&bitD4);
1916
28.4k
        for ( ; (endSignal==BITv07_DStream_unfinished) && (op4<(oend-7)) ; ) {
1917
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op1, &bitD1);
1918
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op2, &bitD2);
1919
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op3, &bitD3);
1920
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op4, &bitD4);
1921
24.2k
            HUFv07_DECODE_SYMBOLX2_1(op1, &bitD1);
1922
24.2k
            HUFv07_DECODE_SYMBOLX2_1(op2, &bitD2);
1923
24.2k
            HUFv07_DECODE_SYMBOLX2_1(op3, &bitD3);
1924
24.2k
            HUFv07_DECODE_SYMBOLX2_1(op4, &bitD4);
1925
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op1, &bitD1);
1926
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op2, &bitD2);
1927
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op3, &bitD3);
1928
24.2k
            HUFv07_DECODE_SYMBOLX2_2(op4, &bitD4);
1929
24.2k
            HUFv07_DECODE_SYMBOLX2_0(op1, &bitD1);
1930
24.2k
            HUFv07_DECODE_SYMBOLX2_0(op2, &bitD2);
1931
24.2k
            HUFv07_DECODE_SYMBOLX2_0(op3, &bitD3);
1932
24.2k
            HUFv07_DECODE_SYMBOLX2_0(op4, &bitD4);
1933
24.2k
            endSignal = BITv07_reloadDStream(&bitD1) | BITv07_reloadDStream(&bitD2) | BITv07_reloadDStream(&bitD3) | BITv07_reloadDStream(&bitD4);
1934
24.2k
        }
1935
1936
        /* check corruption */
1937
4.18k
        if (op1 > opStart2) return ERROR(corruption_detected);
1938
4.18k
        if (op2 > opStart3) return ERROR(corruption_detected);
1939
4.18k
        if (op3 > opStart4) return ERROR(corruption_detected);
1940
        /* note : op4 supposed already verified within main loop */
1941
1942
        /* finish bitStreams one by one */
1943
4.18k
        HUFv07_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
1944
4.18k
        HUFv07_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
1945
4.18k
        HUFv07_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
1946
4.18k
        HUFv07_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);
1947
1948
        /* check */
1949
4.18k
        endSignal = BITv07_endOfDStream(&bitD1) & BITv07_endOfDStream(&bitD2) & BITv07_endOfDStream(&bitD3) & BITv07_endOfDStream(&bitD4);
1950
4.18k
        if (!endSignal) return ERROR(corruption_detected);
1951
1952
        /* decoded size */
1953
3.88k
        return dstSize;
1954
4.18k
    }
1955
4.18k
}
1956
1957
1958
size_t HUFv07_decompress4X2_usingDTable(
1959
          void* dst,  size_t dstSize,
1960
    const void* cSrc, size_t cSrcSize,
1961
    const HUFv07_DTable* DTable)
1962
0
{
1963
0
    DTableDesc dtd = HUFv07_getDTableDesc(DTable);
1964
0
    if (dtd.tableType != 0) return ERROR(GENERIC);
1965
0
    return HUFv07_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
1966
0
}
1967
1968
1969
size_t HUFv07_decompress4X2_DCtx (HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1970
4.57k
{
1971
4.57k
    const BYTE* ip = (const BYTE*) cSrc;
1972
1973
4.57k
    size_t const hSize = HUFv07_readDTableX2 (dctx, cSrc, cSrcSize);
1974
4.57k
    if (HUFv07_isError(hSize)) return hSize;
1975
4.37k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1976
4.34k
    ip += hSize; cSrcSize -= hSize;
1977
1978
4.34k
    return HUFv07_decompress4X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, dctx);
1979
4.37k
}
1980
1981
size_t HUFv07_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1982
0
{
1983
0
    HUFv07_CREATE_STATIC_DTABLEX2(DTable, HUFv07_TABLELOG_MAX);
1984
0
    return HUFv07_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
1985
0
}
1986
1987
1988
/* *************************/
1989
/* double-symbols decoding */
1990
/* *************************/
1991
typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUFv07_DEltX4;  /* double-symbols decoding */
1992
1993
typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
1994
1995
static void HUFv07_fillDTableX4Level2(HUFv07_DEltX4* DTable, U32 sizeLog, const U32 consumed,
1996
                           const U32* rankValOrigin, const int minWeight,
1997
                           const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
1998
                           U32 nbBitsBaseline, U16 baseSeq)
1999
1.11M
{
2000
1.11M
    HUFv07_DEltX4 DElt;
2001
1.11M
    U32 rankVal[HUFv07_TABLELOG_ABSOLUTEMAX + 1];
2002
2003
    /* get pre-calculated rankVal */
2004
1.11M
    memcpy(rankVal, rankValOrigin, sizeof(rankVal));
2005
2006
    /* fill skipped values */
2007
1.11M
    if (minWeight>1) {
2008
1.09M
        U32 i, skipSize = rankVal[minWeight];
2009
1.09M
        MEM_writeLE16(&(DElt.sequence), baseSeq);
2010
1.09M
        DElt.nbBits   = (BYTE)(consumed);
2011
1.09M
        DElt.length   = 1;
2012
15.4M
        for (i = 0; i < skipSize; i++)
2013
14.3M
            DTable[i] = DElt;
2014
1.09M
    }
2015
2016
    /* fill DTable */
2017
4.71M
    { U32 s; for (s=0; s<sortedListSize; s++) {   /* note : sortedSymbols already skipped */
2018
3.60M
        const U32 symbol = sortedSymbols[s].symbol;
2019
3.60M
        const U32 weight = sortedSymbols[s].weight;
2020
3.60M
        const U32 nbBits = nbBitsBaseline - weight;
2021
3.60M
        const U32 length = 1 << (sizeLog-nbBits);
2022
3.60M
        const U32 start = rankVal[weight];
2023
3.60M
        U32 i = start;
2024
3.60M
        const U32 end = start + length;
2025
2026
3.60M
        MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
2027
3.60M
        DElt.nbBits = (BYTE)(nbBits + consumed);
2028
3.60M
        DElt.length = 2;
2029
13.6M
        do { DTable[i++] = DElt; } while (i<end);   /* since length >= 1 */
2030
2031
3.60M
        rankVal[weight] += length;
2032
3.60M
    }}
2033
1.11M
}
2034
2035
typedef U32 rankVal_t[HUFv07_TABLELOG_ABSOLUTEMAX][HUFv07_TABLELOG_ABSOLUTEMAX + 1];
2036
2037
static void HUFv07_fillDTableX4(HUFv07_DEltX4* DTable, const U32 targetLog,
2038
                           const sortedSymbol_t* sortedList, const U32 sortedListSize,
2039
                           const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
2040
                           const U32 nbBitsBaseline)
2041
10.2k
{
2042
10.2k
    U32 rankVal[HUFv07_TABLELOG_ABSOLUTEMAX + 1];
2043
10.2k
    const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */
2044
10.2k
    const U32 minBits  = nbBitsBaseline - maxWeight;
2045
10.2k
    U32 s;
2046
2047
10.2k
    memcpy(rankVal, rankValOrigin, sizeof(rankVal));
2048
2049
    /* fill DTable */
2050
2.17M
    for (s=0; s<sortedListSize; s++) {
2051
2.16M
        const U16 symbol = sortedList[s].symbol;
2052
2.16M
        const U32 weight = sortedList[s].weight;
2053
2.16M
        const U32 nbBits = nbBitsBaseline - weight;
2054
2.16M
        const U32 start = rankVal[weight];
2055
2.16M
        const U32 length = 1 << (targetLog-nbBits);
2056
2057
2.16M
        if (targetLog-nbBits >= minBits) {   /* enough room for a second symbol */
2058
1.11M
            U32 sortedRank;
2059
1.11M
            int minWeight = nbBits + scaleLog;
2060
1.11M
            if (minWeight < 1) minWeight = 1;
2061
1.11M
            sortedRank = rankStart[minWeight];
2062
1.11M
            HUFv07_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,
2063
1.11M
                           rankValOrigin[nbBits], minWeight,
2064
1.11M
                           sortedList+sortedRank, sortedListSize-sortedRank,
2065
1.11M
                           nbBitsBaseline, symbol);
2066
1.11M
        } else {
2067
1.05M
            HUFv07_DEltX4 DElt;
2068
1.05M
            MEM_writeLE16(&(DElt.sequence), symbol);
2069
1.05M
            DElt.nbBits = (BYTE)(nbBits);
2070
1.05M
            DElt.length = 1;
2071
1.05M
            {   U32 u;
2072
1.05M
                const U32 end = start + length;
2073
15.1M
                for (u = start; u < end; u++) DTable[u] = DElt;
2074
1.05M
        }   }
2075
2.16M
        rankVal[weight] += length;
2076
2.16M
    }
2077
10.2k
}
2078
2079
size_t HUFv07_readDTableX4 (HUFv07_DTable* DTable, const void* src, size_t srcSize)
2080
10.2k
{
2081
10.2k
    BYTE weightList[HUFv07_SYMBOLVALUE_MAX + 1];
2082
10.2k
    sortedSymbol_t sortedSymbol[HUFv07_SYMBOLVALUE_MAX + 1];
2083
10.2k
    U32 rankStats[HUFv07_TABLELOG_ABSOLUTEMAX + 1] = { 0 };
2084
10.2k
    U32 rankStart0[HUFv07_TABLELOG_ABSOLUTEMAX + 2] = { 0 };
2085
10.2k
    U32* const rankStart = rankStart0+1;
2086
10.2k
    rankVal_t rankVal;
2087
10.2k
    U32 tableLog, maxW, sizeOfSort, nbSymbols;
2088
10.2k
    DTableDesc dtd = HUFv07_getDTableDesc(DTable);
2089
10.2k
    U32 const maxTableLog = dtd.maxTableLog;
2090
10.2k
    size_t iSize;
2091
10.2k
    void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */
2092
10.2k
    HUFv07_DEltX4* const dt = (HUFv07_DEltX4*)dtPtr;
2093
2094
10.2k
    HUFv07_STATIC_ASSERT(sizeof(HUFv07_DEltX4) == sizeof(HUFv07_DTable));   /* if compilation fails here, assertion is false */
2095
10.2k
    if (maxTableLog > HUFv07_TABLELOG_ABSOLUTEMAX) return ERROR(tableLog_tooLarge);
2096
    /* memset(weightList, 0, sizeof(weightList)); */   /* is not necessary, even though some analyzer complain ... */
2097
2098
10.2k
    iSize = HUFv07_readStats(weightList, HUFv07_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
2099
10.2k
    if (HUFv07_isError(iSize)) return iSize;
2100
2101
    /* check result */
2102
10.2k
    if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */
2103
2104
    /* find maxWeight */
2105
40.0k
    for (maxW = tableLog; rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */
2106
2107
    /* Get start index of each weight */
2108
10.2k
    {   U32 w, nextRankStart = 0;
2109
65.0k
        for (w=1; w<maxW+1; w++) {
2110
54.8k
            U32 current = nextRankStart;
2111
54.8k
            nextRankStart += rankStats[w];
2112
54.8k
            rankStart[w] = current;
2113
54.8k
        }
2114
10.2k
        rankStart[0] = nextRankStart;   /* put all 0w symbols at the end of sorted list*/
2115
10.2k
        sizeOfSort = nextRankStart;
2116
10.2k
    }
2117
2118
    /* sort symbols by weight */
2119
10.2k
    {   U32 s;
2120
2.17M
        for (s=0; s<nbSymbols; s++) {
2121
2.16M
            U32 const w = weightList[s];
2122
2.16M
            U32 const r = rankStart[w]++;
2123
2.16M
            sortedSymbol[r].symbol = (BYTE)s;
2124
2.16M
            sortedSymbol[r].weight = (BYTE)w;
2125
2.16M
        }
2126
10.2k
        rankStart[0] = 0;   /* forget 0w symbols; this is beginning of weight(1) */
2127
10.2k
    }
2128
2129
    /* Build rankVal */
2130
10.2k
    {   U32* const rankVal0 = rankVal[0];
2131
10.2k
        {   int const rescale = (maxTableLog-tableLog) - 1;   /* tableLog <= maxTableLog */
2132
10.2k
            U32 nextRankVal = 0;
2133
10.2k
            U32 w;
2134
65.0k
            for (w=1; w<maxW+1; w++) {
2135
54.8k
                U32 current = nextRankVal;
2136
54.8k
                nextRankVal += rankStats[w] << (w+rescale);
2137
54.8k
                rankVal0[w] = current;
2138
54.8k
        }   }
2139
10.2k
        {   U32 const minBits = tableLog+1 - maxW;
2140
10.2k
            U32 consumed;
2141
65.9k
            for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
2142
55.6k
                U32* const rankValPtr = rankVal[consumed];
2143
55.6k
                U32 w;
2144
385k
                for (w = 1; w < maxW+1; w++) {
2145
329k
                    rankValPtr[w] = rankVal0[w] >> consumed;
2146
329k
    }   }   }   }
2147
2148
10.2k
    HUFv07_fillDTableX4(dt, maxTableLog,
2149
10.2k
                   sortedSymbol, sizeOfSort,
2150
10.2k
                   rankStart0, rankVal, maxW,
2151
10.2k
                   tableLog+1);
2152
2153
10.2k
    dtd.tableLog = (BYTE)maxTableLog;
2154
10.2k
    dtd.tableType = 1;
2155
10.2k
    memcpy(DTable, &dtd, sizeof(dtd));
2156
10.2k
    return iSize;
2157
10.2k
}
2158
2159
2160
static U32 HUFv07_decodeSymbolX4(void* op, BITv07_DStream_t* DStream, const HUFv07_DEltX4* dt, const U32 dtLog)
2161
8.62M
{
2162
8.62M
    const size_t val = BITv07_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
2163
8.62M
    memcpy(op, dt+val, 2);
2164
8.62M
    BITv07_skipBits(DStream, dt[val].nbBits);
2165
8.62M
    return dt[val].length;
2166
8.62M
}
2167
2168
static U32 HUFv07_decodeLastSymbolX4(void* op, BITv07_DStream_t* DStream, const HUFv07_DEltX4* dt, const U32 dtLog)
2169
7.24k
{
2170
7.24k
    const size_t val = BITv07_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
2171
7.24k
    memcpy(op, dt+val, 1);
2172
7.24k
    if (dt[val].length==1) BITv07_skipBits(DStream, dt[val].nbBits);
2173
7.02k
    else {
2174
7.02k
        if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
2175
5.20k
            BITv07_skipBits(DStream, dt[val].nbBits);
2176
5.20k
            if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
2177
2.43k
                DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);   /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
2178
5.20k
    }   }
2179
7.24k
    return 1;
2180
7.24k
}
2181
2182
2183
#define HUFv07_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \
2184
3.65M
    ptr += HUFv07_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
2185
2186
#define HUFv07_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
2187
1.65M
    if (MEM_64bits() || (HUFv07_TABLELOG_MAX<=12)) \
2188
1.65M
        ptr += HUFv07_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
2189
2190
#define HUFv07_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
2191
3.31M
    if (MEM_64bits()) \
2192
3.31M
        ptr += HUFv07_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
2193
2194
static inline size_t HUFv07_decodeStreamX4(BYTE* p, BITv07_DStream_t* bitDPtr, BYTE* const pEnd, const HUFv07_DEltX4* const dt, const U32 dtLog)
2195
7.52k
{
2196
7.52k
    BYTE* const pStart = p;
2197
2198
    /* up to 8 symbols at a time */
2199
290k
    while ((BITv07_reloadDStream(bitDPtr) == BITv07_DStream_unfinished) && (p < pEnd-7)) {
2200
282k
        HUFv07_DECODE_SYMBOLX4_2(p, bitDPtr);
2201
282k
        HUFv07_DECODE_SYMBOLX4_1(p, bitDPtr);
2202
282k
        HUFv07_DECODE_SYMBOLX4_2(p, bitDPtr);
2203
282k
        HUFv07_DECODE_SYMBOLX4_0(p, bitDPtr);
2204
282k
    }
2205
2206
    /* closer to end : up to 2 symbols at a time */
2207
8.00k
    while ((BITv07_reloadDStream(bitDPtr) == BITv07_DStream_unfinished) && (p <= pEnd-2))
2208
485
        HUFv07_DECODE_SYMBOLX4_0(p, bitDPtr);
2209
2210
2.00M
    while (p <= pEnd-2)
2211
1.99M
        HUFv07_DECODE_SYMBOLX4_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */
2212
2213
7.52k
    if (p < pEnd)
2214
7.24k
        p += HUFv07_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);
2215
2216
7.52k
    return p-pStart;
2217
7.52k
}
2218
2219
2220
static size_t HUFv07_decompress1X4_usingDTable_internal(
2221
          void* dst,  size_t dstSize,
2222
    const void* cSrc, size_t cSrcSize,
2223
    const HUFv07_DTable* DTable)
2224
160
{
2225
160
    BITv07_DStream_t bitD;
2226
2227
    /* Init */
2228
160
    {   size_t const errorCode = BITv07_initDStream(&bitD, cSrc, cSrcSize);
2229
160
        if (HUFv07_isError(errorCode)) return errorCode;
2230
160
    }
2231
2232
    /* decode */
2233
149
    {   BYTE* const ostart = (BYTE*) dst;
2234
149
        BYTE* const oend = ostart + dstSize;
2235
149
        const void* const dtPtr = DTable+1;   /* force compiler to not use strict-aliasing */
2236
149
        const HUFv07_DEltX4* const dt = (const HUFv07_DEltX4*)dtPtr;
2237
149
        DTableDesc const dtd = HUFv07_getDTableDesc(DTable);
2238
149
        HUFv07_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
2239
149
    }
2240
2241
    /* check */
2242
149
    if (!BITv07_endOfDStream(&bitD)) return ERROR(corruption_detected);
2243
2244
    /* decoded size */
2245
88
    return dstSize;
2246
149
}
2247
2248
size_t HUFv07_decompress1X4_usingDTable(
2249
          void* dst,  size_t dstSize,
2250
    const void* cSrc, size_t cSrcSize,
2251
    const HUFv07_DTable* DTable)
2252
163
{
2253
163
    DTableDesc dtd = HUFv07_getDTableDesc(DTable);
2254
163
    if (dtd.tableType != 1) return ERROR(GENERIC);
2255
160
    return HUFv07_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
2256
163
}
2257
2258
size_t HUFv07_decompress1X4_DCtx (HUFv07_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2259
0
{
2260
0
    const BYTE* ip = (const BYTE*) cSrc;
2261
2262
0
    size_t const hSize = HUFv07_readDTableX4 (DCtx, cSrc, cSrcSize);
2263
0
    if (HUFv07_isError(hSize)) return hSize;
2264
0
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
2265
0
    ip += hSize; cSrcSize -= hSize;
2266
2267
0
    return HUFv07_decompress1X4_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
2268
0
}
2269
2270
size_t HUFv07_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2271
0
{
2272
0
    HUFv07_CREATE_STATIC_DTABLEX4(DTable, HUFv07_TABLELOG_MAX);
2273
0
    return HUFv07_decompress1X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
2274
0
}
2275
2276
static size_t HUFv07_decompress4X4_usingDTable_internal(
2277
          void* dst,  size_t dstSize,
2278
    const void* cSrc, size_t cSrcSize,
2279
    const HUFv07_DTable* DTable)
2280
1.96k
{
2281
1.96k
    if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */
2282
2283
1.96k
    {   const BYTE* const istart = (const BYTE*) cSrc;
2284
1.96k
        BYTE* const ostart = (BYTE*) dst;
2285
1.96k
        BYTE* const oend = ostart + dstSize;
2286
1.96k
        const void* const dtPtr = DTable+1;
2287
1.96k
        const HUFv07_DEltX4* const dt = (const HUFv07_DEltX4*)dtPtr;
2288
2289
        /* Init */
2290
1.96k
        BITv07_DStream_t bitD1;
2291
1.96k
        BITv07_DStream_t bitD2;
2292
1.96k
        BITv07_DStream_t bitD3;
2293
1.96k
        BITv07_DStream_t bitD4;
2294
1.96k
        size_t const length1 = MEM_readLE16(istart);
2295
1.96k
        size_t const length2 = MEM_readLE16(istart+2);
2296
1.96k
        size_t const length3 = MEM_readLE16(istart+4);
2297
1.96k
        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
2298
1.96k
        const BYTE* const istart1 = istart + 6;  /* jumpTable */
2299
1.96k
        const BYTE* const istart2 = istart1 + length1;
2300
1.96k
        const BYTE* const istart3 = istart2 + length2;
2301
1.96k
        const BYTE* const istart4 = istart3 + length3;
2302
1.96k
        size_t const segmentSize = (dstSize+3) / 4;
2303
1.96k
        BYTE* const opStart2 = ostart + segmentSize;
2304
1.96k
        BYTE* const opStart3 = opStart2 + segmentSize;
2305
1.96k
        BYTE* const opStart4 = opStart3 + segmentSize;
2306
1.96k
        BYTE* op1 = ostart;
2307
1.96k
        BYTE* op2 = opStart2;
2308
1.96k
        BYTE* op3 = opStart3;
2309
1.96k
        BYTE* op4 = opStart4;
2310
1.96k
        U32 endSignal;
2311
1.96k
        DTableDesc const dtd = HUFv07_getDTableDesc(DTable);
2312
1.96k
        U32 const dtLog = dtd.tableLog;
2313
2314
1.96k
        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
2315
1.91k
        { size_t const errorCode = BITv07_initDStream(&bitD1, istart1, length1);
2316
1.91k
          if (HUFv07_isError(errorCode)) return errorCode; }
2317
1.89k
        { size_t const errorCode = BITv07_initDStream(&bitD2, istart2, length2);
2318
1.89k
          if (HUFv07_isError(errorCode)) return errorCode; }
2319
1.88k
        { size_t const errorCode = BITv07_initDStream(&bitD3, istart3, length3);
2320
1.88k
          if (HUFv07_isError(errorCode)) return errorCode; }
2321
1.85k
        { size_t const errorCode = BITv07_initDStream(&bitD4, istart4, length4);
2322
1.85k
          if (HUFv07_isError(errorCode)) return errorCode; }
2323
2324
        /* 16-32 symbols per loop (4-8 symbols per stream) */
2325
1.85k
        endSignal = BITv07_reloadDStream(&bitD1) | BITv07_reloadDStream(&bitD2) | BITv07_reloadDStream(&bitD3) | BITv07_reloadDStream(&bitD4);
2326
345k
        for ( ; (endSignal==BITv07_DStream_unfinished) && (op4<(oend-7)) ; ) {
2327
343k
            HUFv07_DECODE_SYMBOLX4_2(op1, &bitD1);
2328
343k
            HUFv07_DECODE_SYMBOLX4_2(op2, &bitD2);
2329
343k
            HUFv07_DECODE_SYMBOLX4_2(op3, &bitD3);
2330
343k
            HUFv07_DECODE_SYMBOLX4_2(op4, &bitD4);
2331
343k
            HUFv07_DECODE_SYMBOLX4_1(op1, &bitD1);
2332
343k
            HUFv07_DECODE_SYMBOLX4_1(op2, &bitD2);
2333
343k
            HUFv07_DECODE_SYMBOLX4_1(op3, &bitD3);
2334
343k
            HUFv07_DECODE_SYMBOLX4_1(op4, &bitD4);
2335
343k
            HUFv07_DECODE_SYMBOLX4_2(op1, &bitD1);
2336
343k
            HUFv07_DECODE_SYMBOLX4_2(op2, &bitD2);
2337
343k
            HUFv07_DECODE_SYMBOLX4_2(op3, &bitD3);
2338
343k
            HUFv07_DECODE_SYMBOLX4_2(op4, &bitD4);
2339
343k
            HUFv07_DECODE_SYMBOLX4_0(op1, &bitD1);
2340
343k
            HUFv07_DECODE_SYMBOLX4_0(op2, &bitD2);
2341
343k
            HUFv07_DECODE_SYMBOLX4_0(op3, &bitD3);
2342
343k
            HUFv07_DECODE_SYMBOLX4_0(op4, &bitD4);
2343
2344
343k
            endSignal = BITv07_reloadDStream(&bitD1) | BITv07_reloadDStream(&bitD2) | BITv07_reloadDStream(&bitD3) | BITv07_reloadDStream(&bitD4);
2345
343k
        }
2346
2347
        /* check corruption */
2348
1.85k
        if (op1 > opStart2) return ERROR(corruption_detected);
2349
1.84k
        if (op2 > opStart3) return ERROR(corruption_detected);
2350
1.84k
        if (op3 > opStart4) return ERROR(corruption_detected);
2351
        /* note : op4 supposed already verified within main loop */
2352
2353
        /* finish bitStreams one by one */
2354
1.84k
        HUFv07_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
2355
1.84k
        HUFv07_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
2356
1.84k
        HUFv07_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
2357
1.84k
        HUFv07_decodeStreamX4(op4, &bitD4, oend,     dt, dtLog);
2358
2359
        /* check */
2360
1.84k
        { U32 const endCheck = BITv07_endOfDStream(&bitD1) & BITv07_endOfDStream(&bitD2) & BITv07_endOfDStream(&bitD3) & BITv07_endOfDStream(&bitD4);
2361
1.84k
          if (!endCheck) return ERROR(corruption_detected); }
2362
2363
        /* decoded size */
2364
1.56k
        return dstSize;
2365
1.84k
    }
2366
1.84k
}
2367
2368
2369
size_t HUFv07_decompress4X4_usingDTable(
2370
          void* dst,  size_t dstSize,
2371
    const void* cSrc, size_t cSrcSize,
2372
    const HUFv07_DTable* DTable)
2373
0
{
2374
0
    DTableDesc dtd = HUFv07_getDTableDesc(DTable);
2375
0
    if (dtd.tableType != 1) return ERROR(GENERIC);
2376
0
    return HUFv07_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
2377
0
}
2378
2379
2380
size_t HUFv07_decompress4X4_DCtx (HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2381
1.98k
{
2382
1.98k
    const BYTE* ip = (const BYTE*) cSrc;
2383
2384
1.98k
    size_t hSize = HUFv07_readDTableX4 (dctx, cSrc, cSrcSize);
2385
1.98k
    if (HUFv07_isError(hSize)) return hSize;
2386
1.96k
    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
2387
1.96k
    ip += hSize; cSrcSize -= hSize;
2388
2389
1.96k
    return HUFv07_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
2390
1.96k
}
2391
2392
size_t HUFv07_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2393
0
{
2394
0
    HUFv07_CREATE_STATIC_DTABLEX4(DTable, HUFv07_TABLELOG_MAX);
2395
0
    return HUFv07_decompress4X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
2396
0
}
2397
2398
2399
/* ********************************/
2400
/* Generic decompression selector */
2401
/* ********************************/
2402
2403
size_t HUFv07_decompress1X_usingDTable(void* dst, size_t maxDstSize,
2404
                                    const void* cSrc, size_t cSrcSize,
2405
                                    const HUFv07_DTable* DTable)
2406
0
{
2407
0
    DTableDesc const dtd = HUFv07_getDTableDesc(DTable);
2408
0
    return dtd.tableType ? HUFv07_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
2409
0
                           HUFv07_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
2410
0
}
2411
2412
size_t HUFv07_decompress4X_usingDTable(void* dst, size_t maxDstSize,
2413
                                    const void* cSrc, size_t cSrcSize,
2414
                                    const HUFv07_DTable* DTable)
2415
0
{
2416
0
    DTableDesc const dtd = HUFv07_getDTableDesc(DTable);
2417
0
    return dtd.tableType ? HUFv07_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
2418
0
                           HUFv07_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
2419
0
}
2420
2421
2422
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
2423
static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
2424
{
2425
    /* single, double, quad */
2426
    {{0,0}, {1,1}, {2,2}},  /* Q==0 : impossible */
2427
    {{0,0}, {1,1}, {2,2}},  /* Q==1 : impossible */
2428
    {{  38,130}, {1313, 74}, {2151, 38}},   /* Q == 2 : 12-18% */
2429
    {{ 448,128}, {1353, 74}, {2238, 41}},   /* Q == 3 : 18-25% */
2430
    {{ 556,128}, {1353, 74}, {2238, 47}},   /* Q == 4 : 25-32% */
2431
    {{ 714,128}, {1418, 74}, {2436, 53}},   /* Q == 5 : 32-38% */
2432
    {{ 883,128}, {1437, 74}, {2464, 61}},   /* Q == 6 : 38-44% */
2433
    {{ 897,128}, {1515, 75}, {2622, 68}},   /* Q == 7 : 44-50% */
2434
    {{ 926,128}, {1613, 75}, {2730, 75}},   /* Q == 8 : 50-56% */
2435
    {{ 947,128}, {1729, 77}, {3359, 77}},   /* Q == 9 : 56-62% */
2436
    {{1107,128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */
2437
    {{1177,128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */
2438
    {{1242,128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */
2439
    {{1349,128}, {2644,106}, {5260,106}},   /* Q ==13 : 81-87% */
2440
    {{1455,128}, {2422,124}, {4174,124}},   /* Q ==14 : 87-93% */
2441
    {{ 722,128}, {1891,145}, {1936,146}},   /* Q ==15 : 93-99% */
2442
};
2443
2444
/** HUFv07_selectDecoder() :
2445
*   Tells which decoder is likely to decode faster,
2446
*   based on a set of pre-determined metrics.
2447
*   @return : 0==HUFv07_decompress4X2, 1==HUFv07_decompress4X4 .
2448
*   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
2449
U32 HUFv07_selectDecoder (size_t dstSize, size_t cSrcSize)
2450
6.56k
{
2451
    /* decoder timing evaluation */
2452
6.56k
    U32 const Q = (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 since dstSize > cSrcSize */
2453
6.56k
    U32 const D256 = (U32)(dstSize >> 8);
2454
6.56k
    U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
2455
6.56k
    U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
2456
6.56k
    DTime1 += DTime1 >> 3;  /* advantage to algorithm using less memory, for cache eviction */
2457
2458
6.56k
    return DTime1 < DTime0;
2459
6.56k
}
2460
2461
2462
typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
2463
2464
size_t HUFv07_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2465
0
{
2466
0
    static const decompressionAlgo decompress[2] = { HUFv07_decompress4X2, HUFv07_decompress4X4 };
2467
2468
    /* validation checks */
2469
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
2470
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
2471
0
    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
2472
0
    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
2473
2474
0
    {   U32 const algoNb = HUFv07_selectDecoder(dstSize, cSrcSize);
2475
0
        return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
2476
0
    }
2477
2478
    /* return HUFv07_decompress4X2(dst, dstSize, cSrc, cSrcSize); */   /* multi-streams single-symbol decoding */
2479
    /* return HUFv07_decompress4X4(dst, dstSize, cSrc, cSrcSize); */   /* multi-streams double-symbols decoding */
2480
0
}
2481
2482
size_t HUFv07_decompress4X_DCtx (HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2483
0
{
2484
    /* validation checks */
2485
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
2486
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
2487
0
    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
2488
0
    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
2489
2490
0
    {   U32 const algoNb = HUFv07_selectDecoder(dstSize, cSrcSize);
2491
0
        return algoNb ? HUFv07_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
2492
0
                        HUFv07_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
2493
0
    }
2494
0
}
2495
2496
size_t HUFv07_decompress4X_hufOnly (HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2497
6.64k
{
2498
    /* validation checks */
2499
6.64k
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
2500
6.62k
    if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected);   /* invalid */
2501
2502
6.56k
    {   U32 const algoNb = HUFv07_selectDecoder(dstSize, cSrcSize);
2503
6.56k
        return algoNb ? HUFv07_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
2504
6.56k
                        HUFv07_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
2505
6.62k
    }
2506
6.62k
}
2507
2508
size_t HUFv07_decompress1X_DCtx (HUFv07_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
2509
0
{
2510
    /* validation checks */
2511
0
    if (dstSize == 0) return ERROR(dstSize_tooSmall);
2512
0
    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
2513
0
    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
2514
0
    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
2515
2516
0
    {   U32 const algoNb = HUFv07_selectDecoder(dstSize, cSrcSize);
2517
0
        return algoNb ? HUFv07_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
2518
0
                        HUFv07_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
2519
0
    }
2520
0
}
2521
/*
2522
    Common functions of Zstd compression library
2523
    Copyright (C) 2015-2016, Yann Collet.
2524
2525
    BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
2526
2527
    Redistribution and use in source and binary forms, with or without
2528
    modification, are permitted provided that the following conditions are
2529
    met:
2530
    * Redistributions of source code must retain the above copyright
2531
    notice, this list of conditions and the following disclaimer.
2532
    * Redistributions in binary form must reproduce the above
2533
    copyright notice, this list of conditions and the following disclaimer
2534
    in the documentation and/or other materials provided with the
2535
    distribution.
2536
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2537
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2538
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2539
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2540
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2541
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2542
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2543
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2544
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2545
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2546
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2547
2548
    You can contact the author at :
2549
    - zstd homepage : https://facebook.github.io/zstd/
2550
*/
2551
2552
2553
2554
/*-****************************************
2555
*  ZSTD Error Management
2556
******************************************/
2557
/*! ZSTDv07_isError() :
2558
*   tells if a return value is an error code */
2559
0
unsigned ZSTDv07_isError(size_t code) { return ERR_isError(code); }
2560
2561
/*! ZSTDv07_getErrorName() :
2562
*   provides error code string from function result (useful for debugging) */
2563
0
const char* ZSTDv07_getErrorName(size_t code) { return ERR_getErrorName(code); }
2564
2565
2566
2567
/* **************************************************************
2568
*  ZBUFF Error Management
2569
****************************************************************/
2570
0
unsigned ZBUFFv07_isError(size_t errorCode) { return ERR_isError(errorCode); }
2571
2572
0
const char* ZBUFFv07_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
2573
2574
2575
2576
static void* ZSTDv07_defaultAllocFunction(void* opaque, size_t size)
2577
24.2k
{
2578
24.2k
    void* address = malloc(size);
2579
24.2k
    (void)opaque;
2580
    /* printf("alloc %p, %d opaque=%p \n", address, (int)size, opaque); */
2581
24.2k
    return address;
2582
24.2k
}
2583
2584
static void ZSTDv07_defaultFreeFunction(void* opaque, void* address)
2585
30.0k
{
2586
30.0k
    (void)opaque;
2587
    /* if (address) printf("free %p opaque=%p \n", address, opaque); */
2588
30.0k
    free(address);
2589
30.0k
}
2590
/*
2591
    zstd_internal - common functions to include
2592
    Header File for include
2593
    Copyright (C) 2014-2016, Yann Collet.
2594
2595
    BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
2596
2597
    Redistribution and use in source and binary forms, with or without
2598
    modification, are permitted provided that the following conditions are
2599
    met:
2600
    * Redistributions of source code must retain the above copyright
2601
    notice, this list of conditions and the following disclaimer.
2602
    * Redistributions in binary form must reproduce the above
2603
    copyright notice, this list of conditions and the following disclaimer
2604
    in the documentation and/or other materials provided with the
2605
    distribution.
2606
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2607
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2608
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2609
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2610
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2611
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2612
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2613
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2614
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2615
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2616
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2617
2618
    You can contact the author at :
2619
    - zstd homepage : https://www.zstd.net
2620
*/
2621
#ifndef ZSTDv07_CCOMMON_H_MODULE
2622
#define ZSTDv07_CCOMMON_H_MODULE
2623
2624
2625
/*-*************************************
2626
*  Common macros
2627
***************************************/
2628
22.8k
#define MIN(a,b) ((a)<(b) ? (a) : (b))
2629
4.86k
#define MAX(a,b) ((a)>(b) ? (a) : (b))
2630
2631
2632
/*-*************************************
2633
*  Common constants
2634
***************************************/
2635
#define ZSTDv07_OPT_NUM    (1<<12)
2636
8.30k
#define ZSTDv07_DICT_MAGIC  0xEC30A437   /* v0.7 */
2637
2638
211k
#define ZSTDv07_REP_NUM    3
2639
81.7k
#define ZSTDv07_REP_INIT   ZSTDv07_REP_NUM
2640
#define ZSTDv07_REP_MOVE   (ZSTDv07_REP_NUM-1)
2641
static const U32 repStartValue[ZSTDv07_REP_NUM] = { 1, 4, 8 };
2642
2643
#define KB *(1 <<10)
2644
#define MB *(1 <<20)
2645
#define GB *(1U<<30)
2646
2647
#define BIT7 128
2648
#define BIT6  64
2649
#define BIT5  32
2650
#define BIT4  16
2651
#define BIT1   2
2652
#define BIT0   1
2653
2654
23.4k
#define ZSTDv07_WINDOWLOG_ABSOLUTEMIN 10
2655
static const size_t ZSTDv07_fcs_fieldSize[4] = { 0, 2, 4, 8 };
2656
static const size_t ZSTDv07_did_fieldSize[4] = { 0, 1, 2, 4 };
2657
2658
#define ZSTDv07_BLOCKHEADERSIZE 3   /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
2659
static const size_t ZSTDv07_blockHeaderSize = ZSTDv07_BLOCKHEADERSIZE;
2660
typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
2661
2662
79.8k
#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
2663
41.1k
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */)   /* for a non-null block */
2664
2665
32.5k
#define ZSTD_HUFFDTABLE_CAPACITY_LOG 12
2666
typedef enum { lbt_huffman, lbt_repeat, lbt_raw, lbt_rle } litBlockType_t;
2667
2668
168
#define LONGNBSEQ 0x7F00
2669
2670
8.82M
#define MINMATCH 3
2671
#define EQUAL_READ32 4
2672
2673
#define Litbits  8
2674
#define MaxLit ((1<<Litbits) - 1)
2675
20.1k
#define MaxML  52
2676
20.4k
#define MaxLL  35
2677
20.2k
#define MaxOff 28
2678
#define MaxSeq MAX(MaxLL, MaxML)   /* Assumption : MaxOff < MaxLL,MaxML */
2679
8.84M
#define MLFSELog    9
2680
8.84M
#define LLFSELog    9
2681
8.84M
#define OffFSELog   8
2682
2683
18.7k
#define FSEv07_ENCODING_RAW     0
2684
9.33k
#define FSEv07_ENCODING_RLE     1
2685
2.01k
#define FSEv07_ENCODING_STATIC  2
2686
5.81k
#define FSEv07_ENCODING_DYNAMIC 3
2687
2688
1.00k
#define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2)
2689
2690
static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2691
                                      1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
2692
                                     13,14,15,16 };
2693
static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
2694
                                             2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
2695
                                            -1,-1,-1,-1 };
2696
static const U32 LL_defaultNormLog = 6;
2697
2698
static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2699
                                      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2700
                                      1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9,10,11,
2701
                                     12,13,14,15,16 };
2702
static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
2703
                                             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2704
                                             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,
2705
                                            -1,-1,-1,-1,-1 };
2706
static const U32 ML_defaultNormLog = 6;
2707
2708
static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
2709
                                              1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 };
2710
static const U32 OF_defaultNormLog = 5;
2711
2712
2713
/*-*******************************************
2714
*  Shared functions to include for inlining
2715
*********************************************/
2716
211M
static void ZSTDv07_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
2717
211M
#define COPY8(d,s) { ZSTDv07_copy8(d,s); d+=8; s+=8; }
2718
2719
/*! ZSTDv07_wildcopy() :
2720
*   custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */
2721
17.6M
#define WILDCOPY_OVERLENGTH 8
2722
MEM_STATIC void ZSTDv07_wildcopy(void* dst, const void* src, ptrdiff_t length)
2723
17.6M
{
2724
17.6M
    const BYTE* ip = (const BYTE*)src;
2725
17.6M
    BYTE* op = (BYTE*)dst;
2726
17.6M
    BYTE* const oend = op + length;
2727
17.6M
    do
2728
211M
        COPY8(op, ip)
2729
211M
    while (op < oend);
2730
17.6M
}
2731
2732
2733
/*-*******************************************
2734
*  Private interfaces
2735
*********************************************/
2736
typedef struct ZSTDv07_stats_s ZSTDv07_stats_t;
2737
2738
typedef struct {
2739
    U32 off;
2740
    U32 len;
2741
} ZSTDv07_match_t;
2742
2743
typedef struct {
2744
    U32 price;
2745
    U32 off;
2746
    U32 mlen;
2747
    U32 litlen;
2748
    U32 rep[ZSTDv07_REP_INIT];
2749
} ZSTDv07_optimal_t;
2750
2751
struct ZSTDv07_stats_s { U32 unused; };
2752
2753
typedef struct {
2754
    void* buffer;
2755
    U32*  offsetStart;
2756
    U32*  offset;
2757
    BYTE* offCodeStart;
2758
    BYTE* litStart;
2759
    BYTE* lit;
2760
    U16*  litLengthStart;
2761
    U16*  litLength;
2762
    BYTE* llCodeStart;
2763
    U16*  matchLengthStart;
2764
    U16*  matchLength;
2765
    BYTE* mlCodeStart;
2766
    U32   longLengthID;   /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
2767
    U32   longLengthPos;
2768
    /* opt */
2769
    ZSTDv07_optimal_t* priceTable;
2770
    ZSTDv07_match_t* matchTable;
2771
    U32* matchLengthFreq;
2772
    U32* litLengthFreq;
2773
    U32* litFreq;
2774
    U32* offCodeFreq;
2775
    U32  matchLengthSum;
2776
    U32  matchSum;
2777
    U32  litLengthSum;
2778
    U32  litSum;
2779
    U32  offCodeSum;
2780
    U32  log2matchLengthSum;
2781
    U32  log2matchSum;
2782
    U32  log2litLengthSum;
2783
    U32  log2litSum;
2784
    U32  log2offCodeSum;
2785
    U32  factor;
2786
    U32  cachedPrice;
2787
    U32  cachedLitLength;
2788
    const BYTE* cachedLiterals;
2789
    ZSTDv07_stats_t stats;
2790
} SeqStore_t;
2791
2792
void ZSTDv07_seqToCodes(const SeqStore_t* seqStorePtr, size_t const nbSeq);
2793
2794
/* custom memory allocation functions */
2795
static const ZSTDv07_customMem defaultCustomMem = { ZSTDv07_defaultAllocFunction, ZSTDv07_defaultFreeFunction, NULL };
2796
2797
#endif   /* ZSTDv07_CCOMMON_H_MODULE */
2798
/*
2799
    zstd - standard compression library
2800
    Copyright (C) 2014-2016, Yann Collet.
2801
2802
    BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
2803
2804
    Redistribution and use in source and binary forms, with or without
2805
    modification, are permitted provided that the following conditions are
2806
    met:
2807
    * Redistributions of source code must retain the above copyright
2808
    notice, this list of conditions and the following disclaimer.
2809
    * Redistributions in binary form must reproduce the above
2810
    copyright notice, this list of conditions and the following disclaimer
2811
    in the documentation and/or other materials provided with the
2812
    distribution.
2813
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2814
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2815
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2816
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2817
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2818
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2819
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2820
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2821
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2822
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2823
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2824
2825
    You can contact the author at :
2826
    - zstd homepage : https://facebook.github.io/zstd
2827
*/
2828
2829
/* ***************************************************************
2830
*  Tuning parameters
2831
*****************************************************************/
2832
/*!
2833
 * HEAPMODE :
2834
 * Select how default decompression function ZSTDv07_decompress() will allocate memory,
2835
 * in memory stack (0), or in memory heap (1, requires malloc())
2836
 */
2837
#ifndef ZSTDv07_HEAPMODE
2838
#  define ZSTDv07_HEAPMODE 1
2839
#endif
2840
2841
2842
/*-*******************************************************
2843
*  Compiler specifics
2844
*********************************************************/
2845
#ifdef _MSC_VER    /* Visual Studio */
2846
#  include <intrin.h>                    /* For Visual 2005 */
2847
#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
2848
#  pragma warning(disable : 4324)        /* disable: C4324: padded structure */
2849
#  pragma warning(disable : 4100)        /* disable: C4100: unreferenced formal parameter */
2850
#endif
2851
2852
2853
/*-*************************************
2854
*  Macros
2855
***************************************/
2856
12.3M
#define ZSTDv07_isError ERR_isError   /* for inlining */
2857
55.6k
#define FSEv07_isError  ERR_isError
2858
32.5k
#define HUFv07_isError  ERR_isError
2859
2860
2861
/*_*******************************************************
2862
*  Memory operations
2863
**********************************************************/
2864
8.57M
static void ZSTDv07_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
2865
2866
2867
/*-*************************************************************
2868
*   Context management
2869
***************************************************************/
2870
typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
2871
               ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
2872
               ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTDv07_dStage;
2873
2874
struct ZSTDv07_DCtx_s
2875
{
2876
    FSEv07_DTable LLTable[FSEv07_DTABLE_SIZE_U32(LLFSELog)];
2877
    FSEv07_DTable OffTable[FSEv07_DTABLE_SIZE_U32(OffFSELog)];
2878
    FSEv07_DTable MLTable[FSEv07_DTABLE_SIZE_U32(MLFSELog)];
2879
    HUFv07_DTable hufTable[HUFv07_DTABLE_SIZE(ZSTD_HUFFDTABLE_CAPACITY_LOG)];  /* can accommodate HUFv07_decompress4X */
2880
    const void* previousDstEnd;
2881
    const void* base;
2882
    const void* vBase;
2883
    const void* dictEnd;
2884
    size_t expected;
2885
    U32 rep[3];
2886
    ZSTDv07_frameParams fParams;
2887
    blockType_t bType;   /* used in ZSTDv07_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
2888
    ZSTDv07_dStage stage;
2889
    U32 litEntropy;
2890
    U32 fseEntropy;
2891
    XXH64_state_t xxhState;
2892
    size_t headerSize;
2893
    U32 dictID;
2894
    const BYTE* litPtr;
2895
    ZSTDv07_customMem customMem;
2896
    size_t litSize;
2897
    BYTE litBuffer[ZSTDv07_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
2898
    BYTE headerBuffer[ZSTDv07_FRAMEHEADERSIZE_MAX];
2899
};  /* typedef'd to ZSTDv07_DCtx within "zstd_static.h" */
2900
2901
int ZSTDv07_isSkipFrame(ZSTDv07_DCtx* dctx);
2902
2903
0
size_t ZSTDv07_sizeofDCtx (const ZSTDv07_DCtx* dctx) { return sizeof(*dctx); }
2904
2905
0
size_t ZSTDv07_estimateDCtxSize(void) { return sizeof(ZSTDv07_DCtx); }
2906
2907
size_t ZSTDv07_decompressBegin(ZSTDv07_DCtx* dctx)
2908
32.5k
{
2909
32.5k
    dctx->expected = ZSTDv07_frameHeaderSize_min;
2910
32.5k
    dctx->stage = ZSTDds_getFrameHeaderSize;
2911
32.5k
    dctx->previousDstEnd = NULL;
2912
32.5k
    dctx->base = NULL;
2913
32.5k
    dctx->vBase = NULL;
2914
32.5k
    dctx->dictEnd = NULL;
2915
32.5k
    dctx->hufTable[0] = (HUFv07_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001);
2916
32.5k
    dctx->litEntropy = dctx->fseEntropy = 0;
2917
32.5k
    dctx->dictID = 0;
2918
130k
    { int i; for (i=0; i<ZSTDv07_REP_NUM; i++) dctx->rep[i] = repStartValue[i]; }
2919
32.5k
    return 0;
2920
32.5k
}
2921
2922
ZSTDv07_DCtx* ZSTDv07_createDCtx_advanced(ZSTDv07_customMem customMem)
2923
15.2k
{
2924
15.2k
    ZSTDv07_DCtx* dctx;
2925
2926
15.2k
    if (!customMem.customAlloc && !customMem.customFree)
2927
0
        customMem = defaultCustomMem;
2928
2929
15.2k
    if (!customMem.customAlloc || !customMem.customFree)
2930
0
        return NULL;
2931
2932
15.2k
    dctx = (ZSTDv07_DCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTDv07_DCtx));
2933
15.2k
    if (!dctx) return NULL;
2934
15.2k
    memcpy(&dctx->customMem, &customMem, sizeof(ZSTDv07_customMem));
2935
15.2k
    ZSTDv07_decompressBegin(dctx);
2936
15.2k
    return dctx;
2937
15.2k
}
2938
2939
ZSTDv07_DCtx* ZSTDv07_createDCtx(void)
2940
12.2k
{
2941
12.2k
    return ZSTDv07_createDCtx_advanced(defaultCustomMem);
2942
12.2k
}
2943
2944
size_t ZSTDv07_freeDCtx(ZSTDv07_DCtx* dctx)
2945
15.2k
{
2946
15.2k
    if (dctx==NULL) return 0;   /* support free on NULL */
2947
15.2k
    dctx->customMem.customFree(dctx->customMem.opaque, dctx);
2948
15.2k
    return 0;   /* reserved as a potential error code in the future */
2949
15.2k
}
2950
2951
void ZSTDv07_copyDCtx(ZSTDv07_DCtx* dstDCtx, const ZSTDv07_DCtx* srcDCtx)
2952
0
{
2953
0
    memcpy(dstDCtx, srcDCtx,
2954
0
           sizeof(ZSTDv07_DCtx) - (ZSTDv07_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH + ZSTDv07_frameHeaderSize_max));  /* no need to copy workspace */
2955
0
}
2956
2957
2958
/*-*************************************************************
2959
*   Decompression section
2960
***************************************************************/
2961
2962
/* Frame format description
2963
   Frame Header -  [ Block Header - Block ] - Frame End
2964
   1) Frame Header
2965
      - 4 bytes - Magic Number : ZSTDv07_MAGICNUMBER (defined within zstd.h)
2966
      - 1 byte  - Frame Descriptor
2967
   2) Block Header
2968
      - 3 bytes, starting with a 2-bits descriptor
2969
                 Uncompressed, Compressed, Frame End, unused
2970
   3) Block
2971
      See Block Format Description
2972
   4) Frame End
2973
      - 3 bytes, compatible with Block Header
2974
*/
2975
2976
2977
/* Frame Header :
2978
2979
   1 byte - FrameHeaderDescription :
2980
   bit 0-1 : dictID (0, 1, 2 or 4 bytes)
2981
   bit 2   : checksumFlag
2982
   bit 3   : reserved (must be zero)
2983
   bit 4   : reserved (unused, can be any value)
2984
   bit 5   : Single Segment (if 1, WindowLog byte is not present)
2985
   bit 6-7 : FrameContentFieldSize (0, 2, 4, or 8)
2986
             if (SkippedWindowLog && !FrameContentFieldsize) FrameContentFieldsize=1;
2987
2988
   Optional : WindowLog (0 or 1 byte)
2989
   bit 0-2 : octal Fractional (1/8th)
2990
   bit 3-7 : Power of 2, with 0 = 1 KB (up to 2 TB)
2991
2992
   Optional : dictID (0, 1, 2 or 4 bytes)
2993
   Automatic adaptation
2994
   0 : no dictID
2995
   1 : 1 - 255
2996
   2 : 256 - 65535
2997
   4 : all other values
2998
2999
   Optional : content size (0, 1, 2, 4 or 8 bytes)
3000
   0 : unknown          (fcfs==0 and swl==0)
3001
   1 : 0-255 bytes      (fcfs==0 and swl==1)
3002
   2 : 256 - 65535+256  (fcfs==1)
3003
   4 : 0 - 4GB-1        (fcfs==2)
3004
   8 : 0 - 16EB-1       (fcfs==3)
3005
*/
3006
3007
3008
/* Compressed Block, format description
3009
3010
   Block = Literal Section - Sequences Section
3011
   Prerequisite : size of (compressed) block, maximum size of regenerated data
3012
3013
   1) Literal Section
3014
3015
   1.1) Header : 1-5 bytes
3016
        flags: 2 bits
3017
            00 compressed by Huff0
3018
            01 unused
3019
            10 is Raw (uncompressed)
3020
            11 is Rle
3021
            Note : using 01 => Huff0 with precomputed table ?
3022
            Note : delta map ? => compressed ?
3023
3024
   1.1.1) Huff0-compressed literal block : 3-5 bytes
3025
            srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
3026
            srcSize < 1 KB => 3 bytes (2-2-10-10)
3027
            srcSize < 16KB => 4 bytes (2-2-14-14)
3028
            else           => 5 bytes (2-2-18-18)
3029
            big endian convention
3030
3031
   1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
3032
        size :  5 bits: (IS_RAW<<6) + (0<<4) + size
3033
               12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
3034
                        size&255
3035
               20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
3036
                        size>>8&255
3037
                        size&255
3038
3039
   1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
3040
        size :  5 bits: (IS_RLE<<6) + (0<<4) + size
3041
               12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
3042
                        size&255
3043
               20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
3044
                        size>>8&255
3045
                        size&255
3046
3047
   1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
3048
            srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
3049
            srcSize < 1 KB => 3 bytes (2-2-10-10)
3050
            srcSize < 16KB => 4 bytes (2-2-14-14)
3051
            else           => 5 bytes (2-2-18-18)
3052
            big endian convention
3053
3054
        1- CTable available (stored into workspace ?)
3055
        2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
3056
3057
3058
   1.2) Literal block content
3059
3060
   1.2.1) Huff0 block, using sizes from header
3061
        See Huff0 format
3062
3063
   1.2.2) Huff0 block, using prepared table
3064
3065
   1.2.3) Raw content
3066
3067
   1.2.4) single byte
3068
3069
3070
   2) Sequences section
3071
      TO DO
3072
*/
3073
3074
/** ZSTDv07_frameHeaderSize() :
3075
*   srcSize must be >= ZSTDv07_frameHeaderSize_min.
3076
*   @return : size of the Frame Header */
3077
static size_t ZSTDv07_frameHeaderSize(const void* src, size_t srcSize)
3078
78.8k
{
3079
78.8k
    if (srcSize < ZSTDv07_frameHeaderSize_min) return ERROR(srcSize_wrong);
3080
78.8k
    {   BYTE const fhd = ((const BYTE*)src)[4];
3081
78.8k
        U32 const dictID= fhd & 3;
3082
78.8k
        U32 const directMode = (fhd >> 5) & 1;
3083
78.8k
        U32 const fcsId = fhd >> 6;
3084
78.8k
        return ZSTDv07_frameHeaderSize_min + !directMode + ZSTDv07_did_fieldSize[dictID] + ZSTDv07_fcs_fieldSize[fcsId]
3085
78.8k
                + (directMode && !ZSTDv07_fcs_fieldSize[fcsId]);
3086
78.8k
    }
3087
78.8k
}
3088
3089
3090
/** ZSTDv07_getFrameParams() :
3091
*   decode Frame Header, or require larger `srcSize`.
3092
*   @return : 0, `fparamsPtr` is correctly filled,
3093
*            >0, `srcSize` is too small, result is expected `srcSize`,
3094
*             or an error code, which can be tested using ZSTDv07_isError() */
3095
size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const void* src, size_t srcSize)
3096
46.8k
{
3097
46.8k
    const BYTE* ip = (const BYTE*)src;
3098
3099
46.8k
    if (srcSize < ZSTDv07_frameHeaderSize_min) return ZSTDv07_frameHeaderSize_min;
3100
41.6k
    memset(fparamsPtr, 0, sizeof(*fparamsPtr));
3101
41.6k
    if (MEM_readLE32(src) != ZSTDv07_MAGICNUMBER) {
3102
0
        if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTDv07_MAGIC_SKIPPABLE_START) {
3103
0
            if (srcSize < ZSTDv07_skippableHeaderSize) return ZSTDv07_skippableHeaderSize; /* magic number + skippable frame length */
3104
0
            fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
3105
0
            fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
3106
0
            return 0;
3107
0
        }
3108
0
        return ERROR(prefix_unknown);
3109
0
    }
3110
3111
    /* ensure there is enough `srcSize` to fully read/decode frame header */
3112
41.6k
    { size_t const fhsize = ZSTDv07_frameHeaderSize(src, srcSize);
3113
41.6k
      if (srcSize < fhsize) return fhsize; }
3114
3115
36.0k
    {   BYTE const fhdByte = ip[4];
3116
36.0k
        size_t pos = 5;
3117
36.0k
        U32 const dictIDSizeCode = fhdByte&3;
3118
36.0k
        U32 const checksumFlag = (fhdByte>>2)&1;
3119
36.0k
        U32 const directMode = (fhdByte>>5)&1;
3120
36.0k
        U32 const fcsID = fhdByte>>6;
3121
36.0k
        U32 const windowSizeMax = 1U << ZSTDv07_WINDOWLOG_MAX;
3122
36.0k
        U32 windowSize = 0;
3123
36.0k
        U32 dictID = 0;
3124
36.0k
        U64 frameContentSize = 0;
3125
36.0k
        if ((fhdByte & 0x08) != 0)   /* reserved bits, which must be zero */
3126
79
            return ERROR(frameParameter_unsupported);
3127
35.9k
        if (!directMode) {
3128
23.4k
            BYTE const wlByte = ip[pos++];
3129
23.4k
            U32 const windowLog = (wlByte >> 3) + ZSTDv07_WINDOWLOG_ABSOLUTEMIN;
3130
23.4k
            if (windowLog > ZSTDv07_WINDOWLOG_MAX)
3131
53
                return ERROR(frameParameter_unsupported);
3132
23.4k
            windowSize = (1U << windowLog);
3133
23.4k
            windowSize += (windowSize >> 3) * (wlByte&7);
3134
23.4k
        }
3135
3136
35.9k
        switch(dictIDSizeCode)
3137
35.9k
        {
3138
0
            default:   /* impossible */
3139
32.2k
            case 0 : break;
3140
1.84k
            case 1 : dictID = ip[pos]; pos++; break;
3141
740
            case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
3142
1.02k
            case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
3143
35.9k
        }
3144
35.9k
        switch(fcsID)
3145
35.9k
        {
3146
0
            default:   /* impossible */
3147
31.8k
            case 0 : if (directMode) frameContentSize = ip[pos]; break;
3148
1.90k
            case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
3149
1.13k
            case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
3150
1.02k
            case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
3151
35.9k
        }
3152
35.9k
        if (!windowSize) windowSize = (U32)frameContentSize;
3153
35.9k
        if (windowSize > windowSizeMax)
3154
107
            return ERROR(frameParameter_unsupported);
3155
35.7k
        fparamsPtr->frameContentSize = frameContentSize;
3156
35.7k
        fparamsPtr->windowSize = windowSize;
3157
35.7k
        fparamsPtr->dictID = dictID;
3158
35.7k
        fparamsPtr->checksumFlag = checksumFlag;
3159
35.7k
    }
3160
0
    return 0;
3161
35.9k
}
3162
3163
3164
/** ZSTDv07_getDecompressedSize() :
3165
*   compatible with legacy mode
3166
*   @return : decompressed size if known, 0 otherwise
3167
              note : 0 can mean any of the following :
3168
                   - decompressed size is not provided within frame header
3169
                   - frame header unknown / not supported
3170
                   - frame header not completely provided (`srcSize` too small) */
3171
unsigned long long ZSTDv07_getDecompressedSize(const void* src, size_t srcSize)
3172
0
{
3173
0
    ZSTDv07_frameParams fparams;
3174
0
    size_t const frResult = ZSTDv07_getFrameParams(&fparams, src, srcSize);
3175
0
    if (frResult!=0) return 0;
3176
0
    return fparams.frameContentSize;
3177
0
}
3178
3179
3180
/** ZSTDv07_decodeFrameHeader() :
3181
*   `srcSize` must be the size provided by ZSTDv07_frameHeaderSize().
3182
*   @return : 0 if success, or an error code, which can be tested using ZSTDv07_isError() */
3183
static size_t ZSTDv07_decodeFrameHeader(ZSTDv07_DCtx* dctx, const void* src, size_t srcSize)
3184
17.2k
{
3185
17.2k
    size_t const result = ZSTDv07_getFrameParams(&(dctx->fParams), src, srcSize);
3186
17.2k
    if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
3187
16.9k
    if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
3188
16.9k
    return result;
3189
17.2k
}
3190
3191
3192
typedef struct
3193
{
3194
    blockType_t blockType;
3195
    U32 origSize;
3196
} blockProperties_t;
3197
3198
/*! ZSTDv07_getcBlockSize() :
3199
*   Provides the size of compressed block from block header `src` */
3200
static size_t ZSTDv07_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
3201
3.26M
{
3202
3.26M
    const BYTE* const in = (const BYTE*)src;
3203
3.26M
    U32 cSize;
3204
3205
3.26M
    if (srcSize < ZSTDv07_blockHeaderSize) return ERROR(srcSize_wrong);
3206
3207
3.26M
    bpPtr->blockType = (blockType_t)((*in) >> 6);
3208
3.26M
    cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
3209
3.26M
    bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
3210
3211
3.26M
    if (bpPtr->blockType == bt_end) return 0;
3212
3.23M
    if (bpPtr->blockType == bt_rle) return 1;
3213
3.20M
    return cSize;
3214
3.23M
}
3215
3216
3217
static size_t ZSTDv07_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
3218
10.9k
{
3219
10.9k
    if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
3220
10.9k
    if (srcSize > 0) {
3221
4.04k
        memcpy(dst, src, srcSize);
3222
4.04k
    }
3223
10.9k
    return srcSize;
3224
10.9k
}
3225
3226
3227
/*! ZSTDv07_decodeLiteralsBlock() :
3228
    @return : nb of bytes read from src (< srcSize ) */
3229
static size_t ZSTDv07_decodeLiteralsBlock(ZSTDv07_DCtx* dctx,
3230
                          const void* src, size_t srcSize)   /* note : srcSize < BLOCKSIZE */
3231
41.1k
{
3232
41.1k
    const BYTE* const istart = (const BYTE*) src;
3233
3234
41.1k
    if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
3235
3236
41.0k
    switch((litBlockType_t)(istart[0]>> 6))
3237
41.0k
    {
3238
24.1k
    case lbt_huffman:
3239
24.1k
        {   size_t litSize, litCSize, singleStream=0;
3240
24.1k
            U32 lhSize = (istart[0] >> 4) & 3;
3241
24.1k
            if (srcSize < 5) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for lhSize, + cSize (+nbSeq) */
3242
24.1k
            switch(lhSize)
3243
24.1k
            {
3244
21.8k
            case 0: case 1: default:   /* note : default is impossible, since lhSize into [0..3] */
3245
                /* 2 - 2 - 10 - 10 */
3246
21.8k
                lhSize=3;
3247
21.8k
                singleStream = istart[0] & 16;
3248
21.8k
                litSize  = ((istart[0] & 15) << 6) + (istart[1] >> 2);
3249
21.8k
                litCSize = ((istart[1] &  3) << 8) + istart[2];
3250
21.8k
                break;
3251
415
            case 2:
3252
                /* 2 - 2 - 14 - 14 */
3253
415
                lhSize=4;
3254
415
                litSize  = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
3255
415
                litCSize = ((istart[2] & 63) <<  8) + istart[3];
3256
415
                break;
3257
1.90k
            case 3:
3258
                /* 2 - 2 - 18 - 18 */
3259
1.90k
                lhSize=5;
3260
1.90k
                litSize  = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
3261
1.90k
                litCSize = ((istart[2] &  3) << 16) + (istart[3] << 8) + istart[4];
3262
1.90k
                break;
3263
24.1k
            }
3264
24.1k
            if (litSize > ZSTDv07_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
3265
24.1k
            if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
3266
3267
24.0k
            if (HUFv07_isError(singleStream ?
3268
17.3k
                            HUFv07_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
3269
24.0k
                            HUFv07_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
3270
2.02k
                return ERROR(corruption_detected);
3271
3272
22.0k
            dctx->litPtr = dctx->litBuffer;
3273
22.0k
            dctx->litSize = litSize;
3274
22.0k
            dctx->litEntropy = 1;
3275
22.0k
            memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
3276
22.0k
            return litCSize + lhSize;
3277
24.0k
        }
3278
181
    case lbt_repeat:
3279
181
        {   size_t litSize, litCSize;
3280
181
            U32 lhSize = ((istart[0]) >> 4) & 3;
3281
181
            if (lhSize != 1)  /* only case supported for now : small litSize, single stream */
3282
9
                return ERROR(corruption_detected);
3283
172
            if (dctx->litEntropy==0)
3284
3
                return ERROR(dictionary_corrupted);
3285
3286
            /* 2 - 2 - 10 - 10 */
3287
169
            lhSize=3;
3288
169
            litSize  = ((istart[0] & 15) << 6) + (istart[1] >> 2);
3289
169
            litCSize = ((istart[1] &  3) << 8) + istart[2];
3290
169
            if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
3291
3292
163
            {   size_t const errorCode = HUFv07_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable);
3293
163
                if (HUFv07_isError(errorCode)) return ERROR(corruption_detected);
3294
163
            }
3295
88
            dctx->litPtr = dctx->litBuffer;
3296
88
            dctx->litSize = litSize;
3297
88
            memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
3298
88
            return litCSize + lhSize;
3299
163
        }
3300
5.63k
    case lbt_raw:
3301
5.63k
        {   size_t litSize;
3302
5.63k
            U32 lhSize = ((istart[0]) >> 4) & 3;
3303
5.63k
            switch(lhSize)
3304
5.63k
            {
3305
4.05k
            case 0: case 1: default:   /* note : default is impossible, since lhSize into [0..3] */
3306
4.05k
                lhSize=1;
3307
4.05k
                litSize = istart[0] & 31;
3308
4.05k
                break;
3309
943
            case 2:
3310
943
                litSize = ((istart[0] & 15) << 8) + istart[1];
3311
943
                break;
3312
634
            case 3:
3313
634
                litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
3314
634
                break;
3315
5.63k
            }
3316
3317
5.63k
            if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) {  /* risk reading beyond src buffer with wildcopy */
3318
2.76k
                if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
3319
2.65k
                memcpy(dctx->litBuffer, istart+lhSize, litSize);
3320
2.65k
                dctx->litPtr = dctx->litBuffer;
3321
2.65k
                dctx->litSize = litSize;
3322
2.65k
                memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
3323
2.65k
                return lhSize+litSize;
3324
2.76k
            }
3325
            /* direct reference into compressed stream */
3326
2.86k
            dctx->litPtr = istart+lhSize;
3327
2.86k
            dctx->litSize = litSize;
3328
2.86k
            return lhSize+litSize;
3329
5.63k
        }
3330
11.1k
    case lbt_rle:
3331
11.1k
        {   size_t litSize;
3332
11.1k
            U32 lhSize = ((istart[0]) >> 4) & 3;
3333
11.1k
            switch(lhSize)
3334
11.1k
            {
3335
8.25k
            case 0: case 1: default:   /* note : default is impossible, since lhSize into [0..3] */
3336
8.25k
                lhSize = 1;
3337
8.25k
                litSize = istart[0] & 31;
3338
8.25k
                break;
3339
1.78k
            case 2:
3340
1.78k
                litSize = ((istart[0] & 15) << 8) + istart[1];
3341
1.78k
                break;
3342
1.09k
            case 3:
3343
1.09k
                litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
3344
1.09k
                if (srcSize<4) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
3345
1.08k
                break;
3346
11.1k
            }
3347
11.1k
            if (litSize > ZSTDv07_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
3348
11.1k
            memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
3349
11.1k
            dctx->litPtr = dctx->litBuffer;
3350
11.1k
            dctx->litSize = litSize;
3351
11.1k
            return lhSize+1;
3352
11.1k
        }
3353
0
    default:
3354
0
        return ERROR(corruption_detected);   /* impossible */
3355
41.0k
    }
3356
41.0k
}
3357
3358
3359
/*! ZSTDv07_buildSeqTable() :
3360
    @return : nb bytes read from src,
3361
              or an error code if it fails, testable with ZSTDv07_isError()
3362
*/
3363
static size_t ZSTDv07_buildSeqTable(FSEv07_DTable* DTable, U32 type, U32 max, U32 maxLog,
3364
                                 const void* src, size_t srcSize,
3365
                                 const S16* defaultNorm, U32 defaultLog, U32 flagRepeatTable)
3366
35.9k
{
3367
35.9k
    switch(type)
3368
35.9k
    {
3369
9.33k
    case FSEv07_ENCODING_RLE :
3370
9.33k
        if (!srcSize) return ERROR(srcSize_wrong);
3371
9.31k
        if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
3372
9.28k
        FSEv07_buildDTable_rle(DTable, *(const BYTE*)src);   /* if *src > max, data is corrupted */
3373
9.28k
        return 1;
3374
18.7k
    case FSEv07_ENCODING_RAW :
3375
18.7k
        FSEv07_buildDTable(DTable, defaultNorm, max, defaultLog);
3376
18.7k
        return 0;
3377
2.01k
    case FSEv07_ENCODING_STATIC:
3378
2.01k
        if (!flagRepeatTable) return ERROR(corruption_detected);
3379
1.99k
        return 0;
3380
0
    default :   /* impossible */
3381
5.81k
    case FSEv07_ENCODING_DYNAMIC :
3382
5.81k
        {   U32 tableLog;
3383
5.81k
            S16 norm[MaxSeq+1];
3384
5.81k
            size_t const headerSize = FSEv07_readNCount(norm, &max, &tableLog, src, srcSize);
3385
5.81k
            if (FSEv07_isError(headerSize)) return ERROR(corruption_detected);
3386
5.60k
            if (tableLog > maxLog) return ERROR(corruption_detected);
3387
5.58k
            FSEv07_buildDTable(DTable, norm, max, tableLog);
3388
5.58k
            return headerSize;
3389
5.60k
    }   }
3390
35.9k
}
3391
3392
3393
static size_t ZSTDv07_decodeSeqHeaders(int* nbSeqPtr,
3394
                             FSEv07_DTable* DTableLL, FSEv07_DTable* DTableML, FSEv07_DTable* DTableOffb, U32 flagRepeatTable,
3395
                             const void* src, size_t srcSize)
3396
38.7k
{
3397
38.7k
    const BYTE* const istart = (const BYTE*)src;
3398
38.7k
    const BYTE* const iend = istart + srcSize;
3399
38.7k
    const BYTE* ip = istart;
3400
3401
    /* check */
3402
38.7k
    if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
3403
3404
    /* SeqHead */
3405
38.6k
    {   int nbSeq = *ip++;
3406
38.6k
        if (!nbSeq) { *nbSeqPtr=0; return 1; }
3407
12.2k
        if (nbSeq > 0x7F) {
3408
1.78k
            if (nbSeq == 0xFF) {
3409
195
                if (ip+2 > iend) return ERROR(srcSize_wrong);
3410
168
                nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
3411
1.58k
            } else {
3412
1.58k
                if (ip >= iend) return ERROR(srcSize_wrong);
3413
1.55k
                nbSeq = ((nbSeq-0x80)<<8) + *ip++;
3414
1.55k
            }
3415
1.78k
        }
3416
12.1k
        *nbSeqPtr = nbSeq;
3417
12.1k
    }
3418
3419
    /* FSE table descriptors */
3420
12.1k
    if (ip + 4 > iend) return ERROR(srcSize_wrong); /* min : header byte + all 3 are "raw", hence no header, but at least xxLog bits per type */
3421
12.1k
    {   U32 const LLtype  = *ip >> 6;
3422
12.1k
        U32 const OFtype = (*ip >> 4) & 3;
3423
12.1k
        U32 const MLtype  = (*ip >> 2) & 3;
3424
12.1k
        ip++;
3425
3426
        /* Build DTables */
3427
12.1k
        {   size_t const llhSize = ZSTDv07_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
3428
12.1k
            if (ZSTDv07_isError(llhSize)) return ERROR(corruption_detected);
3429
11.9k
            ip += llhSize;
3430
11.9k
        }
3431
11.9k
        {   size_t const ofhSize = ZSTDv07_buildSeqTable(DTableOffb, OFtype, MaxOff, OffFSELog, ip, iend-ip, OF_defaultNorm, OF_defaultNormLog, flagRepeatTable);
3432
11.9k
            if (ZSTDv07_isError(ofhSize)) return ERROR(corruption_detected);
3433
11.8k
            ip += ofhSize;
3434
11.8k
        }
3435
11.8k
        {   size_t const mlhSize = ZSTDv07_buildSeqTable(DTableML, MLtype, MaxML, MLFSELog, ip, iend-ip, ML_defaultNorm, ML_defaultNormLog, flagRepeatTable);
3436
11.8k
            if (ZSTDv07_isError(mlhSize)) return ERROR(corruption_detected);
3437
11.8k
            ip += mlhSize;
3438
11.8k
    }   }
3439
3440
0
    return ip-istart;
3441
11.8k
}
3442
3443
3444
typedef struct {
3445
    size_t litLength;
3446
    size_t matchLength;
3447
    size_t offset;
3448
} seq_t;
3449
3450
typedef struct {
3451
    BITv07_DStream_t DStream;
3452
    FSEv07_DState_t stateLL;
3453
    FSEv07_DState_t stateOffb;
3454
    FSEv07_DState_t stateML;
3455
    size_t prevOffset[ZSTDv07_REP_INIT];
3456
} seqState_t;
3457
3458
3459
static seq_t ZSTDv07_decodeSequence(seqState_t* seqState)
3460
8.82M
{
3461
8.82M
    seq_t seq;
3462
3463
8.82M
    U32 const llCode = FSEv07_peekSymbol(&(seqState->stateLL));
3464
8.82M
    U32 const mlCode = FSEv07_peekSymbol(&(seqState->stateML));
3465
8.82M
    U32 const ofCode = FSEv07_peekSymbol(&(seqState->stateOffb));   /* <= maxOff, by table construction */
3466
3467
8.82M
    U32 const llBits = LL_bits[llCode];
3468
8.82M
    U32 const mlBits = ML_bits[mlCode];
3469
8.82M
    U32 const ofBits = ofCode;
3470
8.82M
    U32 const totalBits = llBits+mlBits+ofBits;
3471
3472
8.82M
    static const U32 LL_base[MaxLL+1] = {
3473
8.82M
                             0,  1,  2,  3,  4,  5,  6,  7,  8,  9,   10,    11,    12,    13,    14,     15,
3474
8.82M
                            16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
3475
8.82M
                            0x2000, 0x4000, 0x8000, 0x10000 };
3476
3477
8.82M
    static const U32 ML_base[MaxML+1] = {
3478
8.82M
                             3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,   14,    15,    16,    17,    18,
3479
8.82M
                            19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,   30,    31,    32,    33,    34,
3480
8.82M
                            35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
3481
8.82M
                            0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
3482
3483
8.82M
    static const U32 OF_base[MaxOff+1] = {
3484
8.82M
                 0,        1,       1,       5,     0xD,     0x1D,     0x3D,     0x7D,
3485
8.82M
                 0xFD,   0x1FD,   0x3FD,   0x7FD,   0xFFD,   0x1FFD,   0x3FFD,   0x7FFD,
3486
8.82M
                 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
3487
8.82M
                 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
3488
3489
    /* sequence */
3490
8.82M
    {   size_t offset;
3491
8.82M
        if (!ofCode)
3492
8.66M
            offset = 0;
3493
157k
        else {
3494
157k
            offset = OF_base[ofCode] + BITv07_readBits(&(seqState->DStream), ofBits);   /* <=  (ZSTDv07_WINDOWLOG_MAX-1) bits */
3495
157k
            if (MEM_32bits()) BITv07_reloadDStream(&(seqState->DStream));
3496
157k
        }
3497
3498
8.82M
        if (ofCode <= 1) {
3499
8.75M
            if ((llCode == 0) & (offset <= 1)) offset = 1-offset;
3500
8.75M
            if (offset) {
3501
1.74M
                size_t const temp = seqState->prevOffset[offset];
3502
1.74M
                if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
3503
1.74M
                seqState->prevOffset[1] = seqState->prevOffset[0];
3504
1.74M
                seqState->prevOffset[0] = offset = temp;
3505
7.01M
            } else {
3506
7.01M
                offset = seqState->prevOffset[0];
3507
7.01M
            }
3508
8.75M
        } else {
3509
66.2k
            seqState->prevOffset[2] = seqState->prevOffset[1];
3510
66.2k
            seqState->prevOffset[1] = seqState->prevOffset[0];
3511
66.2k
            seqState->prevOffset[0] = offset;
3512
66.2k
        }
3513
8.82M
        seq.offset = offset;
3514
8.82M
    }
3515
3516
8.82M
    seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BITv07_readBits(&(seqState->DStream), mlBits) : 0);   /* <=  16 bits */
3517
8.82M
    if (MEM_32bits() && (mlBits+llBits>24)) BITv07_reloadDStream(&(seqState->DStream));
3518
3519
8.82M
    seq.litLength = LL_base[llCode] + ((llCode>15) ? BITv07_readBits(&(seqState->DStream), llBits) : 0);   /* <=  16 bits */
3520
8.82M
    if (MEM_32bits() ||
3521
8.82M
       (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BITv07_reloadDStream(&(seqState->DStream));
3522
3523
    /* ANS state update */
3524
8.82M
    FSEv07_updateState(&(seqState->stateLL), &(seqState->DStream));   /* <=  9 bits */
3525
8.82M
    FSEv07_updateState(&(seqState->stateML), &(seqState->DStream));   /* <=  9 bits */
3526
8.82M
    if (MEM_32bits()) BITv07_reloadDStream(&(seqState->DStream));     /* <= 18 bits */
3527
8.82M
    FSEv07_updateState(&(seqState->stateOffb), &(seqState->DStream)); /* <=  8 bits */
3528
3529
8.82M
    return seq;
3530
8.82M
}
3531
3532
3533
static
3534
size_t ZSTDv07_execSequence(BYTE* op,
3535
                                BYTE* const oend, seq_t sequence,
3536
                                const BYTE** litPtr, const BYTE* const litLimit,
3537
                                const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
3538
8.82M
{
3539
8.82M
    BYTE* const oLitEnd = op + sequence.litLength;
3540
8.82M
    size_t const sequenceLength = sequence.litLength + sequence.matchLength;
3541
8.82M
    BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */
3542
8.82M
    BYTE* const oend_w = oend-WILDCOPY_OVERLENGTH;
3543
8.82M
    const BYTE* const iLitEnd = *litPtr + sequence.litLength;
3544
8.82M
    const BYTE* match = oLitEnd - sequence.offset;
3545
3546
    /* check */
3547
8.82M
    assert(oend >= op);
3548
8.82M
    if (sequence.litLength + WILDCOPY_OVERLENGTH > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
3549
8.82M
    if (sequenceLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
3550
8.82M
    assert(litLimit >= *litPtr);
3551
8.82M
    if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);;
3552
3553
    /* copy Literals */
3554
8.82M
    ZSTDv07_wildcopy(op, *litPtr, (ptrdiff_t)sequence.litLength);   /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
3555
8.82M
    op = oLitEnd;
3556
8.82M
    *litPtr = iLitEnd;   /* update for next sequence */
3557
3558
    /* copy Match */
3559
8.82M
    if (sequence.offset > (size_t)(oLitEnd - base)) {
3560
        /* offset beyond prefix */
3561
2.45k
        if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
3562
2.28k
        match = dictEnd - (base-match);
3563
2.28k
        if (match + sequence.matchLength <= dictEnd) {
3564
1.40k
            memmove(oLitEnd, match, sequence.matchLength);
3565
1.40k
            return sequenceLength;
3566
1.40k
        }
3567
        /* span extDict & currentPrefixSegment */
3568
886
        {   size_t const length1 = (size_t)(dictEnd - match);
3569
886
            memmove(oLitEnd, match, length1);
3570
886
            op = oLitEnd + length1;
3571
886
            sequence.matchLength -= length1;
3572
886
            match = base;
3573
886
            if (op > oend_w || sequence.matchLength < MINMATCH) {
3574
1.56k
              while (op < oMatchEnd) *op++ = *match++;
3575
449
              return sequenceLength;
3576
449
            }
3577
886
    }   }
3578
    /* Requirement: op <= oend_w */
3579
3580
    /* match within prefix */
3581
8.82M
    if (sequence.offset < 8) {
3582
        /* close range match, overlap */
3583
8.57M
        static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };   /* added */
3584
8.57M
        static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 };   /* subtracted */
3585
8.57M
        int const sub2 = dec64table[sequence.offset];
3586
8.57M
        op[0] = match[0];
3587
8.57M
        op[1] = match[1];
3588
8.57M
        op[2] = match[2];
3589
8.57M
        op[3] = match[3];
3590
8.57M
        match += dec32table[sequence.offset];
3591
8.57M
        ZSTDv07_copy4(op+4, match);
3592
8.57M
        match -= sub2;
3593
8.57M
    } else {
3594
250k
        ZSTDv07_copy8(op, match);
3595
250k
    }
3596
8.82M
    op += 8; match += 8;
3597
3598
8.82M
    if (oMatchEnd > oend-(16-MINMATCH)) {
3599
470
        if (op < oend_w) {
3600
320
            ZSTDv07_wildcopy(op, match, oend_w - op);
3601
320
            match += oend_w - op;
3602
320
            op = oend_w;
3603
320
        }
3604
1.84k
        while (op < oMatchEnd) *op++ = *match++;
3605
8.82M
    } else {
3606
8.82M
        ZSTDv07_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8);   /* works even if matchLength < 8 */
3607
8.82M
    }
3608
8.82M
    return sequenceLength;
3609
8.82M
}
3610
3611
3612
static size_t ZSTDv07_decompressSequences(
3613
                               ZSTDv07_DCtx* dctx,
3614
                               void* dst, size_t maxDstSize,
3615
                         const void* seqStart, size_t seqSize)
3616
38.7k
{
3617
38.7k
    const BYTE* ip = (const BYTE*)seqStart;
3618
38.7k
    const BYTE* const iend = ip + seqSize;
3619
38.7k
    BYTE* const ostart = (BYTE*)dst;
3620
38.7k
    BYTE* const oend = ostart + maxDstSize;
3621
38.7k
    BYTE* op = ostart;
3622
38.7k
    const BYTE* litPtr = dctx->litPtr;
3623
38.7k
    const BYTE* const litEnd = litPtr + dctx->litSize;
3624
38.7k
    FSEv07_DTable* DTableLL = dctx->LLTable;
3625
38.7k
    FSEv07_DTable* DTableML = dctx->MLTable;
3626
38.7k
    FSEv07_DTable* DTableOffb = dctx->OffTable;
3627
38.7k
    const BYTE* const base = (const BYTE*) (dctx->base);
3628
38.7k
    const BYTE* const vBase = (const BYTE*) (dctx->vBase);
3629
38.7k
    const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
3630
38.7k
    int nbSeq;
3631
3632
    /* Build Decoding Tables */
3633
38.7k
    {   size_t const seqHSize = ZSTDv07_decodeSeqHeaders(&nbSeq, DTableLL, DTableML, DTableOffb, dctx->fseEntropy, ip, seqSize);
3634
38.7k
        if (ZSTDv07_isError(seqHSize)) return seqHSize;
3635
38.2k
        ip += seqHSize;
3636
38.2k
    }
3637
3638
    /* Regen sequences */
3639
38.2k
    if (nbSeq) {
3640
10.6k
        seqState_t seqState;
3641
10.6k
        dctx->fseEntropy = 1;
3642
42.5k
        { U32 i; for (i=0; i<ZSTDv07_REP_INIT; i++) seqState.prevOffset[i] = dctx->rep[i]; }
3643
10.6k
        { size_t const errorCode = BITv07_initDStream(&(seqState.DStream), ip, iend-ip);
3644
10.6k
          if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
3645
10.5k
        FSEv07_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
3646
10.5k
        FSEv07_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
3647
10.5k
        FSEv07_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
3648
3649
8.83M
        for ( ; (BITv07_reloadDStream(&(seqState.DStream)) <= BITv07_DStream_completed) && nbSeq ; ) {
3650
8.82M
            nbSeq--;
3651
8.82M
            {   seq_t const sequence = ZSTDv07_decodeSequence(&seqState);
3652
8.82M
                size_t const oneSeqSize = ZSTDv07_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
3653
8.82M
                if (ZSTDv07_isError(oneSeqSize)) return oneSeqSize;
3654
8.82M
                op += oneSeqSize;
3655
8.82M
        }   }
3656
3657
        /* check if reached exact end */
3658
9.98k
        if (nbSeq) return ERROR(corruption_detected);
3659
        /* save reps for next block */
3660
39.1k
        { U32 i; for (i=0; i<ZSTDv07_REP_INIT; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
3661
9.78k
    }
3662
3663
    /* last literal segment */
3664
37.3k
    {   size_t const lastLLSize = litEnd - litPtr;
3665
        /* if (litPtr > litEnd) return ERROR(corruption_detected); */   /* too many literals already used */
3666
37.3k
        if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
3667
37.2k
        if (lastLLSize > 0) {
3668
21.5k
            memcpy(op, litPtr, lastLLSize);
3669
21.5k
            op += lastLLSize;
3670
21.5k
        }
3671
37.2k
    }
3672
3673
0
    return op-ostart;
3674
37.3k
}
3675
3676
3677
static void ZSTDv07_checkContinuity(ZSTDv07_DCtx* dctx, const void* dst)
3678
47.1k
{
3679
47.1k
    if (dst != dctx->previousDstEnd) {   /* not contiguous */
3680
18.7k
        dctx->dictEnd = dctx->previousDstEnd;
3681
18.7k
        dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
3682
18.7k
        dctx->base = dst;
3683
18.7k
        dctx->previousDstEnd = dst;
3684
18.7k
    }
3685
47.1k
}
3686
3687
3688
static size_t ZSTDv07_decompressBlock_internal(ZSTDv07_DCtx* dctx,
3689
                            void* dst, size_t dstCapacity,
3690
                      const void* src, size_t srcSize)
3691
41.1k
{   /* blockType == blockCompressed */
3692
41.1k
    const BYTE* ip = (const BYTE*)src;
3693
3694
41.1k
    if (srcSize >= ZSTDv07_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
3695
3696
    /* Decode literals sub-block */
3697
41.1k
    {   size_t const litCSize = ZSTDv07_decodeLiteralsBlock(dctx, src, srcSize);
3698
41.1k
        if (ZSTDv07_isError(litCSize)) return litCSize;
3699
38.7k
        ip += litCSize;
3700
38.7k
        srcSize -= litCSize;
3701
38.7k
    }
3702
0
    return ZSTDv07_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
3703
41.1k
}
3704
3705
3706
size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx,
3707
                            void* dst, size_t dstCapacity,
3708
                      const void* src, size_t srcSize)
3709
0
{
3710
0
    size_t dSize;
3711
0
    ZSTDv07_checkContinuity(dctx, dst);
3712
0
    dSize = ZSTDv07_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
3713
0
    dctx->previousDstEnd = (char*)dst + dSize;
3714
0
    return dSize;
3715
0
}
3716
3717
3718
/** ZSTDv07_insertBlock() :
3719
    insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
3720
ZSTDLIBv07_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize)
3721
0
{
3722
0
    ZSTDv07_checkContinuity(dctx, blockStart);
3723
0
    dctx->previousDstEnd = (const char*)blockStart + blockSize;
3724
0
    return blockSize;
3725
0
}
3726
3727
3728
static size_t ZSTDv07_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
3729
2.45k
{
3730
2.45k
    if (length > dstCapacity) return ERROR(dstSize_tooSmall);
3731
2.37k
    if (length > 0) {
3732
2.02k
        memset(dst, byte, length);
3733
2.02k
    }
3734
2.37k
    return length;
3735
2.45k
}
3736
3737
3738
/*! ZSTDv07_decompressFrame() :
3739
*   `dctx` must be properly initialized */
3740
static size_t ZSTDv07_decompressFrame(ZSTDv07_DCtx* dctx,
3741
                                 void* dst, size_t dstCapacity,
3742
                                 const void* src, size_t srcSize)
3743
12.2k
{
3744
12.2k
    const BYTE* ip = (const BYTE*)src;
3745
12.2k
    const BYTE* const iend = ip + srcSize;
3746
12.2k
    BYTE* const ostart = (BYTE*)dst;
3747
12.2k
    BYTE* const oend = ostart + dstCapacity;
3748
12.2k
    BYTE* op = ostart;
3749
12.2k
    size_t remainingSize = srcSize;
3750
3751
    /* check */
3752
12.2k
    if (srcSize < ZSTDv07_frameHeaderSize_min+ZSTDv07_blockHeaderSize) return ERROR(srcSize_wrong);
3753
3754
    /* Frame Header */
3755
12.2k
    {   size_t const frameHeaderSize = ZSTDv07_frameHeaderSize(src, ZSTDv07_frameHeaderSize_min);
3756
12.2k
        if (ZSTDv07_isError(frameHeaderSize)) return frameHeaderSize;
3757
12.2k
        if (srcSize < frameHeaderSize+ZSTDv07_blockHeaderSize) return ERROR(srcSize_wrong);
3758
12.2k
        if (ZSTDv07_decodeFrameHeader(dctx, src, frameHeaderSize)) return ERROR(corruption_detected);
3759
12.0k
        ip += frameHeaderSize; remainingSize -= frameHeaderSize;
3760
12.0k
    }
3761
3762
    /* Loop on each block */
3763
47.9k
    while (1) {
3764
47.9k
        size_t decodedSize;
3765
47.9k
        blockProperties_t blockProperties;
3766
47.9k
        size_t const cBlockSize = ZSTDv07_getcBlockSize(ip, iend-ip, &blockProperties);
3767
47.9k
        if (ZSTDv07_isError(cBlockSize)) return cBlockSize;
3768
3769
47.9k
        ip += ZSTDv07_blockHeaderSize;
3770
47.9k
        remainingSize -= ZSTDv07_blockHeaderSize;
3771
47.9k
        if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
3772
3773
47.9k
        switch(blockProperties.blockType)
3774
47.9k
        {
3775
26.8k
        case bt_compressed:
3776
26.8k
            decodedSize = ZSTDv07_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
3777
26.8k
            break;
3778
9.36k
        case bt_raw :
3779
9.36k
            decodedSize = ZSTDv07_copyRawBlock(op, oend-op, ip, cBlockSize);
3780
9.36k
            break;
3781
2.45k
        case bt_rle :
3782
2.45k
            decodedSize = ZSTDv07_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
3783
2.45k
            break;
3784
9.29k
        case bt_end :
3785
            /* end of frame */
3786
9.29k
            if (remainingSize) return ERROR(srcSize_wrong);
3787
9.29k
            decodedSize = 0;
3788
9.29k
            break;
3789
0
        default:
3790
0
            return ERROR(GENERIC);   /* impossible */
3791
47.9k
        }
3792
47.9k
        if (blockProperties.blockType == bt_end) break;   /* bt_end */
3793
3794
38.7k
        if (ZSTDv07_isError(decodedSize)) return decodedSize;
3795
35.9k
        if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
3796
35.9k
        op += decodedSize;
3797
35.9k
        ip += cBlockSize;
3798
35.9k
        remainingSize -= cBlockSize;
3799
35.9k
    }
3800
3801
9.29k
    return op-ostart;
3802
12.0k
}
3803
3804
3805
/*! ZSTDv07_decompress_usingPreparedDCtx() :
3806
*   Same as ZSTDv07_decompress_usingDict, but using a reference context `preparedDCtx`, where dictionary has been loaded.
3807
*   It avoids reloading the dictionary each time.
3808
*   `preparedDCtx` must have been properly initialized using ZSTDv07_decompressBegin_usingDict().
3809
*   Requires 2 contexts : 1 for reference (preparedDCtx), which will not be modified, and 1 to run the decompression operation (dctx) */
3810
static size_t ZSTDv07_decompress_usingPreparedDCtx(ZSTDv07_DCtx* dctx, const ZSTDv07_DCtx* refDCtx,
3811
                                         void* dst, size_t dstCapacity,
3812
                                   const void* src, size_t srcSize)
3813
0
{
3814
0
    ZSTDv07_copyDCtx(dctx, refDCtx);
3815
0
    ZSTDv07_checkContinuity(dctx, dst);
3816
0
    return ZSTDv07_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
3817
0
}
3818
3819
3820
size_t ZSTDv07_decompress_usingDict(ZSTDv07_DCtx* dctx,
3821
                                 void* dst, size_t dstCapacity,
3822
                                 const void* src, size_t srcSize,
3823
                                 const void* dict, size_t dictSize)
3824
12.2k
{
3825
12.2k
    ZSTDv07_decompressBegin_usingDict(dctx, dict, dictSize);
3826
12.2k
    ZSTDv07_checkContinuity(dctx, dst);
3827
12.2k
    return ZSTDv07_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
3828
12.2k
}
3829
3830
3831
size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
3832
0
{
3833
0
    return ZSTDv07_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
3834
0
}
3835
3836
3837
size_t ZSTDv07_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
3838
0
{
3839
0
#if defined(ZSTDv07_HEAPMODE) && (ZSTDv07_HEAPMODE==1)
3840
0
    size_t regenSize;
3841
0
    ZSTDv07_DCtx* const dctx = ZSTDv07_createDCtx();
3842
0
    if (dctx==NULL) return ERROR(memory_allocation);
3843
0
    regenSize = ZSTDv07_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
3844
0
    ZSTDv07_freeDCtx(dctx);
3845
0
    return regenSize;
3846
#else   /* stack mode */
3847
    ZSTDv07_DCtx dctx;
3848
    return ZSTDv07_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
3849
#endif
3850
0
}
3851
3852
/* ZSTD_errorFrameSizeInfoLegacy() :
3853
   assumes `cSize` and `dBound` are _not_ NULL */
3854
static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret)
3855
1.00k
{
3856
1.00k
    *cSize = ret;
3857
1.00k
    *dBound = ZSTD_CONTENTSIZE_ERROR;
3858
1.00k
}
3859
3860
void ZSTDv07_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound)
3861
20.2k
{
3862
20.2k
    const BYTE* ip = (const BYTE*)src;
3863
20.2k
    size_t remainingSize = srcSize;
3864
20.2k
    size_t nbBlocks = 0;
3865
3866
    /* check */
3867
20.2k
    if (srcSize < ZSTDv07_frameHeaderSize_min+ZSTDv07_blockHeaderSize) {
3868
238
        ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3869
238
        return;
3870
238
    }
3871
3872
    /* Frame Header */
3873
19.9k
    {   size_t const frameHeaderSize = ZSTDv07_frameHeaderSize(src, srcSize);
3874
19.9k
        if (ZSTDv07_isError(frameHeaderSize)) {
3875
0
            ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, frameHeaderSize);
3876
0
            return;
3877
0
        }
3878
19.9k
        if (MEM_readLE32(src) != ZSTDv07_MAGICNUMBER) {
3879
0
            ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown));
3880
0
            return;
3881
0
        }
3882
19.9k
        if (srcSize < frameHeaderSize+ZSTDv07_blockHeaderSize) {
3883
269
            ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3884
269
            return;
3885
269
        }
3886
19.6k
        ip += frameHeaderSize; remainingSize -= frameHeaderSize;
3887
19.6k
    }
3888
3889
    /* Loop on each block */
3890
3.19M
    while (1) {
3891
3.19M
        blockProperties_t blockProperties;
3892
3.19M
        size_t const cBlockSize = ZSTDv07_getcBlockSize(ip, remainingSize, &blockProperties);
3893
3.19M
        if (ZSTDv07_isError(cBlockSize)) {
3894
43
            ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, cBlockSize);
3895
43
            return;
3896
43
        }
3897
3898
3.19M
        ip += ZSTDv07_blockHeaderSize;
3899
3.19M
        remainingSize -= ZSTDv07_blockHeaderSize;
3900
3901
3.19M
        if (blockProperties.blockType == bt_end) break;
3902
3903
3.17M
        if (cBlockSize > remainingSize) {
3904
453
            ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3905
453
            return;
3906
453
        }
3907
3908
3.17M
        ip += cBlockSize;
3909
3.17M
        remainingSize -= cBlockSize;
3910
3.17M
        nbBlocks++;
3911
3.17M
    }
3912
3913
19.1k
    *cSize = ip - (const BYTE*)src;
3914
19.1k
    *dBound = nbBlocks * ZSTDv07_BLOCKSIZE_ABSOLUTEMAX;
3915
19.1k
}
3916
3917
/*_******************************
3918
*  Streaming Decompression API
3919
********************************/
3920
size_t ZSTDv07_nextSrcSizeToDecompress(ZSTDv07_DCtx* dctx)
3921
60.9k
{
3922
60.9k
    return dctx->expected;
3923
60.9k
}
3924
3925
int ZSTDv07_isSkipFrame(ZSTDv07_DCtx* dctx)
3926
34.8k
{
3927
34.8k
    return dctx->stage == ZSTDds_skipFrame;
3928
34.8k
}
3929
3930
/** ZSTDv07_decompressContinue() :
3931
*   @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
3932
*             or an error code, which can be tested using ZSTDv07_isError() */
3933
size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
3934
44.7k
{
3935
    /* Sanity check */
3936
44.7k
    if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
3937
44.7k
    if (dstCapacity) ZSTDv07_checkContinuity(dctx, dst);
3938
3939
44.7k
    switch (dctx->stage)
3940
44.7k
    {
3941
4.92k
    case ZSTDds_getFrameHeaderSize :
3942
4.92k
        if (srcSize != ZSTDv07_frameHeaderSize_min) return ERROR(srcSize_wrong);   /* impossible */
3943
4.92k
        if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTDv07_MAGIC_SKIPPABLE_START) {
3944
0
            memcpy(dctx->headerBuffer, src, ZSTDv07_frameHeaderSize_min);
3945
0
            dctx->expected = ZSTDv07_skippableHeaderSize - ZSTDv07_frameHeaderSize_min; /* magic number + skippable frame length */
3946
0
            dctx->stage = ZSTDds_decodeSkippableHeader;
3947
0
            return 0;
3948
0
        }
3949
4.92k
        dctx->headerSize = ZSTDv07_frameHeaderSize(src, ZSTDv07_frameHeaderSize_min);
3950
4.92k
        if (ZSTDv07_isError(dctx->headerSize)) return dctx->headerSize;
3951
4.92k
        memcpy(dctx->headerBuffer, src, ZSTDv07_frameHeaderSize_min);
3952
4.92k
        if (dctx->headerSize > ZSTDv07_frameHeaderSize_min) {
3953
4.92k
            dctx->expected = dctx->headerSize - ZSTDv07_frameHeaderSize_min;
3954
4.92k
            dctx->stage = ZSTDds_decodeFrameHeader;
3955
4.92k
            return 0;
3956
4.92k
        }
3957
0
        dctx->expected = 0;   /* not necessary to copy more */
3958
  /* fall-through */
3959
4.92k
    case ZSTDds_decodeFrameHeader:
3960
4.92k
        {   size_t result;
3961
4.92k
            memcpy(dctx->headerBuffer + ZSTDv07_frameHeaderSize_min, src, dctx->expected);
3962
4.92k
            result = ZSTDv07_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
3963
4.92k
            if (ZSTDv07_isError(result)) return result;
3964
4.86k
            dctx->expected = ZSTDv07_blockHeaderSize;
3965
4.86k
            dctx->stage = ZSTDds_decodeBlockHeader;
3966
4.86k
            return 0;
3967
4.92k
        }
3968
18.9k
    case ZSTDds_decodeBlockHeader:
3969
18.9k
        {   blockProperties_t bp;
3970
18.9k
            size_t const cBlockSize = ZSTDv07_getcBlockSize(src, ZSTDv07_blockHeaderSize, &bp);
3971
18.9k
            if (ZSTDv07_isError(cBlockSize)) return cBlockSize;
3972
18.9k
            if (bp.blockType == bt_end) {
3973
1.48k
                if (dctx->fParams.checksumFlag) {
3974
438
                    U64 const h64 = XXH64_digest(&dctx->xxhState);
3975
438
                    U32 const h32 = (U32)(h64>>11) & ((1<<22)-1);
3976
438
                    const BYTE* const ip = (const BYTE*)src;
3977
438
                    U32 const check32 = ip[2] + (ip[1] << 8) + ((ip[0] & 0x3F) << 16);
3978
438
                    if (check32 != h32) return ERROR(checksum_wrong);
3979
438
                }
3980
1.44k
                dctx->expected = 0;
3981
1.44k
                dctx->stage = ZSTDds_getFrameHeaderSize;
3982
17.4k
            } else {
3983
17.4k
                dctx->expected = cBlockSize;
3984
17.4k
                dctx->bType = bp.blockType;
3985
17.4k
                dctx->stage = ZSTDds_decompressBlock;
3986
17.4k
            }
3987
18.9k
            return 0;
3988
18.9k
        }
3989
15.9k
    case ZSTDds_decompressBlock:
3990
15.9k
        {   size_t rSize;
3991
15.9k
            switch(dctx->bType)
3992
15.9k
            {
3993
14.2k
            case bt_compressed:
3994
14.2k
                rSize = ZSTDv07_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
3995
14.2k
                break;
3996
1.63k
            case bt_raw :
3997
1.63k
                rSize = ZSTDv07_copyRawBlock(dst, dstCapacity, src, srcSize);
3998
1.63k
                break;
3999
7
            case bt_rle :
4000
7
                return ERROR(GENERIC);   /* not yet handled */
4001
0
                break;
4002
0
            case bt_end :   /* should never happen (filtered at phase 1) */
4003
0
                rSize = 0;
4004
0
                break;
4005
0
            default:
4006
0
                return ERROR(GENERIC);   /* impossible */
4007
15.9k
            }
4008
15.9k
            dctx->stage = ZSTDds_decodeBlockHeader;
4009
15.9k
            dctx->expected = ZSTDv07_blockHeaderSize;
4010
15.9k
            if (ZSTDv07_isError(rSize)) return rSize;
4011
14.5k
            dctx->previousDstEnd = (char*)dst + rSize;
4012
14.5k
            if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
4013
14.5k
            return rSize;
4014
15.9k
        }
4015
0
    case ZSTDds_decodeSkippableHeader:
4016
0
        {   memcpy(dctx->headerBuffer + ZSTDv07_frameHeaderSize_min, src, dctx->expected);
4017
0
            dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
4018
0
            dctx->stage = ZSTDds_skipFrame;
4019
0
            return 0;
4020
15.9k
        }
4021
0
    case ZSTDds_skipFrame:
4022
0
        {   dctx->expected = 0;
4023
0
            dctx->stage = ZSTDds_getFrameHeaderSize;
4024
0
            return 0;
4025
15.9k
        }
4026
0
    default:
4027
0
        return ERROR(GENERIC);   /* impossible */
4028
44.7k
    }
4029
44.7k
}
4030
4031
4032
static size_t ZSTDv07_refDictContent(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize)
4033
8.30k
{
4034
8.30k
    dctx->dictEnd = dctx->previousDstEnd;
4035
8.30k
    dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
4036
8.30k
    dctx->base = dict;
4037
8.30k
    dctx->previousDstEnd = (const char*)dict + dictSize;
4038
8.30k
    return 0;
4039
8.30k
}
4040
4041
static size_t ZSTDv07_loadEntropy(ZSTDv07_DCtx* dctx, const void* const dict, size_t const dictSize)
4042
8.30k
{
4043
8.30k
    const BYTE* dictPtr = (const BYTE*)dict;
4044
8.30k
    const BYTE* const dictEnd = dictPtr + dictSize;
4045
4046
8.30k
    {   size_t const hSize = HUFv07_readDTableX4(dctx->hufTable, dict, dictSize);
4047
8.30k
        if (HUFv07_isError(hSize)) return ERROR(dictionary_corrupted);
4048
8.30k
        dictPtr += hSize;
4049
8.30k
    }
4050
4051
0
    {   short offcodeNCount[MaxOff+1];
4052
8.30k
        U32 offcodeMaxValue=MaxOff, offcodeLog;
4053
8.30k
        size_t const offcodeHeaderSize = FSEv07_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
4054
8.30k
        if (FSEv07_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
4055
8.30k
        if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
4056
8.30k
        { size_t const errorCode = FSEv07_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
4057
8.30k
          if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
4058
8.30k
        dictPtr += offcodeHeaderSize;
4059
8.30k
    }
4060
4061
0
    {   short matchlengthNCount[MaxML+1];
4062
8.30k
        unsigned matchlengthMaxValue = MaxML, matchlengthLog;
4063
8.30k
        size_t const matchlengthHeaderSize = FSEv07_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
4064
8.30k
        if (FSEv07_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
4065
8.30k
        if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
4066
8.30k
        { size_t const errorCode = FSEv07_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
4067
8.30k
          if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
4068
8.30k
        dictPtr += matchlengthHeaderSize;
4069
8.30k
    }
4070
4071
0
    {   short litlengthNCount[MaxLL+1];
4072
8.30k
        unsigned litlengthMaxValue = MaxLL, litlengthLog;
4073
8.30k
        size_t const litlengthHeaderSize = FSEv07_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
4074
8.30k
        if (FSEv07_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
4075
8.30k
        if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
4076
8.30k
        { size_t const errorCode = FSEv07_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
4077
8.30k
          if (FSEv07_isError(errorCode)) return ERROR(dictionary_corrupted); }
4078
8.30k
        dictPtr += litlengthHeaderSize;
4079
8.30k
    }
4080
4081
8.30k
    if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
4082
8.30k
    dctx->rep[0] = MEM_readLE32(dictPtr+0); if (dctx->rep[0] == 0 || dctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
4083
8.30k
    dctx->rep[1] = MEM_readLE32(dictPtr+4); if (dctx->rep[1] == 0 || dctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
4084
8.30k
    dctx->rep[2] = MEM_readLE32(dictPtr+8); if (dctx->rep[2] == 0 || dctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
4085
8.30k
    dictPtr += 12;
4086
4087
8.30k
    dctx->litEntropy = dctx->fseEntropy = 1;
4088
8.30k
    return dictPtr - (const BYTE*)dict;
4089
8.30k
}
4090
4091
static size_t ZSTDv07_decompress_insertDictionary(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize)
4092
8.30k
{
4093
8.30k
    if (dictSize < 8) return ZSTDv07_refDictContent(dctx, dict, dictSize);
4094
8.30k
    {   U32 const magic = MEM_readLE32(dict);
4095
8.30k
        if (magic != ZSTDv07_DICT_MAGIC) {
4096
0
            return ZSTDv07_refDictContent(dctx, dict, dictSize);   /* pure content mode */
4097
0
    }   }
4098
8.30k
    dctx->dictID = MEM_readLE32((const char*)dict + 4);
4099
4100
    /* load entropy tables */
4101
8.30k
    dict = (const char*)dict + 8;
4102
8.30k
    dictSize -= 8;
4103
8.30k
    {   size_t const eSize = ZSTDv07_loadEntropy(dctx, dict, dictSize);
4104
8.30k
        if (ZSTDv07_isError(eSize)) return ERROR(dictionary_corrupted);
4105
8.30k
        dict = (const char*)dict + eSize;
4106
8.30k
        dictSize -= eSize;
4107
8.30k
    }
4108
4109
    /* reference dictionary content */
4110
0
    return ZSTDv07_refDictContent(dctx, dict, dictSize);
4111
8.30k
}
4112
4113
4114
size_t ZSTDv07_decompressBegin_usingDict(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize)
4115
17.2k
{
4116
17.2k
    { size_t const errorCode = ZSTDv07_decompressBegin(dctx);
4117
17.2k
      if (ZSTDv07_isError(errorCode)) return errorCode; }
4118
4119
17.2k
    if (dict && dictSize) {
4120
8.30k
        size_t const errorCode = ZSTDv07_decompress_insertDictionary(dctx, dict, dictSize);
4121
8.30k
        if (ZSTDv07_isError(errorCode)) return ERROR(dictionary_corrupted);
4122
8.30k
    }
4123
4124
17.2k
    return 0;
4125
17.2k
}
4126
4127
4128
struct ZSTDv07_DDict_s {
4129
    void* dict;
4130
    size_t dictSize;
4131
    ZSTDv07_DCtx* refContext;
4132
};  /* typedef'd tp ZSTDv07_CDict within zstd.h */
4133
4134
static ZSTDv07_DDict* ZSTDv07_createDDict_advanced(const void* dict, size_t dictSize, ZSTDv07_customMem customMem)
4135
0
{
4136
0
    if (!customMem.customAlloc && !customMem.customFree)
4137
0
        customMem = defaultCustomMem;
4138
4139
0
    if (!customMem.customAlloc || !customMem.customFree)
4140
0
        return NULL;
4141
4142
0
    {   ZSTDv07_DDict* const ddict = (ZSTDv07_DDict*) customMem.customAlloc(customMem.opaque, sizeof(*ddict));
4143
0
        void* const dictContent = customMem.customAlloc(customMem.opaque, dictSize);
4144
0
        ZSTDv07_DCtx* const dctx = ZSTDv07_createDCtx_advanced(customMem);
4145
4146
0
        if (!dictContent || !ddict || !dctx) {
4147
0
            customMem.customFree(customMem.opaque, dictContent);
4148
0
            customMem.customFree(customMem.opaque, ddict);
4149
0
            customMem.customFree(customMem.opaque, dctx);
4150
0
            return NULL;
4151
0
        }
4152
4153
0
        memcpy(dictContent, dict, dictSize);
4154
0
        {   size_t const errorCode = ZSTDv07_decompressBegin_usingDict(dctx, dictContent, dictSize);
4155
0
            if (ZSTDv07_isError(errorCode)) {
4156
0
                customMem.customFree(customMem.opaque, dictContent);
4157
0
                customMem.customFree(customMem.opaque, ddict);
4158
0
                customMem.customFree(customMem.opaque, dctx);
4159
0
                return NULL;
4160
0
        }   }
4161
4162
0
        ddict->dict = dictContent;
4163
0
        ddict->dictSize = dictSize;
4164
0
        ddict->refContext = dctx;
4165
0
        return ddict;
4166
0
    }
4167
0
}
4168
4169
/*! ZSTDv07_createDDict() :
4170
*   Create a digested dictionary, ready to start decompression without startup delay.
4171
*   `dict` can be released after `ZSTDv07_DDict` creation */
4172
ZSTDv07_DDict* ZSTDv07_createDDict(const void* dict, size_t dictSize)
4173
0
{
4174
0
    ZSTDv07_customMem const allocator = { NULL, NULL, NULL };
4175
0
    return ZSTDv07_createDDict_advanced(dict, dictSize, allocator);
4176
0
}
4177
4178
size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict)
4179
0
{
4180
0
    ZSTDv07_freeFunction const cFree = ddict->refContext->customMem.customFree;
4181
0
    void* const opaque = ddict->refContext->customMem.opaque;
4182
0
    ZSTDv07_freeDCtx(ddict->refContext);
4183
0
    cFree(opaque, ddict->dict);
4184
0
    cFree(opaque, ddict);
4185
0
    return 0;
4186
0
}
4187
4188
/*! ZSTDv07_decompress_usingDDict() :
4189
*   Decompression using a pre-digested Dictionary
4190
*   Use dictionary without significant overhead. */
4191
ZSTDLIBv07_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx,
4192
                                           void* dst, size_t dstCapacity,
4193
                                     const void* src, size_t srcSize,
4194
                                     const ZSTDv07_DDict* ddict)
4195
0
{
4196
0
    return ZSTDv07_decompress_usingPreparedDCtx(dctx, ddict->refContext,
4197
0
                                           dst, dstCapacity,
4198
0
                                           src, srcSize);
4199
0
}
4200
/*
4201
    Buffered version of Zstd compression library
4202
    Copyright (C) 2015-2016, Yann Collet.
4203
4204
    BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
4205
4206
    Redistribution and use in source and binary forms, with or without
4207
    modification, are permitted provided that the following conditions are
4208
    met:
4209
    * Redistributions of source code must retain the above copyright
4210
    notice, this list of conditions and the following disclaimer.
4211
    * Redistributions in binary form must reproduce the above
4212
    copyright notice, this list of conditions and the following disclaimer
4213
    in the documentation and/or other materials provided with the
4214
    distribution.
4215
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4216
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
4217
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
4218
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
4219
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4220
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4221
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
4222
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
4223
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4224
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
4225
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4226
4227
    You can contact the author at :
4228
    - zstd homepage : https://facebook.github.io/zstd/
4229
*/
4230
4231
4232
4233
/*-***************************************************************************
4234
*  Streaming decompression howto
4235
*
4236
*  A ZBUFFv07_DCtx object is required to track streaming operations.
4237
*  Use ZBUFFv07_createDCtx() and ZBUFFv07_freeDCtx() to create/release resources.
4238
*  Use ZBUFFv07_decompressInit() to start a new decompression operation,
4239
*   or ZBUFFv07_decompressInitDictionary() if decompression requires a dictionary.
4240
*  Note that ZBUFFv07_DCtx objects can be re-init multiple times.
4241
*
4242
*  Use ZBUFFv07_decompressContinue() repetitively to consume your input.
4243
*  *srcSizePtr and *dstCapacityPtr can be any size.
4244
*  The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr.
4245
*  Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again.
4246
*  The content of @dst will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters, or change @dst.
4247
*  @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to help latency),
4248
*            or 0 when a frame is completely decoded,
4249
*            or an error code, which can be tested using ZBUFFv07_isError().
4250
*
4251
*  Hint : recommended buffer sizes (not compulsory) : ZBUFFv07_recommendedDInSize() and ZBUFFv07_recommendedDOutSize()
4252
*  output : ZBUFFv07_recommendedDOutSize==128 KB block size is the internal unit, it ensures it's always possible to write a full block when decoded.
4253
*  input  : ZBUFFv07_recommendedDInSize == 128KB + 3;
4254
*           just follow indications from ZBUFFv07_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 .
4255
* *******************************************************************************/
4256
4257
typedef enum { ZBUFFds_init, ZBUFFds_loadHeader,
4258
               ZBUFFds_read, ZBUFFds_load, ZBUFFds_flush } ZBUFFv07_dStage;
4259
4260
/* *** Resource management *** */
4261
struct ZBUFFv07_DCtx_s {
4262
    ZSTDv07_DCtx* zd;
4263
    ZSTDv07_frameParams fParams;
4264
    ZBUFFv07_dStage stage;
4265
    char*  inBuff;
4266
    size_t inBuffSize;
4267
    size_t inPos;
4268
    char*  outBuff;
4269
    size_t outBuffSize;
4270
    size_t outStart;
4271
    size_t outEnd;
4272
    size_t blockSize;
4273
    BYTE headerBuffer[ZSTDv07_FRAMEHEADERSIZE_MAX];
4274
    size_t lhSize;
4275
    ZSTDv07_customMem customMem;
4276
};   /* typedef'd to ZBUFFv07_DCtx within "zstd_buffered.h" */
4277
4278
ZSTDLIBv07_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx_advanced(ZSTDv07_customMem customMem);
4279
4280
ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void)
4281
3.00k
{
4282
3.00k
    return ZBUFFv07_createDCtx_advanced(defaultCustomMem);
4283
3.00k
}
4284
4285
ZBUFFv07_DCtx* ZBUFFv07_createDCtx_advanced(ZSTDv07_customMem customMem)
4286
3.00k
{
4287
3.00k
    ZBUFFv07_DCtx* zbd;
4288
4289
3.00k
    if (!customMem.customAlloc && !customMem.customFree)
4290
0
        customMem = defaultCustomMem;
4291
4292
3.00k
    if (!customMem.customAlloc || !customMem.customFree)
4293
0
        return NULL;
4294
4295
3.00k
    zbd = (ZBUFFv07_DCtx*)customMem.customAlloc(customMem.opaque, sizeof(ZBUFFv07_DCtx));
4296
3.00k
    if (zbd==NULL) return NULL;
4297
3.00k
    memset(zbd, 0, sizeof(ZBUFFv07_DCtx));
4298
3.00k
    memcpy(&zbd->customMem, &customMem, sizeof(ZSTDv07_customMem));
4299
3.00k
    zbd->zd = ZSTDv07_createDCtx_advanced(customMem);
4300
3.00k
    if (zbd->zd == NULL) { ZBUFFv07_freeDCtx(zbd); return NULL; }
4301
3.00k
    zbd->stage = ZBUFFds_init;
4302
3.00k
    return zbd;
4303
3.00k
}
4304
4305
size_t ZBUFFv07_freeDCtx(ZBUFFv07_DCtx* zbd)
4306
3.00k
{
4307
3.00k
    if (zbd==NULL) return 0;   /* support free on null */
4308
3.00k
    ZSTDv07_freeDCtx(zbd->zd);
4309
3.00k
    if (zbd->inBuff) zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff);
4310
3.00k
    if (zbd->outBuff) zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff);
4311
3.00k
    zbd->customMem.customFree(zbd->customMem.opaque, zbd);
4312
3.00k
    return 0;
4313
3.00k
}
4314
4315
4316
/* *** Initialization *** */
4317
4318
size_t ZBUFFv07_decompressInitDictionary(ZBUFFv07_DCtx* zbd, const void* dict, size_t dictSize)
4319
5.00k
{
4320
5.00k
    zbd->stage = ZBUFFds_loadHeader;
4321
5.00k
    zbd->lhSize = zbd->inPos = zbd->outStart = zbd->outEnd = 0;
4322
5.00k
    return ZSTDv07_decompressBegin_usingDict(zbd->zd, dict, dictSize);
4323
5.00k
}
4324
4325
size_t ZBUFFv07_decompressInit(ZBUFFv07_DCtx* zbd)
4326
0
{
4327
0
    return ZBUFFv07_decompressInitDictionary(zbd, NULL, 0);
4328
0
}
4329
4330
4331
/* internal util function */
4332
MEM_STATIC size_t ZBUFFv07_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
4333
17.9k
{
4334
17.9k
    size_t const length = MIN(dstCapacity, srcSize);
4335
17.9k
    if (length > 0) {
4336
16.9k
        memcpy(dst, src, length);
4337
16.9k
    }
4338
17.9k
    return length;
4339
17.9k
}
4340
4341
4342
/* *** Decompression *** */
4343
4344
size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd,
4345
                                void* dst, size_t* dstCapacityPtr,
4346
                          const void* src, size_t* srcSizePtr)
4347
12.8k
{
4348
12.8k
    const char* const istart = (const char*)src;
4349
12.8k
    const char* const iend = istart + *srcSizePtr;
4350
12.8k
    const char* ip = istart;
4351
12.8k
    char* const ostart = (char*)dst;
4352
12.8k
    char* const oend = ostart + *dstCapacityPtr;
4353
12.8k
    char* op = ostart;
4354
12.8k
    U32 notDone = 1;
4355
4356
77.3k
    while (notDone) {
4357
66.7k
        switch(zbd->stage)
4358
66.7k
        {
4359
0
        case ZBUFFds_init :
4360
0
            return ERROR(init_missing);
4361
4362
15.6k
        case ZBUFFds_loadHeader :
4363
15.6k
            {   size_t const hSize = ZSTDv07_getFrameParams(&(zbd->fParams), zbd->headerBuffer, zbd->lhSize);
4364
15.6k
                if (ZSTDv07_isError(hSize)) return hSize;
4365
15.6k
                if (hSize != 0) {
4366
10.7k
                    size_t const toLoad = hSize - zbd->lhSize;   /* if hSize!=0, hSize > zbd->lhSize */
4367
10.7k
                    if (toLoad > (size_t)(iend-ip)) {   /* not enough input to load full header */
4368
781
                        if (ip != NULL)
4369
781
                            memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
4370
781
                        zbd->lhSize += iend-ip;
4371
781
                        *dstCapacityPtr = 0;
4372
781
                        return (hSize - zbd->lhSize) + ZSTDv07_blockHeaderSize;   /* remaining header bytes + next block header */
4373
781
                    }
4374
9.95k
                    memcpy(zbd->headerBuffer + zbd->lhSize, ip, toLoad); zbd->lhSize = hSize; ip += toLoad;
4375
9.95k
                    break;
4376
10.7k
            }   }
4377
4378
            /* Consume header */
4379
4.92k
            {   size_t const h1Size = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);  /* == ZSTDv07_frameHeaderSize_min */
4380
4.92k
                size_t const h1Result = ZSTDv07_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer, h1Size);
4381
4.92k
                if (ZSTDv07_isError(h1Result)) return h1Result;
4382
4.92k
                if (h1Size < zbd->lhSize) {   /* long header */
4383
4.92k
                    size_t const h2Size = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
4384
4.92k
                    size_t const h2Result = ZSTDv07_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer+h1Size, h2Size);
4385
4.92k
                    if (ZSTDv07_isError(h2Result)) return h2Result;
4386
4.92k
            }   }
4387
4388
4.86k
            zbd->fParams.windowSize = MAX(zbd->fParams.windowSize, 1U << ZSTDv07_WINDOWLOG_ABSOLUTEMIN);
4389
4390
            /* Frame header instruct buffer sizes */
4391
4.86k
            {   size_t const blockSize = MIN(zbd->fParams.windowSize, ZSTDv07_BLOCKSIZE_ABSOLUTEMAX);
4392
4.86k
                zbd->blockSize = blockSize;
4393
4.86k
                if (zbd->inBuffSize < blockSize) {
4394
2.96k
                    zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff);
4395
2.96k
                    zbd->inBuffSize = blockSize;
4396
2.96k
                    zbd->inBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, blockSize);
4397
2.96k
                    if (zbd->inBuff == NULL) return ERROR(memory_allocation);
4398
2.96k
                }
4399
4.86k
                {   size_t const neededOutSize = zbd->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
4400
4.86k
                    if (zbd->outBuffSize < neededOutSize) {
4401
2.97k
                        zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff);
4402
2.97k
                        zbd->outBuffSize = neededOutSize;
4403
2.97k
                        zbd->outBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, neededOutSize);
4404
2.97k
                        if (zbd->outBuff == NULL) return ERROR(memory_allocation);
4405
2.97k
            }   }   }
4406
4.86k
            zbd->stage = ZBUFFds_read;
4407
            /* pass-through */
4408
      /* fall-through */
4409
38.6k
        case ZBUFFds_read:
4410
38.6k
            {   size_t const neededInSize = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
4411
38.6k
                if (neededInSize==0) {  /* end of frame */
4412
2.84k
                    zbd->stage = ZBUFFds_init;
4413
2.84k
                    notDone = 0;
4414
2.84k
                    break;
4415
2.84k
                }
4416
35.7k
                if ((size_t)(iend-ip) >= neededInSize) {  /* decode directly from src */
4417
34.5k
                    const int isSkipFrame = ZSTDv07_isSkipFrame(zbd->zd);
4418
34.5k
                    size_t const decodedSize = ZSTDv07_decompressContinue(zbd->zd,
4419
34.5k
                        zbd->outBuff + zbd->outStart, (isSkipFrame ? 0 : zbd->outBuffSize - zbd->outStart),
4420
34.5k
                        ip, neededInSize);
4421
34.5k
                    if (ZSTDv07_isError(decodedSize)) return decodedSize;
4422
33.2k
                    ip += neededInSize;
4423
33.2k
                    if (!decodedSize && !isSkipFrame) break;   /* this was just a header */
4424
10.5k
                    zbd->outEnd = zbd->outStart +  decodedSize;
4425
10.5k
                    zbd->stage = ZBUFFds_flush;
4426
10.5k
                    break;
4427
33.2k
                }
4428
1.22k
                if (ip==iend) { notDone = 0; break; }   /* no more input */
4429
560
                zbd->stage = ZBUFFds_load;
4430
560
            }
4431
      /* fall-through */
4432
1.97k
        case ZBUFFds_load:
4433
1.97k
            {   size_t const neededInSize = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
4434
1.97k
                size_t const toLoad = neededInSize - zbd->inPos;   /* should always be <= remaining space within inBuff */
4435
1.97k
                size_t loadedSize;
4436
1.97k
                if (toLoad > zbd->inBuffSize - zbd->inPos) return ERROR(corruption_detected);   /* should never happen */
4437
1.92k
                loadedSize = ZBUFFv07_limitCopy(zbd->inBuff + zbd->inPos, toLoad, ip, iend-ip);
4438
1.92k
                ip += loadedSize;
4439
1.92k
                zbd->inPos += loadedSize;
4440
1.92k
                if (loadedSize < toLoad) { notDone = 0; break; }   /* not enough input, wait for more */
4441
4442
                /* decode loaded input */
4443
343
                {  const int isSkipFrame = ZSTDv07_isSkipFrame(zbd->zd);
4444
343
                   size_t const decodedSize = ZSTDv07_decompressContinue(zbd->zd,
4445
343
                        zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
4446
343
                        zbd->inBuff, neededInSize);
4447
343
                    if (ZSTDv07_isError(decodedSize)) return decodedSize;
4448
310
                    zbd->inPos = 0;   /* input is consumed */
4449
310
                    if (!decodedSize && !isSkipFrame) { zbd->stage = ZBUFFds_read; break; }   /* this was just a header */
4450
145
                    zbd->outEnd = zbd->outStart +  decodedSize;
4451
145
                    zbd->stage = ZBUFFds_flush;
4452
                    /* break; */
4453
                    /* pass-through */
4454
145
                }
4455
145
      }
4456
      /* fall-through */
4457
16.0k
        case ZBUFFds_flush:
4458
16.0k
            {   size_t const toFlushSize = zbd->outEnd - zbd->outStart;
4459
16.0k
                size_t const flushedSize = ZBUFFv07_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
4460
16.0k
                op += flushedSize;
4461
16.0k
                zbd->outStart += flushedSize;
4462
16.0k
                if (flushedSize == toFlushSize) {
4463
10.6k
                    zbd->stage = ZBUFFds_read;
4464
10.6k
                    if (zbd->outStart + zbd->blockSize > zbd->outBuffSize)
4465
1.81k
                        zbd->outStart = zbd->outEnd = 0;
4466
10.6k
                    break;
4467
10.6k
                }
4468
                /* cannot flush everything */
4469
5.43k
                notDone = 0;
4470
5.43k
                break;
4471
16.0k
            }
4472
0
        default: return ERROR(GENERIC);   /* impossible */
4473
66.7k
    }   }
4474
4475
    /* result */
4476
10.5k
    *srcSizePtr = ip-istart;
4477
10.5k
    *dstCapacityPtr = op-ostart;
4478
10.5k
    {   size_t nextSrcSizeHint = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
4479
10.5k
        nextSrcSizeHint -= zbd->inPos;   /* already loaded*/
4480
10.5k
        return nextSrcSizeHint;
4481
12.8k
    }
4482
12.8k
}
4483
4484
4485
4486
/* *************************************
4487
*  Tool functions
4488
***************************************/
4489
0
size_t ZBUFFv07_recommendedDInSize(void)  { return ZSTDv07_BLOCKSIZE_ABSOLUTEMAX + ZSTDv07_blockHeaderSize /* block header size*/ ; }
4490
0
size_t ZBUFFv07_recommendedDOutSize(void) { return ZSTDv07_BLOCKSIZE_ABSOLUTEMAX; }