1
0
mirror of https://github.com/facebook/zstd.git synced 2025-07-30 22:23:13 +03:00

Convert all spaces to tabs

This commit is contained in:
Nick Terrell
2017-03-29 19:57:22 -07:00
parent 78063ca2bd
commit 1075c12078
20 changed files with 7669 additions and 7669 deletions

View File

@ -41,12 +41,12 @@ extern "C" {
decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22. decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
Levels >= 20, labeled `--ultra`, should be used with caution, as they require more memory. Levels >= 20, labeled `--ultra`, should be used with caution, as they require more memory.
Compression can be done in: Compression can be done in:
- a single step (described as Simple API) - a single step (described as Simple API)
- a single step, reusing a context (described as Explicit memory management) - a single step, reusing a context (described as Explicit memory management)
- unbounded multiple steps (described as Streaming compression) - unbounded multiple steps (described as Streaming compression)
The compression ratio achievable on small data can be highly improved using compression with a dictionary in: The compression ratio achievable on small data can be highly improved using compression with a dictionary in:
- a single step (described as Simple dictionary API) - a single step (described as Simple dictionary API)
- a single step, reusing a dictionary (described as Fast dictionary API) - a single step, reusing a dictionary (described as Fast dictionary API)
Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h. Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h.
These APIs shall never be used with a dynamic library. These APIs shall never be used with a dynamic library.
@ -71,22 +71,22 @@ ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< library version number; to
* Simple API * Simple API
***************************************/ ***************************************/
/*! ZSTD_compress() : /*! ZSTD_compress() :
Compresses `src` content as a single zstd compressed frame into already allocated `dst`. Compresses `src` content as a single zstd compressed frame into already allocated `dst`.
Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
@return : compressed size written into `dst` (<= `dstCapacity), @return : compressed size written into `dst` (<= `dstCapacity),
or an error code if it fails (which can be tested using ZSTD_isError()). */ or an error code if it fails (which can be tested using ZSTD_isError()). */
ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
int compressionLevel); int compressionLevel);
/*! ZSTD_decompress() : /*! ZSTD_decompress() :
`compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames. `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames.
`dstCapacity` is an upper bound of originalSize. `dstCapacity` is an upper bound of originalSize.
If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`), @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
or an errorCode if it fails (which can be tested using ZSTD_isError()). */ or an errorCode if it fails (which can be tested using ZSTD_isError()). */
ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity, ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
const void* src, size_t compressedSize); const void* src, size_t compressedSize);
/*! ZSTD_getDecompressedSize() : /*! ZSTD_getDecompressedSize() :
* NOTE: This function is planned to be obsolete, in favour of ZSTD_getFrameContentSize. * NOTE: This function is planned to be obsolete, in favour of ZSTD_getFrameContentSize.
@ -136,7 +136,7 @@ ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
/*! ZSTD_compressCCtx() : /*! ZSTD_compressCCtx() :
Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */ Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel); ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
/*= Decompression context /*= Decompression context
@ -161,10 +161,10 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapa
* Note : This function loads the dictionary, resulting in significant startup delay. * Note : This function loads the dictionary, resulting in significant startup delay.
* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const void* dict,size_t dictSize, const void* dict,size_t dictSize,
int compressionLevel); int compressionLevel);
/*! ZSTD_decompress_usingDict() : /*! ZSTD_decompress_usingDict() :
* Decompression using a predefined Dictionary (see dictBuilder/zdict.h). * Decompression using a predefined Dictionary (see dictBuilder/zdict.h).
@ -172,9 +172,9 @@ ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
* Note : This function loads the dictionary, resulting in significant startup delay. * Note : This function loads the dictionary, resulting in significant startup delay.
* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const void* dict,size_t dictSize); const void* dict,size_t dictSize);
/**************************** /****************************
@ -198,9 +198,9 @@ ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
* Note that compression level is decided during dictionary creation. */ * Note that compression level is decided during dictionary creation. */
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const ZSTD_CDict* cdict); const ZSTD_CDict* cdict);
typedef struct ZSTD_DDict_s ZSTD_DDict; typedef struct ZSTD_DDict_s ZSTD_DDict;
@ -218,9 +218,9 @@ ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
* Decompression using a digested Dictionary. * Decompression using a digested Dictionary.
* Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */ * Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */
ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const ZSTD_DDict* ddict); const ZSTD_DDict* ddict);
/**************************** /****************************
@ -379,24 +379,24 @@ static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable f
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy; /* from faster to stronger */ typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy; /* from faster to stronger */
typedef struct { typedef struct {
unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */ unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */
unsigned chainLog; /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */ unsigned chainLog; /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
unsigned hashLog; /**< dispatch table : larger == faster, more memory */ unsigned hashLog; /**< dispatch table : larger == faster, more memory */
unsigned searchLog; /**< nb of searches : larger == more compression, slower */ unsigned searchLog; /**< nb of searches : larger == more compression, slower */
unsigned searchLength; /**< match length searched : larger == faster decompression, sometimes less compression */ unsigned searchLength; /**< match length searched : larger == faster decompression, sometimes less compression */
unsigned targetLength; /**< acceptable match size for optimal parser (only) : larger == more compression, slower */ unsigned targetLength; /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
ZSTD_strategy strategy; ZSTD_strategy strategy;
} ZSTD_compressionParameters; } ZSTD_compressionParameters;
typedef struct { typedef struct {
unsigned contentSizeFlag; /**< 1: content size will be in frame header (when known) */ unsigned contentSizeFlag; /**< 1: content size will be in frame header (when known) */
unsigned checksumFlag; /**< 1: generate a 32-bits checksum at end of frame, for error detection */ unsigned checksumFlag; /**< 1: generate a 32-bits checksum at end of frame, for error detection */
unsigned noDictIDFlag; /**< 1: no dictID will be saved into frame header (if dictionary compression) */ unsigned noDictIDFlag; /**< 1: no dictID will be saved into frame header (if dictionary compression) */
} ZSTD_frameParameters; } ZSTD_frameParameters;
typedef struct { typedef struct {
ZSTD_compressionParameters cParams; ZSTD_compressionParameters cParams;
ZSTD_frameParameters fParams; ZSTD_frameParameters fParams;
} ZSTD_parameters; } ZSTD_parameters;
/*= Custom memory allocation functions */ /*= Custom memory allocation functions */
@ -470,8 +470,8 @@ ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
typedef enum { typedef enum {
ZSTD_p_forceWindow, /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */ ZSTD_p_forceWindow, /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
ZSTD_p_forceRawDict /* Force loading dictionary in "content-only" mode (no header analysis) */ ZSTD_p_forceRawDict /* Force loading dictionary in "content-only" mode (no header analysis) */
} ZSTD_CCtxParameter; } ZSTD_CCtxParameter;
/*! ZSTD_setCCtxParameter() : /*! ZSTD_setCCtxParameter() :
* Set advanced parameters, selected through enum ZSTD_CCtxParameter * Set advanced parameters, selected through enum ZSTD_CCtxParameter
@ -487,7 +487,7 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, siz
/*! ZSTD_createCDict_advanced() : /*! ZSTD_createCDict_advanced() :
* Create a ZSTD_CDict using external alloc and free, and customized compression parameters */ * Create a ZSTD_CDict using external alloc and free, and customized compression parameters */
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
ZSTD_parameters params, ZSTD_customMem customMem); ZSTD_parameters params, ZSTD_customMem customMem);
/*! ZSTD_sizeof_CDict() : /*! ZSTD_sizeof_CDict() :
* Gives the amount of memory used by a given ZSTD_sizeof_CDict */ * Gives the amount of memory used by a given ZSTD_sizeof_CDict */
@ -515,10 +515,10 @@ ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParame
/*! ZSTD_compress_advanced() : /*! ZSTD_compress_advanced() :
* Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter */ * Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter */
ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const void* dict,size_t dictSize, const void* dict,size_t dictSize,
ZSTD_parameters params); ZSTD_parameters params);
/*--- Advanced decompression functions ---*/ /*--- Advanced decompression functions ---*/
@ -551,7 +551,7 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, siz
/*! ZSTD_createDDict_advanced() : /*! ZSTD_createDDict_advanced() :
* Create a ZSTD_DDict using external alloc and free, optionally by reference */ * Create a ZSTD_DDict using external alloc and free, optionally by reference */
ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
unsigned byReference, ZSTD_customMem customMem); unsigned byReference, ZSTD_customMem customMem);
/*! ZSTD_sizeof_DDict() : /*! ZSTD_sizeof_DDict() :
* Gives the amount of memory used by a given ZSTD_DDict */ * Gives the amount of memory used by a given ZSTD_DDict */
@ -591,7 +591,7 @@ ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */ ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */
ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */ ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */ ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */ ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */
ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before. note: pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */ ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before. note: pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */
ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs); ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
@ -632,12 +632,12 @@ ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
- ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only. - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
- Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks. - Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks.
- Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario. - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
Worst case evaluation is provided by ZSTD_compressBound(). Worst case evaluation is provided by ZSTD_compressBound().
ZSTD_compressContinue() doesn't guarantee recover after a failed compression. ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
- ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog). - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks) It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
- ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps. - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
In which case, it will "discard" the relevant memory section from its history. In which case, it will "discard" the relevant memory section from its history.
Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum. Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame. It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame.
@ -675,8 +675,8 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
Frame parameters are extracted from the beginning of the compressed frame. Frame parameters are extracted from the beginning of the compressed frame.
Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes. Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
@result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled. @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
>0 : `srcSize` is too small, please provide at least @result bytes on next attempt. >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
errorCode, which can be tested using ZSTD_isError(). errorCode, which can be tested using ZSTD_isError().
Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict(). Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
Alternatively, you can copy a prepared context, using ZSTD_copyDCtx(). Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
@ -711,17 +711,17 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
c) Frame Content - any content (User Data) of length equal to Frame Size c) Frame Content - any content (User Data) of length equal to Frame Size
For skippable frames ZSTD_decompressContinue() always returns 0. For skippable frames ZSTD_decompressContinue() always returns 0.
For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable. For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
Note : If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might actually be a Zstd encoded frame with no content. Note : If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might actually be a Zstd encoded frame with no content.
For purposes of decompression, it is valid in both cases to skip the frame using For purposes of decompression, it is valid in both cases to skip the frame using
ZSTD_findFrameCompressedSize to find its size in bytes. ZSTD_findFrameCompressedSize to find its size in bytes.
It also returns Frame Size as fparamsPtr->frameContentSize. It also returns Frame Size as fparamsPtr->frameContentSize.
*/ */
typedef struct { typedef struct {
unsigned long long frameContentSize; unsigned long long frameContentSize;
unsigned windowSize; unsigned windowSize;
unsigned dictID; unsigned dictID;
unsigned checksumFlag; unsigned checksumFlag;
} ZSTD_frameParams; } ZSTD_frameParams;
/*===== Buffer-less streaming decompression functions =====*/ /*===== Buffer-less streaming decompression functions =====*/
@ -735,29 +735,29 @@ typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_
ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
/** /**
Block functions Block functions
Block functions produce and decode raw zstd blocks, without frame metadata. Block functions produce and decode raw zstd blocks, without frame metadata.
Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes). Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
User will have to take in charge required information to regenerate data, such as compressed and content sizes. User will have to take in charge required information to regenerate data, such as compressed and content sizes.
A few rules to respect : A few rules to respect :
- Compressing and decompressing require a context structure - Compressing and decompressing require a context structure
+ Use ZSTD_createCCtx() and ZSTD_createDCtx() + Use ZSTD_createCCtx() and ZSTD_createDCtx()
- It is necessary to init context before starting - It is necessary to init context before starting
+ compression : ZSTD_compressBegin() + compression : ZSTD_compressBegin()
+ decompression : ZSTD_decompressBegin() + decompression : ZSTD_decompressBegin()
+ variants _usingDict() are also allowed + variants _usingDict() are also allowed
+ copyCCtx() and copyDCtx() work too + copyCCtx() and copyDCtx() work too
- Block size is limited, it must be <= ZSTD_getBlockSizeMax() - Block size is limited, it must be <= ZSTD_getBlockSizeMax()
+ If you need to compress more, cut data into multiple blocks + If you need to compress more, cut data into multiple blocks
+ Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large. + Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large.
- When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero. - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
In which case, nothing is produced into `dst`. In which case, nothing is produced into `dst`.
+ User must test for such outcome and deal directly with uncompressed data + User must test for such outcome and deal directly with uncompressed data
+ ZSTD_decompressBlock() doesn't accept uncompressed data as input !!! + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
+ In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history. + In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
Use ZSTD_insertBlock() in such a case. Use ZSTD_insertBlock() in such a case.
*/ */
#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */ #define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */

