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:
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
@ -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
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
@ -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);
|
||||||
|
|
||||||
|
@ -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
Reference in New Issue
Block a user