Merge remote-tracking branch 'refs/remotes/facebook/dev' into dev11
This commit is contained in:
@@ -159,6 +159,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
/*! 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.
|
||||||
@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?() .
|
||||||
*/
|
*/
|
||||||
@@ -187,17 +188,17 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
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(5)]; /* 5 is max possible tableLog for HUF header */
|
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, 5); /* 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_ABSOLUTEMAX + 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_ABSOLUTEMAX) 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;
|
||||||
} }
|
} }
|
||||||
@@ -205,7 +206,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
|
|
||||||
/* 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_ABSOLUTEMAX) 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;
|
||||||
|
|||||||
+27
-9
@@ -294,8 +294,31 @@ If there is an error, the function will return an error code, which can be teste
|
|||||||
/* *****************************************
|
/* *****************************************
|
||||||
* FSE advanced API
|
* FSE advanced API
|
||||||
*******************************************/
|
*******************************************/
|
||||||
|
/* FSE_count_wksp() :
|
||||||
|
* Same as FSE_count(), but using an externally provided scratch buffer.
|
||||||
|
* `workSpace` size must be table of >= `1024` unsigned
|
||||||
|
*/
|
||||||
|
size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
||||||
|
const void* source, size_t sourceSize, unsigned* workSpace);
|
||||||
|
|
||||||
|
/** FSE_countFast() :
|
||||||
|
* same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr
|
||||||
|
*/
|
||||||
size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
|
size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
|
||||||
/**< same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr */
|
|
||||||
|
/* FSE_countFast_wksp() :
|
||||||
|
* Same as FSE_countFast(), but using an externally provided scratch buffer.
|
||||||
|
* `workSpace` must be a table of minimum `1024` unsigned
|
||||||
|
*/
|
||||||
|
size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* workSpace);
|
||||||
|
|
||||||
|
/*! FSE_count_simple
|
||||||
|
* Same as FSE_countFast(), but does not use any additional memory (not even on stack).
|
||||||
|
* This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` (presuming it's also the size of `count`).
|
||||||
|
*/
|
||||||
|
size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
|
unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
|
||||||
/**< same as FSE_optimalTableLog(), which used `minus==2` */
|
/**< same as FSE_optimalTableLog(), which used `minus==2` */
|
||||||
@@ -334,13 +357,9 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size
|
|||||||
*******************************************/
|
*******************************************/
|
||||||
/*!
|
/*!
|
||||||
This API consists of small unitary functions, which highly benefit from being inlined.
|
This API consists of small unitary functions, which highly benefit from being inlined.
|
||||||
You will want to enable link-time-optimization to ensure these functions are properly inlined in your binary.
|
Hence their body are included in next section.
|
||||||
Visual seems to do it automatically.
|
|
||||||
For gcc or clang, you'll need to add -flto flag at compilation and linking stages.
|
|
||||||
If none of these solutions is applicable, include "fse.c" directly.
|
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
ptrdiff_t value;
|
ptrdiff_t value;
|
||||||
const void* stateTable;
|
const void* stateTable;
|
||||||
const void* symbolTT;
|
const void* symbolTT;
|
||||||
@@ -400,8 +419,7 @@ 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;
|
||||||
|
|||||||
+27
-17
@@ -62,21 +62,19 @@ size_t HUF_compress(void* dst, size_t dstCapacity,
|
|||||||
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'.
|
||||||
`dstSize` : **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 (== dstSize),
|
@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 dstSize,
|
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
|
#define HUF_BLOCKSIZE_MAX (128 * 1024) /*< maximum input size for a single block compressed with HUF_compress */
|
||||||
******************************************/
|
|
||||||
#define HUF_BLOCKSIZE_MAX (128 * 1024)
|
|
||||||
size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
|
size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
|
||||||
|
|
||||||
/* Error Management */
|
/* Error Management */
|
||||||
@@ -87,9 +85,15 @@ const char* HUF_getErrorName(size_t code); /**< provides error code string (us
|
|||||||
/* *** Advanced function *** */
|
/* *** Advanced function *** */
|
||||||
|
|
||||||
/** HUF_compress2() :
|
/** HUF_compress2() :
|
||||||
* Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog` */
|
* Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog` .
|
||||||
|
* `tableLog` must be `<= HUF_TABLELOG_MAX` . */
|
||||||
size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
||||||
|
|
||||||
|
/** HUF_compress4X_wksp() :
|
||||||
|
* Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */
|
||||||
|
size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least 1024 unsigned */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HUF_STATIC_LINKING_ONLY
|
#ifdef HUF_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
@@ -98,7 +102,7 @@ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize
|
|||||||
|
|
||||||
|
|
||||||
/* *** Constants *** */
|
/* *** Constants *** */
|
||||||
#define HUF_TABLELOG_ABSOLUTEMAX 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
|
#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
|
||||||
#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
|
#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
|
||||||
#define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */
|
#define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */
|
||||||
#define HUF_SYMBOLVALUE_MAX 255
|
#define HUF_SYMBOLVALUE_MAX 255
|
||||||
@@ -125,9 +129,9 @@ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize
|
|||||||
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)*0x1000001) }
|
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)*0x1000001) }
|
HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
/* ****************************************
|
||||||
@@ -141,10 +145,6 @@ size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, con
|
|||||||
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
|
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
|
||||||
size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
|
size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
|
||||||
|
|
||||||
size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
|
||||||
size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
|
|
||||||
size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
/* ****************************************
|
||||||
* HUF detailed API
|
* HUF detailed API
|
||||||
@@ -169,6 +169,12 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, un
|
|||||||
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
||||||
|
|
||||||
|
|
||||||
|
/** HUF_buildCTable_wksp() :
|
||||||
|
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
|
||||||
|
* `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
@@ -208,16 +214,20 @@ size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* c
|
|||||||
/* single stream variants */
|
/* single stream variants */
|
||||||
|
|
||||||
size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
||||||
|
size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least 1024 unsigned */
|
||||||
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
||||||
|
|
||||||
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
||||||
size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
|
size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
|
||||||
|
|
||||||
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
||||||
|
size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
|
||||||
|
size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
|
||||||
|
|
||||||
|
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */
|
||||||
size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
|
|
||||||
|
|
||||||
#endif /* HUF_STATIC_LINKING_ONLY */
|
#endif /* HUF_STATIC_LINKING_ONLY */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+33
-26
@@ -308,13 +308,13 @@ size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalized
|
|||||||
* Counting histogram
|
* Counting histogram
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
/*! FSE_count_simple
|
/*! FSE_count_simple
|
||||||
This function just counts byte values within `src`,
|
This function counts byte values within `src`, and store the histogram into table `count`.
|
||||||
and store the histogram into table `count`.
|
It doesn't use any additional memory.
|
||||||
This function is unsafe : it doesn't check that all values within `src` can fit into `count`.
|
But this function is unsafe : it doesn't check that all values within `src` can fit into `count`.
|
||||||
For this reason, prefer using a table `count` with 256 elements.
|
For this reason, prefer using a table `count` with 256 elements.
|
||||||
@return : count of most numerous element
|
@return : count of most numerous element
|
||||||
*/
|
*/
|
||||||
static size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
|
size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
@@ -409,31 +409,41 @@ static size_t FSE_count_parallel_wksp(
|
|||||||
return (size_t)max;
|
return (size_t)max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FSE_countFast_wksp() :
|
||||||
static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr,
|
* Same as FSE_countFast(), but using an externally provided scratch buffer.
|
||||||
const void* source, size_t sourceSize,
|
* `workSpace` size must be table of >= `1024` unsigned */
|
||||||
unsigned checkMax)
|
size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
||||||
|
const void* source, size_t sourceSize, unsigned* workSpace)
|
||||||
{
|
{
|
||||||
U32 tmpCounters[1024];
|
if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
|
||||||
return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMax, tmpCounters);
|
return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
|
/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
|
||||||
size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
|
size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
|
||||||
const void* source, size_t sourceSize)
|
const void* source, size_t sourceSize)
|
||||||
{
|
{
|
||||||
if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
|
unsigned tmpCounters[1024];
|
||||||
return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 0);
|
return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FSE_count_wksp() :
|
||||||
|
* Same as FSE_count(), but using an externally provided scratch buffer.
|
||||||
|
* `workSpace` size must be table of >= `1024` unsigned */
|
||||||
|
size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
||||||
|
const void* source, size_t sourceSize, unsigned* workSpace)
|
||||||
|
{
|
||||||
|
if (*maxSymbolValuePtr < 255)
|
||||||
|
return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace);
|
||||||
|
*maxSymbolValuePtr = 255;
|
||||||
|
return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr,
|
size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr,
|
||||||
const void* source, size_t sourceSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (*maxSymbolValuePtr < 255)
|
unsigned tmpCounters[1024];
|
||||||
return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 1);
|
return FSE_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters);
|
||||||
*maxSymbolValuePtr = 255;
|
|
||||||
return FSE_countFast(count, maxSymbolValuePtr, source, sourceSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -764,8 +774,8 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
|
|||||||
|
|
||||||
size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
|
size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
|
||||||
|
|
||||||
#define CHECK_E_F(e, f) size_t const e = f; if (FSE_isError(e)) return f
|
#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
|
||||||
#define CHECK_F(f) { CHECK_E_F(_var_err__, f); }
|
#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
|
||||||
|
|
||||||
/* FSE_compress_wksp() :
|
/* FSE_compress_wksp() :
|
||||||
* Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
|
* Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
|
||||||
@@ -773,9 +783,6 @@ size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
|
|||||||
*/
|
*/
|
||||||
size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
|
size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
|
||||||
{
|
{
|
||||||
const BYTE* const istart = (const BYTE*) src;
|
|
||||||
const BYTE* ip = istart;
|
|
||||||
|
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
BYTE* const oend = ostart + dstSize;
|
BYTE* const oend = ostart + dstSize;
|
||||||
@@ -794,7 +801,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
|
|||||||
if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
|
if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
|
||||||
|
|
||||||
/* Scan input and build symbol stats */
|
/* Scan input and build symbol stats */
|
||||||
{ CHECK_E_F(maxCount, FSE_count(count, &maxSymbolValue, ip, srcSize) );
|
{ CHECK_V_F(maxCount, FSE_count(count, &maxSymbolValue, src, srcSize) );
|
||||||
if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
|
if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
|
||||||
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
|
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
|
||||||
if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
|
if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
|
||||||
@@ -804,13 +811,13 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
|
|||||||
CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
|
CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
|
||||||
|
|
||||||
/* Write table description header */
|
/* Write table description header */
|
||||||
{ CHECK_E_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
|
{ CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
|
||||||
op += nc_err;
|
op += nc_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compress */
|
/* Compress */
|
||||||
CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
|
CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
|
||||||
{ CHECK_E_F(cSize, FSE_compress_usingCTable(op, oend - op, ip, srcSize, CTable) );
|
{ CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
|
||||||
if (cSize == 0) return 0; /* not enough space for compressed data */
|
if (cSize == 0) return 0; /* not enough space for compressed data */
|
||||||
op += cSize;
|
op += cSize;
|
||||||
}
|
}
|
||||||
|
|||||||
+123
-48
@@ -56,6 +56,8 @@
|
|||||||
* Error Management
|
* Error Management
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
||||||
|
#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
|
||||||
|
#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
@@ -70,18 +72,60 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
|
|||||||
/* *******************************************************
|
/* *******************************************************
|
||||||
* HUF : Huffman block compression
|
* HUF : Huffman block compression
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
/* HUF_compressWeights() :
|
||||||
|
* Same as FSE_compress(), but dedicated to huff0's weights compression.
|
||||||
|
* The use case needs much less stack memory.
|
||||||
|
* Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
|
||||||
|
*/
|
||||||
|
#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
|
||||||
|
size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
|
||||||
|
{
|
||||||
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
|
BYTE* op = ostart;
|
||||||
|
BYTE* const oend = ostart + dstSize;
|
||||||
|
|
||||||
|
U32 maxSymbolValue = HUF_TABLELOG_MAX;
|
||||||
|
U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
|
||||||
|
|
||||||
|
FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
|
||||||
|
BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER];
|
||||||
|
|
||||||
|
U32 count[HUF_TABLELOG_MAX+1];
|
||||||
|
S16 norm[HUF_TABLELOG_MAX+1];
|
||||||
|
|
||||||
|
/* init conditions */
|
||||||
|
if (wtSize <= 1) return 0; /* Not compressible */
|
||||||
|
|
||||||
|
/* Scan input and build symbol stats */
|
||||||
|
{ CHECK_V_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize) );
|
||||||
|
if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */
|
||||||
|
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
|
||||||
|
}
|
||||||
|
|
||||||
|
tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
|
||||||
|
CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
|
||||||
|
|
||||||
|
/* Write table description header */
|
||||||
|
{ CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
|
||||||
|
op += hSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compress */
|
||||||
|
CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
|
||||||
|
{ CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
|
||||||
|
if (cSize == 0) return 0; /* not enough space for compressed data */
|
||||||
|
op += cSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return op-ostart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct HUF_CElt_s {
|
struct HUF_CElt_s {
|
||||||
U16 val;
|
U16 val;
|
||||||
BYTE nbBits;
|
BYTE nbBits;
|
||||||
}; /* typedef'd to HUF_CElt within "huf.h" */
|
}; /* typedef'd to HUF_CElt within "huf.h" */
|
||||||
|
|
||||||
typedef struct nodeElt_s {
|
|
||||||
U32 count;
|
|
||||||
U16 parent;
|
|
||||||
BYTE byte;
|
|
||||||
BYTE nbBits;
|
|
||||||
} nodeElt;
|
|
||||||
|
|
||||||
/*! HUF_writeCTable() :
|
/*! HUF_writeCTable() :
|
||||||
`CTable` : huffman tree to save, using huf representation.
|
`CTable` : huffman tree to save, using huf representation.
|
||||||
@return : size of saved CTable */
|
@return : size of saved CTable */
|
||||||
@@ -91,8 +135,6 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
|||||||
BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
|
BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
|
||||||
BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
|
BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
|
||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
|
|
||||||
FSE_CTable scratchBuffer[FSE_WKSP_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
|
|
||||||
U32 n;
|
U32 n;
|
||||||
|
|
||||||
/* check conditions */
|
/* check conditions */
|
||||||
@@ -106,18 +148,17 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
|||||||
huffWeight[n] = bitsToWeight[CTable[n].nbBits];
|
huffWeight[n] = bitsToWeight[CTable[n].nbBits];
|
||||||
|
|
||||||
/* attempt weights compression by FSE */
|
/* attempt weights compression by FSE */
|
||||||
{ size_t const size = FSE_compress_wksp(op+1, maxDstSize-1, huffWeight, maxSymbolValue, HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER, scratchBuffer, sizeof(scratchBuffer));
|
{ CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );
|
||||||
if (FSE_isError(size)) return size;
|
if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */
|
||||||
if ((size>1) & (size < maxSymbolValue/2)) { /* FSE compressed */
|
op[0] = (BYTE)hSize;
|
||||||
op[0] = (BYTE)size;
|
return hSize+1;
|
||||||
return size+1;
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* raw values */
|
/* write raw values as 4-bits (max : 15) */
|
||||||
if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */
|
if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */
|
||||||
if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
|
if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
|
||||||
op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
|
op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
|
||||||
huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */
|
huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */
|
||||||
for (n=0; n<maxSymbolValue; n+=2)
|
for (n=0; n<maxSymbolValue; n+=2)
|
||||||
op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
|
op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
|
||||||
return ((maxSymbolValue+1)/2) + 1;
|
return ((maxSymbolValue+1)/2) + 1;
|
||||||
@@ -126,16 +167,13 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
|||||||
|
|
||||||
size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
|
size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */
|
||||||
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
|
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
|
||||||
U32 tableLog = 0;
|
U32 tableLog = 0;
|
||||||
size_t readSize;
|
|
||||||
U32 nbSymbols = 0;
|
U32 nbSymbols = 0;
|
||||||
/*memset(huffWeight, 0, sizeof(huffWeight));*/ /* is not necessary, even though some analyzer complain ... */
|
|
||||||
|
|
||||||
/* get symbol weights */
|
/* get symbol weights */
|
||||||
readSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));
|
||||||
if (HUF_isError(readSize)) return readSize;
|
|
||||||
|
|
||||||
/* check result */
|
/* check result */
|
||||||
if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
|
if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
|
||||||
@@ -175,6 +213,13 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct nodeElt_s {
|
||||||
|
U32 count;
|
||||||
|
U16 parent;
|
||||||
|
BYTE byte;
|
||||||
|
BYTE nbBits;
|
||||||
|
} nodeElt;
|
||||||
|
|
||||||
static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
||||||
{
|
{
|
||||||
const U32 largestBits = huffNode[lastNonNull].nbBits;
|
const U32 largestBits = huffNode[lastNonNull].nbBits;
|
||||||
@@ -280,20 +325,26 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** HUF_buildCTable_wksp() :
|
||||||
|
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
|
||||||
|
* `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
|
||||||
|
*/
|
||||||
#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
|
#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
|
||||||
size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits)
|
typedef nodeElt huffNodeTable[2*HUF_SYMBOLVALUE_MAX+1 +1];
|
||||||
|
size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
|
||||||
{
|
{
|
||||||
nodeElt huffNode0[2*HUF_SYMBOLVALUE_MAX+1 +1];
|
nodeElt* const huffNode0 = (nodeElt*)workSpace;
|
||||||
nodeElt* huffNode = huffNode0 + 1;
|
nodeElt* const huffNode = huffNode0+1;
|
||||||
U32 n, nonNullRank;
|
U32 n, nonNullRank;
|
||||||
int lowS, lowN;
|
int lowS, lowN;
|
||||||
U16 nodeNb = STARTNODE;
|
U16 nodeNb = STARTNODE;
|
||||||
U32 nodeRoot;
|
U32 nodeRoot;
|
||||||
|
|
||||||
/* safety checks */
|
/* safety checks */
|
||||||
|
if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC); /* workSpace is not large enough */
|
||||||
if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
|
if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
|
||||||
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
|
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
|
||||||
memset(huffNode0, 0, sizeof(huffNode0));
|
memset(huffNode0, 0, sizeof(huffNodeTable));
|
||||||
|
|
||||||
/* sort, decreasing order */
|
/* sort, decreasing order */
|
||||||
HUF_sort(huffNode, count, maxSymbolValue);
|
HUF_sort(huffNode, count, maxSymbolValue);
|
||||||
@@ -306,7 +357,7 @@ size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U3
|
|||||||
huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
|
huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
|
||||||
nodeNb++; lowS-=2;
|
nodeNb++; lowS-=2;
|
||||||
for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
|
for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
|
||||||
huffNode0[0].count = (U32)(1U<<31);
|
huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */
|
||||||
|
|
||||||
/* create parents */
|
/* create parents */
|
||||||
while (nodeNb <= nodeRoot) {
|
while (nodeNb <= nodeRoot) {
|
||||||
@@ -349,6 +400,15 @@ size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U3
|
|||||||
return maxNbBits;
|
return maxNbBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** HUF_buildCTable() :
|
||||||
|
* Note : count is used before tree is written, so they can safely overlap
|
||||||
|
*/
|
||||||
|
size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits)
|
||||||
|
{
|
||||||
|
huffNodeTable nodeTable;
|
||||||
|
return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, nodeTable, sizeof(nodeTable));
|
||||||
|
}
|
||||||
|
|
||||||
static void HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
|
static void HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
|
||||||
{
|
{
|
||||||
BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
|
BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
|
||||||
@@ -376,8 +436,8 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
if (dstSize < 8) return 0; /* not enough space to compress */
|
if (dstSize < 8) return 0; /* not enough space to compress */
|
||||||
{ size_t const errorCode = BIT_initCStream(&bitC, op, oend-op);
|
{ size_t const initErr = BIT_initCStream(&bitC, op, oend-op);
|
||||||
if (HUF_isError(errorCode)) return 0; }
|
if (HUF_isError(initErr)) return 0; }
|
||||||
|
|
||||||
n = srcSize & ~3; /* join to mod 4 */
|
n = srcSize & ~3; /* join to mod 4 */
|
||||||
switch (srcSize & 3)
|
switch (srcSize & 3)
|
||||||
@@ -420,32 +480,28 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si
|
|||||||
if (srcSize < 12) return 0; /* no saving possible : too small input */
|
if (srcSize < 12) return 0; /* no saving possible : too small input */
|
||||||
op += 6; /* jumpTable */
|
op += 6; /* jumpTable */
|
||||||
|
|
||||||
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
|
||||||
if (HUF_isError(cSize)) return cSize;
|
|
||||||
if (cSize==0) return 0;
|
if (cSize==0) return 0;
|
||||||
MEM_writeLE16(ostart, (U16)cSize);
|
MEM_writeLE16(ostart, (U16)cSize);
|
||||||
op += cSize;
|
op += cSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip += segmentSize;
|
ip += segmentSize;
|
||||||
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
|
||||||
if (HUF_isError(cSize)) return cSize;
|
|
||||||
if (cSize==0) return 0;
|
if (cSize==0) return 0;
|
||||||
MEM_writeLE16(ostart+2, (U16)cSize);
|
MEM_writeLE16(ostart+2, (U16)cSize);
|
||||||
op += cSize;
|
op += cSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip += segmentSize;
|
ip += segmentSize;
|
||||||
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
|
||||||
if (HUF_isError(cSize)) return cSize;
|
|
||||||
if (cSize==0) return 0;
|
if (cSize==0) return 0;
|
||||||
MEM_writeLE16(ostart+4, (U16)cSize);
|
MEM_writeLE16(ostart+4, (U16)cSize);
|
||||||
op += cSize;
|
op += cSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip += segmentSize;
|
ip += segmentSize;
|
||||||
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable);
|
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
|
||||||
if (HUF_isError(cSize)) return cSize;
|
|
||||||
if (cSize==0) return 0;
|
if (cSize==0) return 0;
|
||||||
op += cSize;
|
op += cSize;
|
||||||
}
|
}
|
||||||
@@ -454,20 +510,25 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* `workSpace` must a table of at least 1024 unsigned */
|
||||||
static size_t HUF_compress_internal (
|
static size_t HUF_compress_internal (
|
||||||
void* dst, size_t dstSize,
|
void* dst, size_t dstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
unsigned maxSymbolValue, unsigned huffLog,
|
unsigned maxSymbolValue, unsigned huffLog,
|
||||||
unsigned singleStream)
|
unsigned singleStream,
|
||||||
|
void* workSpace, size_t wkspSize)
|
||||||
{
|
{
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
BYTE* const oend = ostart + dstSize;
|
BYTE* const oend = ostart + dstSize;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
|
|
||||||
|
union {
|
||||||
U32 count[HUF_SYMBOLVALUE_MAX+1];
|
U32 count[HUF_SYMBOLVALUE_MAX+1];
|
||||||
HUF_CElt CTable[HUF_SYMBOLVALUE_MAX+1];
|
HUF_CElt CTable[HUF_SYMBOLVALUE_MAX+1];
|
||||||
|
} table; /* `count` can overlap with `CTable`; saves 1 KB */
|
||||||
|
|
||||||
/* checks & inits */
|
/* checks & inits */
|
||||||
|
if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC);
|
||||||
if (!srcSize) return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */
|
if (!srcSize) return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */
|
||||||
if (!dstSize) return 0; /* cannot fit within dst budget */
|
if (!dstSize) return 0; /* cannot fit within dst budget */
|
||||||
if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
|
if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
|
||||||
@@ -476,30 +537,27 @@ static size_t HUF_compress_internal (
|
|||||||
if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
|
if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
|
||||||
|
|
||||||
/* Scan input and build symbol stats */
|
/* Scan input and build symbol stats */
|
||||||
{ size_t const largest = FSE_count (count, &maxSymbolValue, (const BYTE*)src, srcSize);
|
{ CHECK_V_F(largest, FSE_count_wksp (table.count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
|
||||||
if (HUF_isError(largest)) return largest;
|
|
||||||
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
|
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
|
||||||
if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
|
if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build Huffman Tree */
|
/* Build Huffman Tree */
|
||||||
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
|
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
|
||||||
{ size_t const maxBits = HUF_buildCTable (CTable, count, maxSymbolValue, huffLog);
|
{ CHECK_V_F(maxBits, HUF_buildCTable_wksp (table.CTable, table.count, maxSymbolValue, huffLog, workSpace, wkspSize) );
|
||||||
if (HUF_isError(maxBits)) return maxBits;
|
|
||||||
huffLog = (U32)maxBits;
|
huffLog = (U32)maxBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write table description header */
|
/* Write table description header */
|
||||||
{ size_t const hSize = HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog);
|
{ CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, table.CTable, maxSymbolValue, huffLog) );
|
||||||
if (HUF_isError(hSize)) return hSize;
|
|
||||||
if (hSize + 12 >= srcSize) return 0; /* not useful to try compression */
|
if (hSize + 12 >= srcSize) return 0; /* not useful to try compression */
|
||||||
op += hSize;
|
op += hSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compress */
|
/* Compress */
|
||||||
{ size_t const cSize = (singleStream) ?
|
{ size_t const cSize = (singleStream) ?
|
||||||
HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) : /* single segment */
|
HUF_compress1X_usingCTable(op, oend - op, src, srcSize, table.CTable) : /* single segment */
|
||||||
HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
|
HUF_compress4X_usingCTable(op, oend - op, src, srcSize, table.CTable);
|
||||||
if (HUF_isError(cSize)) return cSize;
|
if (HUF_isError(cSize)) return cSize;
|
||||||
if (cSize==0) return 0; /* uncompressible */
|
if (cSize==0) return 0; /* uncompressible */
|
||||||
op += cSize;
|
op += cSize;
|
||||||
@@ -513,21 +571,38 @@ static size_t HUF_compress_internal (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
unsigned maxSymbolValue, unsigned huffLog,
|
||||||
|
void* workSpace, size_t wkspSize)
|
||||||
|
{
|
||||||
|
return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize);
|
||||||
|
}
|
||||||
|
|
||||||
size_t HUF_compress1X (void* dst, size_t dstSize,
|
size_t HUF_compress1X (void* dst, size_t dstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
unsigned maxSymbolValue, unsigned huffLog)
|
unsigned maxSymbolValue, unsigned huffLog)
|
||||||
{
|
{
|
||||||
return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1);
|
unsigned workSpace[1024];
|
||||||
|
return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
unsigned maxSymbolValue, unsigned huffLog,
|
||||||
|
void* workSpace, size_t wkspSize)
|
||||||
|
{
|
||||||
|
return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HUF_compress2 (void* dst, size_t dstSize,
|
size_t HUF_compress2 (void* dst, size_t dstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
unsigned maxSymbolValue, unsigned huffLog)
|
unsigned maxSymbolValue, unsigned huffLog)
|
||||||
{
|
{
|
||||||
return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0);
|
unsigned workSpace[1024];
|
||||||
|
return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_TABLELOG_DEFAULT);
|
return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_TABLELOG_DEFAULT);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ struct ZSTD_CCtx_s
|
|||||||
FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
|
FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
|
||||||
FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
|
FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
|
||||||
FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
|
FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
|
||||||
|
unsigned tmpCounters[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
ZSTD_CCtx* ZSTD_createCCtx(void)
|
ZSTD_CCtx* ZSTD_createCCtx(void)
|
||||||
@@ -470,8 +471,8 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
|
|||||||
singleStream = 1;
|
singleStream = 1;
|
||||||
cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable);
|
cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable);
|
||||||
} else {
|
} else {
|
||||||
cLitSize = singleStream ? HUF_compress1X(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11)
|
cLitSize = singleStream ? HUF_compress1X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters))
|
||||||
: HUF_compress2 (ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11);
|
: HUF_compress4X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cLitSize==0) | (cLitSize >= srcSize - minGain))
|
if ((cLitSize==0) | (cLitSize >= srcSize - minGain))
|
||||||
@@ -594,7 +595,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
/* CTable for Literal Lengths */
|
/* CTable for Literal Lengths */
|
||||||
{ U32 max = MaxLL;
|
{ U32 max = MaxLL;
|
||||||
size_t const mostFrequent = FSE_countFast(count, &max, llCodeTable, nbSeq);
|
size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters);
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
||||||
*op++ = llCodeTable[0];
|
*op++ = llCodeTable[0];
|
||||||
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
||||||
@@ -618,7 +619,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
/* CTable for Offsets */
|
/* CTable for Offsets */
|
||||||
{ U32 max = MaxOff;
|
{ U32 max = MaxOff;
|
||||||
size_t const mostFrequent = FSE_countFast(count, &max, ofCodeTable, nbSeq);
|
size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters);
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
||||||
*op++ = ofCodeTable[0];
|
*op++ = ofCodeTable[0];
|
||||||
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
||||||
@@ -642,7 +643,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
/* CTable for MatchLengths */
|
/* CTable for MatchLengths */
|
||||||
{ U32 max = MaxML;
|
{ U32 max = MaxML;
|
||||||
size_t const mostFrequent = FSE_countFast(count, &max, mlCodeTable, nbSeq);
|
size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters);
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
||||||
*op++ = *mlCodeTable;
|
*op++ = *mlCodeTable;
|
||||||
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
||||||
@@ -2508,6 +2509,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
const BYTE* const dictEnd = dictPtr + dictSize;
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
||||||
short offcodeNCount[MaxOff+1];
|
short offcodeNCount[MaxOff+1];
|
||||||
unsigned offcodeMaxValue = MaxOff;
|
unsigned offcodeMaxValue = MaxOff;
|
||||||
|
BYTE scratchBuffer[1<<MAX(MLFSELog,LLFSELog)];
|
||||||
|
|
||||||
{ size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
|
{ size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
|
||||||
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
@@ -2519,7 +2521,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
||||||
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
|
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
|
||||||
CHECK_E (FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
CHECK_E (FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
|
||||||
dictPtr += offcodeHeaderSize;
|
dictPtr += offcodeHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2530,7 +2532,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
||||||
/* Every match length code must have non-zero probability */
|
/* Every match length code must have non-zero probability */
|
||||||
CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
|
CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
|
||||||
CHECK_E (FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
CHECK_E (FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
|
||||||
dictPtr += matchlengthHeaderSize;
|
dictPtr += matchlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2541,7 +2543,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
||||||
/* Every literal length code must have non-zero probability */
|
/* Every literal length code must have non-zero probability */
|
||||||
CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
|
CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
|
||||||
CHECK_E(FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
|
||||||
dictPtr += litlengthHeaderSize;
|
dictPtr += litlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -398,14 +398,14 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
|
|||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef U32 rankVal_t[HUF_TABLELOG_ABSOLUTEMAX][HUF_TABLELOG_ABSOLUTEMAX + 1];
|
typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1];
|
||||||
|
|
||||||
static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
|
static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
|
||||||
const sortedSymbol_t* sortedList, const U32 sortedListSize,
|
const sortedSymbol_t* sortedList, const U32 sortedListSize,
|
||||||
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
|
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
|
||||||
const U32 nbBitsBaseline)
|
const U32 nbBitsBaseline)
|
||||||
{
|
{
|
||||||
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
|
U32 rankVal[HUF_TABLELOG_MAX + 1];
|
||||||
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
|
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
|
||||||
const U32 minBits = nbBitsBaseline - maxWeight;
|
const U32 minBits = nbBitsBaseline - maxWeight;
|
||||||
U32 s;
|
U32 s;
|
||||||
@@ -446,8 +446,8 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
|
|||||||
{
|
{
|
||||||
BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
|
BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
|
sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
U32 rankStats[HUF_TABLELOG_ABSOLUTEMAX + 1] = { 0 };
|
U32 rankStats[HUF_TABLELOG_MAX + 1] = { 0 };
|
||||||
U32 rankStart0[HUF_TABLELOG_ABSOLUTEMAX + 2] = { 0 };
|
U32 rankStart0[HUF_TABLELOG_MAX + 2] = { 0 };
|
||||||
U32* const rankStart = rankStart0+1;
|
U32* const rankStart = rankStart0+1;
|
||||||
rankVal_t rankVal;
|
rankVal_t rankVal;
|
||||||
U32 tableLog, maxW, sizeOfSort, nbSymbols;
|
U32 tableLog, maxW, sizeOfSort, nbSymbols;
|
||||||
@@ -458,7 +458,7 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
|
|||||||
HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr;
|
HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr;
|
||||||
|
|
||||||
HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compilation fails here, assertion is false */
|
HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compilation fails here, assertion is false */
|
||||||
if (maxTableLog > HUF_TABLELOG_ABSOLUTEMAX) return ERROR(tableLog_tooLarge);
|
if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
|
||||||
/* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
|
/* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
||||||
|
|||||||
Reference in New Issue
Block a user