View File

@ -10,9 +10,9 @@
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
@ -73,11 +73,11 @@ extern "C" {
*/ */
typedef struct typedef struct
{ {
size_t bitContainer; size_t bitContainer;
int bitPos; int bitPos;
char* startPtr; char* startPtr;
char* ptr; char* ptr;
char* endPtr; char* endPtr;
} BIT_CStream_t; } BIT_CStream_t;
MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
@ -108,17 +108,17 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
**********************************************/ **********************************************/
typedef struct typedef struct
{ {
size_t bitContainer; size_t bitContainer;
unsigned bitsConsumed; unsigned bitsConsumed;
const char* ptr; const char* ptr;
const char* start; const char* start;
} BIT_DStream_t; } BIT_DStream_t;
typedef enum { BIT_DStream_unfinished = 0, typedef enum { BIT_DStream_unfinished = 0,
BIT_DStream_endOfBuffer = 1, BIT_DStream_endOfBuffer = 1,
BIT_DStream_completed = 2, BIT_DStream_completed = 2,
BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */ BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */
/* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
@ -157,20 +157,20 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
MEM_STATIC unsigned BIT_highbit32 (register U32 val) MEM_STATIC unsigned BIT_highbit32 (register U32 val)
{ {
# if defined(_MSC_VER) /* Visual */ # if defined(_MSC_VER) /* Visual */
unsigned long r=0; unsigned long r=0;
_BitScanReverse ( &r, val ); _BitScanReverse ( &r, val );
return (unsigned) r; return (unsigned) r;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
return 31 - __builtin_clz (val); return 31 - __builtin_clz (val);
# else /* Software version */ # else /* Software version */
static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
U32 v = val; U32 v = val;
v |= v >> 1; v |= v >> 1;
v |= v >> 2; v |= v >> 2;
v |= v >> 4; v |= v >> 4;
v |= v >> 8; v |= v >> 8;
v |= v >> 16; v |= v >> 16;
return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
# endif # endif
} }
@ -184,44 +184,44 @@ static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x
/*! BIT_initCStream() : /*! BIT_initCStream() :
* `dstCapacity` must be > sizeof(void*) * `dstCapacity` must be > sizeof(void*)
* @return : 0 if success, * @return : 0 if success,
otherwise an error code (can be tested using ERR_isError() ) */ otherwise an error code (can be tested using ERR_isError() ) */
MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t dstCapacity) MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t dstCapacity)
{ {
bitC->bitContainer = 0; bitC->bitContainer = 0;
bitC->bitPos = 0; bitC->bitPos = 0;
bitC->startPtr = (char*)startPtr; bitC->startPtr = (char*)startPtr;
bitC->ptr = bitC->startPtr; bitC->ptr = bitC->startPtr;
bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->ptr); bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->ptr);
if (dstCapacity <= sizeof(bitC->ptr)) return ERROR(dstSize_tooSmall); if (dstCapacity <= sizeof(bitC->ptr)) return ERROR(dstSize_tooSmall);
return 0; return 0;
} }
/*! BIT_addBits() : /*! BIT_addBits() :
can add up to 26 bits into `bitC`. can add up to 26 bits into `bitC`.
Does not check for register overflow ! */ Does not check for register overflow ! */
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits) MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
{ {
bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
bitC->bitPos += nbBits; bitC->bitPos += nbBits;
} }
/*! BIT_addBitsFast() : /*! BIT_addBitsFast() :
* works only if `value` is _clean_, meaning all high bits above nbBits are 0 */ * works only if `value` is _clean_, meaning all high bits above nbBits are 0 */
MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits) MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
{ {
bitC->bitContainer |= value << bitC->bitPos; bitC->bitContainer |= value << bitC->bitPos;
bitC->bitPos += nbBits; bitC->bitPos += nbBits;
} }
/*! BIT_flushBitsFast() : /*! BIT_flushBitsFast() :
* unsafe version; does not check buffer overflow */ * unsafe version; does not check buffer overflow */
MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
{ {
size_t const nbBytes = bitC->bitPos >> 3; size_t const nbBytes = bitC->bitPos >> 3;
MEM_writeLEST(bitC->ptr, bitC->bitContainer); MEM_writeLEST(bitC->ptr, bitC->bitContainer);
bitC->ptr += nbBytes; bitC->ptr += nbBytes;
bitC->bitPos &= 7; bitC->bitPos &= 7;
bitC->bitContainer >>= nbBytes*8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */ bitC->bitContainer >>= nbBytes*8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
} }
/*! BIT_flushBits() : /*! BIT_flushBits() :
@ -229,25 +229,25 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
* note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */ * note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */
MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
{ {
size_t const nbBytes = bitC->bitPos >> 3; size_t const nbBytes = bitC->bitPos >> 3;
MEM_writeLEST(bitC->ptr, bitC->bitContainer); MEM_writeLEST(bitC->ptr, bitC->bitContainer);
bitC->ptr += nbBytes; bitC->ptr += nbBytes;
if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
bitC->bitPos &= 7; bitC->bitPos &= 7;
bitC->bitContainer >>= nbBytes*8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */ bitC->bitContainer >>= nbBytes*8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
} }
/*! BIT_closeCStream() : /*! BIT_closeCStream() :
* @return : size of CStream, in bytes, * @return : size of CStream, in bytes,
or 0 if it could not fit into dstBuffer */ or 0 if it could not fit into dstBuffer */
MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
{ {
BIT_addBitsFast(bitC, 1, 1); /* endMark */ BIT_addBitsFast(bitC, 1, 1); /* endMark */
BIT_flushBits(bitC); BIT_flushBits(bitC);
if (bitC->ptr >= bitC->endPtr) return 0; /* doesn't fit within authorized budget : cancel */ if (bitC->ptr >= bitC->endPtr) return 0; /* doesn't fit within authorized budget : cancel */
return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
} }
@ -262,60 +262,60 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
*/ */
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
{ {
if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
bitD->start = (const char*)srcBuffer; bitD->start = (const char*)srcBuffer;
bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
bitD->bitContainer = MEM_readLEST(bitD->ptr); bitD->bitContainer = MEM_readLEST(bitD->ptr);
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
} else { } else {
bitD->start = (const char*)srcBuffer; bitD->start = (const char*)srcBuffer;
bitD->ptr = bitD->start; bitD->ptr = bitD->start;
bitD->bitContainer = *(const BYTE*)(bitD->start); bitD->bitContainer = *(const BYTE*)(bitD->start);
switch(srcSize) switch(srcSize)
{ {
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
default:; default:;
} }
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
} }
return srcSize; return srcSize;
} }
MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
{ {
return bitContainer >> start; return bitContainer >> start;
} }
MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
{ {
#if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */ #if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */
# if defined(__x86_64__) # if defined(__x86_64__)
if (sizeof(bitContainer)==8) if (sizeof(bitContainer)==8)
return _bextr_u64(bitContainer, start, nbBits); return _bextr_u64(bitContainer, start, nbBits);
else else
# endif # endif
return _bextr_u32(bitContainer, start, nbBits); return _bextr_u32(bitContainer, start, nbBits);
#else #else
return (bitContainer >> start) & BIT_mask[nbBits]; return (bitContainer >> start) & BIT_mask[nbBits];
#endif #endif
} }
MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
{ {
return bitContainer & BIT_mask[nbBits]; return bitContainer & BIT_mask[nbBits];
} }
/*! BIT_lookBits() : /*! BIT_lookBits() :
@ -328,10 +328,10 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
{ {
#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */ #if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */
return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
#else #else
U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1; U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask); return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
#endif #endif
} }
@ -339,13 +339,13 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
* unsafe version; only works only if nbBits >= 1 */ * unsafe version; only works only if nbBits >= 1 */
MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
{ {
U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1; U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask); return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
} }
MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
{ {
bitD->bitsConsumed += nbBits; bitD->bitsConsumed += nbBits;
} }
/*! BIT_readBits() : /*! BIT_readBits() :
@ -355,51 +355,51 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
*/ */
MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
{ {
size_t const value = BIT_lookBits(bitD, nbBits); size_t const value = BIT_lookBits(bitD, nbBits);
BIT_skipBits(bitD, nbBits); BIT_skipBits(bitD, nbBits);
return value; return value;
} }
/*! BIT_readBitsFast() : /*! BIT_readBitsFast() :
* unsafe version; only works only if nbBits >= 1 */ * unsafe version; only works only if nbBits >= 1 */
MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
{ {
size_t const value = BIT_lookBitsFast(bitD, nbBits); size_t const value = BIT_lookBitsFast(bitD, nbBits);
BIT_skipBits(bitD, nbBits); BIT_skipBits(bitD, nbBits);
return value; return value;
} }
/*! BIT_reloadDStream() : /*! BIT_reloadDStream() :
* Refill `bitD` from buffer previously set in BIT_initDStream() . * Refill `bitD` from buffer previously set in BIT_initDStream() .
* This function is safe, it guarantees it will not read beyond src buffer. * This function is safe, it guarantees it will not read beyond src buffer.
* @return : status of `BIT_DStream_t` internal register. * @return : status of `BIT_DStream_t` internal register.
if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */ if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
{ {
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */ if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */
return BIT_DStream_overflow; return BIT_DStream_overflow;
if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) { if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
bitD->ptr -= bitD->bitsConsumed >> 3; bitD->ptr -= bitD->bitsConsumed >> 3;
bitD->bitsConsumed &= 7; bitD->bitsConsumed &= 7;
bitD->bitContainer = MEM_readLEST(bitD->ptr); bitD->bitContainer = MEM_readLEST(bitD->ptr);
return BIT_DStream_unfinished; return BIT_DStream_unfinished;
} }
if (bitD->ptr == bitD->start) { if (bitD->ptr == bitD->start) {
if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
return BIT_DStream_completed; return BIT_DStream_completed;
} }
{ U32 nbBytes = bitD->bitsConsumed >> 3; { U32 nbBytes = bitD->bitsConsumed >> 3;
BIT_DStream_status result = BIT_DStream_unfinished; BIT_DStream_status result = BIT_DStream_unfinished;
if (bitD->ptr - nbBytes < bitD->start) { if (bitD->ptr - nbBytes < bitD->start) {
nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
result = BIT_DStream_endOfBuffer; result = BIT_DStream_endOfBuffer;
} }
bitD->ptr -= nbBytes; bitD->ptr -= nbBytes;
bitD->bitsConsumed -= nbBytes*8; bitD->bitsConsumed -= nbBytes*8;
bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */ bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */
return result; return result;
} }
} }
/*! BIT_endOfDStream() : /*! BIT_endOfDStream() :
@ -407,7 +407,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
*/ */
MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
{ {
return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
} }
#if defined (__cplusplus) #if defined (__cplusplus)

