source: thirdparty/blosc/internal-complibs/zstd-0.7.4/legacy/zstd_v05.c @ 8ebc79b

Revision 8ebc79b, 163.1 KB checked in by Hal Finkel <hfinkel@…>, 8 years ago (diff)

Add the other internal compression libraries from blocs

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