159 lines
5.2 KiB
C
Executable File
159 lines
5.2 KiB
C
Executable File
#define FSE_STATIC_LINKING_ONLY
|
|
#include "../zstd/lib/common/fse.h"
|
|
#include "fse.h"
|
|
|
|
/* Function templates */
|
|
FSE_DTable* FSE_createDTable (unsigned tableLog)
|
|
{
|
|
if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
|
|
return (FSE_DTable*)ZSTD_malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
|
|
}
|
|
|
|
void FSE_freeDTable (FSE_DTable* dt)
|
|
{
|
|
ZSTD_free(dt);
|
|
}
|
|
|
|
size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
|
|
{
|
|
void* ptr = dt;
|
|
FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
|
|
void* dPtr = dt + 1;
|
|
FSE_decode_t* const cell = (FSE_decode_t*)dPtr;
|
|
|
|
DTableH->tableLog = 0;
|
|
DTableH->fastMode = 0;
|
|
|
|
cell->newState = 0;
|
|
cell->symbol = symbolValue;
|
|
cell->nbBits = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
|
|
{
|
|
void* ptr = dt;
|
|
FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
|
|
void* dPtr = dt + 1;
|
|
FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
|
|
const unsigned tableSize = 1 << nbBits;
|
|
const unsigned tableMask = tableSize - 1;
|
|
const unsigned maxSV1 = tableMask+1;
|
|
unsigned s;
|
|
|
|
/* Sanity checks */
|
|
if (nbBits < 1) return ERROR(GENERIC); /* min size */
|
|
|
|
/* Build Decoding Table */
|
|
DTableH->tableLog = (U16)nbBits;
|
|
DTableH->fastMode = 1;
|
|
for (s=0; s<maxSV1; s++) {
|
|
dinfo[s].newState = 0;
|
|
dinfo[s].symbol = (BYTE)s;
|
|
dinfo[s].nbBits = (BYTE)nbBits;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
|
|
void* dst, size_t maxDstSize,
|
|
const void* cSrc, size_t cSrcSize,
|
|
const FSE_DTable* dt, const unsigned fast)
|
|
{
|
|
BYTE* const ostart = (BYTE*) dst;
|
|
BYTE* op = ostart;
|
|
BYTE* const omax = op + maxDstSize;
|
|
BYTE* const olimit = omax-3;
|
|
|
|
BIT_DStream_t bitD;
|
|
FSE_DState_t state1;
|
|
FSE_DState_t state2;
|
|
|
|
/* Init */
|
|
CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize));
|
|
|
|
FSE_initDState(&state1, &bitD, dt);
|
|
FSE_initDState(&state2, &bitD, dt);
|
|
|
|
#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
|
|
|
|
/* 4 symbols per loop */
|
|
for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) {
|
|
op[0] = FSE_GETSYMBOL(&state1);
|
|
|
|
if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
|
|
BIT_reloadDStream(&bitD);
|
|
|
|
op[1] = FSE_GETSYMBOL(&state2);
|
|
|
|
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; } }
|
|
|
|
op[2] = FSE_GETSYMBOL(&state1);
|
|
|
|
if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
|
|
BIT_reloadDStream(&bitD);
|
|
|
|
op[3] = FSE_GETSYMBOL(&state2);
|
|
}
|
|
|
|
/* tail */
|
|
/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
|
|
while (1) {
|
|
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
|
*op++ = FSE_GETSYMBOL(&state1);
|
|
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
|
|
*op++ = FSE_GETSYMBOL(&state2);
|
|
break;
|
|
}
|
|
|
|
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
|
*op++ = FSE_GETSYMBOL(&state2);
|
|
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
|
|
*op++ = FSE_GETSYMBOL(&state1);
|
|
break;
|
|
} }
|
|
|
|
return op-ostart;
|
|
}
|
|
|
|
size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
|
|
const void* cSrc, size_t cSrcSize,
|
|
const FSE_DTable* dt)
|
|
{
|
|
const void* ptr = dt;
|
|
const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
|
|
const U32 fastMode = DTableH->fastMode;
|
|
|
|
/* select fast mode (static) */
|
|
if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
|
|
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, unsigned maxLog, void* workSpace, size_t wkspSize)
|
|
{
|
|
return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0);
|
|
}
|
|
|
|
|
|
typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
|
|
|
|
#ifndef ZSTD_NO_UNUSED_FUNCTIONS
|
|
size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) {
|
|
U32 wksp[FSE_BUILD_DTABLE_WKSP_SIZE_U32(FSE_TABLELOG_ABSOLUTE_MAX, FSE_MAX_SYMBOL_VALUE)];
|
|
return FSE_buildDTable_wksp(dt, normalizedCounter, maxSymbolValue, tableLog, wksp, sizeof(wksp));
|
|
}
|
|
|
|
size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize)
|
|
{
|
|
/* Static analyzer seems unable to understand this table will be properly initialized later */
|
|
U32 wksp[FSE_DECOMPRESS_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
|
|
return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, FSE_MAX_TABLELOG, wksp, sizeof(wksp));
|
|
}
|
|
#endif
|
|
|