View File

@ -8,9 +8,9 @@
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
@ -27,9 +27,9 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at : You can contact the author at :
- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
- Public forum : https://groups.google.com/forum/#!forum/lz4c - Public forum : https://groups.google.com/forum/#!forum/lz4c
*************************************************************************** */ *************************************************************************** */
/* ************************************* /* *************************************
@ -59,163 +59,163 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
* FSE NCount encoding-decoding * FSE NCount encoding-decoding
****************************************************************/ ****************************************************************/
size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
const void* headerBuffer, size_t hbSize) const void* headerBuffer, size_t hbSize)
{ {
const BYTE* const istart = (const BYTE*) headerBuffer; const BYTE* const istart = (const BYTE*) headerBuffer;
const BYTE* const iend = istart + hbSize; const BYTE* const iend = istart + hbSize;
const BYTE* ip = istart; const BYTE* ip = istart;
int nbBits; int nbBits;
int remaining; int remaining;
int threshold; int threshold;
U32 bitStream; U32 bitStream;
int bitCount; int bitCount;
unsigned charnum = 0; unsigned charnum = 0;
int previous0 = 0; int previous0 = 0;
if (hbSize < 4) return ERROR(srcSize_wrong); if (hbSize < 4) return ERROR(srcSize_wrong);
bitStream = MEM_readLE32(ip); bitStream = MEM_readLE32(ip);
nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
bitStream >>= 4; bitStream >>= 4;
bitCount = 4; bitCount = 4;
*tableLogPtr = nbBits; *tableLogPtr = nbBits;
remaining = (1<<nbBits)+1; remaining = (1<<nbBits)+1;
threshold = 1<<nbBits; threshold = 1<<nbBits;
nbBits++; nbBits++;
while ((remaining>1) & (charnum<=*maxSVPtr)) { while ((remaining>1) & (charnum<=*maxSVPtr)) {
if (previous0) { if (previous0) {
unsigned n0 = charnum; unsigned n0 = charnum;
while ((bitStream & 0xFFFF) == 0xFFFF) { while ((bitStream & 0xFFFF) == 0xFFFF) {
n0 += 24; n0 += 24;
if (ip < iend-5) { if (ip < iend-5) {
ip += 2; ip += 2;
bitStream = MEM_readLE32(ip) >> bitCount; bitStream = MEM_readLE32(ip) >> bitCount;
} else { } else {
bitStream >>= 16; bitStream >>= 16;
bitCount += 16; bitCount += 16;
} } } }
while ((bitStream & 3) == 3) { while ((bitStream & 3) == 3) {
n0 += 3; n0 += 3;
bitStream >>= 2; bitStream >>= 2;
bitCount += 2; bitCount += 2;
} }
n0 += bitStream & 3; n0 += bitStream & 3;
bitCount += 2; bitCount += 2;
if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
while (charnum < n0) normalizedCounter[charnum++] = 0; while (charnum < n0) normalizedCounter[charnum++] = 0;
if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
ip += bitCount>>3; ip += bitCount>>3;
bitCount &= 7; bitCount &= 7;
bitStream = MEM_readLE32(ip) >> bitCount; bitStream = MEM_readLE32(ip) >> bitCount;
} else { } else {
bitStream >>= 2; bitStream >>= 2;
} } } }
{ int const max = (2*threshold-1) - remaining; { int const max = (2*threshold-1) - remaining;
int count; int count;
if ((bitStream & (threshold-1)) < (U32)max) { if ((bitStream & (threshold-1)) < (U32)max) {
count = bitStream & (threshold-1); count = bitStream & (threshold-1);
bitCount += nbBits-1; bitCount += nbBits-1;
} else { } else {
count = bitStream & (2*threshold-1); count = bitStream & (2*threshold-1);
if (count >= threshold) count -= max; if (count >= threshold) count -= max;
bitCount += nbBits; bitCount += nbBits;
} }
count--; /* extra accuracy */ count--; /* extra accuracy */
remaining -= count < 0 ? -count : count; /* -1 means +1 */ remaining -= count < 0 ? -count : count; /* -1 means +1 */
normalizedCounter[charnum++] = (short)count; normalizedCounter[charnum++] = (short)count;
previous0 = !count; previous0 = !count;
while (remaining < threshold) { while (remaining < threshold) {
nbBits--; nbBits--;
threshold >>= 1; threshold >>= 1;
} }
if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
ip += bitCount>>3; ip += bitCount>>3;
bitCount &= 7; bitCount &= 7;
} else { } else {
bitCount -= (int)(8 * (iend - 4 - ip)); bitCount -= (int)(8 * (iend - 4 - ip));
ip = iend - 4; ip = iend - 4;
} }
bitStream = MEM_readLE32(ip) >> (bitCount & 31); bitStream = MEM_readLE32(ip) >> (bitCount & 31);
} } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
if (remaining != 1) return ERROR(corruption_detected); if (remaining != 1) return ERROR(corruption_detected);
if (bitCount > 32) return ERROR(corruption_detected); if (bitCount > 32) return ERROR(corruption_detected);
*maxSVPtr = charnum-1; *maxSVPtr = charnum-1;
ip += (bitCount+7)>>3; ip += (bitCount+7)>>3;
return ip-istart; return ip-istart;
} }
/*! HUF_readStats() : /*! HUF_readStats() :
Read compact Huffman tree, saved by HUF_writeCTable(). Read compact Huffman tree, saved by HUF_writeCTable().
`huffWeight` is destination buffer. `huffWeight` is destination buffer.
`rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32.
@return : size read from `src` , or an error Code . @return : size read from `src` , or an error Code .
Note : Needed by HUF_readCTable() and HUF_readDTableX?() . Note : Needed by HUF_readCTable() and HUF_readDTableX?() .
*/ */
size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
U32* nbSymbolsPtr, U32* tableLogPtr, U32* nbSymbolsPtr, U32* tableLogPtr,
const void* src, size_t srcSize) const void* src, size_t srcSize)
{ {
U32 weightTotal; U32 weightTotal;
const BYTE* ip = (const BYTE*) src; const BYTE* ip = (const BYTE*) src;
size_t iSize; size_t iSize;
size_t oSize; size_t oSize;
if (!srcSize) return ERROR(srcSize_wrong); if (!srcSize) return ERROR(srcSize_wrong);
iSize = ip[0]; iSize = ip[0];
/* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
if (iSize >= 128) { /* special header */ if (iSize >= 128) { /* special header */
oSize = iSize - 127; oSize = iSize - 127;
iSize = ((oSize+1)/2); iSize = ((oSize+1)/2);
if (iSize+1 > srcSize) return ERROR(srcSize_wrong); if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
if (oSize >= hwSize) return ERROR(corruption_detected); if (oSize >= hwSize) return ERROR(corruption_detected);
ip += 1; ip += 1;
{ U32 n; { U32 n;
for (n=0; n<oSize; n+=2) { for (n=0; n<oSize; n+=2) {
huffWeight[n] = ip[n/2] >> 4; huffWeight[n] = ip[n/2] >> 4;
huffWeight[n+1] = ip[n/2] & 15; huffWeight[n+1] = ip[n/2] & 15;
} } } } } }
else { /* header compressed with FSE (normal case) */ else { /* header compressed with FSE (normal case) */
FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */
if (iSize+1 > srcSize) return ERROR(srcSize_wrong); if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */
if (FSE_isError(oSize)) return oSize; if (FSE_isError(oSize)) return oSize;
} }
/* collect weight stats */ /* collect weight stats */
memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
weightTotal = 0; weightTotal = 0;
{ U32 n; for (n=0; n<oSize; n++) { { U32 n; for (n=0; n<oSize; n++) {
if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected); if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
rankStats[huffWeight[n]]++; rankStats[huffWeight[n]]++;
weightTotal += (1 << huffWeight[n]) >> 1; weightTotal += (1 << huffWeight[n]) >> 1;
} } } }
if (weightTotal == 0) return ERROR(corruption_detected); if (weightTotal == 0) return ERROR(corruption_detected);
/* get last non-null symbol weight (implied, total must be 2^n) */ /* get last non-null symbol weight (implied, total must be 2^n) */
{ U32 const tableLog = BIT_highbit32(weightTotal) + 1; { U32 const tableLog = BIT_highbit32(weightTotal) + 1;
if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
*tableLogPtr = tableLog; *tableLogPtr = tableLog;
/* determine last weight */ /* determine last weight */
{ U32 const total = 1 << tableLog; { U32 const total = 1 << tableLog;
U32 const rest = total - weightTotal; U32 const rest = total - weightTotal;
U32 const verif = 1 << BIT_highbit32(rest); U32 const verif = 1 << BIT_highbit32(rest);
U32 const lastWeight = BIT_highbit32(rest) + 1; U32 const lastWeight = BIT_highbit32(rest) + 1;
if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
huffWeight[oSize] = (BYTE)lastWeight; huffWeight[oSize] = (BYTE)lastWeight;
rankStats[lastWeight]++; rankStats[lastWeight]++;
} } } }
/* check tree construction validity */ /* check tree construction validity */
if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
/* results */ /* results */
*nbSymbolsPtr = (U32)(oSize+1); *nbSymbolsPtr = (U32)(oSize+1);
return iSize+1; return iSize+1;
} }

