The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/zstd/lib/legacy/zstd_v07.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e6366a180379e4a5cb8566a001d3d03f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.