Path: blob/main/sys/contrib/zstd/lib/legacy/zstd_v02.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#include <stddef.h> /* size_t, ptrdiff_t */12#include "zstd_v02.h"13#include "../common/error_private.h"141516/******************************************17* Compiler-specific18******************************************/19#if defined(_MSC_VER) /* Visual Studio */20# include <stdlib.h> /* _byteswap_ulong */21# include <intrin.h> /* _byteswap_* */22#endif232425/* ******************************************************************26mem.h27low-level memory access routines28Copyright (C) 2013-2015, Yann Collet.2930BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)3132Redistribution and use in source and binary forms, with or without33modification, are permitted provided that the following conditions are34met:3536* Redistributions of source code must retain the above copyright37notice, this list of conditions and the following disclaimer.38* Redistributions in binary form must reproduce the above39copyright notice, this list of conditions and the following disclaimer40in the documentation and/or other materials provided with the41distribution.4243THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS44"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT45LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR46A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT47OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,48SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT49LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,50DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY51THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT52(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE53OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.5455You can contact the author at :56- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy57- Public forum : https://groups.google.com/forum/#!forum/lz4c58****************************************************************** */59#ifndef MEM_H_MODULE60#define MEM_H_MODULE6162#if defined (__cplusplus)63extern "C" {64#endif6566/******************************************67* Includes68******************************************/69#include <stddef.h> /* size_t, ptrdiff_t */70#include <string.h> /* memcpy */717273/******************************************74* Compiler-specific75******************************************/76#if defined(__GNUC__)77# define MEM_STATIC static __attribute__((unused))78#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)79# define MEM_STATIC static inline80#elif defined(_MSC_VER)81# define MEM_STATIC static __inline82#else83# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */84#endif858687/****************************************************************88* Basic Types89*****************************************************************/90#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)91# if defined(_AIX)92# include <inttypes.h>93# else94# include <stdint.h> /* intptr_t */95# endif96typedef uint8_t BYTE;97typedef uint16_t U16;98typedef int16_t S16;99typedef uint32_t U32;100typedef int32_t S32;101typedef uint64_t U64;102typedef int64_t S64;103#else104typedef unsigned char BYTE;105typedef unsigned short U16;106typedef signed short S16;107typedef unsigned int U32;108typedef signed int S32;109typedef unsigned long long U64;110typedef signed long long S64;111#endif112113114/****************************************************************115* Memory I/O116*****************************************************************/117/* MEM_FORCE_MEMORY_ACCESS118* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.119* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.120* The below switch allow to select different access method for improved performance.121* Method 0 (default) : use `memcpy()`. Safe and portable.122* Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).123* This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.124* Method 2 : direct access. This method is portable but violate C standard.125* It can generate buggy code on targets generating assembly depending on alignment.126* But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)127* See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.128* Prefer these methods in priority order (0 > 1 > 2)129*/130#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */131# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)132# define MEM_FORCE_MEMORY_ACCESS 1133# endif134#endif135136MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; }137MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; }138139MEM_STATIC unsigned MEM_isLittleEndian(void)140{141const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */142return one.c[0];143}144145#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)146147/* violates C standard on structure alignment.148Only use if no other choice to achieve best performance on target platform */149MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }150MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }151MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }152153MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }154155#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)156157/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */158/* currently only defined for gcc and icc */159typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign;160161MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }162MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }163MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }164165MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }166167#else168169/* default method, safe and standard.170can sometimes prove slower */171172MEM_STATIC U16 MEM_read16(const void* memPtr)173{174U16 val; memcpy(&val, memPtr, sizeof(val)); return val;175}176177MEM_STATIC U32 MEM_read32(const void* memPtr)178{179U32 val; memcpy(&val, memPtr, sizeof(val)); return val;180}181182MEM_STATIC U64 MEM_read64(const void* memPtr)183{184U64 val; memcpy(&val, memPtr, sizeof(val)); return val;185}186187MEM_STATIC void MEM_write16(void* memPtr, U16 value)188{189memcpy(memPtr, &value, sizeof(value));190}191192#endif /* MEM_FORCE_MEMORY_ACCESS */193194195MEM_STATIC U16 MEM_readLE16(const void* memPtr)196{197if (MEM_isLittleEndian())198return MEM_read16(memPtr);199else200{201const BYTE* p = (const BYTE*)memPtr;202return (U16)(p[0] + (p[1]<<8));203}204}205206MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)207{208if (MEM_isLittleEndian())209{210MEM_write16(memPtr, val);211}212else213{214BYTE* p = (BYTE*)memPtr;215p[0] = (BYTE)val;216p[1] = (BYTE)(val>>8);217}218}219220MEM_STATIC U32 MEM_readLE24(const void* memPtr)221{222return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);223}224225MEM_STATIC U32 MEM_readLE32(const void* memPtr)226{227if (MEM_isLittleEndian())228return MEM_read32(memPtr);229else230{231const BYTE* p = (const BYTE*)memPtr;232return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24));233}234}235236237MEM_STATIC U64 MEM_readLE64(const void* memPtr)238{239if (MEM_isLittleEndian())240return MEM_read64(memPtr);241else242{243const BYTE* p = (const BYTE*)memPtr;244return (U64)((U64)p[0] + ((U64)p[1]<<8) + ((U64)p[2]<<16) + ((U64)p[3]<<24)245+ ((U64)p[4]<<32) + ((U64)p[5]<<40) + ((U64)p[6]<<48) + ((U64)p[7]<<56));246}247}248249250MEM_STATIC size_t MEM_readLEST(const void* memPtr)251{252if (MEM_32bits())253return (size_t)MEM_readLE32(memPtr);254else255return (size_t)MEM_readLE64(memPtr);256}257258#if defined (__cplusplus)259}260#endif261262#endif /* MEM_H_MODULE */263264265/* ******************************************************************266bitstream267Part of NewGen Entropy library268header file (to include)269Copyright (C) 2013-2015, Yann Collet.270271BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)272273Redistribution and use in source and binary forms, with or without274modification, are permitted provided that the following conditions are275met:276277* Redistributions of source code must retain the above copyright278notice, this list of conditions and the following disclaimer.279* Redistributions in binary form must reproduce the above280copyright notice, this list of conditions and the following disclaimer281in the documentation and/or other materials provided with the282distribution.283284THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS285"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT286LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR287A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT288OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,289SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT290LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,291DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY292THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT293(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE294OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.295296You can contact the author at :297- Source repository : https://github.com/Cyan4973/FiniteStateEntropy298- Public forum : https://groups.google.com/forum/#!forum/lz4c299****************************************************************** */300#ifndef BITSTREAM_H_MODULE301#define BITSTREAM_H_MODULE302303#if defined (__cplusplus)304extern "C" {305#endif306307308/*309* This API consists of small unitary functions, which highly benefit from being inlined.310* Since link-time-optimization is not available for all compilers,311* these functions are defined into a .h to be included.312*/313314315/**********************************************316* bitStream decompression API (read backward)317**********************************************/318typedef struct319{320size_t bitContainer;321unsigned bitsConsumed;322const char* ptr;323const char* start;324} BIT_DStream_t;325326typedef enum { BIT_DStream_unfinished = 0,327BIT_DStream_endOfBuffer = 1,328BIT_DStream_completed = 2,329BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */330/* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */331332MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);333MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);334MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);335MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);336337338/******************************************339* unsafe API340******************************************/341MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);342/* faster, but works only if nbBits >= 1 */343344345346/****************************************************************347* Helper functions348****************************************************************/349MEM_STATIC unsigned BIT_highbit32 (U32 val)350{351# if defined(_MSC_VER) /* Visual */352unsigned long r;353return _BitScanReverse(&r, val) ? (unsigned)r : 0;354# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */355return __builtin_clz (val) ^ 31;356# else /* Software version */357static 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 };358U32 v = val;359unsigned r;360v |= v >> 1;361v |= v >> 2;362v |= v >> 4;363v |= v >> 8;364v |= v >> 16;365r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];366return r;367# endif368}369370371372/**********************************************************373* bitStream decoding374**********************************************************/375376/*!BIT_initDStream377* Initialize a BIT_DStream_t.378* @bitD : a pointer to an already allocated BIT_DStream_t structure379* @srcBuffer must point at the beginning of a bitStream380* @srcSize must be the exact size of the bitStream381* @result : size of stream (== srcSize) or an errorCode if a problem is detected382*/383MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)384{385if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }386387if (srcSize >= sizeof(size_t)) /* normal case */388{389U32 contain32;390bitD->start = (const char*)srcBuffer;391bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(size_t);392bitD->bitContainer = MEM_readLEST(bitD->ptr);393contain32 = ((const BYTE*)srcBuffer)[srcSize-1];394if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */395bitD->bitsConsumed = 8 - BIT_highbit32(contain32);396}397else398{399U32 contain32;400bitD->start = (const char*)srcBuffer;401bitD->ptr = bitD->start;402bitD->bitContainer = *(const BYTE*)(bitD->start);403switch(srcSize)404{405case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);406/* fallthrough */407case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);408/* fallthrough */409case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);410/* fallthrough */411case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24;412/* fallthrough */413case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16;414/* fallthrough */415case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) << 8;416/* fallthrough */417default:;418}419contain32 = ((const BYTE*)srcBuffer)[srcSize-1];420if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */421bitD->bitsConsumed = 8 - BIT_highbit32(contain32);422bitD->bitsConsumed += (U32)(sizeof(size_t) - srcSize)*8;423}424425return srcSize;426}427428MEM_STATIC size_t BIT_lookBits(BIT_DStream_t* bitD, U32 nbBits)429{430const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1;431return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);432}433434/*! BIT_lookBitsFast :435* unsafe version; only works only if nbBits >= 1 */436MEM_STATIC size_t BIT_lookBitsFast(BIT_DStream_t* bitD, U32 nbBits)437{438const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1;439return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);440}441442MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)443{444bitD->bitsConsumed += nbBits;445}446447MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)448{449size_t value = BIT_lookBits(bitD, nbBits);450BIT_skipBits(bitD, nbBits);451return value;452}453454/*!BIT_readBitsFast :455* unsafe version; only works only if nbBits >= 1 */456MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)457{458size_t value = BIT_lookBitsFast(bitD, nbBits);459BIT_skipBits(bitD, nbBits);460return value;461}462463MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)464{465if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */466return BIT_DStream_overflow;467468if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer))469{470bitD->ptr -= bitD->bitsConsumed >> 3;471bitD->bitsConsumed &= 7;472bitD->bitContainer = MEM_readLEST(bitD->ptr);473return BIT_DStream_unfinished;474}475if (bitD->ptr == bitD->start)476{477if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;478return BIT_DStream_completed;479}480{481U32 nbBytes = bitD->bitsConsumed >> 3;482BIT_DStream_status result = BIT_DStream_unfinished;483if (bitD->ptr - nbBytes < bitD->start)484{485nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */486result = BIT_DStream_endOfBuffer;487}488bitD->ptr -= nbBytes;489bitD->bitsConsumed -= nbBytes*8;490bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */491return result;492}493}494495/*! BIT_endOfDStream496* @return Tells if DStream has reached its exact end497*/498MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)499{500return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));501}502503#if defined (__cplusplus)504}505#endif506507#endif /* BITSTREAM_H_MODULE */508/* ******************************************************************509Error codes and messages510Copyright (C) 2013-2015, Yann Collet511512BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)513514Redistribution and use in source and binary forms, with or without515modification, are permitted provided that the following conditions are516met:517518* Redistributions of source code must retain the above copyright519notice, this list of conditions and the following disclaimer.520* Redistributions in binary form must reproduce the above521copyright notice, this list of conditions and the following disclaimer522in the documentation and/or other materials provided with the523distribution.524525THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS526"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT527LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR528A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT529OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,530SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT531LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,532DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY533THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT534(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE535OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.536537You can contact the author at :538- Source repository : https://github.com/Cyan4973/FiniteStateEntropy539- Public forum : https://groups.google.com/forum/#!forum/lz4c540****************************************************************** */541#ifndef ERROR_H_MODULE542#define ERROR_H_MODULE543544#if defined (__cplusplus)545extern "C" {546#endif547548549/******************************************550* Compiler-specific551******************************************/552#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)553# define ERR_STATIC static inline554#elif defined(_MSC_VER)555# define ERR_STATIC static __inline556#elif defined(__GNUC__)557# define ERR_STATIC static __attribute__((unused))558#else559# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */560#endif561562563/******************************************564* Error Management565******************************************/566#define PREFIX(name) ZSTD_error_##name567568#define ERROR(name) (size_t)-PREFIX(name)569570#define ERROR_LIST(ITEM) \571ITEM(PREFIX(No_Error)) ITEM(PREFIX(GENERIC)) \572ITEM(PREFIX(dstSize_tooSmall)) ITEM(PREFIX(srcSize_wrong)) \573ITEM(PREFIX(prefix_unknown)) ITEM(PREFIX(corruption_detected)) \574ITEM(PREFIX(tableLog_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooSmall)) \575ITEM(PREFIX(maxCode))576577#define ERROR_GENERATE_ENUM(ENUM) ENUM,578typedef enum { ERROR_LIST(ERROR_GENERATE_ENUM) } ERR_codes; /* enum is exposed, to detect & handle specific errors; compare function result to -enum value */579580#define ERROR_CONVERTTOSTRING(STRING) #STRING,581#define ERROR_GENERATE_STRING(EXPR) ERROR_CONVERTTOSTRING(EXPR)582static const char* ERR_strings[] = { ERROR_LIST(ERROR_GENERATE_STRING) };583584ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }585586ERR_STATIC const char* ERR_getErrorName(size_t code)587{588static const char* codeError = "Unspecified error code";589if (ERR_isError(code)) return ERR_strings[-(int)(code)];590return codeError;591}592593594#if defined (__cplusplus)595}596#endif597598#endif /* ERROR_H_MODULE */599/*600Constructor and Destructor of type FSE_CTable601Note that its size depends on 'tableLog' and 'maxSymbolValue' */602typedef unsigned FSE_CTable; /* don't allocate that. It's just a way to be more restrictive than void* */603typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */604605606/* ******************************************************************607FSE : Finite State Entropy coder608header file for static linking (only)609Copyright (C) 2013-2015, Yann Collet610611BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)612613Redistribution and use in source and binary forms, with or without614modification, are permitted provided that the following conditions are615met:616617* Redistributions of source code must retain the above copyright618notice, this list of conditions and the following disclaimer.619* Redistributions in binary form must reproduce the above620copyright notice, this list of conditions and the following disclaimer621in the documentation and/or other materials provided with the622distribution.623624THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS625"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT626LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR627A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT628OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,629SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT630LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,631DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY632THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT633(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE634OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.635636You can contact the author at :637- Source repository : https://github.com/Cyan4973/FiniteStateEntropy638- Public forum : https://groups.google.com/forum/#!forum/lz4c639****************************************************************** */640#if defined (__cplusplus)641extern "C" {642#endif643644645/******************************************646* Static allocation647******************************************/648/* FSE buffer bounds */649#define FSE_NCOUNTBOUND 512650#define FSE_BLOCKBOUND(size) (size + (size>>7))651#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */652653/* You can statically allocate FSE CTable/DTable as a table of unsigned using below macro */654#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))655#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))656657658/******************************************659* FSE advanced API660******************************************/661static size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);662/* build a fake FSE_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */663664static size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);665/* build a fake FSE_DTable, designed to always generate the same symbolValue */666667668/******************************************669* FSE symbol decompression API670******************************************/671typedef struct672{673size_t state;674const void* table; /* precise table may vary, depending on U16 */675} FSE_DState_t;676677678static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);679680static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);681682static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);683684685/******************************************686* FSE unsafe API687******************************************/688static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);689/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */690691692/******************************************693* Implementation of inline functions694******************************************/695696/* decompression */697698typedef struct {699U16 tableLog;700U16 fastMode;701} FSE_DTableHeader; /* sizeof U32 */702703typedef struct704{705unsigned short newState;706unsigned char symbol;707unsigned char nbBits;708} FSE_decode_t; /* size == U32 */709710MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)711{712FSE_DTableHeader DTableH;713memcpy(&DTableH, dt, sizeof(DTableH));714DStatePtr->state = BIT_readBits(bitD, DTableH.tableLog);715BIT_reloadDStream(bitD);716DStatePtr->table = dt + 1;717}718719MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)720{721const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];722const U32 nbBits = DInfo.nbBits;723BYTE symbol = DInfo.symbol;724size_t lowBits = BIT_readBits(bitD, nbBits);725726DStatePtr->state = DInfo.newState + lowBits;727return symbol;728}729730MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)731{732const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];733const U32 nbBits = DInfo.nbBits;734BYTE symbol = DInfo.symbol;735size_t lowBits = BIT_readBitsFast(bitD, nbBits);736737DStatePtr->state = DInfo.newState + lowBits;738return symbol;739}740741MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)742{743return DStatePtr->state == 0;744}745746747#if defined (__cplusplus)748}749#endif750/* ******************************************************************751Huff0 : Huffman coder, part of New Generation Entropy library752header file for static linking (only)753Copyright (C) 2013-2015, Yann Collet754755BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)756757Redistribution and use in source and binary forms, with or without758modification, are permitted provided that the following conditions are759met:760761* Redistributions of source code must retain the above copyright762notice, this list of conditions and the following disclaimer.763* Redistributions in binary form must reproduce the above764copyright notice, this list of conditions and the following disclaimer765in the documentation and/or other materials provided with the766distribution.767768THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS769"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT770LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR771A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT772OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,773SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT774LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,775DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY776THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT777(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE778OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.779780You can contact the author at :781- Source repository : https://github.com/Cyan4973/FiniteStateEntropy782- Public forum : https://groups.google.com/forum/#!forum/lz4c783****************************************************************** */784785#if defined (__cplusplus)786extern "C" {787#endif788789/******************************************790* Static allocation macros791******************************************/792/* Huff0 buffer bounds */793#define HUF_CTABLEBOUND 129794#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true if incompressible pre-filtered with fast heuristic */795#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */796797/* static allocation of Huff0's DTable */798#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<maxTableLog)) /* nb Cells; use unsigned short for X2, unsigned int for X4 */799#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \800unsigned short DTable[HUF_DTABLE_SIZE(maxTableLog)] = { maxTableLog }801#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \802unsigned int DTable[HUF_DTABLE_SIZE(maxTableLog)] = { maxTableLog }803#define HUF_CREATE_STATIC_DTABLEX6(DTable, maxTableLog) \804unsigned int DTable[HUF_DTABLE_SIZE(maxTableLog) * 3 / 2] = { maxTableLog }805806807/******************************************808* Advanced functions809******************************************/810static size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */811static size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */812static size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder */813814815#if defined (__cplusplus)816}817#endif818819/*820zstd - standard compression library821Header File822Copyright (C) 2014-2015, Yann Collet.823824BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)825826Redistribution and use in source and binary forms, with or without827modification, are permitted provided that the following conditions are828met:829* Redistributions of source code must retain the above copyright830notice, this list of conditions and the following disclaimer.831* Redistributions in binary form must reproduce the above832copyright notice, this list of conditions and the following disclaimer833in the documentation and/or other materials provided with the834distribution.835THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS836"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT837LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR838A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT839OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,840SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT841LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,842DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY843THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT844(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE845OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.846847You can contact the author at :848- zstd source repository : https://github.com/Cyan4973/zstd849- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c850*/851852#if defined (__cplusplus)853extern "C" {854#endif855856/* *************************************857* Includes858***************************************/859#include <stddef.h> /* size_t */860861862/* *************************************863* Version864***************************************/865#define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */866#define ZSTD_VERSION_MINOR 2 /* for new (non-breaking) interface capabilities */867#define ZSTD_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */868#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)869870871/* *************************************872* Advanced functions873***************************************/874typedef struct ZSTD_CCtx_s ZSTD_CCtx; /* incomplete type */875876#if defined (__cplusplus)877}878#endif879/*880zstd - standard compression library881Header File for static linking only882Copyright (C) 2014-2015, Yann Collet.883884BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)885886Redistribution and use in source and binary forms, with or without887modification, are permitted provided that the following conditions are888met:889* Redistributions of source code must retain the above copyright890notice, this list of conditions and the following disclaimer.891* Redistributions in binary form must reproduce the above892copyright notice, this list of conditions and the following disclaimer893in the documentation and/or other materials provided with the894distribution.895THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS896"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT897LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR898A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT899OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,900SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT901LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,902DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY903THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT904(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE905OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.906907You can contact the author at :908- zstd source repository : https://github.com/Cyan4973/zstd909- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c910*/911912/* The objects defined into this file should be considered experimental.913* They are not labelled stable, as their prototype may change in the future.914* You can use them for tests, provide feedback, or if you can endure risk of future changes.915*/916917#if defined (__cplusplus)918extern "C" {919#endif920921/* *************************************922* Streaming functions923***************************************/924925typedef struct ZSTD_DCtx_s ZSTD_DCtx;926927/*928Use above functions alternatively.929ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().930ZSTD_decompressContinue() will use previous data blocks to improve compression if they are located prior to current block.931Result is the number of bytes regenerated within 'dst'.932It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header.933*/934935/* *************************************936* Prefix - version detection937***************************************/938#define ZSTD_magicNumber 0xFD2FB522 /* v0.2 (current)*/939940941#if defined (__cplusplus)942}943#endif944/* ******************************************************************945FSE : Finite State Entropy coder946Copyright (C) 2013-2015, Yann Collet.947948BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)949950Redistribution and use in source and binary forms, with or without951modification, are permitted provided that the following conditions are952met:953954* Redistributions of source code must retain the above copyright955notice, this list of conditions and the following disclaimer.956* Redistributions in binary form must reproduce the above957copyright notice, this list of conditions and the following disclaimer958in the documentation and/or other materials provided with the959distribution.960961THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS962"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT963LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR964A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT965OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,966SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT967LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,968DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY969THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT970(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE971OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.972973You can contact the author at :974- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy975- Public forum : https://groups.google.com/forum/#!forum/lz4c976****************************************************************** */977978#ifndef FSE_COMMONDEFS_ONLY979980/****************************************************************981* Tuning parameters982****************************************************************/983/* MEMORY_USAGE :984* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)985* Increasing memory usage improves compression ratio986* Reduced memory usage can improve speed, due to cache effect987* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */988#define FSE_MAX_MEMORY_USAGE 14989#define FSE_DEFAULT_MEMORY_USAGE 13990991/* FSE_MAX_SYMBOL_VALUE :992* Maximum symbol value authorized.993* Required for proper stack allocation */994#define FSE_MAX_SYMBOL_VALUE 255995996997/****************************************************************998* template functions type & suffix999****************************************************************/1000#define FSE_FUNCTION_TYPE BYTE1001#define FSE_FUNCTION_EXTENSION100210031004/****************************************************************1005* Byte symbol type1006****************************************************************/1007#endif /* !FSE_COMMONDEFS_ONLY */100810091010/****************************************************************1011* Compiler specifics1012****************************************************************/1013#ifdef _MSC_VER /* Visual Studio */1014# define FORCE_INLINE static __forceinline1015# include <intrin.h> /* For Visual 2005 */1016# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */1017# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */1018#else1019# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */1020# ifdef __GNUC__1021# define FORCE_INLINE static inline __attribute__((always_inline))1022# else1023# define FORCE_INLINE static inline1024# endif1025# else1026# define FORCE_INLINE static1027# endif /* __STDC_VERSION__ */1028#endif102910301031/****************************************************************1032* Includes1033****************************************************************/1034#include <stdlib.h> /* malloc, free, qsort */1035#include <string.h> /* memcpy, memset */1036#include <stdio.h> /* printf (debug) */10371038/****************************************************************1039* Constants1040*****************************************************************/1041#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)1042#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)1043#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)1044#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)1045#define FSE_MIN_TABLELOG 510461047#define FSE_TABLELOG_ABSOLUTE_MAX 151048#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX1049#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"1050#endif105110521053/****************************************************************1054* Error Management1055****************************************************************/1056#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */105710581059/****************************************************************1060* Complex types1061****************************************************************/1062typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];106310641065/****************************************************************1066* Templates1067****************************************************************/1068/*1069designed to be included1070for type-specific functions (template emulation in C)1071Objective is to write these functions only once, for improved maintenance1072*/10731074/* safety checks */1075#ifndef FSE_FUNCTION_EXTENSION1076# error "FSE_FUNCTION_EXTENSION must be defined"1077#endif1078#ifndef FSE_FUNCTION_TYPE1079# error "FSE_FUNCTION_TYPE must be defined"1080#endif10811082/* Function names */1083#define FSE_CAT(X,Y) X##Y1084#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)1085#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)108610871088/* Function templates */10891090#define FSE_DECODE_TYPE FSE_decode_t10911092static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; }10931094static size_t FSE_buildDTable1095(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)1096{1097void* ptr = dt+1;1098FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*)ptr;1099FSE_DTableHeader DTableH;1100const U32 tableSize = 1 << tableLog;1101const U32 tableMask = tableSize-1;1102const U32 step = FSE_tableStep(tableSize);1103U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];1104U32 position = 0;1105U32 highThreshold = tableSize-1;1106const S16 largeLimit= (S16)(1 << (tableLog-1));1107U32 noLarge = 1;1108U32 s;11091110/* Sanity Checks */1111if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);1112if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);11131114/* Init, lay down lowprob symbols */1115DTableH.tableLog = (U16)tableLog;1116for (s=0; s<=maxSymbolValue; s++)1117{1118if (normalizedCounter[s]==-1)1119{1120tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;1121symbolNext[s] = 1;1122}1123else1124{1125if (normalizedCounter[s] >= largeLimit) noLarge=0;1126symbolNext[s] = normalizedCounter[s];1127}1128}11291130/* Spread symbols */1131for (s=0; s<=maxSymbolValue; s++)1132{1133int i;1134for (i=0; i<normalizedCounter[s]; i++)1135{1136tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;1137position = (position + step) & tableMask;1138while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */1139}1140}11411142if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */11431144/* Build Decoding table */1145{1146U32 i;1147for (i=0; i<tableSize; i++)1148{1149FSE_FUNCTION_TYPE symbol = (FSE_FUNCTION_TYPE)(tableDecode[i].symbol);1150U16 nextState = symbolNext[symbol]++;1151tableDecode[i].nbBits = (BYTE) (tableLog - BIT_highbit32 ((U32)nextState) );1152tableDecode[i].newState = (U16) ( (nextState << tableDecode[i].nbBits) - tableSize);1153}1154}11551156DTableH.fastMode = (U16)noLarge;1157memcpy(dt, &DTableH, sizeof(DTableH)); /* memcpy(), to avoid strict aliasing warnings */1158return 0;1159}116011611162#ifndef FSE_COMMONDEFS_ONLY1163/******************************************1164* FSE helper functions1165******************************************/1166static unsigned FSE_isError(size_t code) { return ERR_isError(code); }116711681169/****************************************************************1170* FSE NCount encoding-decoding1171****************************************************************/1172static short FSE_abs(short a)1173{1174return (short)(a<0 ? -a : a);1175}11761177static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,1178const void* headerBuffer, size_t hbSize)1179{1180const BYTE* const istart = (const BYTE*) headerBuffer;1181const BYTE* const iend = istart + hbSize;1182const BYTE* ip = istart;1183int nbBits;1184int remaining;1185int threshold;1186U32 bitStream;1187int bitCount;1188unsigned charnum = 0;1189int previous0 = 0;11901191if (hbSize < 4) return ERROR(srcSize_wrong);1192bitStream = MEM_readLE32(ip);1193nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */1194if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);1195bitStream >>= 4;1196bitCount = 4;1197*tableLogPtr = nbBits;1198remaining = (1<<nbBits)+1;1199threshold = 1<<nbBits;1200nbBits++;12011202while ((remaining>1) && (charnum<=*maxSVPtr))1203{1204if (previous0)1205{1206unsigned n0 = charnum;1207while ((bitStream & 0xFFFF) == 0xFFFF)1208{1209n0+=24;1210if (ip < iend-5)1211{1212ip+=2;1213bitStream = MEM_readLE32(ip) >> bitCount;1214}1215else1216{1217bitStream >>= 16;1218bitCount+=16;1219}1220}1221while ((bitStream & 3) == 3)1222{1223n0+=3;1224bitStream>>=2;1225bitCount+=2;1226}1227n0 += bitStream & 3;1228bitCount += 2;1229if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);1230while (charnum < n0) normalizedCounter[charnum++] = 0;1231if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))1232{1233ip += bitCount>>3;1234bitCount &= 7;1235bitStream = MEM_readLE32(ip) >> bitCount;1236}1237else1238bitStream >>= 2;1239}1240{1241const short max = (short)((2*threshold-1)-remaining);1242short count;12431244if ((bitStream & (threshold-1)) < (U32)max)1245{1246count = (short)(bitStream & (threshold-1));1247bitCount += nbBits-1;1248}1249else1250{1251count = (short)(bitStream & (2*threshold-1));1252if (count >= threshold) count -= max;1253bitCount += nbBits;1254}12551256count--; /* extra accuracy */1257remaining -= FSE_abs(count);1258normalizedCounter[charnum++] = count;1259previous0 = !count;1260while (remaining < threshold)1261{1262nbBits--;1263threshold >>= 1;1264}12651266{1267if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))1268{1269ip += bitCount>>3;1270bitCount &= 7;1271}1272else1273{1274bitCount -= (int)(8 * (iend - 4 - ip));1275ip = iend - 4;1276}1277bitStream = MEM_readLE32(ip) >> (bitCount & 31);1278}1279}1280}1281if (remaining != 1) return ERROR(GENERIC);1282*maxSVPtr = charnum-1;12831284ip += (bitCount+7)>>3;1285if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);1286return ip-istart;1287}128812891290/*********************************************************1291* Decompression (Byte symbols)1292*********************************************************/1293static size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)1294{1295void* ptr = dt;1296FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;1297FSE_decode_t* const cell = (FSE_decode_t*)(ptr) + 1; /* because dt is unsigned */12981299DTableH->tableLog = 0;1300DTableH->fastMode = 0;13011302cell->newState = 0;1303cell->symbol = symbolValue;1304cell->nbBits = 0;13051306return 0;1307}130813091310static size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)1311{1312void* ptr = dt;1313FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;1314FSE_decode_t* const dinfo = (FSE_decode_t*)(ptr) + 1; /* because dt is unsigned */1315const unsigned tableSize = 1 << nbBits;1316const unsigned tableMask = tableSize - 1;1317const unsigned maxSymbolValue = tableMask;1318unsigned s;13191320/* Sanity checks */1321if (nbBits < 1) return ERROR(GENERIC); /* min size */13221323/* Build Decoding Table */1324DTableH->tableLog = (U16)nbBits;1325DTableH->fastMode = 1;1326for (s=0; s<=maxSymbolValue; s++)1327{1328dinfo[s].newState = 0;1329dinfo[s].symbol = (BYTE)s;1330dinfo[s].nbBits = (BYTE)nbBits;1331}13321333return 0;1334}13351336FORCE_INLINE size_t FSE_decompress_usingDTable_generic(1337void* dst, size_t maxDstSize,1338const void* cSrc, size_t cSrcSize,1339const FSE_DTable* dt, const unsigned fast)1340{1341BYTE* const ostart = (BYTE*) dst;1342BYTE* op = ostart;1343BYTE* const omax = op + maxDstSize;1344BYTE* const olimit = omax-3;13451346BIT_DStream_t bitD;1347FSE_DState_t state1;1348FSE_DState_t state2;1349size_t errorCode;13501351/* Init */1352errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */1353if (FSE_isError(errorCode)) return errorCode;13541355FSE_initDState(&state1, &bitD, dt);1356FSE_initDState(&state2, &bitD, dt);13571358#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)13591360/* 4 symbols per loop */1361for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) && (op<olimit) ; op+=4)1362{1363op[0] = FSE_GETSYMBOL(&state1);13641365if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */1366BIT_reloadDStream(&bitD);13671368op[1] = FSE_GETSYMBOL(&state2);13691370if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */1371{ if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }13721373op[2] = FSE_GETSYMBOL(&state1);13741375if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */1376BIT_reloadDStream(&bitD);13771378op[3] = FSE_GETSYMBOL(&state2);1379}13801381/* tail */1382/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */1383while (1)1384{1385if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state1))) )1386break;13871388*op++ = FSE_GETSYMBOL(&state1);13891390if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state2))) )1391break;13921393*op++ = FSE_GETSYMBOL(&state2);1394}13951396/* end ? */1397if (BIT_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2))1398return op-ostart;13991400if (op==omax) return ERROR(dstSize_tooSmall); /* dst buffer is full, but cSrc unfinished */14011402return ERROR(corruption_detected);1403}140414051406static size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,1407const void* cSrc, size_t cSrcSize,1408const FSE_DTable* dt)1409{1410FSE_DTableHeader DTableH;1411memcpy(&DTableH, dt, sizeof(DTableH));14121413/* select fast mode (static) */1414if (DTableH.fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);1415return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);1416}141714181419static size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)1420{1421const BYTE* const istart = (const BYTE*)cSrc;1422const BYTE* ip = istart;1423short counting[FSE_MAX_SYMBOL_VALUE+1];1424DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */1425unsigned tableLog;1426unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;1427size_t errorCode;14281429if (cSrcSize<2) return ERROR(srcSize_wrong); /* too small input size */14301431/* normal FSE decoding mode */1432errorCode = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);1433if (FSE_isError(errorCode)) return errorCode;1434if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */1435ip += errorCode;1436cSrcSize -= errorCode;14371438errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog);1439if (FSE_isError(errorCode)) return errorCode;14401441/* always return, even if it is an error code */1442return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt);1443}1444144514461447#endif /* FSE_COMMONDEFS_ONLY */1448/* ******************************************************************1449Huff0 : Huffman coder, part of New Generation Entropy library1450Copyright (C) 2013-2015, Yann Collet.14511452BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)14531454Redistribution and use in source and binary forms, with or without1455modification, are permitted provided that the following conditions are1456met:14571458* Redistributions of source code must retain the above copyright1459notice, this list of conditions and the following disclaimer.1460* Redistributions in binary form must reproduce the above1461copyright notice, this list of conditions and the following disclaimer1462in the documentation and/or other materials provided with the1463distribution.14641465THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS1466"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT1467LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR1468A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT1469OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,1470SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT1471LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,1472DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY1473THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT1474(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE1475OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.14761477You can contact the author at :1478- FSE+Huff0 source repository : https://github.com/Cyan4973/FiniteStateEntropy1479- Public forum : https://groups.google.com/forum/#!forum/lz4c1480****************************************************************** */14811482/****************************************************************1483* Compiler specifics1484****************************************************************/1485#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)1486/* inline is defined */1487#elif defined(_MSC_VER)1488# define inline __inline1489#else1490# define inline /* disable inline */1491#endif149214931494#ifdef _MSC_VER /* Visual Studio */1495# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */1496#endif149714981499/****************************************************************1500* Includes1501****************************************************************/1502#include <stdlib.h> /* malloc, free, qsort */1503#include <string.h> /* memcpy, memset */1504#include <stdio.h> /* printf (debug) */15051506/****************************************************************1507* Error Management1508****************************************************************/1509#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */151015111512/******************************************1513* Helper functions1514******************************************/1515static unsigned HUF_isError(size_t code) { return ERR_isError(code); }15161517#define HUF_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */1518#define HUF_MAX_TABLELOG 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */1519#define HUF_DEFAULT_TABLELOG HUF_MAX_TABLELOG /* tableLog by default, when not specified */1520#define HUF_MAX_SYMBOL_VALUE 2551521#if (HUF_MAX_TABLELOG > HUF_ABSOLUTEMAX_TABLELOG)1522# error "HUF_MAX_TABLELOG is too large !"1523#endif1524152515261527/*********************************************************1528* Huff0 : Huffman block decompression1529*********************************************************/1530typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */15311532typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4; /* double-symbols decoding */15331534typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;15351536/*! HUF_readStats1537Read compact Huffman tree, saved by HUF_writeCTable1538@huffWeight : destination buffer1539@return : size read from `src`1540*/1541static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,1542U32* nbSymbolsPtr, U32* tableLogPtr,1543const void* src, size_t srcSize)1544{1545U32 weightTotal;1546U32 tableLog;1547const BYTE* ip = (const BYTE*) src;1548size_t iSize;1549size_t oSize;1550U32 n;15511552if (!srcSize) return ERROR(srcSize_wrong);1553iSize = ip[0];1554//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */15551556if (iSize >= 128) /* special header */1557{1558if (iSize >= (242)) /* RLE */1559{1560static int l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };1561oSize = l[iSize-242];1562memset(huffWeight, 1, hwSize);1563iSize = 0;1564}1565else /* Incompressible */1566{1567oSize = iSize - 127;1568iSize = ((oSize+1)/2);1569if (iSize+1 > srcSize) return ERROR(srcSize_wrong);1570if (oSize >= hwSize) return ERROR(corruption_detected);1571ip += 1;1572for (n=0; n<oSize; n+=2)1573{1574huffWeight[n] = ip[n/2] >> 4;1575huffWeight[n+1] = ip[n/2] & 15;1576}1577}1578}1579else /* header compressed with FSE (normal case) */1580{1581if (iSize+1 > srcSize) return ERROR(srcSize_wrong);1582oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */1583if (FSE_isError(oSize)) return oSize;1584}15851586/* collect weight stats */1587memset(rankStats, 0, (HUF_ABSOLUTEMAX_TABLELOG + 1) * sizeof(U32));1588weightTotal = 0;1589for (n=0; n<oSize; n++)1590{1591if (huffWeight[n] >= HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);1592rankStats[huffWeight[n]]++;1593weightTotal += (1 << huffWeight[n]) >> 1;1594}1595if (weightTotal == 0) return ERROR(corruption_detected);15961597/* get last non-null symbol weight (implied, total must be 2^n) */1598tableLog = BIT_highbit32(weightTotal) + 1;1599if (tableLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);1600{1601U32 total = 1 << tableLog;1602U32 rest = total - weightTotal;1603U32 verif = 1 << BIT_highbit32(rest);1604U32 lastWeight = BIT_highbit32(rest) + 1;1605if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */1606huffWeight[oSize] = (BYTE)lastWeight;1607rankStats[lastWeight]++;1608}16091610/* check tree construction validity */1611if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */16121613/* results */1614*nbSymbolsPtr = (U32)(oSize+1);1615*tableLogPtr = tableLog;1616return iSize+1;1617}161816191620/**************************/1621/* single-symbol decoding */1622/**************************/16231624static size_t HUF_readDTableX2 (U16* DTable, const void* src, size_t srcSize)1625{1626BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1];1627U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */1628U32 tableLog = 0;1629const BYTE* ip = (const BYTE*) src;1630size_t iSize = ip[0];1631U32 nbSymbols = 0;1632U32 n;1633U32 nextRankStart;1634void* ptr = DTable+1;1635HUF_DEltX2* const dt = (HUF_DEltX2*)ptr;16361637HUF_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */1638//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */16391640iSize = HUF_readStats(huffWeight, HUF_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);1641if (HUF_isError(iSize)) return iSize;16421643/* check result */1644if (tableLog > DTable[0]) return ERROR(tableLog_tooLarge); /* DTable is too small */1645DTable[0] = (U16)tableLog; /* maybe should separate sizeof DTable, as allocated, from used size of DTable, in case of DTable re-use */16461647/* Prepare ranks */1648nextRankStart = 0;1649for (n=1; n<=tableLog; n++)1650{1651U32 current = nextRankStart;1652nextRankStart += (rankVal[n] << (n-1));1653rankVal[n] = current;1654}16551656/* fill DTable */1657for (n=0; n<nbSymbols; n++)1658{1659const U32 w = huffWeight[n];1660const U32 length = (1 << w) >> 1;1661U32 i;1662HUF_DEltX2 D;1663D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);1664for (i = rankVal[w]; i < rankVal[w] + length; i++)1665dt[i] = D;1666rankVal[w] += length;1667}16681669return iSize;1670}16711672static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)1673{1674const size_t val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */1675const BYTE c = dt[val].byte;1676BIT_skipBits(Dstream, dt[val].nbBits);1677return c;1678}16791680#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \1681*ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)16821683#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \1684if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \1685HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)16861687#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \1688if (MEM_64bits()) \1689HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)16901691static inline size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog)1692{1693BYTE* const pStart = p;16941695/* up to 4 symbols at a time */1696while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4))1697{1698HUF_DECODE_SYMBOLX2_2(p, bitDPtr);1699HUF_DECODE_SYMBOLX2_1(p, bitDPtr);1700HUF_DECODE_SYMBOLX2_2(p, bitDPtr);1701HUF_DECODE_SYMBOLX2_0(p, bitDPtr);1702}17031704/* closer to the end */1705while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd))1706HUF_DECODE_SYMBOLX2_0(p, bitDPtr);17071708/* no more data to retrieve from bitstream, hence no need to reload */1709while (p < pEnd)1710HUF_DECODE_SYMBOLX2_0(p, bitDPtr);17111712return pEnd-pStart;1713}171417151716static size_t HUF_decompress4X2_usingDTable(1717void* dst, size_t dstSize,1718const void* cSrc, size_t cSrcSize,1719const U16* DTable)1720{1721if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */17221723{1724const BYTE* const istart = (const BYTE*) cSrc;1725BYTE* const ostart = (BYTE*) dst;1726BYTE* const oend = ostart + dstSize;17271728const void* ptr = DTable;1729const HUF_DEltX2* const dt = ((const HUF_DEltX2*)ptr) +1;1730const U32 dtLog = DTable[0];1731size_t errorCode;17321733/* Init */1734BIT_DStream_t bitD1;1735BIT_DStream_t bitD2;1736BIT_DStream_t bitD3;1737BIT_DStream_t bitD4;1738const size_t length1 = MEM_readLE16(istart);1739const size_t length2 = MEM_readLE16(istart+2);1740const size_t length3 = MEM_readLE16(istart+4);1741size_t length4;1742const BYTE* const istart1 = istart + 6; /* jumpTable */1743const BYTE* const istart2 = istart1 + length1;1744const BYTE* const istart3 = istart2 + length2;1745const BYTE* const istart4 = istart3 + length3;1746const size_t segmentSize = (dstSize+3) / 4;1747BYTE* const opStart2 = ostart + segmentSize;1748BYTE* const opStart3 = opStart2 + segmentSize;1749BYTE* const opStart4 = opStart3 + segmentSize;1750BYTE* op1 = ostart;1751BYTE* op2 = opStart2;1752BYTE* op3 = opStart3;1753BYTE* op4 = opStart4;1754U32 endSignal;17551756length4 = cSrcSize - (length1 + length2 + length3 + 6);1757if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */1758errorCode = BIT_initDStream(&bitD1, istart1, length1);1759if (HUF_isError(errorCode)) return errorCode;1760errorCode = BIT_initDStream(&bitD2, istart2, length2);1761if (HUF_isError(errorCode)) return errorCode;1762errorCode = BIT_initDStream(&bitD3, istart3, length3);1763if (HUF_isError(errorCode)) return errorCode;1764errorCode = BIT_initDStream(&bitD4, istart4, length4);1765if (HUF_isError(errorCode)) return errorCode;17661767/* 16-32 symbols per loop (4-8 symbols per stream) */1768endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);1769for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; )1770{1771HUF_DECODE_SYMBOLX2_2(op1, &bitD1);1772HUF_DECODE_SYMBOLX2_2(op2, &bitD2);1773HUF_DECODE_SYMBOLX2_2(op3, &bitD3);1774HUF_DECODE_SYMBOLX2_2(op4, &bitD4);1775HUF_DECODE_SYMBOLX2_1(op1, &bitD1);1776HUF_DECODE_SYMBOLX2_1(op2, &bitD2);1777HUF_DECODE_SYMBOLX2_1(op3, &bitD3);1778HUF_DECODE_SYMBOLX2_1(op4, &bitD4);1779HUF_DECODE_SYMBOLX2_2(op1, &bitD1);1780HUF_DECODE_SYMBOLX2_2(op2, &bitD2);1781HUF_DECODE_SYMBOLX2_2(op3, &bitD3);1782HUF_DECODE_SYMBOLX2_2(op4, &bitD4);1783HUF_DECODE_SYMBOLX2_0(op1, &bitD1);1784HUF_DECODE_SYMBOLX2_0(op2, &bitD2);1785HUF_DECODE_SYMBOLX2_0(op3, &bitD3);1786HUF_DECODE_SYMBOLX2_0(op4, &bitD4);17871788endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);1789}17901791/* check corruption */1792if (op1 > opStart2) return ERROR(corruption_detected);1793if (op2 > opStart3) return ERROR(corruption_detected);1794if (op3 > opStart4) return ERROR(corruption_detected);1795/* note : op4 supposed already verified within main loop */17961797/* finish bitStreams one by one */1798HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);1799HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);1800HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);1801HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);18021803/* check */1804endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);1805if (!endSignal) return ERROR(corruption_detected);18061807/* decoded size */1808return dstSize;1809}1810}181118121813static size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)1814{1815HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_MAX_TABLELOG);1816const BYTE* ip = (const BYTE*) cSrc;1817size_t errorCode;18181819errorCode = HUF_readDTableX2 (DTable, cSrc, cSrcSize);1820if (HUF_isError(errorCode)) return errorCode;1821if (errorCode >= cSrcSize) return ERROR(srcSize_wrong);1822ip += errorCode;1823cSrcSize -= errorCode;18241825return HUF_decompress4X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable);1826}182718281829/***************************/1830/* double-symbols decoding */1831/***************************/18321833static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,1834const U32* rankValOrigin, const int minWeight,1835const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,1836U32 nbBitsBaseline, U16 baseSeq)1837{1838HUF_DEltX4 DElt;1839U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];1840U32 s;18411842/* get pre-calculated rankVal */1843memcpy(rankVal, rankValOrigin, sizeof(rankVal));18441845/* fill skipped values */1846if (minWeight>1)1847{1848U32 i, skipSize = rankVal[minWeight];1849MEM_writeLE16(&(DElt.sequence), baseSeq);1850DElt.nbBits = (BYTE)(consumed);1851DElt.length = 1;1852for (i = 0; i < skipSize; i++)1853DTable[i] = DElt;1854}18551856/* fill DTable */1857for (s=0; s<sortedListSize; s++) /* note : sortedSymbols already skipped */1858{1859const U32 symbol = sortedSymbols[s].symbol;1860const U32 weight = sortedSymbols[s].weight;1861const U32 nbBits = nbBitsBaseline - weight;1862const U32 length = 1 << (sizeLog-nbBits);1863const U32 start = rankVal[weight];1864U32 i = start;1865const U32 end = start + length;18661867MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));1868DElt.nbBits = (BYTE)(nbBits + consumed);1869DElt.length = 2;1870do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */18711872rankVal[weight] += length;1873}1874}18751876typedef U32 rankVal_t[HUF_ABSOLUTEMAX_TABLELOG][HUF_ABSOLUTEMAX_TABLELOG + 1];18771878static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,1879const sortedSymbol_t* sortedList, const U32 sortedListSize,1880const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,1881const U32 nbBitsBaseline)1882{1883U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];1884const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */1885const U32 minBits = nbBitsBaseline - maxWeight;1886U32 s;18871888memcpy(rankVal, rankValOrigin, sizeof(rankVal));18891890/* fill DTable */1891for (s=0; s<sortedListSize; s++)1892{1893const U16 symbol = sortedList[s].symbol;1894const U32 weight = sortedList[s].weight;1895const U32 nbBits = nbBitsBaseline - weight;1896const U32 start = rankVal[weight];1897const U32 length = 1 << (targetLog-nbBits);18981899if (targetLog-nbBits >= minBits) /* enough room for a second symbol */1900{1901U32 sortedRank;1902int minWeight = nbBits + scaleLog;1903if (minWeight < 1) minWeight = 1;1904sortedRank = rankStart[minWeight];1905HUF_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,1906rankValOrigin[nbBits], minWeight,1907sortedList+sortedRank, sortedListSize-sortedRank,1908nbBitsBaseline, symbol);1909}1910else1911{1912U32 i;1913const U32 end = start + length;1914HUF_DEltX4 DElt;19151916MEM_writeLE16(&(DElt.sequence), symbol);1917DElt.nbBits = (BYTE)(nbBits);1918DElt.length = 1;1919for (i = start; i < end; i++)1920DTable[i] = DElt;1921}1922rankVal[weight] += length;1923}1924}19251926static size_t HUF_readDTableX4 (U32* DTable, const void* src, size_t srcSize)1927{1928BYTE weightList[HUF_MAX_SYMBOL_VALUE + 1];1929sortedSymbol_t sortedSymbol[HUF_MAX_SYMBOL_VALUE + 1];1930U32 rankStats[HUF_ABSOLUTEMAX_TABLELOG + 1] = { 0 };1931U32 rankStart0[HUF_ABSOLUTEMAX_TABLELOG + 2] = { 0 };1932U32* const rankStart = rankStart0+1;1933rankVal_t rankVal;1934U32 tableLog, maxW, sizeOfSort, nbSymbols;1935const U32 memLog = DTable[0];1936const BYTE* ip = (const BYTE*) src;1937size_t iSize = ip[0];1938void* ptr = DTable;1939HUF_DEltX4* const dt = ((HUF_DEltX4*)ptr) + 1;19401941HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(U32)); /* if compilation fails here, assertion is false */1942if (memLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);1943//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */19441945iSize = HUF_readStats(weightList, HUF_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);1946if (HUF_isError(iSize)) return iSize;19471948/* check result */1949if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */19501951/* find maxWeight */1952for (maxW = tableLog; rankStats[maxW]==0; maxW--)1953{if (!maxW) return ERROR(GENERIC); } /* necessarily finds a solution before maxW==0 */19541955/* Get start index of each weight */1956{1957U32 w, nextRankStart = 0;1958for (w=1; w<=maxW; w++)1959{1960U32 current = nextRankStart;1961nextRankStart += rankStats[w];1962rankStart[w] = current;1963}1964rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/1965sizeOfSort = nextRankStart;1966}19671968/* sort symbols by weight */1969{1970U32 s;1971for (s=0; s<nbSymbols; s++)1972{1973U32 w = weightList[s];1974U32 r = rankStart[w]++;1975sortedSymbol[r].symbol = (BYTE)s;1976sortedSymbol[r].weight = (BYTE)w;1977}1978rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */1979}19801981/* Build rankVal */1982{1983const U32 minBits = tableLog+1 - maxW;1984U32 nextRankVal = 0;1985U32 w, consumed;1986const int rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */1987U32* rankVal0 = rankVal[0];1988for (w=1; w<=maxW; w++)1989{1990U32 current = nextRankVal;1991nextRankVal += rankStats[w] << (w+rescale);1992rankVal0[w] = current;1993}1994for (consumed = minBits; consumed <= memLog - minBits; consumed++)1995{1996U32* rankValPtr = rankVal[consumed];1997for (w = 1; w <= maxW; w++)1998{1999rankValPtr[w] = rankVal0[w] >> consumed;2000}2001}2002}20032004HUF_fillDTableX4(dt, memLog,2005sortedSymbol, sizeOfSort,2006rankStart0, rankVal, maxW,2007tableLog+1);20082009return iSize;2010}201120122013static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)2014{2015const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */2016memcpy(op, dt+val, 2);2017BIT_skipBits(DStream, dt[val].nbBits);2018return dt[val].length;2019}20202021static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)2022{2023const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */2024memcpy(op, dt+val, 1);2025if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);2026else2027{2028if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8))2029{2030BIT_skipBits(DStream, dt[val].nbBits);2031if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))2032DStream->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 */2033}2034}2035return 1;2036}203720382039#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \2040ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)20412042#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \2043if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \2044ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)20452046#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \2047if (MEM_64bits()) \2048ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)20492050static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog)2051{2052BYTE* const pStart = p;20532054/* up to 8 symbols at a time */2055while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd-7))2056{2057HUF_DECODE_SYMBOLX4_2(p, bitDPtr);2058HUF_DECODE_SYMBOLX4_1(p, bitDPtr);2059HUF_DECODE_SYMBOLX4_2(p, bitDPtr);2060HUF_DECODE_SYMBOLX4_0(p, bitDPtr);2061}20622063/* closer to the end */2064while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-2))2065HUF_DECODE_SYMBOLX4_0(p, bitDPtr);20662067while (p <= pEnd-2)2068HUF_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */20692070if (p < pEnd)2071p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);20722073return p-pStart;2074}2075207620772078static size_t HUF_decompress4X4_usingDTable(2079void* dst, size_t dstSize,2080const void* cSrc, size_t cSrcSize,2081const U32* DTable)2082{2083if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */20842085{2086const BYTE* const istart = (const BYTE*) cSrc;2087BYTE* const ostart = (BYTE*) dst;2088BYTE* const oend = ostart + dstSize;20892090const void* ptr = DTable;2091const HUF_DEltX4* const dt = ((const HUF_DEltX4*)ptr) +1;2092const U32 dtLog = DTable[0];2093size_t errorCode;20942095/* Init */2096BIT_DStream_t bitD1;2097BIT_DStream_t bitD2;2098BIT_DStream_t bitD3;2099BIT_DStream_t bitD4;2100const size_t length1 = MEM_readLE16(istart);2101const size_t length2 = MEM_readLE16(istart+2);2102const size_t length3 = MEM_readLE16(istart+4);2103size_t length4;2104const BYTE* const istart1 = istart + 6; /* jumpTable */2105const BYTE* const istart2 = istart1 + length1;2106const BYTE* const istart3 = istart2 + length2;2107const BYTE* const istart4 = istart3 + length3;2108const size_t segmentSize = (dstSize+3) / 4;2109BYTE* const opStart2 = ostart + segmentSize;2110BYTE* const opStart3 = opStart2 + segmentSize;2111BYTE* const opStart4 = opStart3 + segmentSize;2112BYTE* op1 = ostart;2113BYTE* op2 = opStart2;2114BYTE* op3 = opStart3;2115BYTE* op4 = opStart4;2116U32 endSignal;21172118length4 = cSrcSize - (length1 + length2 + length3 + 6);2119if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */2120errorCode = BIT_initDStream(&bitD1, istart1, length1);2121if (HUF_isError(errorCode)) return errorCode;2122errorCode = BIT_initDStream(&bitD2, istart2, length2);2123if (HUF_isError(errorCode)) return errorCode;2124errorCode = BIT_initDStream(&bitD3, istart3, length3);2125if (HUF_isError(errorCode)) return errorCode;2126errorCode = BIT_initDStream(&bitD4, istart4, length4);2127if (HUF_isError(errorCode)) return errorCode;21282129/* 16-32 symbols per loop (4-8 symbols per stream) */2130endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);2131for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; )2132{2133HUF_DECODE_SYMBOLX4_2(op1, &bitD1);2134HUF_DECODE_SYMBOLX4_2(op2, &bitD2);2135HUF_DECODE_SYMBOLX4_2(op3, &bitD3);2136HUF_DECODE_SYMBOLX4_2(op4, &bitD4);2137HUF_DECODE_SYMBOLX4_1(op1, &bitD1);2138HUF_DECODE_SYMBOLX4_1(op2, &bitD2);2139HUF_DECODE_SYMBOLX4_1(op3, &bitD3);2140HUF_DECODE_SYMBOLX4_1(op4, &bitD4);2141HUF_DECODE_SYMBOLX4_2(op1, &bitD1);2142HUF_DECODE_SYMBOLX4_2(op2, &bitD2);2143HUF_DECODE_SYMBOLX4_2(op3, &bitD3);2144HUF_DECODE_SYMBOLX4_2(op4, &bitD4);2145HUF_DECODE_SYMBOLX4_0(op1, &bitD1);2146HUF_DECODE_SYMBOLX4_0(op2, &bitD2);2147HUF_DECODE_SYMBOLX4_0(op3, &bitD3);2148HUF_DECODE_SYMBOLX4_0(op4, &bitD4);21492150endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);2151}21522153/* check corruption */2154if (op1 > opStart2) return ERROR(corruption_detected);2155if (op2 > opStart3) return ERROR(corruption_detected);2156if (op3 > opStart4) return ERROR(corruption_detected);2157/* note : op4 supposed already verified within main loop */21582159/* finish bitStreams one by one */2160HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);2161HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);2162HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);2163HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);21642165/* check */2166endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);2167if (!endSignal) return ERROR(corruption_detected);21682169/* decoded size */2170return dstSize;2171}2172}217321742175static size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)2176{2177HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_MAX_TABLELOG);2178const BYTE* ip = (const BYTE*) cSrc;21792180size_t hSize = HUF_readDTableX4 (DTable, cSrc, cSrcSize);2181if (HUF_isError(hSize)) return hSize;2182if (hSize >= cSrcSize) return ERROR(srcSize_wrong);2183ip += hSize;2184cSrcSize -= hSize;21852186return HUF_decompress4X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable);2187}218821892190/**********************************/2191/* quad-symbol decoding */2192/**********************************/2193typedef struct { BYTE nbBits; BYTE nbBytes; } HUF_DDescX6;2194typedef union { BYTE byte[4]; U32 sequence; } HUF_DSeqX6;21952196/* recursive, up to level 3; may benefit from <template>-like strategy to nest each level inline */2197static void HUF_fillDTableX6LevelN(HUF_DDescX6* DDescription, HUF_DSeqX6* DSequence, int sizeLog,2198const rankVal_t rankValOrigin, const U32 consumed, const int minWeight, const U32 maxWeight,2199const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, const U32* rankStart,2200const U32 nbBitsBaseline, HUF_DSeqX6 baseSeq, HUF_DDescX6 DDesc)2201{2202const int scaleLog = nbBitsBaseline - sizeLog; /* note : targetLog >= (nbBitsBaseline-1), hence scaleLog <= 1 */2203const int minBits = nbBitsBaseline - maxWeight;2204const U32 level = DDesc.nbBytes;2205U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];2206U32 symbolStartPos, s;22072208/* local rankVal, will be modified */2209memcpy(rankVal, rankValOrigin[consumed], sizeof(rankVal));22102211/* fill skipped values */2212if (minWeight>1)2213{2214U32 i;2215const U32 skipSize = rankVal[minWeight];2216for (i = 0; i < skipSize; i++)2217{2218DSequence[i] = baseSeq;2219DDescription[i] = DDesc;2220}2221}22222223/* fill DTable */2224DDesc.nbBytes++;2225symbolStartPos = rankStart[minWeight];2226for (s=symbolStartPos; s<sortedListSize; s++)2227{2228const BYTE symbol = sortedSymbols[s].symbol;2229const U32 weight = sortedSymbols[s].weight; /* >= 1 (sorted) */2230const int nbBits = nbBitsBaseline - weight; /* >= 1 (by construction) */2231const int totalBits = consumed+nbBits;2232const U32 start = rankVal[weight];2233const U32 length = 1 << (sizeLog-nbBits);2234baseSeq.byte[level] = symbol;2235DDesc.nbBits = (BYTE)totalBits;22362237if ((level<3) && (sizeLog-totalBits >= minBits)) /* enough room for another symbol */2238{2239int nextMinWeight = totalBits + scaleLog;2240if (nextMinWeight < 1) nextMinWeight = 1;2241HUF_fillDTableX6LevelN(DDescription+start, DSequence+start, sizeLog-nbBits,2242rankValOrigin, totalBits, nextMinWeight, maxWeight,2243sortedSymbols, sortedListSize, rankStart,2244nbBitsBaseline, baseSeq, DDesc); /* recursive (max : level 3) */2245}2246else2247{2248U32 i;2249const U32 end = start + length;2250for (i = start; i < end; i++)2251{2252DDescription[i] = DDesc;2253DSequence[i] = baseSeq;2254}2255}2256rankVal[weight] += length;2257}2258}225922602261/* note : same preparation as X4 */2262static size_t HUF_readDTableX6 (U32* DTable, const void* src, size_t srcSize)2263{2264BYTE weightList[HUF_MAX_SYMBOL_VALUE + 1];2265sortedSymbol_t sortedSymbol[HUF_MAX_SYMBOL_VALUE + 1];2266U32 rankStats[HUF_ABSOLUTEMAX_TABLELOG + 1] = { 0 };2267U32 rankStart0[HUF_ABSOLUTEMAX_TABLELOG + 2] = { 0 };2268U32* const rankStart = rankStart0+1;2269U32 tableLog, maxW, sizeOfSort, nbSymbols;2270rankVal_t rankVal;2271const U32 memLog = DTable[0];2272const BYTE* ip = (const BYTE*) src;2273size_t iSize = ip[0];22742275if (memLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);2276//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */22772278iSize = HUF_readStats(weightList, HUF_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);2279if (HUF_isError(iSize)) return iSize;22802281/* check result */2282if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable is too small */22832284/* find maxWeight */2285for (maxW = tableLog; rankStats[maxW]==0; maxW--)2286{ if (!maxW) return ERROR(GENERIC); } /* necessarily finds a solution before maxW==0 */228722882289/* Get start index of each weight */2290{2291U32 w, nextRankStart = 0;2292for (w=1; w<=maxW; w++)2293{2294U32 current = nextRankStart;2295nextRankStart += rankStats[w];2296rankStart[w] = current;2297}2298rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/2299sizeOfSort = nextRankStart;2300}23012302/* sort symbols by weight */2303{2304U32 s;2305for (s=0; s<nbSymbols; s++)2306{2307U32 w = weightList[s];2308U32 r = rankStart[w]++;2309sortedSymbol[r].symbol = (BYTE)s;2310sortedSymbol[r].weight = (BYTE)w;2311}2312rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */2313}23142315/* Build rankVal */2316{2317const U32 minBits = tableLog+1 - maxW;2318U32 nextRankVal = 0;2319U32 w, consumed;2320const int rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */2321U32* rankVal0 = rankVal[0];2322for (w=1; w<=maxW; w++)2323{2324U32 current = nextRankVal;2325nextRankVal += rankStats[w] << (w+rescale);2326rankVal0[w] = current;2327}2328for (consumed = minBits; consumed <= memLog - minBits; consumed++)2329{2330U32* rankValPtr = rankVal[consumed];2331for (w = 1; w <= maxW; w++)2332{2333rankValPtr[w] = rankVal0[w] >> consumed;2334}2335}2336}233723382339/* fill tables */2340{2341void* ptr = DTable+1;2342HUF_DDescX6* DDescription = (HUF_DDescX6*)(ptr);2343void* dSeqStart = DTable + 1 + ((size_t)1<<(memLog-1));2344HUF_DSeqX6* DSequence = (HUF_DSeqX6*)(dSeqStart);2345HUF_DSeqX6 DSeq;2346HUF_DDescX6 DDesc;2347DSeq.sequence = 0;2348DDesc.nbBits = 0;2349DDesc.nbBytes = 0;2350HUF_fillDTableX6LevelN(DDescription, DSequence, memLog,2351(const U32 (*)[HUF_ABSOLUTEMAX_TABLELOG + 1])rankVal, 0, 1, maxW,2352sortedSymbol, sizeOfSort, rankStart0,2353tableLog+1, DSeq, DDesc);2354}23552356return iSize;2357}235823592360static U32 HUF_decodeSymbolX6(void* op, BIT_DStream_t* DStream, const HUF_DDescX6* dd, const HUF_DSeqX6* ds, const U32 dtLog)2361{2362const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */2363memcpy(op, ds+val, sizeof(HUF_DSeqX6));2364BIT_skipBits(DStream, dd[val].nbBits);2365return dd[val].nbBytes;2366}23672368static U32 HUF_decodeLastSymbolsX6(void* op, const U32 maxL, BIT_DStream_t* DStream,2369const HUF_DDescX6* dd, const HUF_DSeqX6* ds, const U32 dtLog)2370{2371const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */2372U32 length = dd[val].nbBytes;2373if (length <= maxL)2374{2375memcpy(op, ds+val, length);2376BIT_skipBits(DStream, dd[val].nbBits);2377return length;2378}2379memcpy(op, ds+val, maxL);2380if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8))2381{2382BIT_skipBits(DStream, dd[val].nbBits);2383if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))2384DStream->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 */2385}2386return maxL;2387}238823892390#define HUF_DECODE_SYMBOLX6_0(ptr, DStreamPtr) \2391ptr += HUF_decodeSymbolX6(ptr, DStreamPtr, dd, ds, dtLog)23922393#define HUF_DECODE_SYMBOLX6_1(ptr, DStreamPtr) \2394if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \2395HUF_DECODE_SYMBOLX6_0(ptr, DStreamPtr)23962397#define HUF_DECODE_SYMBOLX6_2(ptr, DStreamPtr) \2398if (MEM_64bits()) \2399HUF_DECODE_SYMBOLX6_0(ptr, DStreamPtr)24002401static inline size_t HUF_decodeStreamX6(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const U32* DTable, const U32 dtLog)2402{2403const void* ddPtr = DTable+1;2404const HUF_DDescX6* dd = (const HUF_DDescX6*)(ddPtr);2405const void* dsPtr = DTable + 1 + ((size_t)1<<(dtLog-1));2406const HUF_DSeqX6* ds = (const HUF_DSeqX6*)(dsPtr);2407BYTE* const pStart = p;24082409/* up to 16 symbols at a time */2410while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-16))2411{2412HUF_DECODE_SYMBOLX6_2(p, bitDPtr);2413HUF_DECODE_SYMBOLX6_1(p, bitDPtr);2414HUF_DECODE_SYMBOLX6_2(p, bitDPtr);2415HUF_DECODE_SYMBOLX6_0(p, bitDPtr);2416}24172418/* closer to the end, up to 4 symbols at a time */2419while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4))2420HUF_DECODE_SYMBOLX6_0(p, bitDPtr);24212422while (p <= pEnd-4)2423HUF_DECODE_SYMBOLX6_0(p, bitDPtr); /* no need to reload : reached the end of DStream */24242425while (p < pEnd)2426p += HUF_decodeLastSymbolsX6(p, (U32)(pEnd-p), bitDPtr, dd, ds, dtLog);24272428return p-pStart;2429}2430243124322433static size_t HUF_decompress4X6_usingDTable(2434void* dst, size_t dstSize,2435const void* cSrc, size_t cSrcSize,2436const U32* DTable)2437{2438if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */24392440{2441const BYTE* const istart = (const BYTE*) cSrc;2442BYTE* const ostart = (BYTE*) dst;2443BYTE* const oend = ostart + dstSize;24442445const U32 dtLog = DTable[0];2446const void* ddPtr = DTable+1;2447const HUF_DDescX6* dd = (const HUF_DDescX6*)(ddPtr);2448const void* dsPtr = DTable + 1 + ((size_t)1<<(dtLog-1));2449const HUF_DSeqX6* ds = (const HUF_DSeqX6*)(dsPtr);2450size_t errorCode;24512452/* Init */2453BIT_DStream_t bitD1;2454BIT_DStream_t bitD2;2455BIT_DStream_t bitD3;2456BIT_DStream_t bitD4;2457const size_t length1 = MEM_readLE16(istart);2458const size_t length2 = MEM_readLE16(istart+2);2459const size_t length3 = MEM_readLE16(istart+4);2460size_t length4;2461const BYTE* const istart1 = istart + 6; /* jumpTable */2462const BYTE* const istart2 = istart1 + length1;2463const BYTE* const istart3 = istart2 + length2;2464const BYTE* const istart4 = istart3 + length3;2465const size_t segmentSize = (dstSize+3) / 4;2466BYTE* const opStart2 = ostart + segmentSize;2467BYTE* const opStart3 = opStart2 + segmentSize;2468BYTE* const opStart4 = opStart3 + segmentSize;2469BYTE* op1 = ostart;2470BYTE* op2 = opStart2;2471BYTE* op3 = opStart3;2472BYTE* op4 = opStart4;2473U32 endSignal;24742475length4 = cSrcSize - (length1 + length2 + length3 + 6);2476if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */2477errorCode = BIT_initDStream(&bitD1, istart1, length1);2478if (HUF_isError(errorCode)) return errorCode;2479errorCode = BIT_initDStream(&bitD2, istart2, length2);2480if (HUF_isError(errorCode)) return errorCode;2481errorCode = BIT_initDStream(&bitD3, istart3, length3);2482if (HUF_isError(errorCode)) return errorCode;2483errorCode = BIT_initDStream(&bitD4, istart4, length4);2484if (HUF_isError(errorCode)) return errorCode;24852486/* 16-64 symbols per loop (4-16 symbols per stream) */2487endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);2488for ( ; (op3 <= opStart4) && (endSignal==BIT_DStream_unfinished) && (op4<=(oend-16)) ; )2489{2490HUF_DECODE_SYMBOLX6_2(op1, &bitD1);2491HUF_DECODE_SYMBOLX6_2(op2, &bitD2);2492HUF_DECODE_SYMBOLX6_2(op3, &bitD3);2493HUF_DECODE_SYMBOLX6_2(op4, &bitD4);2494HUF_DECODE_SYMBOLX6_1(op1, &bitD1);2495HUF_DECODE_SYMBOLX6_1(op2, &bitD2);2496HUF_DECODE_SYMBOLX6_1(op3, &bitD3);2497HUF_DECODE_SYMBOLX6_1(op4, &bitD4);2498HUF_DECODE_SYMBOLX6_2(op1, &bitD1);2499HUF_DECODE_SYMBOLX6_2(op2, &bitD2);2500HUF_DECODE_SYMBOLX6_2(op3, &bitD3);2501HUF_DECODE_SYMBOLX6_2(op4, &bitD4);2502HUF_DECODE_SYMBOLX6_0(op1, &bitD1);2503HUF_DECODE_SYMBOLX6_0(op2, &bitD2);2504HUF_DECODE_SYMBOLX6_0(op3, &bitD3);2505HUF_DECODE_SYMBOLX6_0(op4, &bitD4);25062507endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);2508}25092510/* check corruption */2511if (op1 > opStart2) return ERROR(corruption_detected);2512if (op2 > opStart3) return ERROR(corruption_detected);2513if (op3 > opStart4) return ERROR(corruption_detected);2514/* note : op4 supposed already verified within main loop */25152516/* finish bitStreams one by one */2517HUF_decodeStreamX6(op1, &bitD1, opStart2, DTable, dtLog);2518HUF_decodeStreamX6(op2, &bitD2, opStart3, DTable, dtLog);2519HUF_decodeStreamX6(op3, &bitD3, opStart4, DTable, dtLog);2520HUF_decodeStreamX6(op4, &bitD4, oend, DTable, dtLog);25212522/* check */2523endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);2524if (!endSignal) return ERROR(corruption_detected);25252526/* decoded size */2527return dstSize;2528}2529}253025312532static size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)2533{2534HUF_CREATE_STATIC_DTABLEX6(DTable, HUF_MAX_TABLELOG);2535const BYTE* ip = (const BYTE*) cSrc;25362537size_t hSize = HUF_readDTableX6 (DTable, cSrc, cSrcSize);2538if (HUF_isError(hSize)) return hSize;2539if (hSize >= cSrcSize) return ERROR(srcSize_wrong);2540ip += hSize;2541cSrcSize -= hSize;25422543return HUF_decompress4X6_usingDTable (dst, dstSize, ip, cSrcSize, DTable);2544}254525462547/**********************************/2548/* Generic decompression selector */2549/**********************************/25502551typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;2552static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =2553{2554/* single, double, quad */2555{{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */2556{{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */2557{{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */2558{{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */2559{{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */2560{{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */2561{{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */2562{{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */2563{{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */2564{{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */2565{{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */2566{{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */2567{{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */2568{{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */2569{{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */2570{{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */2571};25722573typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);25742575static size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)2576{2577static const decompressionAlgo decompress[3] = { HUF_decompress4X2, HUF_decompress4X4, HUF_decompress4X6 };2578/* estimate decompression time */2579U32 Q;2580const U32 D256 = (U32)(dstSize >> 8);2581U32 Dtime[3];2582U32 algoNb = 0;2583int n;25842585/* validation checks */2586if (dstSize == 0) return ERROR(dstSize_tooSmall);2587if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */2588if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */2589if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */25902591/* decoder timing evaluation */2592Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */2593for (n=0; n<3; n++)2594Dtime[n] = algoTime[Q][n].tableTime + (algoTime[Q][n].decode256Time * D256);25952596Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */25972598if (Dtime[1] < Dtime[0]) algoNb = 1;2599if (Dtime[2] < Dtime[algoNb]) algoNb = 2;26002601return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);26022603//return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */2604//return HUF_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */2605//return HUF_decompress4X6(dst, dstSize, cSrc, cSrcSize); /* multi-streams quad-symbols decoding */2606}2607/*2608zstd - standard compression library2609Copyright (C) 2014-2015, Yann Collet.26102611BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)26122613Redistribution and use in source and binary forms, with or without2614modification, are permitted provided that the following conditions are2615met:2616* Redistributions of source code must retain the above copyright2617notice, this list of conditions and the following disclaimer.2618* Redistributions in binary form must reproduce the above2619copyright notice, this list of conditions and the following disclaimer2620in the documentation and/or other materials provided with the2621distribution.2622THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS2623"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT2624LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR2625A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT2626OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,2627SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT2628LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,2629DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY2630THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT2631(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE2632OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.26332634You can contact the author at :2635- zstd source repository : https://github.com/Cyan4973/zstd2636- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c2637*/26382639/* ***************************************************************2640* Tuning parameters2641*****************************************************************/2642/*!2643* MEMORY_USAGE :2644* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)2645* Increasing memory usage improves compression ratio2646* Reduced memory usage can improve speed, due to cache effect2647*/2648#define ZSTD_MEMORY_USAGE 1726492650/*!2651* HEAPMODE :2652* Select how default compression functions will allocate memory for their hash table,2653* in memory stack (0, fastest), or in memory heap (1, requires malloc())2654* Note that compression context is fairly large, as a consequence heap memory is recommended.2655*/2656#ifndef ZSTD_HEAPMODE2657# define ZSTD_HEAPMODE 12658#endif /* ZSTD_HEAPMODE */26592660/*!2661* LEGACY_SUPPORT :2662* decompressor can decode older formats (starting from Zstd 0.1+)2663*/2664#ifndef ZSTD_LEGACY_SUPPORT2665# define ZSTD_LEGACY_SUPPORT 12666#endif266726682669/* *******************************************************2670* Includes2671*********************************************************/2672#include <stdlib.h> /* calloc */2673#include <string.h> /* memcpy, memmove */2674#include <stdio.h> /* debug : printf */267526762677/* *******************************************************2678* Compiler specifics2679*********************************************************/2680#ifdef __AVX2__2681# include <immintrin.h> /* AVX2 intrinsics */2682#endif26832684#ifdef _MSC_VER /* Visual Studio */2685# include <intrin.h> /* For Visual 2005 */2686# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */2687# pragma warning(disable : 4324) /* disable: C4324: padded structure */2688#endif268926902691/* *******************************************************2692* Constants2693*********************************************************/2694#define HASH_LOG (ZSTD_MEMORY_USAGE - 2)2695#define HASH_TABLESIZE (1 << HASH_LOG)2696#define HASH_MASK (HASH_TABLESIZE - 1)26972698#define KNUTH 265443576126992700#define BIT7 1282701#define BIT6 642702#define BIT5 322703#define BIT4 162704#define BIT1 22705#define BIT0 127062707#define KB *(1 <<10)2708#define MB *(1 <<20)2709#define GB *(1U<<30)27102711#define BLOCKSIZE (128 KB) /* define, for static allocation */2712#define MIN_SEQUENCES_SIZE (2 /*seqNb*/ + 2 /*dumps*/ + 3 /*seqTables*/ + 1 /*bitStream*/)2713#define MIN_CBLOCK_SIZE (3 /*litCSize*/ + MIN_SEQUENCES_SIZE)2714#define IS_RAW BIT02715#define IS_RLE BIT127162717#define WORKPLACESIZE (BLOCKSIZE*3)2718#define MINMATCH 42719#define MLbits 72720#define LLbits 62721#define Offbits 52722#define MaxML ((1<<MLbits )-1)2723#define MaxLL ((1<<LLbits )-1)2724#define MaxOff 312725#define LitFSELog 112726#define MLFSELog 102727#define LLFSELog 102728#define OffFSELog 92729#define MAX(a,b) ((a)<(b)?(b):(a))2730#define MaxSeq MAX(MaxLL, MaxML)27312732#define LITERAL_NOENTROPY 632733#define COMMAND_NOENTROPY 7 /* to remove */27342735#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)27362737static const size_t ZSTD_blockHeaderSize = 3;2738static const size_t ZSTD_frameHeaderSize = 4;273927402741/* *******************************************************2742* Memory operations2743**********************************************************/2744static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }27452746static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }27472748#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }27492750/*! ZSTD_wildcopy : custom version of memcpy(), can copy up to 7-8 bytes too many */2751static void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)2752{2753const BYTE* ip = (const BYTE*)src;2754BYTE* op = (BYTE*)dst;2755BYTE* const oend = op + length;2756do COPY8(op, ip) while (op < oend);2757}275827592760/* **************************************2761* Local structures2762****************************************/2763typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;27642765typedef struct2766{2767blockType_t blockType;2768U32 origSize;2769} blockProperties_t;27702771typedef struct {2772void* buffer;2773U32* offsetStart;2774U32* offset;2775BYTE* offCodeStart;2776BYTE* offCode;2777BYTE* litStart;2778BYTE* lit;2779BYTE* litLengthStart;2780BYTE* litLength;2781BYTE* matchLengthStart;2782BYTE* matchLength;2783BYTE* dumpsStart;2784BYTE* dumps;2785} seqStore_t;278627872788/* *************************************2789* Error Management2790***************************************/2791/*! ZSTD_isError2792* tells if a return value is an error code */2793static unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }2794279527962797/* *************************************************************2798* Decompression section2799***************************************************************/2800struct ZSTD_DCtx_s2801{2802U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];2803U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];2804U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];2805void* previousDstEnd;2806void* base;2807size_t expected;2808blockType_t bType;2809U32 phase;2810const BYTE* litPtr;2811size_t litSize;2812BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */];2813}; /* typedef'd to ZSTD_Dctx within "zstd_static.h" */281428152816static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)2817{2818const BYTE* const in = (const BYTE* const)src;2819BYTE headerFlags;2820U32 cSize;28212822if (srcSize < 3) return ERROR(srcSize_wrong);28232824headerFlags = *in;2825cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);28262827bpPtr->blockType = (blockType_t)(headerFlags >> 6);2828bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;28292830if (bpPtr->blockType == bt_end) return 0;2831if (bpPtr->blockType == bt_rle) return 1;2832return cSize;2833}28342835static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)2836{2837if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);2838if (srcSize > 0) {2839memcpy(dst, src, srcSize);2840}2841return srcSize;2842}284328442845/** ZSTD_decompressLiterals2846@return : nb of bytes read from src, or an error code*/2847static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr,2848const void* src, size_t srcSize)2849{2850const BYTE* ip = (const BYTE*)src;28512852const size_t litSize = (MEM_readLE32(src) & 0x1FFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */2853const size_t litCSize = (MEM_readLE32(ip+2) & 0xFFFFFF) >> 5; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */28542855if (litSize > *maxDstSizePtr) return ERROR(corruption_detected);2856if (litCSize + 5 > srcSize) return ERROR(corruption_detected);28572858if (HUF_isError(HUF_decompress(dst, litSize, ip+5, litCSize))) return ERROR(corruption_detected);28592860*maxDstSizePtr = litSize;2861return litCSize + 5;2862}286328642865/** ZSTD_decodeLiteralsBlock2866@return : nb of bytes read from src (< srcSize )*/2867static size_t ZSTD_decodeLiteralsBlock(void* ctx,2868const void* src, size_t srcSize)2869{2870ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx;2871const BYTE* const istart = (const BYTE* const)src;28722873/* any compressed block with literals segment must be at least this size */2874if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);28752876switch(*istart & 3)2877{2878default:2879case 0:2880{2881size_t litSize = BLOCKSIZE;2882const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize);2883dctx->litPtr = dctx->litBuffer;2884dctx->litSize = litSize;2885memset(dctx->litBuffer + dctx->litSize, 0, 8);2886return readSize; /* works if it's an error too */2887}2888case IS_RAW:2889{2890const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */2891if (litSize > srcSize-11) /* risk of reading too far with wildcopy */2892{2893if (litSize > BLOCKSIZE) return ERROR(corruption_detected);2894if (litSize > srcSize-3) return ERROR(corruption_detected);2895memcpy(dctx->litBuffer, istart, litSize);2896dctx->litPtr = dctx->litBuffer;2897dctx->litSize = litSize;2898memset(dctx->litBuffer + dctx->litSize, 0, 8);2899return litSize+3;2900}2901/* direct reference into compressed stream */2902dctx->litPtr = istart+3;2903dctx->litSize = litSize;2904return litSize+3;2905}2906case IS_RLE:2907{2908const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */2909if (litSize > BLOCKSIZE) return ERROR(corruption_detected);2910memset(dctx->litBuffer, istart[3], litSize + 8);2911dctx->litPtr = dctx->litBuffer;2912dctx->litSize = litSize;2913return 4;2914}2915}2916}291729182919static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,2920FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,2921const void* src, size_t srcSize)2922{2923const BYTE* const istart = (const BYTE* const)src;2924const BYTE* ip = istart;2925const BYTE* const iend = istart + srcSize;2926U32 LLtype, Offtype, MLtype;2927U32 LLlog, Offlog, MLlog;2928size_t dumpsLength;29292930/* check */2931if (srcSize < 5) return ERROR(srcSize_wrong);29322933/* SeqHead */2934*nbSeq = MEM_readLE16(ip); ip+=2;2935LLtype = *ip >> 6;2936Offtype = (*ip >> 4) & 3;2937MLtype = (*ip >> 2) & 3;2938if (*ip & 2)2939{2940dumpsLength = ip[2];2941dumpsLength += ip[1] << 8;2942ip += 3;2943}2944else2945{2946dumpsLength = ip[1];2947dumpsLength += (ip[0] & 1) << 8;2948ip += 2;2949}2950*dumpsPtr = ip;2951ip += dumpsLength;2952*dumpsLengthPtr = dumpsLength;29532954/* check */2955if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */29562957/* sequences */2958{2959S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL and MaxOff */2960size_t headerSize;29612962/* Build DTables */2963switch(LLtype)2964{2965case bt_rle :2966LLlog = 0;2967FSE_buildDTable_rle(DTableLL, *ip++); break;2968case bt_raw :2969LLlog = LLbits;2970FSE_buildDTable_raw(DTableLL, LLbits); break;2971default :2972{ U32 max = MaxLL;2973headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);2974if (FSE_isError(headerSize)) return ERROR(GENERIC);2975if (LLlog > LLFSELog) return ERROR(corruption_detected);2976ip += headerSize;2977FSE_buildDTable(DTableLL, norm, max, LLlog);2978} }29792980switch(Offtype)2981{2982case bt_rle :2983Offlog = 0;2984if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */2985FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */2986break;2987case bt_raw :2988Offlog = Offbits;2989FSE_buildDTable_raw(DTableOffb, Offbits); break;2990default :2991{ U32 max = MaxOff;2992headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);2993if (FSE_isError(headerSize)) return ERROR(GENERIC);2994if (Offlog > OffFSELog) return ERROR(corruption_detected);2995ip += headerSize;2996FSE_buildDTable(DTableOffb, norm, max, Offlog);2997} }29982999switch(MLtype)3000{3001case bt_rle :3002MLlog = 0;3003if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */3004FSE_buildDTable_rle(DTableML, *ip++); break;3005case bt_raw :3006MLlog = MLbits;3007FSE_buildDTable_raw(DTableML, MLbits); break;3008default :3009{ U32 max = MaxML;3010headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);3011if (FSE_isError(headerSize)) return ERROR(GENERIC);3012if (MLlog > MLFSELog) return ERROR(corruption_detected);3013ip += headerSize;3014FSE_buildDTable(DTableML, norm, max, MLlog);3015} } }30163017return ip-istart;3018}301930203021typedef struct {3022size_t litLength;3023size_t offset;3024size_t matchLength;3025} seq_t;30263027typedef struct {3028BIT_DStream_t DStream;3029FSE_DState_t stateLL;3030FSE_DState_t stateOffb;3031FSE_DState_t stateML;3032size_t prevOffset;3033const BYTE* dumps;3034const BYTE* dumpsEnd;3035} seqState_t;303630373038static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)3039{3040size_t litLength;3041size_t prevOffset;3042size_t offset;3043size_t matchLength;3044const BYTE* dumps = seqState->dumps;3045const BYTE* const de = seqState->dumpsEnd;30463047/* Literal length */3048litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));3049prevOffset = litLength ? seq->offset : seqState->prevOffset;3050seqState->prevOffset = seq->offset;3051if (litLength == MaxLL)3052{3053const U32 add = dumps<de ? *dumps++ : 0;3054if (add < 255) litLength += add;3055else if (dumps + 3 <= de)3056{3057litLength = MEM_readLE24(dumps);3058dumps += 3;3059}3060if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */3061}30623063/* Offset */3064{3065static const size_t offsetPrefix[MaxOff+1] = { /* note : size_t faster than U32 */30661 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,3067512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,3068524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };3069U32 offsetCode, nbBits;3070offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */3071if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));3072nbBits = offsetCode - 1;3073if (offsetCode==0) nbBits = 0; /* cmove */3074offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);3075if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));3076if (offsetCode==0) offset = prevOffset; /* cmove */3077}30783079/* MatchLength */3080matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));3081if (matchLength == MaxML)3082{3083const U32 add = dumps<de ? *dumps++ : 0;3084if (add < 255) matchLength += add;3085else if (dumps + 3 <= de)3086{3087matchLength = MEM_readLE24(dumps);3088dumps += 3;3089}3090if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */3091}3092matchLength += MINMATCH;30933094/* save result */3095seq->litLength = litLength;3096seq->offset = offset;3097seq->matchLength = matchLength;3098seqState->dumps = dumps;3099}310031013102static size_t ZSTD_execSequence(BYTE* op,3103seq_t sequence,3104const BYTE** litPtr, const BYTE* const litLimit,3105BYTE* const base, BYTE* const oend)3106{3107static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */3108static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* subtracted */3109const BYTE* const ostart = op;3110BYTE* const oLitEnd = op + sequence.litLength;3111BYTE* const oMatchEnd = op + sequence.litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */3112BYTE* const oend_8 = oend-8;3113const BYTE* const litEnd = *litPtr + sequence.litLength;31143115/* checks */3116if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */3117if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */3118if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */31193120/* copy Literals */3121ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */3122op = oLitEnd;3123*litPtr = litEnd; /* update for next sequence */31243125/* copy Match */3126{3127const BYTE* match = op - sequence.offset;31283129/* check */3130if (sequence.offset > (size_t)op) return ERROR(corruption_detected); /* address space overflow test (this test seems kept by clang optimizer) */3131//if (match > op) return ERROR(corruption_detected); /* address space overflow test (is clang optimizer removing this test ?) */3132if (match < base) return ERROR(corruption_detected);31333134/* close range match, overlap */3135if (sequence.offset < 8)3136{3137const int dec64 = dec64table[sequence.offset];3138op[0] = match[0];3139op[1] = match[1];3140op[2] = match[2];3141op[3] = match[3];3142match += dec32table[sequence.offset];3143ZSTD_copy4(op+4, match);3144match -= dec64;3145}3146else3147{3148ZSTD_copy8(op, match);3149}3150op += 8; match += 8;31513152if (oMatchEnd > oend-(16-MINMATCH))3153{3154if (op < oend_8)3155{3156ZSTD_wildcopy(op, match, oend_8 - op);3157match += oend_8 - op;3158op = oend_8;3159}3160while (op < oMatchEnd) *op++ = *match++;3161}3162else3163{3164ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */3165}3166}31673168return oMatchEnd - ostart;3169}31703171static size_t ZSTD_decompressSequences(3172void* ctx,3173void* dst, size_t maxDstSize,3174const void* seqStart, size_t seqSize)3175{3176ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx;3177const BYTE* ip = (const BYTE*)seqStart;3178const BYTE* const iend = ip + seqSize;3179BYTE* const ostart = (BYTE* const)dst;3180BYTE* op = ostart;3181BYTE* const oend = ostart + maxDstSize;3182size_t errorCode, dumpsLength;3183const BYTE* litPtr = dctx->litPtr;3184const BYTE* const litEnd = litPtr + dctx->litSize;3185int nbSeq;3186const BYTE* dumps;3187U32* DTableLL = dctx->LLTable;3188U32* DTableML = dctx->MLTable;3189U32* DTableOffb = dctx->OffTable;3190BYTE* const base = (BYTE*) (dctx->base);31913192/* Build Decoding Tables */3193errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,3194DTableLL, DTableML, DTableOffb,3195ip, iend-ip);3196if (ZSTD_isError(errorCode)) return errorCode;3197ip += errorCode;31983199/* Regen sequences */3200{3201seq_t sequence;3202seqState_t seqState;32033204memset(&sequence, 0, sizeof(sequence));3205seqState.dumps = dumps;3206seqState.dumpsEnd = dumps + dumpsLength;3207seqState.prevOffset = 1;3208errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);3209if (ERR_isError(errorCode)) return ERROR(corruption_detected);3210FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);3211FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);3212FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);32133214for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (nbSeq>0) ; )3215{3216size_t oneSeqSize;3217nbSeq--;3218ZSTD_decodeSequence(&sequence, &seqState);3219oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litEnd, base, oend);3220if (ZSTD_isError(oneSeqSize)) return oneSeqSize;3221op += oneSeqSize;3222}32233224/* check if reached exact end */3225if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* requested too much : data is corrupted */3226if (nbSeq<0) return ERROR(corruption_detected); /* requested too many sequences : data is corrupted */32273228/* last literal segment */3229{3230size_t lastLLSize = litEnd - litPtr;3231if (litPtr > litEnd) return ERROR(corruption_detected);3232if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);3233if (lastLLSize > 0) {3234if (op != litPtr) memmove(op, litPtr, lastLLSize);3235op += lastLLSize;3236}3237}3238}32393240return op-ostart;3241}324232433244static size_t ZSTD_decompressBlock(3245void* ctx,3246void* dst, size_t maxDstSize,3247const void* src, size_t srcSize)3248{3249/* blockType == blockCompressed */3250const BYTE* ip = (const BYTE*)src;32513252/* Decode literals sub-block */3253size_t litCSize = ZSTD_decodeLiteralsBlock(ctx, src, srcSize);3254if (ZSTD_isError(litCSize)) return litCSize;3255ip += litCSize;3256srcSize -= litCSize;32573258return ZSTD_decompressSequences(ctx, dst, maxDstSize, ip, srcSize);3259}326032613262static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)3263{3264const BYTE* ip = (const BYTE*)src;3265const BYTE* iend = ip + srcSize;3266BYTE* const ostart = (BYTE* const)dst;3267BYTE* op = ostart;3268BYTE* const oend = ostart + maxDstSize;3269size_t remainingSize = srcSize;3270U32 magicNumber;3271blockProperties_t blockProperties;32723273/* Frame Header */3274if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);3275magicNumber = MEM_readLE32(src);3276if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);3277ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize;32783279/* Loop on each block */3280while (1)3281{3282size_t decodedSize=0;3283size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);3284if (ZSTD_isError(cBlockSize)) return cBlockSize;32853286ip += ZSTD_blockHeaderSize;3287remainingSize -= ZSTD_blockHeaderSize;3288if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);32893290switch(blockProperties.blockType)3291{3292case bt_compressed:3293decodedSize = ZSTD_decompressBlock(ctx, op, oend-op, ip, cBlockSize);3294break;3295case bt_raw :3296decodedSize = ZSTD_copyUncompressedBlock(op, oend-op, ip, cBlockSize);3297break;3298case bt_rle :3299return ERROR(GENERIC); /* not yet supported */3300break;3301case bt_end :3302/* end of frame */3303if (remainingSize) return ERROR(srcSize_wrong);3304break;3305default:3306return ERROR(GENERIC); /* impossible */3307}3308if (cBlockSize == 0) break; /* bt_end */33093310if (ZSTD_isError(decodedSize)) return decodedSize;3311op += decodedSize;3312ip += cBlockSize;3313remainingSize -= cBlockSize;3314}33153316return op-ostart;3317}33183319static size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)3320{3321ZSTD_DCtx ctx;3322ctx.base = dst;3323return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize);3324}33253326/* ZSTD_errorFrameSizeInfoLegacy() :3327assumes `cSize` and `dBound` are _not_ NULL */3328static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret)3329{3330*cSize = ret;3331*dBound = ZSTD_CONTENTSIZE_ERROR;3332}33333334void ZSTDv02_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound)3335{3336const BYTE* ip = (const BYTE*)src;3337size_t remainingSize = srcSize;3338size_t nbBlocks = 0;3339U32 magicNumber;3340blockProperties_t blockProperties;33413342/* Frame Header */3343if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) {3344ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));3345return;3346}3347magicNumber = MEM_readLE32(src);3348if (magicNumber != ZSTD_magicNumber) {3349ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown));3350return;3351}3352ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize;33533354/* Loop on each block */3355while (1)3356{3357size_t cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);3358if (ZSTD_isError(cBlockSize)) {3359ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, cBlockSize);3360return;3361}33623363ip += ZSTD_blockHeaderSize;3364remainingSize -= ZSTD_blockHeaderSize;3365if (cBlockSize > remainingSize) {3366ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));3367return;3368}33693370if (cBlockSize == 0) break; /* bt_end */33713372ip += cBlockSize;3373remainingSize -= cBlockSize;3374nbBlocks++;3375}33763377*cSize = ip - (const BYTE*)src;3378*dBound = nbBlocks * BLOCKSIZE;3379}33803381/*******************************3382* Streaming Decompression API3383*******************************/33843385static size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)3386{3387dctx->expected = ZSTD_frameHeaderSize;3388dctx->phase = 0;3389dctx->previousDstEnd = NULL;3390dctx->base = NULL;3391return 0;3392}33933394static ZSTD_DCtx* ZSTD_createDCtx(void)3395{3396ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));3397if (dctx==NULL) return NULL;3398ZSTD_resetDCtx(dctx);3399return dctx;3400}34013402static size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)3403{3404free(dctx);3405return 0;3406}34073408static size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)3409{3410return dctx->expected;3411}34123413static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)3414{3415/* Sanity check */3416if (srcSize != ctx->expected) return ERROR(srcSize_wrong);3417if (dst != ctx->previousDstEnd) /* not contiguous */3418ctx->base = dst;34193420/* Decompress : frame header */3421if (ctx->phase == 0)3422{3423/* Check frame magic header */3424U32 magicNumber = MEM_readLE32(src);3425if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);3426ctx->phase = 1;3427ctx->expected = ZSTD_blockHeaderSize;3428return 0;3429}34303431/* Decompress : block header */3432if (ctx->phase == 1)3433{3434blockProperties_t bp;3435size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);3436if (ZSTD_isError(blockSize)) return blockSize;3437if (bp.blockType == bt_end)3438{3439ctx->expected = 0;3440ctx->phase = 0;3441}3442else3443{3444ctx->expected = blockSize;3445ctx->bType = bp.blockType;3446ctx->phase = 2;3447}34483449return 0;3450}34513452/* Decompress : block content */3453{3454size_t rSize;3455switch(ctx->bType)3456{3457case bt_compressed:3458rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src, srcSize);3459break;3460case bt_raw :3461rSize = ZSTD_copyUncompressedBlock(dst, maxDstSize, src, srcSize);3462break;3463case bt_rle :3464return ERROR(GENERIC); /* not yet handled */3465break;3466case bt_end : /* should never happen (filtered at phase 1) */3467rSize = 0;3468break;3469default:3470return ERROR(GENERIC);3471}3472ctx->phase = 1;3473ctx->expected = ZSTD_blockHeaderSize;3474ctx->previousDstEnd = (void*)( ((char*)dst) + rSize);3475return rSize;3476}34773478}347934803481/* wrapper layer */34823483unsigned ZSTDv02_isError(size_t code)3484{3485return ZSTD_isError(code);3486}34873488size_t ZSTDv02_decompress( void* dst, size_t maxOriginalSize,3489const void* src, size_t compressedSize)3490{3491return ZSTD_decompress(dst, maxOriginalSize, src, compressedSize);3492}34933494ZSTDv02_Dctx* ZSTDv02_createDCtx(void)3495{3496return (ZSTDv02_Dctx*)ZSTD_createDCtx();3497}34983499size_t ZSTDv02_freeDCtx(ZSTDv02_Dctx* dctx)3500{3501return ZSTD_freeDCtx((ZSTD_DCtx*)dctx);3502}35033504size_t ZSTDv02_resetDCtx(ZSTDv02_Dctx* dctx)3505{3506return ZSTD_resetDCtx((ZSTD_DCtx*)dctx);3507}35083509size_t ZSTDv02_nextSrcSizeToDecompress(ZSTDv02_Dctx* dctx)3510{3511return ZSTD_nextSrcSizeToDecompress((ZSTD_DCtx*)dctx);3512}35133514size_t ZSTDv02_decompressContinue(ZSTDv02_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)3515{3516return ZSTD_decompressContinue((ZSTD_DCtx*)dctx, dst, maxDstSize, src, srcSize);3517}351835193520