View File

@ -13,32 +13,32 @@
const char* ERR_getErrorString(ERR_enum code) const char* ERR_getErrorString(ERR_enum code)
{ {
static const char* const notErrorCode = "Unspecified error code"; static const char* const notErrorCode = "Unspecified error code";
switch( code ) switch( code )
{ {
case PREFIX(no_error): return "No error detected"; case PREFIX(no_error): return "No error detected";
case PREFIX(GENERIC): return "Error (generic)"; case PREFIX(GENERIC): return "Error (generic)";
case PREFIX(prefix_unknown): return "Unknown frame descriptor"; case PREFIX(prefix_unknown): return "Unknown frame descriptor";
case PREFIX(version_unsupported): return "Version not supported"; case PREFIX(version_unsupported): return "Version not supported";
case PREFIX(parameter_unknown): return "Unknown parameter type"; case PREFIX(parameter_unknown): return "Unknown parameter type";
case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
case PREFIX(frameParameter_unsupportedBy32bits): return "Frame parameter unsupported in 32-bits mode"; case PREFIX(frameParameter_unsupportedBy32bits): return "Frame parameter unsupported in 32-bits mode";
case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding";
case PREFIX(compressionParameter_unsupported): return "Compression parameter is out of bound"; case PREFIX(compressionParameter_unsupported): return "Compression parameter is out of bound";
case PREFIX(init_missing): return "Context should be init first"; case PREFIX(init_missing): return "Context should be init first";
case PREFIX(memory_allocation): return "Allocation error : not enough memory"; case PREFIX(memory_allocation): return "Allocation error : not enough memory";
case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; case PREFIX(stage_wrong): return "Operation not authorized at current processing stage";
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
case PREFIX(srcSize_wrong): return "Src size incorrect"; case PREFIX(srcSize_wrong): return "Src size incorrect";
case PREFIX(corruption_detected): return "Corrupted block detected"; case PREFIX(corruption_detected): return "Corrupted block detected";
case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
case PREFIX(dictionary_wrong): return "Dictionary mismatch"; case PREFIX(dictionary_wrong): return "Dictionary mismatch";
case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples";
case PREFIX(maxCode): case PREFIX(maxCode):
default: return notErrorCode; default: return notErrorCode;
} }
} }

View File

@ -66,7 +66,7 @@ const char* ERR_getErrorString(ERR_enum code); /* error_private.c */
ERR_STATIC const char* ERR_getErrorName(size_t code) ERR_STATIC const char* ERR_getErrorName(size_t code)
{ {
return ERR_getErrorString(ERR_getErrorCode(code)); return ERR_getErrorString(ERR_getErrorCode(code));
} }
#if defined (__cplusplus) #if defined (__cplusplus)

View File

