Path: blob/main/sys/contrib/zstd/lib/legacy/zstd_v04.c
48378 views
/*1* Copyright (c) Yann Collet, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under both the BSD-style license (found in the5* LICENSE file in the root directory of this source tree) and the GPLv2 (found6* in the COPYING file in the root directory of this source tree).7* You may select, at your option, one of the above-listed licenses.8*/91011/******************************************12* Includes13******************************************/14#include <stddef.h> /* size_t, ptrdiff_t */15#include <string.h> /* memcpy */1617#include "zstd_v04.h"18#include "../common/error_private.h"192021/* ******************************************************************22* mem.h23*******************************************************************/24#ifndef MEM_H_MODULE25#define MEM_H_MODULE2627#if defined (__cplusplus)28extern "C" {29#endif303132/******************************************33* Compiler-specific34******************************************/35#if defined(_MSC_VER) /* Visual Studio */36# include <stdlib.h> /* _byteswap_ulong */37# include <intrin.h> /* _byteswap_* */38#endif39#if defined(__GNUC__)40# define MEM_STATIC static __attribute__((unused))41#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)42# define MEM_STATIC static inline43#elif defined(_MSC_VER)44# define MEM_STATIC static __inline45#else46# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */47#endif484950/****************************************************************51* Basic Types52*****************************************************************/53#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)54# if defined(_AIX)55# include <inttypes.h>56# else57# include <stdint.h> /* intptr_t */58# endif59typedef uint8_t BYTE;60typedef uint16_t U16;61typedef int16_t S16;62typedef uint32_t U32;63typedef int32_t S32;64typedef uint64_t U64;65typedef int64_t S64;66#else67typedef unsigned char BYTE;68typedef unsigned short U16;69typedef signed short S16;70typedef unsigned int U32;71typedef signed int S32;72typedef unsigned long long U64;73typedef signed long long S64;74#endif757677/*-*************************************78* Debug79***************************************/80#include "../common/debug.h"81#ifndef assert82# define assert(condition) ((void)0)83#endif848586/****************************************************************87* Memory I/O88*****************************************************************/89/* MEM_FORCE_MEMORY_ACCESS90* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.91* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.92* The below switch allow to select different access method for improved performance.93* Method 0 (default) : use `memcpy()`. Safe and portable.94* Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).95* This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.96* Method 2 : direct access. This method is portable but violate C standard.97* It can generate buggy code on targets generating assembly depending on alignment.98* But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)99* See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.100* Prefer these methods in priority order (0 > 1 > 2)101*/102#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */103# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)104# define MEM_FORCE_MEMORY_ACCESS 1105# endif106#endif107108MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; }109MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; }110111MEM_STATIC unsigned MEM_isLittleEndian(void)112{113const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */114return one.c[0];115}116117#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)118119/* violates C standard on structure alignment.120Only use if no other choice to achieve best performance on target platform */121MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }122MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }123MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }124125MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }126127#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)128129/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */130/* currently only defined for gcc and icc */131typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign;132133MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }134MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }135MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }136137MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }138139#else140141/* default method, safe and standard.142can sometimes prove slower */143144MEM_STATIC U16 MEM_read16(const void* memPtr)145{146U16 val; memcpy(&val, memPtr, sizeof(val)); return val;147}148149MEM_STATIC U32 MEM_read32(const void* memPtr)150{151U32 val; memcpy(&val, memPtr, sizeof(val)); return val;152}153154MEM_STATIC U64 MEM_read64(const void* memPtr)155{156U64 val; memcpy(&val, memPtr, sizeof(val)); return val;157}158159MEM_STATIC void MEM_write16(void* memPtr, U16 value)160{161memcpy(memPtr, &value, sizeof(value));162}163164#endif /* MEM_FORCE_MEMORY_ACCESS */165166167MEM_STATIC U16 MEM_readLE16(const void* memPtr)168{169if (MEM_isLittleEndian())170return MEM_read16(memPtr);171else172{173const BYTE* p = (const BYTE*)memPtr;174return (U16)(p[0] + (p[1]<<8));175}176}177178MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)179{180if (MEM_isLittleEndian())181{182MEM_write16(memPtr, val);183}184else185{186BYTE* p = (BYTE*)memPtr;187p[0] = (BYTE)val;188p[1] = (BYTE)(val>>8);189}190}191192MEM_STATIC U32 MEM_readLE24(const void* memPtr)193{194return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);195}196197MEM_STATIC U32 MEM_readLE32(const void* memPtr)198{199if (MEM_isLittleEndian())200return MEM_read32(memPtr);201else202{203const BYTE* p = (const BYTE*)memPtr;204return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24));205}206}207208209MEM_STATIC U64 MEM_readLE64(const void* memPtr)210{211if (MEM_isLittleEndian())212return MEM_read64(memPtr);213else214{215const BYTE* p = (const BYTE*)memPtr;216return (U64)((U64)p[0] + ((U64)p[1]<<8) + ((U64)p[2]<<16) + ((U64)p[3]<<24)217+ ((U64)p[4]<<32) + ((U64)p[5]<<40) + ((U64)p[6]<<48) + ((U64)p[7]<<56));218}219}220221222MEM_STATIC size_t MEM_readLEST(const void* memPtr)223{224if (MEM_32bits())225return (size_t)MEM_readLE32(memPtr);226else227return (size_t)MEM_readLE64(memPtr);228}229230231#if defined (__cplusplus)232}233#endif234235#endif /* MEM_H_MODULE */236237/*238zstd - standard compression library239Header File for static linking only240*/241#ifndef ZSTD_STATIC_H242#define ZSTD_STATIC_H243244245/* *************************************246* Types247***************************************/248#define ZSTD_WINDOWLOG_ABSOLUTEMIN 11249250/** from faster to stronger */251typedef enum { ZSTD_fast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2 } ZSTD_strategy;252253typedef struct254{255U64 srcSize; /* optional : tells how much bytes are present in the frame. Use 0 if not known. */256U32 windowLog; /* largest match distance : larger == more compression, more memory needed during decompression */257U32 contentLog; /* full search segment : larger == more compression, slower, more memory (useless for fast) */258U32 hashLog; /* dispatch table : larger == more memory, faster */259U32 searchLog; /* nb of searches : larger == more compression, slower */260U32 searchLength; /* size of matches : larger == faster decompression, sometimes less compression */261ZSTD_strategy strategy;262} ZSTD_parameters;263264typedef ZSTDv04_Dctx ZSTD_DCtx;265266/* *************************************267* Advanced functions268***************************************/269/** ZSTD_decompress_usingDict270* Same as ZSTD_decompressDCtx, using a Dictionary content as prefix271* Note : dict can be NULL, in which case, it's equivalent to ZSTD_decompressDCtx() */272static size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,273void* dst, size_t maxDstSize,274const void* src, size_t srcSize,275const void* dict,size_t dictSize);276277278/* **************************************279* Streaming functions (direct mode)280****************************************/281static size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx);282static size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize);283static void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* src, size_t srcSize);284285static size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);286static size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);287288/**289Streaming decompression, bufferless mode290291A ZSTD_DCtx object is required to track streaming operations.292Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.293A ZSTD_DCtx object can be re-used multiple times. Use ZSTD_resetDCtx() to return to fresh status.294295First operation is to retrieve frame parameters, using ZSTD_getFrameParams().296This function doesn't consume its input. It needs enough input data to properly decode the frame header.297Objective is to retrieve *params.windowlog, to know minimum amount of memory required during decoding.298Result : 0 when successful, it means the ZSTD_parameters structure has been filled.299>0 : means there is not enough data into src. Provides the expected size to successfully decode header.300errorCode, which can be tested using ZSTD_isError() (For example, if it's not a ZSTD header)301302Then, you can optionally insert a dictionary.303This operation must mimic the compressor behavior, otherwise decompression will fail or be corrupted.304305Then it's possible to start decompression.306Use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.307ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().308ZSTD_decompressContinue() requires this exact amount of bytes, or it will fail.309ZSTD_decompressContinue() needs previous data blocks during decompression, up to (1 << windowlog).310They should preferably be located contiguously, prior to current block. Alternatively, a round buffer is also possible.311312@result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst'.313It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header.314315A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.316Context can then be reset to start a new decompression.317*/318319320321322#endif /* ZSTD_STATIC_H */323324325/*326zstd_internal - common functions to include327Header File for include328*/329#ifndef ZSTD_CCOMMON_H_MODULE330#define ZSTD_CCOMMON_H_MODULE331332/* *************************************333* Common macros334***************************************/335#define MIN(a,b) ((a)<(b) ? (a) : (b))336#define MAX(a,b) ((a)>(b) ? (a) : (b))337338339/* *************************************340* Common constants341***************************************/342#define ZSTD_MAGICNUMBER 0xFD2FB524 /* v0.4 */343344#define KB *(1 <<10)345#define MB *(1 <<20)346#define GB *(1U<<30)347348#define BLOCKSIZE (128 KB) /* define, for static allocation */349350static const size_t ZSTD_blockHeaderSize = 3;351static const size_t ZSTD_frameHeaderSize_min = 5;352#define ZSTD_frameHeaderSize_max 5 /* define, for static allocation */353354#define BIT7 128355#define BIT6 64356#define BIT5 32357#define BIT4 16358#define BIT1 2359#define BIT0 1360361#define IS_RAW BIT0362#define IS_RLE BIT1363364#define MINMATCH 4365#define REPCODE_STARTVALUE 4366367#define MLbits 7368#define LLbits 6369#define Offbits 5370#define MaxML ((1<<MLbits) - 1)371#define MaxLL ((1<<LLbits) - 1)372#define MaxOff ((1<<Offbits)- 1)373#define MLFSELog 10374#define LLFSELog 10375#define OffFSELog 9376#define MaxSeq MAX(MaxLL, MaxML)377378#define MIN_SEQUENCES_SIZE (2 /*seqNb*/ + 2 /*dumps*/ + 3 /*seqTables*/ + 1 /*bitStream*/)379#define MIN_CBLOCK_SIZE (3 /*litCSize*/ + MIN_SEQUENCES_SIZE)380381#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)382383typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;384385386/* ******************************************387* Shared functions to include for inlining388********************************************/389static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }390391#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }392393/*! ZSTD_wildcopy : custom version of memcpy(), can copy up to 7-8 bytes too many */394static void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)395{396const BYTE* ip = (const BYTE*)src;397BYTE* op = (BYTE*)dst;398BYTE* const oend = op + length;399do400COPY8(op, ip)401while (op < oend);402}403404405406/* ******************************************************************407FSE : Finite State Entropy coder408header file409****************************************************************** */410#ifndef FSE_H411#define FSE_H412413#if defined (__cplusplus)414extern "C" {415#endif416417418/* *****************************************419* Includes420******************************************/421#include <stddef.h> /* size_t, ptrdiff_t */422423424/* *****************************************425* FSE simple functions426******************************************/427static size_t FSE_decompress(void* dst, size_t maxDstSize,428const void* cSrc, size_t cSrcSize);429/*!430FSE_decompress():431Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',432into already allocated destination buffer 'dst', of size 'maxDstSize'.433return : size of regenerated data (<= maxDstSize)434or an error code, which can be tested using FSE_isError()435436** Important ** : FSE_decompress() doesn't decompress non-compressible nor RLE data !!!437Why ? : making this distinction requires a header.438Header management is intentionally delegated to the user layer, which can better manage special cases.439*/440441442/* *****************************************443* Tool functions444******************************************/445/* Error Management */446static unsigned FSE_isError(size_t code); /* tells if a return value is an error code */447448449450/* *****************************************451* FSE detailed API452******************************************/453/*!454FSE_compress() does the following:4551. count symbol occurrence from source[] into table count[]4562. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog)4573. save normalized counters to memory buffer using writeNCount()4584. build encoding table 'CTable' from normalized counters4595. encode the data stream using encoding table 'CTable'460461FSE_decompress() does the following:4621. read normalized counters with readNCount()4632. build decoding table 'DTable' from normalized counters4643. decode the data stream using decoding table 'DTable'465466The following API allows targeting specific sub-functions for advanced tasks.467For example, it's possible to compress several blocks using the same 'CTable',468or to save and provide normalized distribution using external method.469*/470471472/* *** DECOMPRESSION *** */473474/*!475FSE_readNCount():476Read compactly saved 'normalizedCounter' from 'rBuffer'.477return : size read from 'rBuffer'478or an errorCode, which can be tested using FSE_isError()479maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */480static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);481482/*!483Constructor and Destructor of type FSE_DTable484Note that its size depends on 'tableLog' */485typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */486487/*!488FSE_buildDTable():489Builds 'dt', which must be already allocated, using FSE_createDTable()490return : 0,491or an errorCode, which can be tested using FSE_isError() */492static size_t FSE_buildDTable ( FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);493494/*!495FSE_decompress_usingDTable():496Decompress compressed source 'cSrc' of size 'cSrcSize' using 'dt'497into 'dst' which must be already allocated.498return : size of regenerated data (necessarily <= maxDstSize)499or an errorCode, which can be tested using FSE_isError() */500static size_t FSE_decompress_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);501502/*!503Tutorial :504----------505(Note : these functions only decompress FSE-compressed blocks.506If block is uncompressed, use memcpy() instead507If block is a single repeated byte, use memset() instead )508509The first step is to obtain the normalized frequencies of symbols.510This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount().511'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short.512In practice, that means it's necessary to know 'maxSymbolValue' beforehand,513or size the table to handle worst case situations (typically 256).514FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'.515The result of FSE_readNCount() is the number of bytes read from 'rBuffer'.516Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that.517If there is an error, the function will return an error code, which can be tested using FSE_isError().518519The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'.520This is performed by the function FSE_buildDTable().521The space required by 'FSE_DTable' must be already allocated using FSE_createDTable().522If there is an error, the function will return an error code, which can be tested using FSE_isError().523524'FSE_DTable' can then be used to decompress 'cSrc', with FSE_decompress_usingDTable().525'cSrcSize' must be strictly correct, otherwise decompression will fail.526FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=maxDstSize).527If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small)528*/529530531#if defined (__cplusplus)532}533#endif534535#endif /* FSE_H */536537538/* ******************************************************************539bitstream540Part of NewGen Entropy library541header file (to include)542Copyright (C) 2013-2015, Yann Collet.543544BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)545546Redistribution and use in source and binary forms, with or without547modification, are permitted provided that the following conditions are548met:549550* Redistributions of source code must retain the above copyright551notice, this list of conditions and the following disclaimer.552* Redistributions in binary form must reproduce the above553copyright notice, this list of conditions and the following disclaimer554in the documentation and/or other materials provided with the555distribution.556557THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS558"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT559LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR560A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT561OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,562SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT563LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,564DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY565THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT566(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE567OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.568569You can contact the author at :570- Source repository : https://github.com/Cyan4973/FiniteStateEntropy571- Public forum : https://groups.google.com/forum/#!forum/lz4c572****************************************************************** */573#ifndef BITSTREAM_H_MODULE574#define BITSTREAM_H_MODULE575576#if defined (__cplusplus)577extern "C" {578#endif579580581/*582* This API consists of small unitary functions, which highly benefit from being inlined.583* Since link-time-optimization is not available for all compilers,584* these functions are defined into a .h to be included.585*/586587/**********************************************588* bitStream decompression API (read backward)589**********************************************/590typedef struct591{592size_t bitContainer;593unsigned bitsConsumed;594const char* ptr;595const char* start;596} BIT_DStream_t;597598typedef enum { BIT_DStream_unfinished = 0,599BIT_DStream_endOfBuffer = 1,600BIT_DStream_completed = 2,601BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */602/* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */603604MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);605MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);606MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);607MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);608609610611612/******************************************613* unsafe API614******************************************/615MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);616/* faster, but works only if nbBits >= 1 */617618619620/****************************************************************621* Helper functions622****************************************************************/623MEM_STATIC unsigned BIT_highbit32 (U32 val)624{625# if defined(_MSC_VER) /* Visual */626unsigned long r;627return _BitScanReverse(&r, val) ? (unsigned)r : 0;628# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */629return __builtin_clz (val) ^ 31;630# else /* Software version */631static 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 };632U32 v = val;633unsigned r;634v |= v >> 1;635v |= v >> 2;636v |= v >> 4;637v |= v >> 8;638v |= v >> 16;639r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];640return r;641# endif642}643644645/**********************************************************646* bitStream decoding647**********************************************************/648649/*!BIT_initDStream650* Initialize a BIT_DStream_t.651* @bitD : a pointer to an already allocated BIT_DStream_t structure652* @srcBuffer must point at the beginning of a bitStream653* @srcSize must be the exact size of the bitStream654* @result : size of stream (== srcSize) or an errorCode if a problem is detected655*/656MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)657{658if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }659660if (srcSize >= sizeof(size_t)) /* normal case */661{662U32 contain32;663bitD->start = (const char*)srcBuffer;664bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(size_t);665bitD->bitContainer = MEM_readLEST(bitD->ptr);666contain32 = ((const BYTE*)srcBuffer)[srcSize-1];667if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */668bitD->bitsConsumed = 8 - BIT_highbit32(contain32);669}670else671{672U32 contain32;673bitD->start = (const char*)srcBuffer;674bitD->ptr = bitD->start;675bitD->bitContainer = *(const BYTE*)(bitD->start);676switch(srcSize)677{678case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);/* fall-through */679case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);/* fall-through */680case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);/* fall-through */681case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24; /* fall-through */682case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16; /* fall-through */683case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) << 8; /* fall-through */684default: break;685}686contain32 = ((const BYTE*)srcBuffer)[srcSize-1];687if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */688bitD->bitsConsumed = 8 - BIT_highbit32(contain32);689bitD->bitsConsumed += (U32)(sizeof(size_t) - srcSize)*8;690}691692return srcSize;693}694695MEM_STATIC size_t BIT_lookBits(BIT_DStream_t* bitD, U32 nbBits)696{697const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1;698return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);699}700701/*! BIT_lookBitsFast :702* unsafe version; only works only if nbBits >= 1 */703MEM_STATIC size_t BIT_lookBitsFast(BIT_DStream_t* bitD, U32 nbBits)704{705const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1;706return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);707}708709MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)710{711bitD->bitsConsumed += nbBits;712}713714MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)715{716size_t value = BIT_lookBits(bitD, nbBits);717BIT_skipBits(bitD, nbBits);718return value;719}720721/*!BIT_readBitsFast :722* unsafe version; only works only if nbBits >= 1 */723MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)724{725size_t value = BIT_lookBitsFast(bitD, nbBits);726BIT_skipBits(bitD, nbBits);727return value;728}729730MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)731{732if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */733return BIT_DStream_overflow;734735if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer))736{737bitD->ptr -= bitD->bitsConsumed >> 3;738bitD->bitsConsumed &= 7;739bitD->bitContainer = MEM_readLEST(bitD->ptr);740return BIT_DStream_unfinished;741}742if (bitD->ptr == bitD->start)743{744if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;745return BIT_DStream_completed;746}747{748U32 nbBytes = bitD->bitsConsumed >> 3;749BIT_DStream_status result = BIT_DStream_unfinished;750if (bitD->ptr - nbBytes < bitD->start)751{752nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */753result = BIT_DStream_endOfBuffer;754}755bitD->ptr -= nbBytes;756bitD->bitsConsumed -= nbBytes*8;757bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */758return result;759}760}761762/*! BIT_endOfDStream763* @return Tells if DStream has reached its exact end764*/765MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)766{767return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));768}769770#if defined (__cplusplus)771}772#endif773774#endif /* BITSTREAM_H_MODULE */775776777778/* ******************************************************************779FSE : Finite State Entropy coder780header file for static linking (only)781Copyright (C) 2013-2015, Yann Collet782783BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)784785Redistribution and use in source and binary forms, with or without786modification, are permitted provided that the following conditions are787met:788789* Redistributions of source code must retain the above copyright790notice, this list of conditions and the following disclaimer.791* Redistributions in binary form must reproduce the above792copyright notice, this list of conditions and the following disclaimer793in the documentation and/or other materials provided with the794distribution.795796THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS797"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT798LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR799A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT800OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,801SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT802LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,803DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY804THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT805(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE806OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.807808You can contact the author at :809- Source repository : https://github.com/Cyan4973/FiniteStateEntropy810- Public forum : https://groups.google.com/forum/#!forum/lz4c811****************************************************************** */812#ifndef FSE_STATIC_H813#define FSE_STATIC_H814815#if defined (__cplusplus)816extern "C" {817#endif818819820/* *****************************************821* Static allocation822*******************************************/823/* FSE buffer bounds */824#define FSE_NCOUNTBOUND 512825#define FSE_BLOCKBOUND(size) (size + (size>>7))826#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */827828/* It is possible to statically allocate FSE CTable/DTable as a table of unsigned using below macros */829#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))830#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))831832833/* *****************************************834* FSE advanced API835*******************************************/836static size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);837/* build a fake FSE_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */838839static size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);840/* build a fake FSE_DTable, designed to always generate the same symbolValue */841842843844/* *****************************************845* FSE symbol decompression API846*******************************************/847typedef struct848{849size_t state;850const void* table; /* precise table may vary, depending on U16 */851} FSE_DState_t;852853854static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);855856static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);857858static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);859860861/* *****************************************862* FSE unsafe API863*******************************************/864static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);865/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */866867868/* *****************************************869* Implementation of inlined functions870*******************************************/871/* decompression */872873typedef struct {874U16 tableLog;875U16 fastMode;876} FSE_DTableHeader; /* sizeof U32 */877878typedef struct879{880unsigned short newState;881unsigned char symbol;882unsigned char nbBits;883} FSE_decode_t; /* size == U32 */884885MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)886{887FSE_DTableHeader DTableH;888memcpy(&DTableH, dt, sizeof(DTableH));889DStatePtr->state = BIT_readBits(bitD, DTableH.tableLog);890BIT_reloadDStream(bitD);891DStatePtr->table = dt + 1;892}893894MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)895{896const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];897const U32 nbBits = DInfo.nbBits;898BYTE symbol = DInfo.symbol;899size_t lowBits = BIT_readBits(bitD, nbBits);900901DStatePtr->state = DInfo.newState + lowBits;902return symbol;903}904905MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)906{907const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];908const U32 nbBits = DInfo.nbBits;909BYTE symbol = DInfo.symbol;910size_t lowBits = BIT_readBitsFast(bitD, nbBits);911912DStatePtr->state = DInfo.newState + lowBits;913return symbol;914}915916MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)917{918return DStatePtr->state == 0;919}920921922#if defined (__cplusplus)923}924#endif925926#endif /* FSE_STATIC_H */927928/* ******************************************************************929FSE : Finite State Entropy coder930Copyright (C) 2013-2015, Yann Collet.931932BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)933934Redistribution and use in source and binary forms, with or without935modification, are permitted provided that the following conditions are936met:937938* Redistributions of source code must retain the above copyright939notice, this list of conditions and the following disclaimer.940* Redistributions in binary form must reproduce the above941copyright notice, this list of conditions and the following disclaimer942in the documentation and/or other materials provided with the943distribution.944945THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS946"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT947LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR948A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT949OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,950SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT951LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,952DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY953THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT954(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE955OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.956957You can contact the author at :958- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy959- Public forum : https://groups.google.com/forum/#!forum/lz4c960****************************************************************** */961962#ifndef FSE_COMMONDEFS_ONLY963964/* **************************************************************965* Tuning parameters966****************************************************************/967/*!MEMORY_USAGE :968* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)969* Increasing memory usage improves compression ratio970* Reduced memory usage can improve speed, due to cache effect971* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */972#define FSE_MAX_MEMORY_USAGE 14973#define FSE_DEFAULT_MEMORY_USAGE 13974975/*!FSE_MAX_SYMBOL_VALUE :976* Maximum symbol value authorized.977* Required for proper stack allocation */978#define FSE_MAX_SYMBOL_VALUE 255979980981/* **************************************************************982* template functions type & suffix983****************************************************************/984#define FSE_FUNCTION_TYPE BYTE985#define FSE_FUNCTION_EXTENSION986#define FSE_DECODE_TYPE FSE_decode_t987988989#endif /* !FSE_COMMONDEFS_ONLY */990991/* **************************************************************992* Compiler specifics993****************************************************************/994#ifdef _MSC_VER /* Visual Studio */995# define FORCE_INLINE static __forceinline996# include <intrin.h> /* For Visual 2005 */997# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */998# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */999#else1000# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */1001# ifdef __GNUC__1002# define FORCE_INLINE static inline __attribute__((always_inline))1003# else1004# define FORCE_INLINE static inline1005# endif1006# else1007# define FORCE_INLINE static1008# endif /* __STDC_VERSION__ */1009#endif101010111012/* **************************************************************1013* Dependencies1014****************************************************************/1015#include <stdlib.h> /* malloc, free, qsort */1016#include <string.h> /* memcpy, memset */1017#include <stdio.h> /* printf (debug) */101810191020/* ***************************************************************1021* Constants1022*****************************************************************/1023#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)1024#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)1025#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)1026#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)1027#define FSE_MIN_TABLELOG 510281029#define FSE_TABLELOG_ABSOLUTE_MAX 151030#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX1031#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"1032#endif103310341035/* **************************************************************1036* Error Management1037****************************************************************/1038#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */103910401041/* **************************************************************1042* Complex types1043****************************************************************/1044typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];104510461047/*-**************************************************************1048* Templates1049****************************************************************/1050/*1051designed to be included1052for type-specific functions (template emulation in C)1053Objective is to write these functions only once, for improved maintenance1054*/10551056/* safety checks */1057#ifndef FSE_FUNCTION_EXTENSION1058# error "FSE_FUNCTION_EXTENSION must be defined"1059#endif1060#ifndef FSE_FUNCTION_TYPE1061# error "FSE_FUNCTION_TYPE must be defined"1062#endif10631064/* Function names */1065#define FSE_CAT(X,Y) X##Y1066#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)1067#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)10681069static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; }107010711072static size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)1073{1074FSE_DTableHeader DTableH;1075void* const tdPtr = dt+1; /* because dt is unsigned, 32-bits aligned on 32-bits */1076FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);1077const U32 tableSize = 1 << tableLog;1078const U32 tableMask = tableSize-1;1079const U32 step = FSE_tableStep(tableSize);1080U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];1081U32 position = 0;1082U32 highThreshold = tableSize-1;1083const S16 largeLimit= (S16)(1 << (tableLog-1));1084U32 noLarge = 1;1085U32 s;10861087/* Sanity Checks */1088if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);1089if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);10901091/* Init, lay down lowprob symbols */1092memset(tableDecode, 0, sizeof(FSE_DECODE_TYPE) * (maxSymbolValue+1) ); /* useless init, but keep static analyzer happy, and we don't need to performance optimize legacy decoders */1093DTableH.tableLog = (U16)tableLog;1094for (s=0; s<=maxSymbolValue; s++)1095{1096if (normalizedCounter[s]==-1)1097{1098tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;1099symbolNext[s] = 1;1100}1101else1102{1103if (normalizedCounter[s] >= largeLimit) noLarge=0;1104symbolNext[s] = normalizedCounter[s];1105}1106}11071108/* Spread symbols */1109for (s=0; s<=maxSymbolValue; s++)1110{1111int i;1112for (i=0; i<normalizedCounter[s]; i++)1113{1114tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;1115position = (position + step) & tableMask;1116while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */1117}1118}11191120if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */11211122/* Build Decoding table */1123{1124U32 i;1125for (i=0; i<tableSize; i++)1126{1127FSE_FUNCTION_TYPE symbol = (FSE_FUNCTION_TYPE)(tableDecode[i].symbol);1128U16 nextState = symbolNext[symbol]++;1129tableDecode[i].nbBits = (BYTE) (tableLog - BIT_highbit32 ((U32)nextState) );1130tableDecode[i].newState = (U16) ( (nextState << tableDecode[i].nbBits) - tableSize);1131}1132}11331134DTableH.fastMode = (U16)noLarge;1135memcpy(dt, &DTableH, sizeof(DTableH));1136return 0;1137}113811391140#ifndef FSE_COMMONDEFS_ONLY1141/******************************************1142* FSE helper functions1143******************************************/1144static unsigned FSE_isError(size_t code) { return ERR_isError(code); }114511461147/****************************************************************1148* FSE NCount encoding-decoding1149****************************************************************/1150static short FSE_abs(short a)1151{1152return a<0 ? -a : a;1153}11541155static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,1156const void* headerBuffer, size_t hbSize)1157{1158const BYTE* const istart = (const BYTE*) headerBuffer;1159const BYTE* const iend = istart + hbSize;1160const BYTE* ip = istart;1161int nbBits;1162int remaining;1163int threshold;1164U32 bitStream;1165int bitCount;1166unsigned charnum = 0;1167int previous0 = 0;11681169if (hbSize < 4) return ERROR(srcSize_wrong);1170bitStream = MEM_readLE32(ip);1171nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */1172if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);1173bitStream >>= 4;1174bitCount = 4;1175*tableLogPtr = nbBits;1176remaining = (1<<nbBits)+1;1177threshold = 1<<nbBits;1178nbBits++;11791180while ((remaining>1) && (charnum<=*maxSVPtr))1181{1182if (previous0)1183{1184unsigned n0 = charnum;1185while ((bitStream & 0xFFFF) == 0xFFFF)1186{1187n0+=24;1188if (ip < iend-5)1189{1190ip+=2;1191bitStream = MEM_readLE32(ip) >> bitCount;1192}1193else1194{1195bitStream >>= 16;1196bitCount+=16;1197}1198}1199while ((bitStream & 3) == 3)1200{1201n0+=3;1202bitStream>>=2;1203bitCount+=2;1204}1205n0 += bitStream & 3;1206bitCount += 2;1207if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);1208while (charnum < n0) normalizedCounter[charnum++] = 0;1209if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))1210{1211ip += bitCount>>3;1212bitCount &= 7;1213bitStream = MEM_readLE32(ip) >> bitCount;1214}1215else1216bitStream >>= 2;1217}1218{1219const short max = (short)((2*threshold-1)-remaining);1220short count;12211222if ((bitStream & (threshold-1)) < (U32)max)1223{1224count = (short)(bitStream & (threshold-1));1225bitCount += nbBits-1;1226}1227else1228{1229count = (short)(bitStream & (2*threshold-1));1230if (count >= threshold) count -= max;1231bitCount += nbBits;1232}12331234count--; /* extra accuracy */1235remaining -= FSE_abs(count);1236normalizedCounter[charnum++] = count;1237previous0 = !count;1238while (remaining < threshold)1239{1240nbBits--;1241threshold >>= 1;1242}12431244{1245if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))1246{1247ip += bitCount>>3;1248bitCount &= 7;1249}1250else1251{1252bitCount -= (int)(8 * (iend - 4 - ip));1253ip = iend - 4;1254}1255bitStream = MEM_readLE32(ip) >> (bitCount & 31);1256}1257}1258}1259if (remaining != 1) return ERROR(GENERIC);1260*maxSVPtr = charnum-1;12611262ip += (bitCount+7)>>3;1263if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);1264return ip-istart;1265}126612671268/*********************************************************1269* Decompression (Byte symbols)1270*********************************************************/1271static size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)1272{1273void* ptr = dt;1274FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;1275void* dPtr = dt + 1;1276FSE_decode_t* const cell = (FSE_decode_t*)dPtr;12771278DTableH->tableLog = 0;1279DTableH->fastMode = 0;12801281cell->newState = 0;1282cell->symbol = symbolValue;1283cell->nbBits = 0;12841285return 0;1286}128712881289static size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)1290{1291void* ptr = dt;1292FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;1293void* dPtr = dt + 1;1294FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;1295const unsigned tableSize = 1 << nbBits;1296const unsigned tableMask = tableSize - 1;1297const unsigned maxSymbolValue = tableMask;1298unsigned s;12991300/* Sanity checks */1301if (nbBits < 1) return ERROR(GENERIC); /* min size */13021303/* Build Decoding Table */1304DTableH->tableLog = (U16)nbBits;1305DTableH->fastMode = 1;1306for (s=0; s<=maxSymbolValue; s++)1307{1308dinfo[s].newState = 0;1309dinfo[s].symbol = (BYTE)s;1310dinfo[s].nbBits = (BYTE)nbBits;1311}13121313return 0;1314}13151316FORCE_INLINE size_t FSE_decompress_usingDTable_generic(1317void* dst, size_t maxDstSize,1318const void* cSrc, size_t cSrcSize,1319const FSE_DTable* dt, const unsigned fast)1320{1321BYTE* const ostart = (BYTE*) dst;1322BYTE* op = ostart;1323BYTE* const omax = op + maxDstSize;1324BYTE* const olimit = omax-3;13251326BIT_DStream_t bitD;1327FSE_DState_t state1;1328FSE_DState_t state2;1329size_t errorCode;13301331/* Init */1332errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */1333if (FSE_isError(errorCode)) return errorCode;13341335FSE_initDState(&state1, &bitD, dt);1336FSE_initDState(&state2, &bitD, dt);13371338#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)13391340/* 4 symbols per loop */1341for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) && (op<olimit) ; op+=4)1342{1343op[0] = FSE_GETSYMBOL(&state1);13441345if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */1346BIT_reloadDStream(&bitD);13471348op[1] = FSE_GETSYMBOL(&state2);13491350if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */1351{ if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }13521353op[2] = FSE_GETSYMBOL(&state1);13541355if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */1356BIT_reloadDStream(&bitD);13571358op[3] = FSE_GETSYMBOL(&state2);1359}13601361/* tail */1362/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */1363while (1)1364{1365if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state1))) )1366break;13671368*op++ = FSE_GETSYMBOL(&state1);13691370if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state2))) )1371break;13721373*op++ = FSE_GETSYMBOL(&state2);1374}13751376/* end ? */1377if (BIT_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2))1378return op-ostart;13791380if (op==omax) return ERROR(dstSize_tooSmall); /* dst buffer is full, but cSrc unfinished */13811382return ERROR(corruption_detected);1383}138413851386static size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,1387const void* cSrc, size_t cSrcSize,1388const FSE_DTable* dt)1389{1390FSE_DTableHeader DTableH;1391U32 fastMode;13921393memcpy(&DTableH, dt, sizeof(DTableH));1394fastMode = DTableH.fastMode;13951396/* select fast mode (static) */1397if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);1398return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);1399}140014011402static size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)1403{1404const BYTE* const istart = (const BYTE*)cSrc;1405const BYTE* ip = istart;1406short counting[FSE_MAX_SYMBOL_VALUE+1];1407DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */1408unsigned tableLog;1409unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;1410size_t errorCode;14111412if (cSrcSize<2) return ERROR(srcSize_wrong); /* too small input size */14131414/* normal FSE decoding mode */1415errorCode = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);1416if (FSE_isError(errorCode)) return errorCode;1417if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */1418ip += errorCode;1419cSrcSize -= errorCode;14201421errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog);1422if (FSE_isError(errorCode)) return errorCode;14231424/* always return, even if it is an error code */1425return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt);1426}1427142814291430#endif /* FSE_COMMONDEFS_ONLY */143114321433/* ******************************************************************1434Huff0 : Huffman coder, part of New Generation Entropy library1435header file1436Copyright (C) 2013-2015, Yann Collet.14371438BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)14391440Redistribution and use in source and binary forms, with or without1441modification, are permitted provided that the following conditions are1442met:14431444* Redistributions of source code must retain the above copyright1445notice, this list of conditions and the following disclaimer.1446* Redistributions in binary form must reproduce the above1447copyright notice, this list of conditions and the following disclaimer1448in the documentation and/or other materials provided with the1449distribution.14501451THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS1452"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT1453LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR1454A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT1455OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,1456SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT1457LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,1458DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY1459THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT1460(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE1461OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.14621463You can contact the author at :1464- Source repository : https://github.com/Cyan4973/FiniteStateEntropy1465- Public forum : https://groups.google.com/forum/#!forum/lz4c1466****************************************************************** */1467#ifndef HUFF0_H1468#define HUFF0_H14691470#if defined (__cplusplus)1471extern "C" {1472#endif147314741475/* ****************************************1476* Dependency1477******************************************/1478#include <stddef.h> /* size_t */147914801481/* ****************************************1482* Huff0 simple functions1483******************************************/1484static size_t HUF_decompress(void* dst, size_t dstSize,1485const void* cSrc, size_t cSrcSize);1486/*!1487HUF_decompress():1488Decompress Huff0 data from buffer 'cSrc', of size 'cSrcSize',1489into already allocated destination buffer 'dst', of size 'dstSize'.1490'dstSize' must be the exact size of original (uncompressed) data.1491Note : in contrast with FSE, HUF_decompress can regenerate RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, because it knows size to regenerate.1492@return : size of regenerated data (== dstSize)1493or an error code, which can be tested using HUF_isError()1494*/149514961497/* ****************************************1498* Tool functions1499******************************************/1500/* Error Management */1501static unsigned HUF_isError(size_t code); /* tells if a return value is an error code */150215031504#if defined (__cplusplus)1505}1506#endif15071508#endif /* HUFF0_H */150915101511/* ******************************************************************1512Huff0 : Huffman coder, part of New Generation Entropy library1513header file for static linking (only)1514Copyright (C) 2013-2015, Yann Collet15151516BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)15171518Redistribution and use in source and binary forms, with or without1519modification, are permitted provided that the following conditions are1520met:15211522* Redistributions of source code must retain the above copyright1523notice, this list of conditions and the following disclaimer.1524* Redistributions in binary form must reproduce the above1525copyright notice, this list of conditions and the following disclaimer1526in the documentation and/or other materials provided with the1527distribution.15281529THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS1530"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT1531LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR1532A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT1533OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,1534SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT1535LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,1536DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY1537THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT1538(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE1539OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.15401541You can contact the author at :1542- Source repository : https://github.com/Cyan4973/FiniteStateEntropy1543- Public forum : https://groups.google.com/forum/#!forum/lz4c1544****************************************************************** */1545#ifndef HUFF0_STATIC_H1546#define HUFF0_STATIC_H15471548#if defined (__cplusplus)1549extern "C" {1550#endif1551155215531554/* ****************************************1555* Static allocation macros1556******************************************/1557/* static allocation of Huff0's DTable */1558#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<maxTableLog)) /* nb Cells; use unsigned short for X2, unsigned int for X4 */1559#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \1560unsigned short DTable[HUF_DTABLE_SIZE(maxTableLog)] = { maxTableLog }1561#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \1562unsigned int DTable[HUF_DTABLE_SIZE(maxTableLog)] = { maxTableLog }1563#define HUF_CREATE_STATIC_DTABLEX6(DTable, maxTableLog) \1564unsigned int DTable[HUF_DTABLE_SIZE(maxTableLog) * 3 / 2] = { maxTableLog }156515661567/* ****************************************1568* Advanced decompression functions1569******************************************/1570static size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */1571static size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */157215731574/* ****************************************1575* Huff0 detailed API1576******************************************/1577/*!1578HUF_decompress() does the following:15791. select the decompression algorithm (X2, X4, X6) based on pre-computed heuristics15802. build Huffman table from save, using HUF_readDTableXn()15813. decode 1 or 4 segments in parallel using HUF_decompressSXn_usingDTable15821583*/1584static size_t HUF_readDTableX2 (unsigned short* DTable, const void* src, size_t srcSize);1585static size_t HUF_readDTableX4 (unsigned* DTable, const void* src, size_t srcSize);15861587static size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);1588static size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);158915901591#if defined (__cplusplus)1592}1593#endif15941595#endif /* HUFF0_STATIC_H */1596159715981599/* ******************************************************************1600Huff0 : Huffman coder, part of New Generation Entropy library1601Copyright (C) 2013-2015, Yann Collet.16021603BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)16041605Redistribution and use in source and binary forms, with or without1606modification, are permitted provided that the following conditions are1607met:16081609* Redistributions of source code must retain the above copyright1610notice, this list of conditions and the following disclaimer.1611* Redistributions in binary form must reproduce the above1612copyright notice, this list of conditions and the following disclaimer1613in the documentation and/or other materials provided with the1614distribution.16151616THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS1617"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT1618LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR1619A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT1620OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,1621SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT1622LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,1623DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY1624THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT1625(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE1626OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.16271628You can contact the author at :1629- FSE+Huff0 source repository : https://github.com/Cyan4973/FiniteStateEntropy1630****************************************************************** */16311632/* **************************************************************1633* Compiler specifics1634****************************************************************/1635#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)1636/* inline is defined */1637#elif defined(_MSC_VER)1638# define inline __inline1639#else1640# define inline /* disable inline */1641#endif164216431644#ifdef _MSC_VER /* Visual Studio */1645# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */1646#endif164716481649/* **************************************************************1650* Includes1651****************************************************************/1652#include <stdlib.h> /* malloc, free, qsort */1653#include <string.h> /* memcpy, memset */1654#include <stdio.h> /* printf (debug) */165516561657/* **************************************************************1658* Constants1659****************************************************************/1660#define HUF_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */1661#define HUF_MAX_TABLELOG 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */1662#define HUF_DEFAULT_TABLELOG HUF_MAX_TABLELOG /* tableLog by default, when not specified */1663#define HUF_MAX_SYMBOL_VALUE 2551664#if (HUF_MAX_TABLELOG > HUF_ABSOLUTEMAX_TABLELOG)1665# error "HUF_MAX_TABLELOG is too large !"1666#endif166716681669/* **************************************************************1670* Error Management1671****************************************************************/1672static unsigned HUF_isError(size_t code) { return ERR_isError(code); }1673#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */1674167516761677/*-*******************************************************1678* Huff0 : Huffman block decompression1679*********************************************************/1680typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */16811682typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4; /* double-symbols decoding */16831684typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;16851686/*! HUF_readStats1687Read compact Huffman tree, saved by HUF_writeCTable1688@huffWeight : destination buffer1689@return : size read from `src`1690*/1691static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,1692U32* nbSymbolsPtr, U32* tableLogPtr,1693const void* src, size_t srcSize)1694{1695U32 weightTotal;1696U32 tableLog;1697const BYTE* ip = (const BYTE*) src;1698size_t iSize;1699size_t oSize;1700U32 n;17011702if (!srcSize) return ERROR(srcSize_wrong);1703iSize = ip[0];1704//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */17051706if (iSize >= 128) /* special header */1707{1708if (iSize >= (242)) /* RLE */1709{1710static int l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };1711oSize = l[iSize-242];1712memset(huffWeight, 1, hwSize);1713iSize = 0;1714}1715else /* Incompressible */1716{1717oSize = iSize - 127;1718iSize = ((oSize+1)/2);1719if (iSize+1 > srcSize) return ERROR(srcSize_wrong);1720if (oSize >= hwSize) return ERROR(corruption_detected);1721ip += 1;1722for (n=0; n<oSize; n+=2)1723{1724huffWeight[n] = ip[n/2] >> 4;1725huffWeight[n+1] = ip[n/2] & 15;1726}1727}1728}1729else /* header compressed with FSE (normal case) */1730{1731if (iSize+1 > srcSize) return ERROR(srcSize_wrong);1732oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */1733if (FSE_isError(oSize)) return oSize;1734}17351736/* collect weight stats */1737memset(rankStats, 0, (HUF_ABSOLUTEMAX_TABLELOG + 1) * sizeof(U32));1738weightTotal = 0;1739for (n=0; n<oSize; n++)1740{1741if (huffWeight[n] >= HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);1742rankStats[huffWeight[n]]++;1743weightTotal += (1 << huffWeight[n]) >> 1;1744}1745if (weightTotal == 0) return ERROR(corruption_detected);17461747/* get last non-null symbol weight (implied, total must be 2^n) */1748tableLog = BIT_highbit32(weightTotal) + 1;1749if (tableLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);1750{1751U32 total = 1 << tableLog;1752U32 rest = total - weightTotal;1753U32 verif = 1 << BIT_highbit32(rest);1754U32 lastWeight = BIT_highbit32(rest) + 1;1755if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */1756huffWeight[oSize] = (BYTE)lastWeight;1757rankStats[lastWeight]++;1758}17591760/* check tree construction validity */1761if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */17621763/* results */1764*nbSymbolsPtr = (U32)(oSize+1);1765*tableLogPtr = tableLog;1766return iSize+1;1767}176817691770/**************************/1771/* single-symbol decoding */1772/**************************/17731774static size_t HUF_readDTableX2 (U16* DTable, const void* src, size_t srcSize)1775{1776BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1];1777U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */1778U32 tableLog = 0;1779size_t iSize;1780U32 nbSymbols = 0;1781U32 n;1782U32 nextRankStart;1783void* const dtPtr = DTable + 1;1784HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;17851786HUF_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */1787//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */17881789iSize = HUF_readStats(huffWeight, HUF_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);1790if (HUF_isError(iSize)) return iSize;17911792/* check result */1793if (tableLog > DTable[0]) return ERROR(tableLog_tooLarge); /* DTable is too small */1794DTable[0] = (U16)tableLog; /* maybe should separate sizeof DTable, as allocated, from used size of DTable, in case of DTable re-use */17951796/* Prepare ranks */1797nextRankStart = 0;1798for (n=1; n<=tableLog; n++)1799{1800U32 current = nextRankStart;1801nextRankStart += (rankVal[n] << (n-1));1802rankVal[n] = current;1803}18041805/* fill DTable */1806for (n=0; n<nbSymbols; n++)1807{1808const U32 w = huffWeight[n];1809const U32 length = (1 << w) >> 1;1810U32 i;1811HUF_DEltX2 D;1812D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);1813for (i = rankVal[w]; i < rankVal[w] + length; i++)1814dt[i] = D;1815rankVal[w] += length;1816}18171818return iSize;1819}18201821static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)1822{1823const size_t val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */1824const BYTE c = dt[val].byte;1825BIT_skipBits(Dstream, dt[val].nbBits);1826return c;1827}18281829#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \1830*ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)18311832#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \1833if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \1834HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)18351836#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \1837if (MEM_64bits()) \1838HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)18391840static inline size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog)1841{1842BYTE* const pStart = p;18431844/* up to 4 symbols at a time */1845while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4))1846{1847HUF_DECODE_SYMBOLX2_2(p, bitDPtr);1848HUF_DECODE_SYMBOLX2_1(p, bitDPtr);1849HUF_DECODE_SYMBOLX2_2(p, bitDPtr);1850HUF_DECODE_SYMBOLX2_0(p, bitDPtr);1851}18521853/* closer to the end */1854while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd))1855HUF_DECODE_SYMBOLX2_0(p, bitDPtr);18561857/* no more data to retrieve from bitstream, hence no need to reload */1858while (p < pEnd)1859HUF_DECODE_SYMBOLX2_0(p, bitDPtr);18601861return pEnd-pStart;1862}186318641865static size_t HUF_decompress4X2_usingDTable(1866void* dst, size_t dstSize,1867const void* cSrc, size_t cSrcSize,1868const U16* DTable)1869{1870if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */18711872{1873const BYTE* const istart = (const BYTE*) cSrc;1874BYTE* const ostart = (BYTE*) dst;1875BYTE* const oend = ostart + dstSize;1876const void* const dtPtr = DTable;1877const HUF_DEltX2* const dt = ((const HUF_DEltX2*)dtPtr) +1;1878const U32 dtLog = DTable[0];1879size_t errorCode;18801881/* Init */1882BIT_DStream_t bitD1;1883BIT_DStream_t bitD2;1884BIT_DStream_t bitD3;1885BIT_DStream_t bitD4;1886const size_t length1 = MEM_readLE16(istart);1887const size_t length2 = MEM_readLE16(istart+2);1888const size_t length3 = MEM_readLE16(istart+4);1889size_t length4;1890const BYTE* const istart1 = istart + 6; /* jumpTable */1891const BYTE* const istart2 = istart1 + length1;1892const BYTE* const istart3 = istart2 + length2;1893const BYTE* const istart4 = istart3 + length3;1894const size_t segmentSize = (dstSize+3) / 4;1895BYTE* const opStart2 = ostart + segmentSize;1896BYTE* const opStart3 = opStart2 + segmentSize;1897BYTE* const opStart4 = opStart3 + segmentSize;1898BYTE* op1 = ostart;1899BYTE* op2 = opStart2;1900BYTE* op3 = opStart3;1901BYTE* op4 = opStart4;1902U32 endSignal;19031904length4 = cSrcSize - (length1 + length2 + length3 + 6);1905if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */1906errorCode = BIT_initDStream(&bitD1, istart1, length1);1907if (HUF_isError(errorCode)) return errorCode;1908errorCode = BIT_initDStream(&bitD2, istart2, length2);1909if (HUF_isError(errorCode)) return errorCode;1910errorCode = BIT_initDStream(&bitD3, istart3, length3);1911if (HUF_isError(errorCode)) return errorCode;1912errorCode = BIT_initDStream(&bitD4, istart4, length4);1913if (HUF_isError(errorCode)) return errorCode;19141915/* 16-32 symbols per loop (4-8 symbols per stream) */1916endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);1917for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; )1918{1919HUF_DECODE_SYMBOLX2_2(op1, &bitD1);1920HUF_DECODE_SYMBOLX2_2(op2, &bitD2);1921HUF_DECODE_SYMBOLX2_2(op3, &bitD3);1922HUF_DECODE_SYMBOLX2_2(op4, &bitD4);1923HUF_DECODE_SYMBOLX2_1(op1, &bitD1);1924HUF_DECODE_SYMBOLX2_1(op2, &bitD2);1925HUF_DECODE_SYMBOLX2_1(op3, &bitD3);1926HUF_DECODE_SYMBOLX2_1(op4, &bitD4);1927HUF_DECODE_SYMBOLX2_2(op1, &bitD1);1928HUF_DECODE_SYMBOLX2_2(op2, &bitD2);1929HUF_DECODE_SYMBOLX2_2(op3, &bitD3);1930HUF_DECODE_SYMBOLX2_2(op4, &bitD4);1931HUF_DECODE_SYMBOLX2_0(op1, &bitD1);1932HUF_DECODE_SYMBOLX2_0(op2, &bitD2);1933HUF_DECODE_SYMBOLX2_0(op3, &bitD3);1934HUF_DECODE_SYMBOLX2_0(op4, &bitD4);19351936endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);1937}19381939/* check corruption */1940if (op1 > opStart2) return ERROR(corruption_detected);1941if (op2 > opStart3) return ERROR(corruption_detected);1942if (op3 > opStart4) return ERROR(corruption_detected);1943/* note : op4 supposed already verified within main loop */19441945/* finish bitStreams one by one */1946HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);1947HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);1948HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);1949HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);19501951/* check */1952endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);1953if (!endSignal) return ERROR(corruption_detected);19541955/* decoded size */1956return dstSize;1957}1958}195919601961static size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)1962{1963HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_MAX_TABLELOG);1964const BYTE* ip = (const BYTE*) cSrc;1965size_t errorCode;19661967errorCode = HUF_readDTableX2 (DTable, cSrc, cSrcSize);1968if (HUF_isError(errorCode)) return errorCode;1969if (errorCode >= cSrcSize) return ERROR(srcSize_wrong);1970ip += errorCode;1971cSrcSize -= errorCode;19721973return HUF_decompress4X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable);1974}197519761977/***************************/1978/* double-symbols decoding */1979/***************************/19801981static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,1982const U32* rankValOrigin, const int minWeight,1983const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,1984U32 nbBitsBaseline, U16 baseSeq)1985{1986HUF_DEltX4 DElt;1987U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];1988U32 s;19891990/* get pre-calculated rankVal */1991memcpy(rankVal, rankValOrigin, sizeof(rankVal));19921993/* fill skipped values */1994if (minWeight>1)1995{1996U32 i, skipSize = rankVal[minWeight];1997MEM_writeLE16(&(DElt.sequence), baseSeq);1998DElt.nbBits = (BYTE)(consumed);1999DElt.length = 1;2000for (i = 0; i < skipSize; i++)2001DTable[i] = DElt;2002}20032004/* fill DTable */2005for (s=0; s<sortedListSize; s++) /* note : sortedSymbols already skipped */2006{2007const U32 symbol = sortedSymbols[s].symbol;2008const U32 weight = sortedSymbols[s].weight;2009const U32 nbBits = nbBitsBaseline - weight;2010const U32 length = 1 << (sizeLog-nbBits);2011const U32 start = rankVal[weight];2012U32 i = start;2013const U32 end = start + length;20142015MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));2016DElt.nbBits = (BYTE)(nbBits + consumed);2017DElt.length = 2;2018do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */20192020rankVal[weight] += length;2021}2022}20232024typedef U32 rankVal_t[HUF_ABSOLUTEMAX_TABLELOG][HUF_ABSOLUTEMAX_TABLELOG + 1];20252026static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,2027const sortedSymbol_t* sortedList, const U32 sortedListSize,2028const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,2029const U32 nbBitsBaseline)2030{2031U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];2032const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */2033const U32 minBits = nbBitsBaseline - maxWeight;2034U32 s;20352036memcpy(rankVal, rankValOrigin, sizeof(rankVal));20372038/* fill DTable */2039for (s=0; s<sortedListSize; s++)2040{2041const U16 symbol = sortedList[s].symbol;2042const U32 weight = sortedList[s].weight;2043const U32 nbBits = nbBitsBaseline - weight;2044const U32 start = rankVal[weight];2045const U32 length = 1 << (targetLog-nbBits);20462047if (targetLog-nbBits >= minBits) /* enough room for a second symbol */2048{2049U32 sortedRank;2050int minWeight = nbBits + scaleLog;2051if (minWeight < 1) minWeight = 1;2052sortedRank = rankStart[minWeight];2053HUF_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,2054rankValOrigin[nbBits], minWeight,2055sortedList+sortedRank, sortedListSize-sortedRank,2056nbBitsBaseline, symbol);2057}2058else2059{2060U32 i;2061const U32 end = start + length;2062HUF_DEltX4 DElt;20632064MEM_writeLE16(&(DElt.sequence), symbol);2065DElt.nbBits = (BYTE)(nbBits);2066DElt.length = 1;2067for (i = start; i < end; i++)2068DTable[i] = DElt;2069}2070rankVal[weight] += length;2071}2072}20732074static size_t HUF_readDTableX4 (U32* DTable, const void* src, size_t srcSize)2075{2076BYTE weightList[HUF_MAX_SYMBOL_VALUE + 1];2077sortedSymbol_t sortedSymbol[HUF_MAX_SYMBOL_VALUE + 1];2078U32 rankStats[HUF_ABSOLUTEMAX_TABLELOG + 1] = { 0 };2079U32 rankStart0[HUF_ABSOLUTEMAX_TABLELOG + 2] = { 0 };2080U32* const rankStart = rankStart0+1;2081rankVal_t rankVal;2082U32 tableLog, maxW, sizeOfSort, nbSymbols;2083const U32 memLog = DTable[0];2084size_t iSize;2085void* dtPtr = DTable;2086HUF_DEltX4* const dt = ((HUF_DEltX4*)dtPtr) + 1;20872088HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(U32)); /* if compilation fails here, assertion is false */2089if (memLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);2090//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */20912092iSize = HUF_readStats(weightList, HUF_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);2093if (HUF_isError(iSize)) return iSize;20942095/* check result */2096if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */20972098/* find maxWeight */2099for (maxW = tableLog; rankStats[maxW]==0; maxW--)2100{ if (!maxW) return ERROR(GENERIC); } /* necessarily finds a solution before maxW==0 */21012102/* Get start index of each weight */2103{2104U32 w, nextRankStart = 0;2105for (w=1; w<=maxW; w++)2106{2107U32 current = nextRankStart;2108nextRankStart += rankStats[w];2109rankStart[w] = current;2110}2111rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/2112sizeOfSort = nextRankStart;2113}21142115/* sort symbols by weight */2116{2117U32 s;2118for (s=0; s<nbSymbols; s++)2119{2120U32 w = weightList[s];2121U32 r = rankStart[w]++;2122sortedSymbol[r].symbol = (BYTE)s;2123sortedSymbol[r].weight = (BYTE)w;2124}2125rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */2126}21272128/* Build rankVal */2129{2130const U32 minBits = tableLog+1 - maxW;2131U32 nextRankVal = 0;2132U32 w, consumed;2133const int rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */2134U32* rankVal0 = rankVal[0];2135for (w=1; w<=maxW; w++)2136{2137U32 current = nextRankVal;2138nextRankVal += rankStats[w] << (w+rescale);2139rankVal0[w] = current;2140}2141for (consumed = minBits; consumed <= memLog - minBits; consumed++)2142{2143U32* rankValPtr = rankVal[consumed];2144for (w = 1; w <= maxW; w++)2145{2146rankValPtr[w] = rankVal0[w] >> consumed;2147}2148}2149}21502151HUF_fillDTableX4(dt, memLog,2152sortedSymbol, sizeOfSort,2153rankStart0, rankVal, maxW,2154tableLog+1);21552156return iSize;2157}215821592160static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)2161{2162const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */2163memcpy(op, dt+val, 2);2164BIT_skipBits(DStream, dt[val].nbBits);2165return dt[val].length;2166}21672168static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)2169{2170const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */2171memcpy(op, dt+val, 1);2172if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);2173else2174{2175if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8))2176{2177BIT_skipBits(DStream, dt[val].nbBits);2178if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))2179DStream->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 */2180}2181}2182return 1;2183}218421852186#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \2187ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)21882189#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \2190if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \2191ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)21922193#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \2194if (MEM_64bits()) \2195ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)21962197static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog)2198{2199BYTE* const pStart = p;22002201/* up to 8 symbols at a time */2202while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd-7))2203{2204HUF_DECODE_SYMBOLX4_2(p, bitDPtr);2205HUF_DECODE_SYMBOLX4_1(p, bitDPtr);2206HUF_DECODE_SYMBOLX4_2(p, bitDPtr);2207HUF_DECODE_SYMBOLX4_0(p, bitDPtr);2208}22092210/* closer to the end */2211while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-2))2212HUF_DECODE_SYMBOLX4_0(p, bitDPtr);22132214while (p <= pEnd-2)2215HUF_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */22162217if (p < pEnd)2218p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);22192220return p-pStart;2221}22222223static size_t HUF_decompress4X4_usingDTable(2224void* dst, size_t dstSize,2225const void* cSrc, size_t cSrcSize,2226const U32* DTable)2227{2228if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */22292230{2231const BYTE* const istart = (const BYTE*) cSrc;2232BYTE* const ostart = (BYTE*) dst;2233BYTE* const oend = ostart + dstSize;2234const void* const dtPtr = DTable;2235const HUF_DEltX4* const dt = ((const HUF_DEltX4*)dtPtr) +1;2236const U32 dtLog = DTable[0];2237size_t errorCode;22382239/* Init */2240BIT_DStream_t bitD1;2241BIT_DStream_t bitD2;2242BIT_DStream_t bitD3;2243BIT_DStream_t bitD4;2244const size_t length1 = MEM_readLE16(istart);2245const size_t length2 = MEM_readLE16(istart+2);2246const size_t length3 = MEM_readLE16(istart+4);2247size_t length4;2248const BYTE* const istart1 = istart + 6; /* jumpTable */2249const BYTE* const istart2 = istart1 + length1;2250const BYTE* const istart3 = istart2 + length2;2251const BYTE* const istart4 = istart3 + length3;2252const size_t segmentSize = (dstSize+3) / 4;2253BYTE* const opStart2 = ostart + segmentSize;2254BYTE* const opStart3 = opStart2 + segmentSize;2255BYTE* const opStart4 = opStart3 + segmentSize;2256BYTE* op1 = ostart;2257BYTE* op2 = opStart2;2258BYTE* op3 = opStart3;2259BYTE* op4 = opStart4;2260U32 endSignal;22612262length4 = cSrcSize - (length1 + length2 + length3 + 6);2263if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */2264errorCode = BIT_initDStream(&bitD1, istart1, length1);2265if (HUF_isError(errorCode)) return errorCode;2266errorCode = BIT_initDStream(&bitD2, istart2, length2);2267if (HUF_isError(errorCode)) return errorCode;2268errorCode = BIT_initDStream(&bitD3, istart3, length3);2269if (HUF_isError(errorCode)) return errorCode;2270errorCode = BIT_initDStream(&bitD4, istart4, length4);2271if (HUF_isError(errorCode)) return errorCode;22722273/* 16-32 symbols per loop (4-8 symbols per stream) */2274endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);2275for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; )2276{2277HUF_DECODE_SYMBOLX4_2(op1, &bitD1);2278HUF_DECODE_SYMBOLX4_2(op2, &bitD2);2279HUF_DECODE_SYMBOLX4_2(op3, &bitD3);2280HUF_DECODE_SYMBOLX4_2(op4, &bitD4);2281HUF_DECODE_SYMBOLX4_1(op1, &bitD1);2282HUF_DECODE_SYMBOLX4_1(op2, &bitD2);2283HUF_DECODE_SYMBOLX4_1(op3, &bitD3);2284HUF_DECODE_SYMBOLX4_1(op4, &bitD4);2285HUF_DECODE_SYMBOLX4_2(op1, &bitD1);2286HUF_DECODE_SYMBOLX4_2(op2, &bitD2);2287HUF_DECODE_SYMBOLX4_2(op3, &bitD3);2288HUF_DECODE_SYMBOLX4_2(op4, &bitD4);2289HUF_DECODE_SYMBOLX4_0(op1, &bitD1);2290HUF_DECODE_SYMBOLX4_0(op2, &bitD2);2291HUF_DECODE_SYMBOLX4_0(op3, &bitD3);2292HUF_DECODE_SYMBOLX4_0(op4, &bitD4);22932294endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);2295}22962297/* check corruption */2298if (op1 > opStart2) return ERROR(corruption_detected);2299if (op2 > opStart3) return ERROR(corruption_detected);2300if (op3 > opStart4) return ERROR(corruption_detected);2301/* note : op4 supposed already verified within main loop */23022303/* finish bitStreams one by one */2304HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);2305HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);2306HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);2307HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);23082309/* check */2310endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);2311if (!endSignal) return ERROR(corruption_detected);23122313/* decoded size */2314return dstSize;2315}2316}231723182319static size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)2320{2321HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_MAX_TABLELOG);2322const BYTE* ip = (const BYTE*) cSrc;23232324size_t hSize = HUF_readDTableX4 (DTable, cSrc, cSrcSize);2325if (HUF_isError(hSize)) return hSize;2326if (hSize >= cSrcSize) return ERROR(srcSize_wrong);2327ip += hSize;2328cSrcSize -= hSize;23292330return HUF_decompress4X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable);2331}233223332334/**********************************/2335/* Generic decompression selector */2336/**********************************/23372338typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;2339static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =2340{2341/* single, double, quad */2342{{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */2343{{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */2344{{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */2345{{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */2346{{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */2347{{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */2348{{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */2349{{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */2350{{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */2351{{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */2352{{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */2353{{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */2354{{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */2355{{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */2356{{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */2357{{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */2358};23592360typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);23612362static size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)2363{2364static const decompressionAlgo decompress[3] = { HUF_decompress4X2, HUF_decompress4X4, NULL };2365/* estimate decompression time */2366U32 Q;2367const U32 D256 = (U32)(dstSize >> 8);2368U32 Dtime[3];2369U32 algoNb = 0;2370int n;23712372/* validation checks */2373if (dstSize == 0) return ERROR(dstSize_tooSmall);2374if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */2375if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */2376if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */23772378/* decoder timing evaluation */2379Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */2380for (n=0; n<3; n++)2381Dtime[n] = algoTime[Q][n].tableTime + (algoTime[Q][n].decode256Time * D256);23822383Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */23842385if (Dtime[1] < Dtime[0]) algoNb = 1;23862387return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);23882389//return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */2390//return HUF_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */2391//return HUF_decompress4X6(dst, dstSize, cSrc, cSrcSize); /* multi-streams quad-symbols decoding */2392}2393239423952396#endif /* ZSTD_CCOMMON_H_MODULE */239723982399/*2400zstd - decompression module fo v0.4 legacy format2401Copyright (C) 2015-2016, Yann Collet.24022403BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)24042405Redistribution and use in source and binary forms, with or without2406modification, are permitted provided that the following conditions are2407met:2408* Redistributions of source code must retain the above copyright2409notice, this list of conditions and the following disclaimer.2410* Redistributions in binary form must reproduce the above2411copyright notice, this list of conditions and the following disclaimer2412in the documentation and/or other materials provided with the2413distribution.2414THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS2415"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT2416LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR2417A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT2418OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,2419SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT2420LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,2421DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY2422THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT2423(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE2424OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24252426You can contact the author at :2427- zstd source repository : https://github.com/Cyan4973/zstd2428- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c2429*/24302431/* ***************************************************************2432* Tuning parameters2433*****************************************************************/2434/*!2435* HEAPMODE :2436* Select how default decompression function ZSTD_decompress() will allocate memory,2437* in memory stack (0), or in memory heap (1, requires malloc())2438*/2439#ifndef ZSTD_HEAPMODE2440# define ZSTD_HEAPMODE 12441#endif244224432444/* *******************************************************2445* Includes2446*********************************************************/2447#include <stdlib.h> /* calloc */2448#include <string.h> /* memcpy, memmove */2449#include <stdio.h> /* debug : printf */245024512452/* *******************************************************2453* Compiler specifics2454*********************************************************/2455#ifdef _MSC_VER /* Visual Studio */2456# include <intrin.h> /* For Visual 2005 */2457# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */2458# pragma warning(disable : 4324) /* disable: C4324: padded structure */2459#endif246024612462/* *************************************2463* Local types2464***************************************/2465typedef struct2466{2467blockType_t blockType;2468U32 origSize;2469} blockProperties_t;247024712472/* *******************************************************2473* Memory operations2474**********************************************************/2475static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }247624772478/* *************************************2479* Error Management2480***************************************/24812482/*! ZSTD_isError2483* tells if a return value is an error code */2484static unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }248524862487/* *************************************************************2488* Context management2489***************************************************************/2490typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,2491ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;24922493struct ZSTDv04_Dctx_s2494{2495U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];2496U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];2497U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];2498const void* previousDstEnd;2499const void* base;2500const void* vBase;2501const void* dictEnd;2502size_t expected;2503size_t headerSize;2504ZSTD_parameters params;2505blockType_t bType;2506ZSTD_dStage stage;2507const BYTE* litPtr;2508size_t litSize;2509BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */];2510BYTE headerBuffer[ZSTD_frameHeaderSize_max];2511}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */25122513static size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)2514{2515dctx->expected = ZSTD_frameHeaderSize_min;2516dctx->stage = ZSTDds_getFrameHeaderSize;2517dctx->previousDstEnd = NULL;2518dctx->base = NULL;2519dctx->vBase = NULL;2520dctx->dictEnd = NULL;2521return 0;2522}25232524static ZSTD_DCtx* ZSTD_createDCtx(void)2525{2526ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));2527if (dctx==NULL) return NULL;2528ZSTD_resetDCtx(dctx);2529return dctx;2530}25312532static size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)2533{2534free(dctx);2535return 0;2536}253725382539/* *************************************************************2540* Decompression section2541***************************************************************/2542/** ZSTD_decodeFrameHeader_Part12543* decode the 1st part of the Frame Header, which tells Frame Header size.2544* srcSize must be == ZSTD_frameHeaderSize_min2545* @return : the full size of the Frame Header */2546static size_t ZSTD_decodeFrameHeader_Part1(ZSTD_DCtx* zc, const void* src, size_t srcSize)2547{2548U32 magicNumber;2549if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);2550magicNumber = MEM_readLE32(src);2551if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);2552zc->headerSize = ZSTD_frameHeaderSize_min;2553return zc->headerSize;2554}255525562557static size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize)2558{2559U32 magicNumber;2560if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_max;2561magicNumber = MEM_readLE32(src);2562if (magicNumber != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);2563memset(params, 0, sizeof(*params));2564params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTD_WINDOWLOG_ABSOLUTEMIN;2565if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */2566return 0;2567}25682569/** ZSTD_decodeFrameHeader_Part22570* decode the full Frame Header2571* srcSize must be the size provided by ZSTD_decodeFrameHeader_Part12572* @return : 0, or an error code, which can be tested using ZSTD_isError() */2573static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_t srcSize)2574{2575size_t result;2576if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);2577result = ZSTD_getFrameParams(&(zc->params), src, srcSize);2578if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupported);2579return result;2580}258125822583static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)2584{2585const BYTE* const in = (const BYTE* const)src;2586BYTE headerFlags;2587U32 cSize;25882589if (srcSize < 3) return ERROR(srcSize_wrong);25902591headerFlags = *in;2592cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);25932594bpPtr->blockType = (blockType_t)(headerFlags >> 6);2595bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;25962597if (bpPtr->blockType == bt_end) return 0;2598if (bpPtr->blockType == bt_rle) return 1;2599return cSize;2600}26012602static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)2603{2604if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);2605if (srcSize > 0) {2606memcpy(dst, src, srcSize);2607}2608return srcSize;2609}261026112612/** ZSTD_decompressLiterals2613@return : nb of bytes read from src, or an error code*/2614static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr,2615const void* src, size_t srcSize)2616{2617const BYTE* ip = (const BYTE*)src;26182619const size_t litSize = (MEM_readLE32(src) & 0x1FFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */2620const size_t litCSize = (MEM_readLE32(ip+2) & 0xFFFFFF) >> 5; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */26212622if (litSize > *maxDstSizePtr) return ERROR(corruption_detected);2623if (litCSize + 5 > srcSize) return ERROR(corruption_detected);26242625if (HUF_isError(HUF_decompress(dst, litSize, ip+5, litCSize))) return ERROR(corruption_detected);26262627*maxDstSizePtr = litSize;2628return litCSize + 5;2629}263026312632/** ZSTD_decodeLiteralsBlock2633@return : nb of bytes read from src (< srcSize ) */2634static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,2635const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */2636{2637const BYTE* const istart = (const BYTE*) src;26382639/* any compressed block with literals segment must be at least this size */2640if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);26412642switch(*istart & 3)2643{2644/* compressed */2645case 0:2646{2647size_t litSize = BLOCKSIZE;2648const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize);2649dctx->litPtr = dctx->litBuffer;2650dctx->litSize = litSize;2651memset(dctx->litBuffer + dctx->litSize, 0, 8);2652return readSize; /* works if it's an error too */2653}2654case IS_RAW:2655{2656const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */2657if (litSize > srcSize-11) /* risk of reading too far with wildcopy */2658{2659if (litSize > BLOCKSIZE) return ERROR(corruption_detected);2660if (litSize > srcSize-3) return ERROR(corruption_detected);2661memcpy(dctx->litBuffer, istart, litSize);2662dctx->litPtr = dctx->litBuffer;2663dctx->litSize = litSize;2664memset(dctx->litBuffer + dctx->litSize, 0, 8);2665return litSize+3;2666}2667/* direct reference into compressed stream */2668dctx->litPtr = istart+3;2669dctx->litSize = litSize;2670return litSize+3; }2671case IS_RLE:2672{2673const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */2674if (litSize > BLOCKSIZE) return ERROR(corruption_detected);2675memset(dctx->litBuffer, istart[3], litSize + 8);2676dctx->litPtr = dctx->litBuffer;2677dctx->litSize = litSize;2678return 4;2679}2680default:2681return ERROR(corruption_detected); /* forbidden nominal case */2682}2683}268426852686static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,2687FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,2688const void* src, size_t srcSize)2689{2690const BYTE* const istart = (const BYTE* const)src;2691const BYTE* ip = istart;2692const BYTE* const iend = istart + srcSize;2693U32 LLtype, Offtype, MLtype;2694U32 LLlog, Offlog, MLlog;2695size_t dumpsLength;26962697/* check */2698if (srcSize < 5) return ERROR(srcSize_wrong);26992700/* SeqHead */2701*nbSeq = MEM_readLE16(ip); ip+=2;2702LLtype = *ip >> 6;2703Offtype = (*ip >> 4) & 3;2704MLtype = (*ip >> 2) & 3;2705if (*ip & 2)2706{2707dumpsLength = ip[2];2708dumpsLength += ip[1] << 8;2709ip += 3;2710}2711else2712{2713dumpsLength = ip[1];2714dumpsLength += (ip[0] & 1) << 8;2715ip += 2;2716}2717*dumpsPtr = ip;2718ip += dumpsLength;2719*dumpsLengthPtr = dumpsLength;27202721/* check */2722if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */27232724/* sequences */2725{2726S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */2727size_t headerSize;27282729/* Build DTables */2730switch(LLtype)2731{2732case bt_rle :2733LLlog = 0;2734FSE_buildDTable_rle(DTableLL, *ip++); break;2735case bt_raw :2736LLlog = LLbits;2737FSE_buildDTable_raw(DTableLL, LLbits); break;2738default :2739{ U32 max = MaxLL;2740headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);2741if (FSE_isError(headerSize)) return ERROR(GENERIC);2742if (LLlog > LLFSELog) return ERROR(corruption_detected);2743ip += headerSize;2744FSE_buildDTable(DTableLL, norm, max, LLlog);2745} }27462747switch(Offtype)2748{2749case bt_rle :2750Offlog = 0;2751if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */2752FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */2753break;2754case bt_raw :2755Offlog = Offbits;2756FSE_buildDTable_raw(DTableOffb, Offbits); break;2757default :2758{ U32 max = MaxOff;2759headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);2760if (FSE_isError(headerSize)) return ERROR(GENERIC);2761if (Offlog > OffFSELog) return ERROR(corruption_detected);2762ip += headerSize;2763FSE_buildDTable(DTableOffb, norm, max, Offlog);2764} }27652766switch(MLtype)2767{2768case bt_rle :2769MLlog = 0;2770if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */2771FSE_buildDTable_rle(DTableML, *ip++); break;2772case bt_raw :2773MLlog = MLbits;2774FSE_buildDTable_raw(DTableML, MLbits); break;2775default :2776{ U32 max = MaxML;2777headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);2778if (FSE_isError(headerSize)) return ERROR(GENERIC);2779if (MLlog > MLFSELog) return ERROR(corruption_detected);2780ip += headerSize;2781FSE_buildDTable(DTableML, norm, max, MLlog);2782} } }27832784return ip-istart;2785}278627872788typedef struct {2789size_t litLength;2790size_t offset;2791size_t matchLength;2792} seq_t;27932794typedef struct {2795BIT_DStream_t DStream;2796FSE_DState_t stateLL;2797FSE_DState_t stateOffb;2798FSE_DState_t stateML;2799size_t prevOffset;2800const BYTE* dumps;2801const BYTE* dumpsEnd;2802} seqState_t;280328042805static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)2806{2807size_t litLength;2808size_t prevOffset;2809size_t offset;2810size_t matchLength;2811const BYTE* dumps = seqState->dumps;2812const BYTE* const de = seqState->dumpsEnd;28132814/* Literal length */2815litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));2816prevOffset = litLength ? seq->offset : seqState->prevOffset;2817if (litLength == MaxLL) {2818const U32 add = dumps<de ? *dumps++ : 0;2819if (add < 255) litLength += add;2820else if (dumps + 3 <= de) {2821litLength = MEM_readLE24(dumps);2822dumps += 3;2823}2824if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */2825}28262827/* Offset */2828{ static const U32 offsetPrefix[MaxOff+1] = {28291 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,2830512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,2831524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };2832U32 offsetCode, nbBits;2833offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */2834if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));2835nbBits = offsetCode - 1;2836if (offsetCode==0) nbBits = 0; /* cmove */2837offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);2838if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));2839if (offsetCode==0) offset = prevOffset; /* cmove */2840if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */2841}28422843/* MatchLength */2844matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));2845if (matchLength == MaxML) {2846const U32 add = dumps<de ? *dumps++ : 0;2847if (add < 255) matchLength += add;2848else if (dumps + 3 <= de){2849matchLength = MEM_readLE24(dumps);2850dumps += 3;2851}2852if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */2853}2854matchLength += MINMATCH;28552856/* save result */2857seq->litLength = litLength;2858seq->offset = offset;2859seq->matchLength = matchLength;2860seqState->dumps = dumps;2861}286228632864static size_t ZSTD_execSequence(BYTE* op,2865BYTE* const oend, seq_t sequence,2866const BYTE** litPtr, const BYTE* const litLimit,2867const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)2868{2869static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */2870static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */2871BYTE* const oLitEnd = op + sequence.litLength;2872const size_t sequenceLength = sequence.litLength + sequence.matchLength;2873BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */2874BYTE* const oend_8 = oend-8;2875const BYTE* const litEnd = *litPtr + sequence.litLength;2876const BYTE* match = oLitEnd - sequence.offset;28772878/* check */2879if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */2880if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */2881if (litEnd > litLimit) return ERROR(corruption_detected); /* risk read beyond lit buffer */28822883/* copy Literals */2884ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */2885op = oLitEnd;2886*litPtr = litEnd; /* update for next sequence */28872888/* copy Match */2889if (sequence.offset > (size_t)(oLitEnd - base))2890{2891/* offset beyond prefix */2892if (sequence.offset > (size_t)(oLitEnd - vBase))2893return ERROR(corruption_detected);2894match = dictEnd - (base-match);2895if (match + sequence.matchLength <= dictEnd)2896{2897memmove(oLitEnd, match, sequence.matchLength);2898return sequenceLength;2899}2900/* span extDict & currentPrefixSegment */2901{2902size_t length1 = dictEnd - match;2903memmove(oLitEnd, match, length1);2904op = oLitEnd + length1;2905sequence.matchLength -= length1;2906match = base;2907if (op > oend_8 || sequence.matchLength < MINMATCH) {2908while (op < oMatchEnd) *op++ = *match++;2909return sequenceLength;2910}2911}2912}2913/* Requirement: op <= oend_8 */29142915/* match within prefix */2916if (sequence.offset < 8) {2917/* close range match, overlap */2918const int sub2 = dec64table[sequence.offset];2919op[0] = match[0];2920op[1] = match[1];2921op[2] = match[2];2922op[3] = match[3];2923match += dec32table[sequence.offset];2924ZSTD_copy4(op+4, match);2925match -= sub2;2926} else {2927ZSTD_copy8(op, match);2928}2929op += 8; match += 8;29302931if (oMatchEnd > oend-(16-MINMATCH))2932{2933if (op < oend_8)2934{2935ZSTD_wildcopy(op, match, oend_8 - op);2936match += oend_8 - op;2937op = oend_8;2938}2939while (op < oMatchEnd) *op++ = *match++;2940}2941else2942{2943ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8, but must be signed */2944}2945return sequenceLength;2946}294729482949static size_t ZSTD_decompressSequences(2950ZSTD_DCtx* dctx,2951void* dst, size_t maxDstSize,2952const void* seqStart, size_t seqSize)2953{2954const BYTE* ip = (const BYTE*)seqStart;2955const BYTE* const iend = ip + seqSize;2956BYTE* const ostart = (BYTE* const)dst;2957BYTE* op = ostart;2958BYTE* const oend = ostart + maxDstSize;2959size_t errorCode, dumpsLength;2960const BYTE* litPtr = dctx->litPtr;2961const BYTE* const litEnd = litPtr + dctx->litSize;2962int nbSeq;2963const BYTE* dumps;2964U32* DTableLL = dctx->LLTable;2965U32* DTableML = dctx->MLTable;2966U32* DTableOffb = dctx->OffTable;2967const BYTE* const base = (const BYTE*) (dctx->base);2968const BYTE* const vBase = (const BYTE*) (dctx->vBase);2969const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);29702971/* Build Decoding Tables */2972errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,2973DTableLL, DTableML, DTableOffb,2974ip, iend-ip);2975if (ZSTD_isError(errorCode)) return errorCode;2976ip += errorCode;29772978/* Regen sequences */2979{2980seq_t sequence;2981seqState_t seqState;29822983memset(&sequence, 0, sizeof(sequence));2984sequence.offset = 4;2985seqState.dumps = dumps;2986seqState.dumpsEnd = dumps + dumpsLength;2987seqState.prevOffset = 4;2988errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);2989if (ERR_isError(errorCode)) return ERROR(corruption_detected);2990FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);2991FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);2992FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);29932994for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; )2995{2996size_t oneSeqSize;2997nbSeq--;2998ZSTD_decodeSequence(&sequence, &seqState);2999oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);3000if (ZSTD_isError(oneSeqSize)) return oneSeqSize;3001op += oneSeqSize;3002}30033004/* check if reached exact end */3005if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* DStream should be entirely and exactly consumed; otherwise data is corrupted */30063007/* last literal segment */3008{3009size_t lastLLSize = litEnd - litPtr;3010if (litPtr > litEnd) return ERROR(corruption_detected);3011if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);3012if (lastLLSize > 0) {3013if (op != litPtr) memcpy(op, litPtr, lastLLSize);3014op += lastLLSize;3015}3016}3017}30183019return op-ostart;3020}302130223023static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)3024{3025if (dst != dctx->previousDstEnd) /* not contiguous */3026{3027dctx->dictEnd = dctx->previousDstEnd;3028dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));3029dctx->base = dst;3030dctx->previousDstEnd = dst;3031}3032}303330343035static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,3036void* dst, size_t maxDstSize,3037const void* src, size_t srcSize)3038{3039/* blockType == blockCompressed */3040const BYTE* ip = (const BYTE*)src;3041size_t litCSize;30423043if (srcSize > BLOCKSIZE) return ERROR(corruption_detected);30443045/* Decode literals sub-block */3046litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);3047if (ZSTD_isError(litCSize)) return litCSize;3048ip += litCSize;3049srcSize -= litCSize;30503051return ZSTD_decompressSequences(dctx, dst, maxDstSize, ip, srcSize);3052}305330543055static size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,3056void* dst, size_t maxDstSize,3057const void* src, size_t srcSize,3058const void* dict, size_t dictSize)3059{3060const BYTE* ip = (const BYTE*)src;3061const BYTE* iend = ip + srcSize;3062BYTE* const ostart = (BYTE* const)dst;3063BYTE* op = ostart;3064BYTE* const oend = ostart + maxDstSize;3065size_t remainingSize = srcSize;3066blockProperties_t blockProperties;30673068/* init */3069ZSTD_resetDCtx(ctx);3070if (dict)3071{3072ZSTD_decompress_insertDictionary(ctx, dict, dictSize);3073ctx->dictEnd = ctx->previousDstEnd;3074ctx->vBase = (const char*)dst - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));3075ctx->base = dst;3076}3077else3078{3079ctx->vBase = ctx->base = ctx->dictEnd = dst;3080}30813082/* Frame Header */3083{3084size_t frameHeaderSize;3085if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);3086frameHeaderSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);3087if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;3088if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);3089ip += frameHeaderSize; remainingSize -= frameHeaderSize;3090frameHeaderSize = ZSTD_decodeFrameHeader_Part2(ctx, src, frameHeaderSize);3091if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;3092}30933094/* Loop on each block */3095while (1)3096{3097size_t decodedSize=0;3098size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);3099if (ZSTD_isError(cBlockSize)) return cBlockSize;31003101ip += ZSTD_blockHeaderSize;3102remainingSize -= ZSTD_blockHeaderSize;3103if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);31043105switch(blockProperties.blockType)3106{3107case bt_compressed:3108decodedSize = ZSTD_decompressBlock_internal(ctx, op, oend-op, ip, cBlockSize);3109break;3110case bt_raw :3111decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);3112break;3113case bt_rle :3114return ERROR(GENERIC); /* not yet supported */3115break;3116case bt_end :3117/* end of frame */3118if (remainingSize) return ERROR(srcSize_wrong);3119break;3120default:3121return ERROR(GENERIC); /* impossible */3122}3123if (cBlockSize == 0) break; /* bt_end */31243125if (ZSTD_isError(decodedSize)) return decodedSize;3126op += decodedSize;3127ip += cBlockSize;3128remainingSize -= cBlockSize;3129}31303131return op-ostart;3132}31333134/* ZSTD_errorFrameSizeInfoLegacy() :3135assumes `cSize` and `dBound` are _not_ NULL */3136static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret)3137{3138*cSize = ret;3139*dBound = ZSTD_CONTENTSIZE_ERROR;3140}31413142void ZSTDv04_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound)3143{3144const BYTE* ip = (const BYTE*)src;3145size_t remainingSize = srcSize;3146size_t nbBlocks = 0;3147blockProperties_t blockProperties;31483149/* Frame Header */3150if (srcSize < ZSTD_frameHeaderSize_min) {3151ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));3152return;3153}3154if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {3155ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown));3156return;3157}3158ip += ZSTD_frameHeaderSize_min; remainingSize -= ZSTD_frameHeaderSize_min;31593160/* Loop on each block */3161while (1)3162{3163size_t cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);3164if (ZSTD_isError(cBlockSize)) {3165ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, cBlockSize);3166return;3167}31683169ip += ZSTD_blockHeaderSize;3170remainingSize -= ZSTD_blockHeaderSize;3171if (cBlockSize > remainingSize) {3172ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));3173return;3174}31753176if (cBlockSize == 0) break; /* bt_end */31773178ip += cBlockSize;3179remainingSize -= cBlockSize;3180nbBlocks++;3181}31823183*cSize = ip - (const BYTE*)src;3184*dBound = nbBlocks * BLOCKSIZE;3185}31863187/* ******************************3188* Streaming Decompression API3189********************************/3190static size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)3191{3192return dctx->expected;3193}31943195static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)3196{3197/* Sanity check */3198if (srcSize != ctx->expected) return ERROR(srcSize_wrong);3199ZSTD_checkContinuity(ctx, dst);32003201/* Decompress : frame header; part 1 */3202switch (ctx->stage)3203{3204case ZSTDds_getFrameHeaderSize :3205/* get frame header size */3206if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */3207ctx->headerSize = ZSTD_decodeFrameHeader_Part1(ctx, src, ZSTD_frameHeaderSize_min);3208if (ZSTD_isError(ctx->headerSize)) return ctx->headerSize;3209memcpy(ctx->headerBuffer, src, ZSTD_frameHeaderSize_min);3210if (ctx->headerSize > ZSTD_frameHeaderSize_min) return ERROR(GENERIC); /* impossible */3211ctx->expected = 0; /* not necessary to copy more */3212/* fallthrough */3213case ZSTDds_decodeFrameHeader:3214/* get frame header */3215{ size_t const result = ZSTD_decodeFrameHeader_Part2(ctx, ctx->headerBuffer, ctx->headerSize);3216if (ZSTD_isError(result)) return result;3217ctx->expected = ZSTD_blockHeaderSize;3218ctx->stage = ZSTDds_decodeBlockHeader;3219return 0;3220}3221case ZSTDds_decodeBlockHeader:3222/* Decode block header */3223{ blockProperties_t bp;3224size_t const blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);3225if (ZSTD_isError(blockSize)) return blockSize;3226if (bp.blockType == bt_end)3227{3228ctx->expected = 0;3229ctx->stage = ZSTDds_getFrameHeaderSize;3230}3231else3232{3233ctx->expected = blockSize;3234ctx->bType = bp.blockType;3235ctx->stage = ZSTDds_decompressBlock;3236}3237return 0;3238}3239case ZSTDds_decompressBlock:3240{3241/* Decompress : block content */3242size_t rSize;3243switch(ctx->bType)3244{3245case bt_compressed:3246rSize = ZSTD_decompressBlock_internal(ctx, dst, maxDstSize, src, srcSize);3247break;3248case bt_raw :3249rSize = ZSTD_copyRawBlock(dst, maxDstSize, src, srcSize);3250break;3251case bt_rle :3252return ERROR(GENERIC); /* not yet handled */3253break;3254case bt_end : /* should never happen (filtered at phase 1) */3255rSize = 0;3256break;3257default:3258return ERROR(GENERIC);3259}3260ctx->stage = ZSTDds_decodeBlockHeader;3261ctx->expected = ZSTD_blockHeaderSize;3262ctx->previousDstEnd = (char*)dst + rSize;3263return rSize;3264}3265default:3266return ERROR(GENERIC); /* impossible */3267}3268}326932703271static void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* dict, size_t dictSize)3272{3273ctx->dictEnd = ctx->previousDstEnd;3274ctx->vBase = (const char*)dict - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));3275ctx->base = dict;3276ctx->previousDstEnd = (const char*)dict + dictSize;3277}3278327932803281/*3282Buffered version of Zstd compression library3283Copyright (C) 2015, Yann Collet.32843285BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)32863287Redistribution and use in source and binary forms, with or without3288modification, are permitted provided that the following conditions are3289met:3290* Redistributions of source code must retain the above copyright3291notice, this list of conditions and the following disclaimer.3292* Redistributions in binary form must reproduce the above3293copyright notice, this list of conditions and the following disclaimer3294in the documentation and/or other materials provided with the3295distribution.3296THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS3297"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT3298LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR3299A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT3300OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,3301SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT3302LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,3303DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY3304THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT3305(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE3306OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.33073308You can contact the author at :3309- zstd source repository : https://github.com/Cyan4973/zstd3310- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c3311*/33123313/* The objects defined into this file should be considered experimental.3314* They are not labelled stable, as their prototype may change in the future.3315* You can use them for tests, provide feedback, or if you can endure risk of future changes.3316*/33173318/* *************************************3319* Includes3320***************************************/3321#include <stdlib.h>332233233324/** ************************************************3325* Streaming decompression3326*3327* A ZBUFF_DCtx object is required to track streaming operation.3328* Use ZBUFF_createDCtx() and ZBUFF_freeDCtx() to create/release resources.3329* Use ZBUFF_decompressInit() to start a new decompression operation.3330* ZBUFF_DCtx objects can be reused multiple times.3331*3332* Use ZBUFF_decompressContinue() repetitively to consume your input.3333* *srcSizePtr and *maxDstSizePtr can be any size.3334* The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr.3335* Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input.3336* The content of dst will be overwritten (up to *maxDstSizePtr) at each function call, so save its content if it matters or change dst .3337* return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency)3338* or 0 when a frame is completely decoded3339* or an error code, which can be tested using ZBUFF_isError().3340*3341* Hint : recommended buffer sizes (not compulsory)3342* output : 128 KB block size is the internal unit, it ensures it's always possible to write a full block when it's decoded.3343* input : just follow indications from ZBUFF_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 .3344* **************************************************/33453346typedef enum { ZBUFFds_init, ZBUFFds_readHeader, ZBUFFds_loadHeader, ZBUFFds_decodeHeader,3347ZBUFFds_read, ZBUFFds_load, ZBUFFds_flush } ZBUFF_dStage;33483349/* *** Resource management *** */33503351#define ZSTD_frameHeaderSize_max 5 /* too magical, should come from reference */3352struct ZBUFFv04_DCtx_s {3353ZSTD_DCtx* zc;3354ZSTD_parameters params;3355char* inBuff;3356size_t inBuffSize;3357size_t inPos;3358char* outBuff;3359size_t outBuffSize;3360size_t outStart;3361size_t outEnd;3362size_t hPos;3363const char* dict;3364size_t dictSize;3365ZBUFF_dStage stage;3366unsigned char headerBuffer[ZSTD_frameHeaderSize_max];3367}; /* typedef'd to ZBUFF_DCtx within "zstd_buffered.h" */33683369typedef ZBUFFv04_DCtx ZBUFF_DCtx;337033713372static ZBUFF_DCtx* ZBUFF_createDCtx(void)3373{3374ZBUFF_DCtx* zbc = (ZBUFF_DCtx*)malloc(sizeof(ZBUFF_DCtx));3375if (zbc==NULL) return NULL;3376memset(zbc, 0, sizeof(*zbc));3377zbc->zc = ZSTD_createDCtx();3378zbc->stage = ZBUFFds_init;3379return zbc;3380}33813382static size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbc)3383{3384if (zbc==NULL) return 0; /* support free on null */3385ZSTD_freeDCtx(zbc->zc);3386free(zbc->inBuff);3387free(zbc->outBuff);3388free(zbc);3389return 0;3390}339133923393/* *** Initialization *** */33943395static size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbc)3396{3397zbc->stage = ZBUFFds_readHeader;3398zbc->hPos = zbc->inPos = zbc->outStart = zbc->outEnd = zbc->dictSize = 0;3399return ZSTD_resetDCtx(zbc->zc);3400}340134023403static size_t ZBUFF_decompressWithDictionary(ZBUFF_DCtx* zbc, const void* src, size_t srcSize)3404{3405zbc->dict = (const char*)src;3406zbc->dictSize = srcSize;3407return 0;3408}34093410static size_t ZBUFF_limitCopy(void* dst, size_t maxDstSize, const void* src, size_t srcSize)3411{3412size_t length = MIN(maxDstSize, srcSize);3413if (length > 0) {3414memcpy(dst, src, length);3415}3416return length;3417}34183419/* *** Decompression *** */34203421static size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr)3422{3423const char* const istart = (const char*)src;3424const char* ip = istart;3425const char* const iend = istart + *srcSizePtr;3426char* const ostart = (char*)dst;3427char* op = ostart;3428char* const oend = ostart + *maxDstSizePtr;3429U32 notDone = 1;34303431DEBUGLOG(5, "ZBUFF_decompressContinue");3432while (notDone)3433{3434switch(zbc->stage)3435{34363437case ZBUFFds_init :3438DEBUGLOG(5, "ZBUFF_decompressContinue: stage==ZBUFFds_init => ERROR(init_missing)");3439return ERROR(init_missing);34403441case ZBUFFds_readHeader :3442/* read header from src */3443{ size_t const headerSize = ZSTD_getFrameParams(&(zbc->params), src, *srcSizePtr);3444if (ZSTD_isError(headerSize)) return headerSize;3445if (headerSize) {3446/* not enough input to decode header : tell how many bytes would be necessary */3447memcpy(zbc->headerBuffer+zbc->hPos, src, *srcSizePtr);3448zbc->hPos += *srcSizePtr;3449*maxDstSizePtr = 0;3450zbc->stage = ZBUFFds_loadHeader;3451return headerSize - zbc->hPos;3452}3453zbc->stage = ZBUFFds_decodeHeader;3454break;3455}34563457case ZBUFFds_loadHeader:3458/* complete header from src */3459{ size_t headerSize = ZBUFF_limitCopy(3460zbc->headerBuffer + zbc->hPos, ZSTD_frameHeaderSize_max - zbc->hPos,3461src, *srcSizePtr);3462zbc->hPos += headerSize;3463ip += headerSize;3464headerSize = ZSTD_getFrameParams(&(zbc->params), zbc->headerBuffer, zbc->hPos);3465if (ZSTD_isError(headerSize)) return headerSize;3466if (headerSize) {3467/* not enough input to decode header : tell how many bytes would be necessary */3468*maxDstSizePtr = 0;3469return headerSize - zbc->hPos;3470} }3471/* intentional fallthrough */34723473case ZBUFFds_decodeHeader:3474/* apply header to create / resize buffers */3475{ size_t const neededOutSize = (size_t)1 << zbc->params.windowLog;3476size_t const neededInSize = BLOCKSIZE; /* a block is never > BLOCKSIZE */3477if (zbc->inBuffSize < neededInSize) {3478free(zbc->inBuff);3479zbc->inBuffSize = neededInSize;3480zbc->inBuff = (char*)malloc(neededInSize);3481if (zbc->inBuff == NULL) return ERROR(memory_allocation);3482}3483if (zbc->outBuffSize < neededOutSize) {3484free(zbc->outBuff);3485zbc->outBuffSize = neededOutSize;3486zbc->outBuff = (char*)malloc(neededOutSize);3487if (zbc->outBuff == NULL) return ERROR(memory_allocation);3488} }3489if (zbc->dictSize)3490ZSTD_decompress_insertDictionary(zbc->zc, zbc->dict, zbc->dictSize);3491if (zbc->hPos) {3492/* some data already loaded into headerBuffer : transfer into inBuff */3493memcpy(zbc->inBuff, zbc->headerBuffer, zbc->hPos);3494zbc->inPos = zbc->hPos;3495zbc->hPos = 0;3496zbc->stage = ZBUFFds_load;3497break;3498}3499zbc->stage = ZBUFFds_read;3500/* fall-through */3501case ZBUFFds_read:3502{3503size_t neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);3504if (neededInSize==0) /* end of frame */3505{3506zbc->stage = ZBUFFds_init;3507notDone = 0;3508break;3509}3510if ((size_t)(iend-ip) >= neededInSize)3511{3512/* directly decode from src */3513size_t decodedSize = ZSTD_decompressContinue(zbc->zc,3514zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart,3515ip, neededInSize);3516if (ZSTD_isError(decodedSize)) return decodedSize;3517ip += neededInSize;3518if (!decodedSize) break; /* this was just a header */3519zbc->outEnd = zbc->outStart + decodedSize;3520zbc->stage = ZBUFFds_flush;3521break;3522}3523if (ip==iend) { notDone = 0; break; } /* no more input */3524zbc->stage = ZBUFFds_load;3525}3526/* fall-through */3527case ZBUFFds_load:3528{3529size_t neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);3530size_t toLoad = neededInSize - zbc->inPos; /* should always be <= remaining space within inBuff */3531size_t loadedSize;3532if (toLoad > zbc->inBuffSize - zbc->inPos) return ERROR(corruption_detected); /* should never happen */3533loadedSize = ZBUFF_limitCopy(zbc->inBuff + zbc->inPos, toLoad, ip, iend-ip);3534ip += loadedSize;3535zbc->inPos += loadedSize;3536if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */3537{3538size_t decodedSize = ZSTD_decompressContinue(zbc->zc,3539zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart,3540zbc->inBuff, neededInSize);3541if (ZSTD_isError(decodedSize)) return decodedSize;3542zbc->inPos = 0; /* input is consumed */3543if (!decodedSize) { zbc->stage = ZBUFFds_read; break; } /* this was just a header */3544zbc->outEnd = zbc->outStart + decodedSize;3545zbc->stage = ZBUFFds_flush;3546/* ZBUFFds_flush follows */3547}3548}3549/* fall-through */3550case ZBUFFds_flush:3551{3552size_t toFlushSize = zbc->outEnd - zbc->outStart;3553size_t flushedSize = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outStart, toFlushSize);3554op += flushedSize;3555zbc->outStart += flushedSize;3556if (flushedSize == toFlushSize)3557{3558zbc->stage = ZBUFFds_read;3559if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize)3560zbc->outStart = zbc->outEnd = 0;3561break;3562}3563/* cannot flush everything */3564notDone = 0;3565break;3566}3567default: return ERROR(GENERIC); /* impossible */3568}3569}35703571*srcSizePtr = ip-istart;3572*maxDstSizePtr = op-ostart;35733574{3575size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbc->zc);3576if (nextSrcSizeHint > 3) nextSrcSizeHint+= 3; /* get the next block header while at it */3577nextSrcSizeHint -= zbc->inPos; /* already loaded*/3578return nextSrcSizeHint;3579}3580}358135823583/* *************************************3584* Tool functions3585***************************************/3586unsigned ZBUFFv04_isError(size_t errorCode) { return ERR_isError(errorCode); }3587const char* ZBUFFv04_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }35883589size_t ZBUFFv04_recommendedDInSize() { return BLOCKSIZE + 3; }3590size_t ZBUFFv04_recommendedDOutSize() { return BLOCKSIZE; }3591359235933594/*- ========================================================================= -*/35953596/* final wrapping stage */35973598size_t ZSTDv04_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)3599{3600return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);3601}36023603size_t ZSTDv04_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)3604{3605#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)3606size_t regenSize;3607ZSTD_DCtx* dctx = ZSTD_createDCtx();3608if (dctx==NULL) return ERROR(memory_allocation);3609regenSize = ZSTDv04_decompressDCtx(dctx, dst, maxDstSize, src, srcSize);3610ZSTD_freeDCtx(dctx);3611return regenSize;3612#else3613ZSTD_DCtx dctx;3614return ZSTDv04_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);3615#endif3616}36173618size_t ZSTDv04_resetDCtx(ZSTDv04_Dctx* dctx) { return ZSTD_resetDCtx(dctx); }36193620size_t ZSTDv04_nextSrcSizeToDecompress(ZSTDv04_Dctx* dctx)3621{3622return ZSTD_nextSrcSizeToDecompress(dctx);3623}36243625size_t ZSTDv04_decompressContinue(ZSTDv04_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)3626{3627return ZSTD_decompressContinue(dctx, dst, maxDstSize, src, srcSize);3628}3629363036313632ZBUFFv04_DCtx* ZBUFFv04_createDCtx(void) { return ZBUFF_createDCtx(); }3633size_t ZBUFFv04_freeDCtx(ZBUFFv04_DCtx* dctx) { return ZBUFF_freeDCtx(dctx); }36343635size_t ZBUFFv04_decompressInit(ZBUFFv04_DCtx* dctx) { return ZBUFF_decompressInit(dctx); }3636size_t ZBUFFv04_decompressWithDictionary(ZBUFFv04_DCtx* dctx, const void* src, size_t srcSize)3637{ return ZBUFF_decompressWithDictionary(dctx, src, srcSize); }36383639size_t ZBUFFv04_decompressContinue(ZBUFFv04_DCtx* dctx, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr)3640{3641DEBUGLOG(5, "ZBUFFv04_decompressContinue");3642return ZBUFF_decompressContinue(dctx, dst, maxDstSizePtr, src, srcSizePtr);3643}36443645ZSTD_DCtx* ZSTDv04_createDCtx(void) { return ZSTD_createDCtx(); }3646size_t ZSTDv04_freeDCtx(ZSTD_DCtx* dctx) { return ZSTD_freeDCtx(dctx); }364736483649