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