@ -9,9 +9,9 @@
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
@ -75,28 +75,28 @@ FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number;
* FSE simple functions * FSE simple functions
******************************************/ ******************************************/
/*! FSE_compress() : /*! FSE_compress() :
Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'. Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'.
'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize). 'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize).
@return : size of compressed data (<= dstCapacity). @return : size of compressed data (<= dstCapacity).
Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead. if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead.
if FSE_isError(return), compression failed (more details using FSE_getErrorName()) if FSE_isError(return), compression failed (more details using FSE_getErrorName())
*/ */
FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity,
const void* src, size_t srcSize); const void* src, size_t srcSize);
/*! FSE_decompress(): /*! FSE_decompress():
Decompress FSE data from buffer 'cSrc', of size 'cSrcSize', Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',
into already allocated destination buffer 'dst', of size 'dstCapacity'. into already allocated destination buffer 'dst', of size 'dstCapacity'.
@return : size of regenerated data (<= maxDstSize), @return : size of regenerated data (<= maxDstSize),
or an error code, which can be tested using FSE_isError() . or an error code, which can be tested using FSE_isError() .
** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!! ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!!
Why ? : making this distinction requires a header. Why ? : making this distinction requires a header.
Header management is intentionally delegated to the user layer, which can better manage special cases. Header management is intentionally delegated to the user layer, which can better manage special cases.
*/ */
FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity, FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity,
const void* cSrc, size_t cSrcSize); const void* cSrc, size_t cSrcSize);
/*-***************************************** /*-*****************************************
@ -113,12 +113,12 @@ FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error co
* FSE advanced functions * FSE advanced functions
******************************************/ ******************************************/
/*! FSE_compress2() : /*! FSE_compress2() :
Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog' Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog'
Both parameters can be defined as '0' to mean : use default value Both parameters can be defined as '0' to mean : use default value
@return : size of compressed data @return : size of compressed data
Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!! Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!!
if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression. if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression.
if FSE_isError(return), it's an error code. if FSE_isError(return), it's an error code.
*/ */
FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
@ -147,55 +147,55 @@ or to save and provide normalized distribution using external method.
/* *** COMPRESSION *** */ /* *** COMPRESSION *** */
/*! FSE_count(): /*! FSE_count():
Provides the precise count of each byte within a table 'count'. Provides the precise count of each byte within a table 'count'.
'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1). 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
*maxSymbolValuePtr will be updated if detected smaller than initial value. *maxSymbolValuePtr will be updated if detected smaller than initial value.
@return : the count of the most frequent symbol (which is not identified). @return : the count of the most frequent symbol (which is not identified).
if return == srcSize, there is only one symbol. if return == srcSize, there is only one symbol.
Can also return an error code, which can be tested with FSE_isError(). */ Can also return an error code, which can be tested with FSE_isError(). */
FSE_PUBLIC_API size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); FSE_PUBLIC_API size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
/*! FSE_optimalTableLog(): /*! FSE_optimalTableLog():
dynamically downsize 'tableLog' when conditions are met. dynamically downsize 'tableLog' when conditions are met.
It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.
@return : recommended tableLog (necessarily <= 'maxTableLog') */ @return : recommended tableLog (necessarily <= 'maxTableLog') */
FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
/*! FSE_normalizeCount(): /*! FSE_normalizeCount():
normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
@return : tableLog, @return : tableLog,
or an errorCode, which can be tested using FSE_isError() */ or an errorCode, which can be tested using FSE_isError() */
FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue); FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
/*! FSE_NCountWriteBound(): /*! FSE_NCountWriteBound():
Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
Typically useful for allocation purpose. */ Typically useful for allocation purpose. */
FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);
/*! FSE_writeNCount(): /*! FSE_writeNCount():
Compactly save 'normalizedCounter' into 'buffer'. Compactly save 'normalizedCounter' into 'buffer'.
@return : size of the compressed table, @return : size of the compressed table,
or an errorCode, which can be tested using FSE_isError(). */ or an errorCode, which can be tested using FSE_isError(). */
FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
/*! Constructor and Destructor of FSE_CTable. /*! Constructor and Destructor of FSE_CTable.
Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */
typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */
FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned tableLog, unsigned maxSymbolValue); FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned tableLog, unsigned maxSymbolValue);
FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct); FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct);
/*! FSE_buildCTable(): /*! FSE_buildCTable():
Builds `ct`, which must be already allocated, using FSE_createCTable(). Builds `ct`, which must be already allocated, using FSE_createCTable().
@return : 0, or an errorCode, which can be tested using FSE_isError() */ @return : 0, or an errorCode, which can be tested using FSE_isError() */
FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
/*! FSE_compress_usingCTable(): /*! FSE_compress_usingCTable():
Compress `src` using `ct` into `dst` which must be already allocated. Compress `src` using `ct` into `dst` which must be already allocated.
@return : size of compressed data (<= `dstCapacity`), @return : size of compressed data (<= `dstCapacity`),
or 0 if compressed data could not fit into `dst`, or 0 if compressed data could not fit into `dst`,
or an errorCode, which can be tested using FSE_isError() */ or an errorCode, which can be tested using FSE_isError() */
FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
/*! /*!
@ -245,28 +245,28 @@ If there is an error, the function will return an ErrorCode (which can be tested
/* *** DECOMPRESSION *** */ /* *** DECOMPRESSION *** */
/*! FSE_readNCount(): /*! FSE_readNCount():
Read compactly saved 'normalizedCounter' from 'rBuffer'. Read compactly saved 'normalizedCounter' from 'rBuffer'.
@return : size read from 'rBuffer', @return : size read from 'rBuffer',
or an errorCode, which can be tested using FSE_isError(). or an errorCode, which can be tested using FSE_isError().
maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize); FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
/*! Constructor and Destructor of FSE_DTable. /*! Constructor and Destructor of FSE_DTable.
Note that its size depends on 'tableLog' */ Note that its size depends on 'tableLog' */
typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog); FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog);
FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt); FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt);
/*! FSE_buildDTable(): /*! FSE_buildDTable():
Builds 'dt', which must be already allocated, using FSE_createDTable(). Builds 'dt', which must be already allocated, using FSE_createDTable().
return : 0, or an errorCode, which can be tested using FSE_isError() */ return : 0, or an errorCode, which can be tested using FSE_isError() */
FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
/*! FSE_decompress_usingDTable(): /*! FSE_decompress_usingDTable():
Decompress compressed source `cSrc` of size `cSrcSize` using `dt` Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
into `dst` which must be already allocated. into `dst` which must be already allocated.
@return : size of regenerated data (necessarily <= `dstCapacity`), @return : size of regenerated data (necessarily <= `dstCapacity`),
or an errorCode, which can be tested using FSE_isError() */ or an errorCode, which can be tested using FSE_isError() */
FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt); FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);
/*! /*!
@ -325,7 +325,7 @@ If there is an error, the function will return an error code, which can be teste
* `workSpace` size must be table of >= `1024` unsigned * `workSpace` size must be table of >= `1024` unsigned
*/ */
size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize, unsigned* workSpace); const void* source, size_t sourceSize, unsigned* workSpace);
/** FSE_countFast() : /** FSE_countFast() :
* same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr * same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr
@ -386,10 +386,10 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size
Hence their body are included in next section. Hence their body are included in next section.
*/ */
typedef struct { typedef struct {
ptrdiff_t value; ptrdiff_t value;
const void* stateTable; const void* stateTable;
const void* symbolTT; const void* symbolTT;
unsigned stateLog; unsigned stateLog;
} FSE_CState_t; } FSE_CState_t;
static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct); static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);
@ -413,32 +413,32 @@ FSE_CState_t state; // State tracking structure (can have several)
The first thing to do is to init bitStream and state. The first thing to do is to init bitStream and state.
size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize); size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize);
FSE_initCState(&state, ct); FSE_initCState(&state, ct);
Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError(); Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError();
You can then encode your input data, byte after byte. You can then encode your input data, byte after byte.
FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time. FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time.
Remember decoding will be done in reverse direction. Remember decoding will be done in reverse direction.
FSE_encodeByte(&bitStream, &state, symbol); FSE_encodeByte(&bitStream, &state, symbol);
At any time, you can also add any bit sequence. At any time, you can also add any bit sequence.
Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders
BIT_addBits(&bitStream, bitField, nbBits); BIT_addBits(&bitStream, bitField, nbBits);
The above methods don't commit data to memory, they just store it into local register, for speed. The above methods don't commit data to memory, they just store it into local register, for speed.
Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
Writing data to memory is a manual operation, performed by the flushBits function. Writing data to memory is a manual operation, performed by the flushBits function.
BIT_flushBits(&bitStream); BIT_flushBits(&bitStream);
Your last FSE encoding operation shall be to flush your last state value(s). Your last FSE encoding operation shall be to flush your last state value(s).
FSE_flushState(&bitStream, &state); FSE_flushState(&bitStream, &state);
Finally, you must close the bitStream. Finally, you must close the bitStream.
The function returns the size of CStream in bytes. The function returns the size of CStream in bytes.
If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible) If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible)
If there is an error, it returns an errorCode (which can be tested using FSE_isError()). If there is an error, it returns an errorCode (which can be tested using FSE_isError()).
size_t size = BIT_closeCStream(&bitStream); size_t size = BIT_closeCStream(&bitStream);
*/ */
@ -446,8 +446,8 @@ If there is an error, it returns an errorCode (which can be tested using FSE_isE
* FSE symbol decompression API * FSE symbol decompression API
*******************************************/ *******************************************/
typedef struct { typedef struct {
size_t state; size_t state;
const void* table; /* precise table may vary, depending on U16 */ const void* table; /* precise table may vary, depending on U16 */
} FSE_DState_t; } FSE_DState_t;
@ -469,24 +469,24 @@ FSE_DState_t DState; // State context. Multiple ones are possible
FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable() FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable()
The first thing to do is to init the bitStream. The first thing to do is to init the bitStream.
errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize); errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize);
You should then retrieve your initial state(s) You should then retrieve your initial state(s)
(in reverse flushing order if you have several ones) : (in reverse flushing order if you have several ones) :
errorCode = FSE_initDState(&DState, &DStream, DTablePtr); errorCode = FSE_initDState(&DState, &DStream, DTablePtr);
You can then decode your data, symbol after symbol. You can then decode your data, symbol after symbol.
For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'. For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'.
Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out). Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
unsigned char symbol = FSE_decodeSymbol(&DState, &DStream); unsigned char symbol = FSE_decodeSymbol(&DState, &DStream);
You can retrieve any bitfield you eventually stored into the bitStream (in reverse order) You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
Note : maximum allowed nbBits is 25, for 32-bits compatibility Note : maximum allowed nbBits is 25, for 32-bits compatibility
size_t bitField = BIT_readBits(&DStream, nbBits); size_t bitField = BIT_readBits(&DStream, nbBits);
All above operations only read from local register (which size depends on size_t). All above operations only read from local register (which size depends on size_t).
Refueling the register from memory is manually performed by the reload method. Refueling the register from memory is manually performed by the reload method.
endSignal = FSE_reloadDStream(&DStream); endSignal = FSE_reloadDStream(&DStream);
BIT_reloadDStream() result tells if there is still some more data to read from DStream. BIT_reloadDStream() result tells if there is still some more data to read from DStream.
BIT_DStream_unfinished : there is still some data left into the DStream. BIT_DStream_unfinished : there is still some data left into the DStream.
@ -497,13 +497,13 @@ BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop, When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
to properly detect the exact end of stream. to properly detect the exact end of stream.
After each decoded symbol, check if DStream is fully consumed using this simple test : After each decoded symbol, check if DStream is fully consumed using this simple test :
BIT_reloadDStream(&DStream) >= BIT_DStream_completed BIT_reloadDStream(&DStream) >= BIT_DStream_completed
When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
Checking if DStream has reached its end is performed by : Checking if DStream has reached its end is performed by :
BIT_endOfDStream(&DStream); BIT_endOfDStream(&DStream);
Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
FSE_endOfDState(&DState); FSE_endOfDState(&DState);
*/ */
@ -518,19 +518,19 @@ static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t
* Implementation of inlined functions * Implementation of inlined functions
*******************************************/ *******************************************/
typedef struct { typedef struct {
int deltaFindState; int deltaFindState;
U32 deltaNbBits; U32 deltaNbBits;
} FSE_symbolCompressionTransform; /* total 8 bytes */ } FSE_symbolCompressionTransform; /* total 8 bytes */
MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
{ {
const void* ptr = ct; const void* ptr = ct;
const U16* u16ptr = (const U16*) ptr; const U16* u16ptr = (const U16*) ptr;
const U32 tableLog = MEM_read16(ptr); const U32 tableLog = MEM_read16(ptr);
statePtr->value = (ptrdiff_t)1<<tableLog; statePtr->value = (ptrdiff_t)1<<tableLog;
statePtr->stateTable = u16ptr+2; statePtr->stateTable = u16ptr+2;
statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1)); statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
statePtr->stateLog = tableLog; statePtr->stateLog = tableLog;
} }
@ -539,95 +539,95 @@ MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
* uses the smallest state value possible, saving the cost of this symbol */ * uses the smallest state value possible, saving the cost of this symbol */
MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
{ {
FSE_initCState(statePtr, ct); FSE_initCState(statePtr, ct);
{ const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
const U16* stateTable = (const U16*)(statePtr->stateTable); const U16* stateTable = (const U16*)(statePtr->stateTable);
U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
} }
} }
MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol) MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
{ {
const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
const U16* const stateTable = (const U16*)(statePtr->stateTable); const U16* const stateTable = (const U16*)(statePtr->stateTable);
U32 nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); U32 nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
BIT_addBits(bitC, statePtr->value, nbBitsOut); BIT_addBits(bitC, statePtr->value, nbBitsOut);
statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
} }
MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
{ {
BIT_addBits(bitC, statePtr->value, statePtr->stateLog); BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
BIT_flushBits(bitC); BIT_flushBits(bitC);
} }
/* ====== Decompression ====== */ /* ====== Decompression ====== */
typedef struct { typedef struct {
U16 tableLog; U16 tableLog;
U16 fastMode; U16 fastMode;
} FSE_DTableHeader; /* sizeof U32 */ } FSE_DTableHeader; /* sizeof U32 */
typedef struct typedef struct
{ {
unsigned short newState; unsigned short newState;
unsigned char symbol; unsigned char symbol;
unsigned char nbBits; unsigned char nbBits;
} FSE_decode_t; /* size == U32 */ } FSE_decode_t; /* size == U32 */
MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
{ {
const void* ptr = dt; const void* ptr = dt;
const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
BIT_reloadDStream(bitD); BIT_reloadDStream(bitD);
DStatePtr->table = dt + 1; DStatePtr->table = dt + 1;
} }
MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
{ {
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
return DInfo.symbol; return DInfo.symbol;
} }
MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
{ {
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
U32 const nbBits = DInfo.nbBits; U32 const nbBits = DInfo.nbBits;
size_t const lowBits = BIT_readBits(bitD, nbBits); size_t const lowBits = BIT_readBits(bitD, nbBits);
DStatePtr->state = DInfo.newState + lowBits; DStatePtr->state = DInfo.newState + lowBits;
} }
MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
{ {
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
U32 const nbBits = DInfo.nbBits; U32 const nbBits = DInfo.nbBits;
BYTE const symbol = DInfo.symbol; BYTE const symbol = DInfo.symbol;
size_t const lowBits = BIT_readBits(bitD, nbBits); size_t const lowBits = BIT_readBits(bitD, nbBits);
DStatePtr->state = DInfo.newState + lowBits; DStatePtr->state = DInfo.newState + lowBits;
return symbol; return symbol;
} }
/*! FSE_decodeSymbolFast() : /*! FSE_decodeSymbolFast() :
unsafe, only works if no symbol has a probability > 50% */ unsafe, only works if no symbol has a probability > 50% */
MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
{ {
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
U32 const nbBits = DInfo.nbBits; U32 const nbBits = DInfo.nbBits;
BYTE const symbol = DInfo.symbol; BYTE const symbol = DInfo.symbol;
size_t const lowBits = BIT_readBitsFast(bitD, nbBits); size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
DStatePtr->state = DInfo.newState + lowBits; DStatePtr->state = DInfo.newState + lowBits;
return symbol; return symbol;
} }
MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
{ {
return DStatePtr->state == 0; return DStatePtr->state == 0;
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
@ -27,9 +27,9 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at : You can contact the author at :
- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
- Public forum : https://groups.google.com/forum/#!forum/lz4c - Public forum : https://groups.google.com/forum/#!forum/lz4c
****************************************************************** */ ****************************************************************** */
@ -100,70 +100,70 @@
/* Function templates */ /* Function templates */
FSE_DTable* FSE_createDTable (unsigned tableLog) FSE_DTable* FSE_createDTable (unsigned tableLog)
{ {
if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
} }
void FSE_freeDTable (FSE_DTable* dt) void FSE_freeDTable (FSE_DTable* dt)
{ {
free(dt); free(dt);
} }
size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
{ {
void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
U32 const maxSV1 = maxSymbolValue + 1; U32 const maxSV1 = maxSymbolValue + 1;
U32 const tableSize = 1 << tableLog; U32 const tableSize = 1 << tableLog;
U32 highThreshold = tableSize-1; U32 highThreshold = tableSize-1;
/* Sanity Checks */ /* Sanity Checks */
if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
/* Init, lay down lowprob symbols */ /* Init, lay down lowprob symbols */
{ FSE_DTableHeader DTableH; { FSE_DTableHeader DTableH;
DTableH.tableLog = (U16)tableLog; DTableH.tableLog = (U16)tableLog;
DTableH.fastMode = 1; DTableH.fastMode = 1;
{ S16 const largeLimit= (S16)(1 << (tableLog-1)); { S16 const largeLimit= (S16)(1 << (tableLog-1));
U32 s; U32 s;
for (s=0; s<maxSV1; s++) { for (s=0; s<maxSV1; s++) {
if (normalizedCounter[s]==-1) { if (normalizedCounter[s]==-1) {
tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
symbolNext[s] = 1; symbolNext[s] = 1;
} else { } else {
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0; if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
symbolNext[s] = normalizedCounter[s]; symbolNext[s] = normalizedCounter[s];
} } } } } }
memcpy(dt, &DTableH, sizeof(DTableH)); memcpy(dt, &DTableH, sizeof(DTableH));
} }
/* Spread symbols */ /* Spread symbols */
{ U32 const tableMask = tableSize-1; { U32 const tableMask = tableSize-1;
U32 const step = FSE_TABLESTEP(tableSize); U32 const step = FSE_TABLESTEP(tableSize);
U32 s, position = 0; U32 s, position = 0;
for (s=0; s<maxSV1; s++) { for (s=0; s<maxSV1; s++) {
int i; int i;
for (i=0; i<normalizedCounter[s]; i++) { for (i=0; i<normalizedCounter[s]; i++) {
tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s; tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
position = (position + step) & tableMask; position = (position + step) & tableMask;
while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */ while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
} } } }
if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
} }
/* Build Decoding table */ /* Build Decoding table */
{ U32 u; { U32 u;
for (u=0; u<tableSize; u++) { for (u=0; u<tableSize; u++) {
FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol); FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);
U16 nextState = symbolNext[symbol]++; U16 nextState = symbolNext[symbol]++;
tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32 ((U32)nextState) ); tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32 ((U32)nextState) );
tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize); tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
} } } }
return 0; return 0;
} }
@ -174,144 +174,144 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned
*********************************************************/ *********************************************************/
size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue) size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
{ {
void* ptr = dt; void* ptr = dt;
FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
void* dPtr = dt + 1; void* dPtr = dt + 1;
FSE_decode_t* const cell = (FSE_decode_t*)dPtr; FSE_decode_t* const cell = (FSE_decode_t*)dPtr;
DTableH->tableLog = 0; DTableH->tableLog = 0;
DTableH->fastMode = 0; DTableH->fastMode = 0;
cell->newState = 0; cell->newState = 0;
cell->symbol = symbolValue; cell->symbol = symbolValue;
cell->nbBits = 0; cell->nbBits = 0;
return 0; return 0;
} }
size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
{ {
void* ptr = dt; void* ptr = dt;
FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
void* dPtr = dt + 1; void* dPtr = dt + 1;
FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr; FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
const unsigned tableSize = 1 << nbBits; const unsigned tableSize = 1 << nbBits;
const unsigned tableMask = tableSize - 1; const unsigned tableMask = tableSize - 1;
const unsigned maxSV1 = tableMask+1; const unsigned maxSV1 = tableMask+1;
unsigned s; unsigned s;
/* Sanity checks */ /* Sanity checks */
if (nbBits < 1) return ERROR(GENERIC); /* min size */ if (nbBits < 1) return ERROR(GENERIC); /* min size */
/* Build Decoding Table */ /* Build Decoding Table */
DTableH->tableLog = (U16)nbBits; DTableH->tableLog = (U16)nbBits;
DTableH->fastMode = 1; DTableH->fastMode = 1;
for (s=0; s<maxSV1; s++) { for (s=0; s<maxSV1; s++) {
dinfo[s].newState = 0; dinfo[s].newState = 0;
dinfo[s].symbol = (BYTE)s; dinfo[s].symbol = (BYTE)s;
dinfo[s].nbBits = (BYTE)nbBits; dinfo[s].nbBits = (BYTE)nbBits;
} }
return 0; return 0;
} }
FORCE_INLINE size_t FSE_decompress_usingDTable_generic( FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
void* dst, size_t maxDstSize, void* dst, size_t maxDstSize,
const void* cSrc, size_t cSrcSize, const void* cSrc, size_t cSrcSize,
const FSE_DTable* dt, const unsigned fast) const FSE_DTable* dt, const unsigned fast)
{ {
BYTE* const ostart = (BYTE*) dst; BYTE* const ostart = (BYTE*) dst;
BYTE* op = ostart; BYTE* op = ostart;
BYTE* const omax = op + maxDstSize; BYTE* const omax = op + maxDstSize;
BYTE* const olimit = omax-3; BYTE* const olimit = omax-3;
BIT_DStream_t bitD; BIT_DStream_t bitD;
FSE_DState_t state1; FSE_DState_t state1;
FSE_DState_t state2; FSE_DState_t state2;
/* Init */ /* Init */
CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize)); CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize));
FSE_initDState(&state1, &bitD, dt); FSE_initDState(&state1, &bitD, dt);
FSE_initDState(&state2, &bitD, dt); FSE_initDState(&state2, &bitD, dt);
#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD) #define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
/* 4 symbols per loop */ /* 4 symbols per loop */
for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) { for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) {
op[0] = FSE_GETSYMBOL(&state1); op[0] = FSE_GETSYMBOL(&state1);
if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
BIT_reloadDStream(&bitD); BIT_reloadDStream(&bitD);
op[1] = FSE_GETSYMBOL(&state2); op[1] = FSE_GETSYMBOL(&state2);
if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
{ if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
op[2] = FSE_GETSYMBOL(&state1); op[2] = FSE_GETSYMBOL(&state1);
if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
BIT_reloadDStream(&bitD); BIT_reloadDStream(&bitD);
op[3] = FSE_GETSYMBOL(&state2); op[3] = FSE_GETSYMBOL(&state2);
} }
/* tail */ /* tail */
/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
while (1) { while (1) {
if (op>(omax-2)) return ERROR(dstSize_tooSmall); if (op>(omax-2)) return ERROR(dstSize_tooSmall);
*op++ = FSE_GETSYMBOL(&state1); *op++ = FSE_GETSYMBOL(&state1);
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
*op++ = FSE_GETSYMBOL(&state2); *op++ = FSE_GETSYMBOL(&state2);
break; break;
} }
if (op>(omax-2)) return ERROR(dstSize_tooSmall); if (op>(omax-2)) return ERROR(dstSize_tooSmall);
*op++ = FSE_GETSYMBOL(&state2); *op++ = FSE_GETSYMBOL(&state2);
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
*op++ = FSE_GETSYMBOL(&state1); *op++ = FSE_GETSYMBOL(&state1);
break; break;
} } } }
return op-ostart; return op-ostart;
} }
size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
const void* cSrc, size_t cSrcSize, const void* cSrc, size_t cSrcSize,
const FSE_DTable* dt) const FSE_DTable* dt)
{ {
const void* ptr = dt; const void* ptr = dt;
const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
const U32 fastMode = DTableH->fastMode; const U32 fastMode = DTableH->fastMode;
/* select fast mode (static) */ /* select fast mode (static) */
if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
} }
size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog) size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog)
{ {
const BYTE* const istart = (const BYTE*)cSrc; const BYTE* const istart = (const BYTE*)cSrc;
const BYTE* ip = istart; const BYTE* ip = istart;
short counting[FSE_MAX_SYMBOL_VALUE+1]; short counting[FSE_MAX_SYMBOL_VALUE+1];
unsigned tableLog; unsigned tableLog;
unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
/* normal FSE decoding mode */ /* normal FSE decoding mode */
size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
if (FSE_isError(NCountLength)) return NCountLength; if (FSE_isError(NCountLength)) return NCountLength;
//if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */
if (tableLog > maxLog) return ERROR(tableLog_tooLarge); if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
ip += NCountLength; ip += NCountLength;
cSrcSize -= NCountLength; cSrcSize -= NCountLength;
CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) ); CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) );
return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */
} }
@ -319,8 +319,8 @@ typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize)
{ {
DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */
return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG); return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG);
} }

View File

@ -9,9 +9,9 @@
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
@ -46,31 +46,31 @@ extern "C" {
/* *** simple functions *** */ /* *** simple functions *** */
/** /**
HUF_compress() : HUF_compress() :
Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'. Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'.
'dst' buffer must be already allocated. 'dst' buffer must be already allocated.
Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize). Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize).
`srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB. `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB.
@return : size of compressed data (<= `dstCapacity`). @return : size of compressed data (<= `dstCapacity`).
Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
if return == 1, srcData is a single repeated byte symbol (RLE compression). if return == 1, srcData is a single repeated byte symbol (RLE compression).
if HUF_isError(return), compression failed (more details using HUF_getErrorName()) if HUF_isError(return), compression failed (more details using HUF_getErrorName())
*/ */
size_t HUF_compress(void* dst, size_t dstCapacity, size_t HUF_compress(void* dst, size_t dstCapacity,
const void* src, size_t srcSize); const void* src, size_t srcSize);
/** /**
HUF_decompress() : HUF_decompress() :
Decompress HUF data from buffer 'cSrc', of size 'cSrcSize', Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
into already allocated buffer 'dst', of minimum size 'dstSize'. into already allocated buffer 'dst', of minimum size 'dstSize'.
`originalSize` : **must** be the ***exact*** size of original (uncompressed) data. `originalSize` : **must** be the ***exact*** size of original (uncompressed) data.
Note : in contrast with FSE, HUF_decompress can regenerate Note : in contrast with FSE, HUF_decompress can regenerate
RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
because it knows size to regenerate. because it knows size to regenerate.
@return : size of regenerated data (== originalSize), @return : size of regenerated data (== originalSize),
or an error code, which can be tested using HUF_isError() or an error code, which can be tested using HUF_isError()
*/ */
size_t HUF_decompress(void* dst, size_t originalSize, size_t HUF_decompress(void* dst, size_t originalSize,
const void* cSrc, size_t cSrcSize); const void* cSrc, size_t cSrcSize);
/* *** Tool functions *** */ /* *** Tool functions *** */
@ -122,17 +122,17 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t s
/* static allocation of HUF's Compression Table */ /* static allocation of HUF's Compression Table */
#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ #define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
U32 name##hb[maxSymbolValue+1]; \ U32 name##hb[maxSymbolValue+1]; \
void* name##hv = &(name##hb); \ void* name##hv = &(name##hb); \
HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */ HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */
/* static allocation of HUF's DTable */ /* static allocation of HUF's DTable */
typedef U32 HUF_DTable; typedef U32 HUF_DTable;
#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) #define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog)))
#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ #define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }
#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \ #define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
/* The workspace must have alignment at least 4 and be at least this large */ /* The workspace must have alignment at least 4 and be at least this large */
#define HUF_WORKSPACE_SIZE (6 << 10) #define HUF_WORKSPACE_SIZE (6 << 10)
@ -192,13 +192,13 @@ size_t HUF_compress4X_repeat(void* dst, size_t dstSize, const void* src, size_t
size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize); size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize);
/*! HUF_readStats() : /*! HUF_readStats() :
Read compact Huffman tree, saved by HUF_writeCTable(). Read compact Huffman tree, saved by HUF_writeCTable().
`huffWeight` is destination buffer. `huffWeight` is destination buffer.
@return : size read from `src` , or an error Code . @return : size read from `src` , or an error Code .
Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */
size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
U32* nbSymbolsPtr, U32* tableLogPtr, U32* nbSymbolsPtr, U32* tableLogPtr,
const void* src, size_t srcSize); const void* src, size_t srcSize);
/** HUF_readCTable() : /** HUF_readCTable() :
* Loading a CTable saved with HUF_writeCTable() */ * Loading a CTable saved with HUF_writeCTable() */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -100,8 +100,8 @@ MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
MEM_STATIC unsigned MEM_isLittleEndian(void) MEM_STATIC unsigned MEM_isLittleEndian(void)
{ {
const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
return one.c[0]; return one.c[0];
} }
#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
@ -122,11 +122,11 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
/* currently only defined for gcc and icc */ /* currently only defined for gcc and icc */
#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32)) #if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
__pragma( pack(push, 1) ) __pragma( pack(push, 1) )
typedef union { U16 u16; U32 u32; U64 u64; size_t st; } unalign; typedef union { U16 u16; U32 u32; U64 u64; size_t st; } unalign;
__pragma( pack(pop) ) __pragma( pack(pop) )
#else #else
typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign; typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign;
#endif #endif
MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
@ -145,37 +145,37 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign*)memPtr)->u64 =
MEM_STATIC U16 MEM_read16(const void* memPtr) MEM_STATIC U16 MEM_read16(const void* memPtr)
{ {
U16 val; memcpy(&val, memPtr, sizeof(val)); return val; U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
} }
MEM_STATIC U32 MEM_read32(const void* memPtr) MEM_STATIC U32 MEM_read32(const void* memPtr)
{ {
U32 val; memcpy(&val, memPtr, sizeof(val)); return val; U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
} }
MEM_STATIC U64 MEM_read64(const void* memPtr) MEM_STATIC U64 MEM_read64(const void* memPtr)
{ {
U64 val; memcpy(&val, memPtr, sizeof(val)); return val; U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
} }
MEM_STATIC size_t MEM_readST(const void* memPtr) MEM_STATIC size_t MEM_readST(const void* memPtr)
{ {
size_t val; memcpy(&val, memPtr, sizeof(val)); return val; size_t val; memcpy(&val, memPtr, sizeof(val)); return val;
} }
MEM_STATIC void MEM_write16(void* memPtr, U16 value) MEM_STATIC void MEM_write16(void* memPtr, U16 value)
{ {
memcpy(memPtr, &value, sizeof(value)); memcpy(memPtr, &value, sizeof(value));
} }
MEM_STATIC void MEM_write32(void* memPtr, U32 value) MEM_STATIC void MEM_write32(void* memPtr, U32 value)
{ {
memcpy(memPtr, &value, sizeof(value)); memcpy(memPtr, &value, sizeof(value));
} }
MEM_STATIC void MEM_write64(void* memPtr, U64 value) MEM_STATIC void MEM_write64(void* memPtr, U64 value)
{ {
memcpy(memPtr, &value, sizeof(value)); memcpy(memPtr, &value, sizeof(value));
} }
#endif /* MEM_FORCE_MEMORY_ACCESS */ #endif /* MEM_FORCE_MEMORY_ACCESS */
@ -183,188 +183,188 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value)
MEM_STATIC U32 MEM_swap32(U32 in) MEM_STATIC U32 MEM_swap32(U32 in)
{ {
#if defined(_MSC_VER) /* Visual Studio */ #if defined(_MSC_VER) /* Visual Studio */
return _byteswap_ulong(in); return _byteswap_ulong(in);
#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
return __builtin_bswap32(in); return __builtin_bswap32(in);
#else #else
return ((in << 24) & 0xff000000 ) | return ((in << 24) & 0xff000000 ) |
((in << 8) & 0x00ff0000 ) | ((in << 8) & 0x00ff0000 ) |
((in >> 8) & 0x0000ff00 ) | ((in >> 8) & 0x0000ff00 ) |
((in >> 24) & 0x000000ff ); ((in >> 24) & 0x000000ff );
#endif #endif
} }
MEM_STATIC U64 MEM_swap64(U64 in) MEM_STATIC U64 MEM_swap64(U64 in)
{ {
#if defined(_MSC_VER) /* Visual Studio */ #if defined(_MSC_VER) /* Visual Studio */
return _byteswap_uint64(in); return _byteswap_uint64(in);
#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
return __builtin_bswap64(in); return __builtin_bswap64(in);
#else #else
return ((in << 56) & 0xff00000000000000ULL) | return ((in << 56) & 0xff00000000000000ULL) |
((in << 40) & 0x00ff000000000000ULL) | ((in << 40) & 0x00ff000000000000ULL) |
((in << 24) & 0x0000ff0000000000ULL) | ((in << 24) & 0x0000ff0000000000ULL) |
((in << 8) & 0x000000ff00000000ULL) | ((in << 8) & 0x000000ff00000000ULL) |
((in >> 8) & 0x00000000ff000000ULL) | ((in >> 8) & 0x00000000ff000000ULL) |
((in >> 24) & 0x0000000000ff0000ULL) | ((in >> 24) & 0x0000000000ff0000ULL) |
((in >> 40) & 0x000000000000ff00ULL) | ((in >> 40) & 0x000000000000ff00ULL) |
((in >> 56) & 0x00000000000000ffULL); ((in >> 56) & 0x00000000000000ffULL);
#endif #endif
} }
MEM_STATIC size_t MEM_swapST(size_t in) MEM_STATIC size_t MEM_swapST(size_t in)
{ {
if (MEM_32bits()) if (MEM_32bits())
return (size_t)MEM_swap32((U32)in); return (size_t)MEM_swap32((U32)in);
else else
return (size_t)MEM_swap64((U64)in); return (size_t)MEM_swap64((U64)in);
} }
/*=== Little endian r/w ===*/ /*=== Little endian r/w ===*/
MEM_STATIC U16 MEM_readLE16(const void* memPtr) MEM_STATIC U16 MEM_readLE16(const void* memPtr)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
return MEM_read16(memPtr); return MEM_read16(memPtr);
else { else {
const BYTE* p = (const BYTE*)memPtr; const BYTE* p = (const BYTE*)memPtr;
return (U16)(p[0] + (p[1]<<8)); return (U16)(p[0] + (p[1]<<8));
} }
} }
MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
{ {
if (MEM_isLittleEndian()) { if (MEM_isLittleEndian()) {
MEM_write16(memPtr, val); MEM_write16(memPtr, val);
} else { } else {
BYTE* p = (BYTE*)memPtr; BYTE* p = (BYTE*)memPtr;
p[0] = (BYTE)val; p[0] = (BYTE)val;
p[1] = (BYTE)(val>>8); p[1] = (BYTE)(val>>8);
} }
} }
MEM_STATIC U32 MEM_readLE24(const void* memPtr) MEM_STATIC U32 MEM_readLE24(const void* memPtr)
{ {
return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16); return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
} }
MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
{ {
MEM_writeLE16(memPtr, (U16)val); MEM_writeLE16(memPtr, (U16)val);
((BYTE*)memPtr)[2] = (BYTE)(val>>16); ((BYTE*)memPtr)[2] = (BYTE)(val>>16);
} }
MEM_STATIC U32 MEM_readLE32(const void* memPtr) MEM_STATIC U32 MEM_readLE32(const void* memPtr)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
return MEM_read32(memPtr); return MEM_read32(memPtr);
else else
return MEM_swap32(MEM_read32(memPtr)); return MEM_swap32(MEM_read32(memPtr));
} }
MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
MEM_write32(memPtr, val32); MEM_write32(memPtr, val32);
else else
MEM_write32(memPtr, MEM_swap32(val32)); MEM_write32(memPtr, MEM_swap32(val32));
} }
MEM_STATIC U64 MEM_readLE64(const void* memPtr) MEM_STATIC U64 MEM_readLE64(const void* memPtr)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
return MEM_read64(memPtr); return MEM_read64(memPtr);
else else
return MEM_swap64(MEM_read64(memPtr)); return MEM_swap64(MEM_read64(memPtr));
} }
MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
MEM_write64(memPtr, val64); MEM_write64(memPtr, val64);
else else
MEM_write64(memPtr, MEM_swap64(val64)); MEM_write64(memPtr, MEM_swap64(val64));
} }
MEM_STATIC size_t MEM_readLEST(const void* memPtr) MEM_STATIC size_t MEM_readLEST(const void* memPtr)
{ {
if (MEM_32bits()) if (MEM_32bits())
return (size_t)MEM_readLE32(memPtr); return (size_t)MEM_readLE32(memPtr);
else else
return (size_t)MEM_readLE64(memPtr); return (size_t)MEM_readLE64(memPtr);
} }
MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
{ {
if (MEM_32bits()) if (MEM_32bits())
MEM_writeLE32(memPtr, (U32)val); MEM_writeLE32(memPtr, (U32)val);
else else
MEM_writeLE64(memPtr, (U64)val); MEM_writeLE64(memPtr, (U64)val);
} }
/*=== Big endian r/w ===*/ /*=== Big endian r/w ===*/
MEM_STATIC U32 MEM_readBE32(const void* memPtr) MEM_STATIC U32 MEM_readBE32(const void* memPtr)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
return MEM_swap32(MEM_read32(memPtr)); return MEM_swap32(MEM_read32(memPtr));
else else
return MEM_read32(memPtr); return MEM_read32(memPtr);
} }
MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
MEM_write32(memPtr, MEM_swap32(val32)); MEM_write32(memPtr, MEM_swap32(val32));
else else
MEM_write32(memPtr, val32); MEM_write32(memPtr, val32);
} }
MEM_STATIC U64 MEM_readBE64(const void* memPtr) MEM_STATIC U64 MEM_readBE64(const void* memPtr)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
return MEM_swap64(MEM_read64(memPtr)); return MEM_swap64(MEM_read64(memPtr));
else else
return MEM_read64(memPtr); return MEM_read64(memPtr);
} }
MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
{ {
if (MEM_isLittleEndian()) if (MEM_isLittleEndian())
MEM_write64(memPtr, MEM_swap64(val64)); MEM_write64(memPtr, MEM_swap64(val64));
else else
MEM_write64(memPtr, val64); MEM_write64(memPtr, val64);
} }
MEM_STATIC size_t MEM_readBEST(const void* memPtr) MEM_STATIC size_t MEM_readBEST(const void* memPtr)
{ {
if (MEM_32bits()) if (MEM_32bits())
return (size_t)MEM_readBE32(memPtr); return (size_t)MEM_readBE32(memPtr);
else else
return (size_t)MEM_readBE64(memPtr); return (size_t)MEM_readBE64(memPtr);
} }
MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
{ {
if (MEM_32bits()) if (MEM_32bits())
MEM_writeBE32(memPtr, (U32)val); MEM_writeBE32(memPtr, (U32)val);
else else
MEM_writeBE64(memPtr, (U64)val); MEM_writeBE64(memPtr, (U64)val);
} }
/* function safe only for comparisons */ /* function safe only for comparisons */
MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length) MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
{ {
switch (length) switch (length)
{ {
default : default :
case 4 : return MEM_read32(memPtr); case 4 : return MEM_read32(memPtr);
case 3 : if (MEM_isLittleEndian()) case 3 : if (MEM_isLittleEndian())
return MEM_read32(memPtr)<<8; return MEM_read32(memPtr)<<8;
else else
return MEM_read32(memPtr)>>8; return MEM_read32(memPtr)>>8;
} }
} }
#if defined (__cplusplus) #if defined (__cplusplus)

File diff suppressed because it is too large Load Diff

View File

@ -9,9 +9,9 @@
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the in the documentation and/or other materials provided with the
distribution. distribution.
@ -165,14 +165,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned lo
/*! /*!
XXH32() : XXH32() :
Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
The memory between input & input+length must be valid (allocated and read-accessible). The memory between input & input+length must be valid (allocated and read-accessible).
"seed" can be used to alter the result predictably. "seed" can be used to alter the result predictably.
Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
XXH64() : XXH64() :
Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
"seed" can be used to alter the result predictably. "seed" can be used to alter the result predictably.
This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark). This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
*/ */
@ -270,26 +270,26 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src
Do not use members directly. */ Do not use members directly. */
struct XXH32_state_s { struct XXH32_state_s {
unsigned total_len_32; unsigned total_len_32;
unsigned large_len; unsigned large_len;
unsigned v1; unsigned v1;
unsigned v2; unsigned v2;
unsigned v3; unsigned v3;
unsigned v4; unsigned v4;
unsigned mem32[4]; /* buffer defined as U32 for alignment */ unsigned mem32[4]; /* buffer defined as U32 for alignment */
unsigned memsize; unsigned memsize;
unsigned reserved; /* never read nor write, will be removed in a future version */ unsigned reserved; /* never read nor write, will be removed in a future version */
}; /* typedef'd to XXH32_state_t */ }; /* typedef'd to XXH32_state_t */
struct XXH64_state_s { struct XXH64_state_s {
unsigned long long total_len; unsigned long long total_len;
unsigned long long v1; unsigned long long v1;
unsigned long long v2; unsigned long long v2;
unsigned long long v3; unsigned long long v3;
unsigned long long v4; unsigned long long v4;
unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ unsigned long long mem64[4]; /* buffer defined as U64 for alignment */
unsigned memsize; unsigned memsize;
unsigned reserved[2]; /* never read nor write, will be removed in a future version */ unsigned reserved[2]; /* never read nor write, will be removed in a future version */
}; /* typedef'd to XXH64_state_t */ }; /* typedef'd to XXH64_state_t */

View File

@ -50,24 +50,24 @@ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString
/* default uses stdlib */ /* default uses stdlib */
void* ZSTD_defaultAllocFunction(void* opaque, size_t size) void* ZSTD_defaultAllocFunction(void* opaque, size_t size)
{ {
void* address = malloc(size); void* address = malloc(size);
(void)opaque; (void)opaque;
return address; return address;
} }
void ZSTD_defaultFreeFunction(void* opaque, void* address) void ZSTD_defaultFreeFunction(void* opaque, void* address)
{ {
(void)opaque; (void)opaque;
free(address); free(address);
} }
void* ZSTD_malloc(size_t size, ZSTD_customMem customMem) void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
{ {
return customMem.customAlloc(customMem.opaque, size); return customMem.customAlloc(customMem.opaque, size);
} }
void ZSTD_free(void* ptr, ZSTD_customMem customMem) void ZSTD_free(void* ptr, ZSTD_customMem customMem)
{ {
if (ptr!=NULL) if (ptr!=NULL)
customMem.customFree(customMem.opaque, ptr); customMem.customFree(customMem.opaque, ptr);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -62,8 +62,8 @@ typedef enum {
} ZSTD_ErrorCode; } ZSTD_ErrorCode;
/*! ZSTD_getErrorCode() : /*! ZSTD_getErrorCode() :
convert a `size_t` function result into a `ZSTD_ErrorCode` enum type, convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,
which can be used to compare directly with enum list published into "error_public.h" */ which can be used to compare directly with enum list published into "error_public.h" */
ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code);

View File

@ -117,27 +117,27 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy
#define OffFSELog 8 #define OffFSELog 8
static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
13,14,15,16 }; 13,14,15,16 };
static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
-1,-1,-1,-1 }; -1,-1,-1,-1 };
#define LL_DEFAULTNORMLOG 6 /* for static allocation */ #define LL_DEFAULTNORMLOG 6 /* for static allocation */
static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG; static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9,10,11, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9,10,11,
12,13,14,15,16 }; 12,13,14,15,16 };
static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,
-1,-1,-1,-1,-1 }; -1,-1,-1,-1,-1 };
#define ML_DEFAULTNORMLOG 6 /* for static allocation */ #define ML_DEFAULTNORMLOG 6 /* for static allocation */
static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG; static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 }; 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 };
#define OF_DEFAULTNORMLOG 5 /* for static allocation */ #define OF_DEFAULTNORMLOG 5 /* for static allocation */
static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
@ -153,22 +153,22 @@ static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
#define WILDCOPY_OVERLENGTH 8 #define WILDCOPY_OVERLENGTH 8
MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length) MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
{ {
const BYTE* ip = (const BYTE*)src; const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst; BYTE* op = (BYTE*)dst;
BYTE* const oend = op + length; BYTE* const oend = op + length;
do do
COPY8(op, ip) COPY8(op, ip)
while (op < oend); while (op < oend);
} }
MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* should be faster for decoding, but strangely, not verified on all platform */ MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* should be faster for decoding, but strangely, not verified on all platform */
{ {
const BYTE* ip = (const BYTE*)src; const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst; BYTE* op = (BYTE*)dst;
BYTE* const oend = (BYTE*)dstEnd; BYTE* const oend = (BYTE*)dstEnd;
do do
COPY8(op, ip) COPY8(op, ip)
while (op < oend); while (op < oend);
} }
@ -178,58 +178,58 @@ MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* s
typedef struct ZSTD_stats_s ZSTD_stats_t; typedef struct ZSTD_stats_s ZSTD_stats_t;
typedef struct { typedef struct {
U32 off; U32 off;
U32 len; U32 len;
} ZSTD_match_t; } ZSTD_match_t;
typedef struct { typedef struct {
U32 price; U32 price;
U32 off; U32 off;
U32 mlen; U32 mlen;
U32 litlen; U32 litlen;
U32 rep[ZSTD_REP_NUM]; U32 rep[ZSTD_REP_NUM];
} ZSTD_optimal_t; } ZSTD_optimal_t;
typedef struct seqDef_s { typedef struct seqDef_s {
U32 offset; U32 offset;
U16 litLength; U16 litLength;
U16 matchLength; U16 matchLength;
} seqDef; } seqDef;
typedef struct { typedef struct {
seqDef* sequencesStart; seqDef* sequencesStart;
seqDef* sequences; seqDef* sequences;
BYTE* litStart; BYTE* litStart;
BYTE* lit; BYTE* lit;
BYTE* llCode; BYTE* llCode;
BYTE* mlCode; BYTE* mlCode;
BYTE* ofCode; BYTE* ofCode;
U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */ U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
U32 longLengthPos; U32 longLengthPos;
/* opt */ /* opt */
ZSTD_optimal_t* priceTable; ZSTD_optimal_t* priceTable;
ZSTD_match_t* matchTable; ZSTD_match_t* matchTable;
U32* matchLengthFreq; U32* matchLengthFreq;
U32* litLengthFreq; U32* litLengthFreq;
U32* litFreq; U32* litFreq;
U32* offCodeFreq; U32* offCodeFreq;
U32 matchLengthSum; U32 matchLengthSum;
U32 matchSum; U32 matchSum;
U32 litLengthSum; U32 litLengthSum;
U32 litSum; U32 litSum;
U32 offCodeSum; U32 offCodeSum;
U32 log2matchLengthSum; U32 log2matchLengthSum;
U32 log2matchSum; U32 log2matchSum;
U32 log2litLengthSum; U32 log2litLengthSum;
U32 log2litSum; U32 log2litSum;
U32 log2offCodeSum; U32 log2offCodeSum;
U32 factor; U32 factor;
U32 staticPrices; U32 staticPrices;
U32 cachedPrice; U32 cachedPrice;
U32 cachedLitLength; U32 cachedLitLength;
const BYTE* cachedLiterals; const BYTE* cachedLiterals;
} seqStore_t; } seqStore_t;
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
@ -251,22 +251,22 @@ void ZSTD_free(void* ptr, ZSTD_customMem customMem);
MEM_STATIC U32 ZSTD_highbit32(U32 val) MEM_STATIC U32 ZSTD_highbit32(U32 val)
{ {
# if defined(_MSC_VER) /* Visual */ # if defined(_MSC_VER) /* Visual */
unsigned long r=0; unsigned long r=0;
_BitScanReverse(&r, val); _BitScanReverse(&r, val);
return (unsigned)r; return (unsigned)r;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */ # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
return 31 - __builtin_clz(val); return 31 - __builtin_clz(val);
# else /* Software version */ # else /* Software version */
static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
U32 v = val; U32 v = val;
int r; int r;
v |= v >> 1; v |= v >> 1;
v |= v >> 2; v |= v >> 2;
v |= v >> 4; v |= v >> 4;
v |= v >> 8; v |= v >> 8;
v |= v >> 16; v |= v >> 16;
r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27]; r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
return r; return r;
# endif # endif
} }

File diff suppressed because it is too large Load Diff