mirror of
https://github.com/facebook/zstd.git
synced 2025-03-07 01:10:04 +02:00
commit
9716250197
@ -132,14 +132,15 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy
|
||||
|
||||
#define Litbits 8
|
||||
#define MaxLit ((1<<Litbits) - 1)
|
||||
#define MaxML 52
|
||||
#define MaxLL 35
|
||||
#define MaxML 52
|
||||
#define MaxLL 35
|
||||
#define DefaultMaxOff 28
|
||||
#define MaxOff 31
|
||||
#define MaxOff 31
|
||||
#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
|
||||
#define MLFSELog 9
|
||||
#define LLFSELog 9
|
||||
#define OffFSELog 8
|
||||
#define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
|
||||
|
||||
static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
@ -1631,7 +1631,8 @@ size_t ZSTD_encodeSequences(
|
||||
DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
|
||||
sequences[n].litLength,
|
||||
sequences[n].matchLength + MINMATCH,
|
||||
sequences[n].offset); /* 32b*/ /* 64b*/
|
||||
sequences[n].offset);
|
||||
/* 32b*/ /* 64b*/
|
||||
/* (7)*/ /* (7)*/
|
||||
FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
|
||||
FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
|
||||
@ -1657,8 +1658,11 @@ size_t ZSTD_encodeSequences(
|
||||
BIT_flushBits(&blockStream); /* (7)*/
|
||||
} }
|
||||
|
||||
DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
|
||||
FSE_flushCState(&blockStream, &stateMatchLength);
|
||||
DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
|
||||
FSE_flushCState(&blockStream, &stateOffsetBits);
|
||||
DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
|
||||
FSE_flushCState(&blockStream, &stateLitLength);
|
||||
|
||||
{ size_t const streamSize = BIT_closeCStream(&blockStream);
|
||||
|
@ -80,10 +80,25 @@ typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
||||
typedef enum { zdss_init=0, zdss_loadHeader,
|
||||
zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
|
||||
|
||||
|
||||
typedef struct {
|
||||
FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
||||
FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
||||
FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
||||
U32 fastMode;
|
||||
U32 tableLog;
|
||||
} ZSTD_seqSymbol_header;
|
||||
|
||||
typedef struct {
|
||||
U16 nextState;
|
||||
BYTE nbAdditionalBits;
|
||||
BYTE nbBits;
|
||||
U32 baseValue;
|
||||
} ZSTD_seqSymbol;
|
||||
|
||||
#define SEQSYMBOL_TABLE_SIZE(log) (1 + (1<<log))
|
||||
|
||||
typedef struct {
|
||||
ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)];
|
||||
ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)];
|
||||
ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)];
|
||||
HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
|
||||
U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
||||
U32 rep[ZSTD_REP_NUM];
|
||||
@ -91,9 +106,9 @@ typedef struct {
|
||||
|
||||
struct ZSTD_DCtx_s
|
||||
{
|
||||
const FSE_DTable* LLTptr;
|
||||
const FSE_DTable* MLTptr;
|
||||
const FSE_DTable* OFTptr;
|
||||
const ZSTD_seqSymbol* LLTptr;
|
||||
const ZSTD_seqSymbol* MLTptr;
|
||||
const ZSTD_seqSymbol* OFTptr;
|
||||
const HUF_DTable* HUFptr;
|
||||
ZSTD_entropyDTables_t entropy;
|
||||
const void* previousDstEnd; /* detect continuity */
|
||||
@ -652,98 +667,219 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef union {
|
||||
FSE_decode_t realData;
|
||||
FSE_DTable dtable;
|
||||
U32 alignedBy4;
|
||||
} FSE_decode_t4;
|
||||
/* Default FSE distribution tables.
|
||||
* These are pre-calculated FSE decoding tables using default distributions as defined in specification :
|
||||
* https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions
|
||||
* They were generated programmatically with following method :
|
||||
* - start from default distributions, present in /lib/common/zstd_internal.h
|
||||
* - generate tables normally, using ZSTD_buildFSETable()
|
||||
* - printout the content of tables
|
||||
* - pretify output, report below, test with fuzzer to ensure it's correct */
|
||||
|
||||
/* Default FSE distribution table for Literal Lengths */
|
||||
static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
|
||||
{ { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
|
||||
/* base, symbol, bits */
|
||||
{ { 0, 0, 4 } }, { { 16, 0, 4 } }, { { 32, 1, 5 } }, { { 0, 3, 5 } },
|
||||
{ { 0, 4, 5 } }, { { 0, 6, 5 } }, { { 0, 7, 5 } }, { { 0, 9, 5 } },
|
||||
{ { 0, 10, 5 } }, { { 0, 12, 5 } }, { { 0, 14, 6 } }, { { 0, 16, 5 } },
|
||||
{ { 0, 18, 5 } }, { { 0, 19, 5 } }, { { 0, 21, 5 } }, { { 0, 22, 5 } },
|
||||
{ { 0, 24, 5 } }, { { 32, 25, 5 } }, { { 0, 26, 5 } }, { { 0, 27, 6 } },
|
||||
{ { 0, 29, 6 } }, { { 0, 31, 6 } }, { { 32, 0, 4 } }, { { 0, 1, 4 } },
|
||||
{ { 0, 2, 5 } }, { { 32, 4, 5 } }, { { 0, 5, 5 } }, { { 32, 7, 5 } },
|
||||
{ { 0, 8, 5 } }, { { 32, 10, 5 } }, { { 0, 11, 5 } }, { { 0, 13, 6 } },
|
||||
{ { 32, 16, 5 } }, { { 0, 17, 5 } }, { { 32, 19, 5 } }, { { 0, 20, 5 } },
|
||||
{ { 32, 22, 5 } }, { { 0, 23, 5 } }, { { 0, 25, 4 } }, { { 16, 25, 4 } },
|
||||
{ { 32, 26, 5 } }, { { 0, 28, 6 } }, { { 0, 30, 6 } }, { { 48, 0, 4 } },
|
||||
{ { 16, 1, 4 } }, { { 32, 2, 5 } }, { { 32, 3, 5 } }, { { 32, 5, 5 } },
|
||||
{ { 32, 6, 5 } }, { { 32, 8, 5 } }, { { 32, 9, 5 } }, { { 32, 11, 5 } },
|
||||
{ { 32, 12, 5 } }, { { 0, 15, 6 } }, { { 32, 17, 5 } }, { { 32, 18, 5 } },
|
||||
{ { 32, 20, 5 } }, { { 32, 21, 5 } }, { { 32, 23, 5 } }, { { 32, 24, 5 } },
|
||||
{ { 0, 35, 6 } }, { { 0, 34, 6 } }, { { 0, 33, 6 } }, { { 0, 32, 6 } },
|
||||
static const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
|
||||
{ 1, 1, 1, LL_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
|
||||
/* nextState, nbAddBits, nbBits, baseVal */
|
||||
{ 0, 0, 4, 0}, { 16, 0, 4, 0},
|
||||
{ 32, 0, 5, 1}, { 0, 0, 5, 3},
|
||||
{ 0, 0, 5, 4}, { 0, 0, 5, 6},
|
||||
{ 0, 0, 5, 7}, { 0, 0, 5, 9},
|
||||
{ 0, 0, 5, 10}, { 0, 0, 5, 12},
|
||||
{ 0, 0, 6, 14}, { 0, 1, 5, 16},
|
||||
{ 0, 1, 5, 20}, { 0, 1, 5, 22},
|
||||
{ 0, 2, 5, 28}, { 0, 3, 5, 32},
|
||||
{ 0, 4, 5, 48}, { 32, 6, 5, 64},
|
||||
{ 0, 7, 5, 128}, { 0, 8, 6, 256},
|
||||
{ 0, 10, 6, 1024}, { 0, 12, 6, 4096},
|
||||
{ 32, 0, 4, 0}, { 0, 0, 4, 1},
|
||||
{ 0, 0, 5, 2}, { 32, 0, 5, 4},
|
||||
{ 0, 0, 5, 5}, { 32, 0, 5, 7},
|
||||
{ 0, 0, 5, 8}, { 32, 0, 5, 10},
|
||||
{ 0, 0, 5, 11}, { 0, 0, 6, 13},
|
||||
{ 32, 1, 5, 16}, { 0, 1, 5, 18},
|
||||
{ 32, 1, 5, 22}, { 0, 2, 5, 24},
|
||||
{ 32, 3, 5, 32}, { 0, 3, 5, 40},
|
||||
{ 0, 6, 4, 64}, { 16, 6, 4, 64},
|
||||
{ 32, 7, 5, 128}, { 0, 9, 6, 512},
|
||||
{ 0, 11, 6, 2048}, { 48, 0, 4, 0},
|
||||
{ 16, 0, 4, 1}, { 32, 0, 5, 2},
|
||||
{ 32, 0, 5, 3}, { 32, 0, 5, 5},
|
||||
{ 32, 0, 5, 6}, { 32, 0, 5, 8},
|
||||
{ 32, 0, 5, 9}, { 32, 0, 5, 11},
|
||||
{ 32, 0, 5, 12}, { 0, 0, 6, 15},
|
||||
{ 32, 1, 5, 18}, { 32, 1, 5, 20},
|
||||
{ 32, 2, 5, 24}, { 32, 2, 5, 28},
|
||||
{ 32, 3, 5, 40}, { 32, 4, 5, 48},
|
||||
{ 0, 16, 6,65536}, { 0, 15, 6,32768},
|
||||
{ 0, 14, 6,16384}, { 0, 13, 6, 8192},
|
||||
}; /* LL_defaultDTable */
|
||||
|
||||
/* Default FSE distribution table for Offset Codes */
|
||||
static const ZSTD_seqSymbol OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
|
||||
{ 1, 1, 1, OF_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
|
||||
/* nextState, nbAddBits, nbBits, baseVal */
|
||||
{ 0, 0, 5, 0}, { 0, 6, 4, 61},
|
||||
{ 0, 9, 5, 509}, { 0, 15, 5,32765},
|
||||
{ 0, 21, 5,2097149}, { 0, 3, 5, 5},
|
||||
{ 0, 7, 4, 125}, { 0, 12, 5, 4093},
|
||||
{ 0, 18, 5,262141}, { 0, 23, 5,8388605},
|
||||
{ 0, 5, 5, 29}, { 0, 8, 4, 253},
|
||||
{ 0, 14, 5,16381}, { 0, 20, 5,1048573},
|
||||
{ 0, 2, 5, 1}, { 16, 7, 4, 125},
|
||||
{ 0, 11, 5, 2045}, { 0, 17, 5,131069},
|
||||
{ 0, 22, 5,4194301}, { 0, 4, 5, 13},
|
||||
{ 16, 8, 4, 253}, { 0, 13, 5, 8189},
|
||||
{ 0, 19, 5,524285}, { 0, 1, 5, 1},
|
||||
{ 16, 6, 4, 61}, { 0, 10, 5, 1021},
|
||||
{ 0, 16, 5,65533}, { 0, 28, 5,268435453},
|
||||
{ 0, 27, 5,134217725}, { 0, 26, 5,67108861},
|
||||
{ 0, 25, 5,33554429}, { 0, 24, 5,16777213},
|
||||
}; /* OF_defaultDTable */
|
||||
|
||||
|
||||
/* Default FSE distribution table for Match Lengths */
|
||||
static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
|
||||
{ { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
|
||||
/* base, symbol, bits */
|
||||
{ { 0, 0, 6 } }, { { 0, 1, 4 } }, { { 32, 2, 5 } }, { { 0, 3, 5 } },
|
||||
{ { 0, 5, 5 } }, { { 0, 6, 5 } }, { { 0, 8, 5 } }, { { 0, 10, 6 } },
|
||||
{ { 0, 13, 6 } }, { { 0, 16, 6 } }, { { 0, 19, 6 } }, { { 0, 22, 6 } },
|
||||
{ { 0, 25, 6 } }, { { 0, 28, 6 } }, { { 0, 31, 6 } }, { { 0, 33, 6 } },
|
||||
{ { 0, 35, 6 } }, { { 0, 37, 6 } }, { { 0, 39, 6 } }, { { 0, 41, 6 } },
|
||||
{ { 0, 43, 6 } }, { { 0, 45, 6 } }, { { 16, 1, 4 } }, { { 0, 2, 4 } },
|
||||
{ { 32, 3, 5 } }, { { 0, 4, 5 } }, { { 32, 6, 5 } }, { { 0, 7, 5 } },
|
||||
{ { 0, 9, 6 } }, { { 0, 12, 6 } }, { { 0, 15, 6 } }, { { 0, 18, 6 } },
|
||||
{ { 0, 21, 6 } }, { { 0, 24, 6 } }, { { 0, 27, 6 } }, { { 0, 30, 6 } },
|
||||
{ { 0, 32, 6 } }, { { 0, 34, 6 } }, { { 0, 36, 6 } }, { { 0, 38, 6 } },
|
||||
{ { 0, 40, 6 } }, { { 0, 42, 6 } }, { { 0, 44, 6 } }, { { 32, 1, 4 } },
|
||||
{ { 48, 1, 4 } }, { { 16, 2, 4 } }, { { 32, 4, 5 } }, { { 32, 5, 5 } },
|
||||
{ { 32, 7, 5 } }, { { 32, 8, 5 } }, { { 0, 11, 6 } }, { { 0, 14, 6 } },
|
||||
{ { 0, 17, 6 } }, { { 0, 20, 6 } }, { { 0, 23, 6 } }, { { 0, 26, 6 } },
|
||||
{ { 0, 29, 6 } }, { { 0, 52, 6 } }, { { 0, 51, 6 } }, { { 0, 50, 6 } },
|
||||
{ { 0, 49, 6 } }, { { 0, 48, 6 } }, { { 0, 47, 6 } }, { { 0, 46, 6 } },
|
||||
static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
|
||||
{ 1, 1, 1, ML_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
|
||||
/* nextState, nbAddBits, nbBits, baseVal */
|
||||
{ 0, 0, 6, 3}, { 0, 0, 4, 4},
|
||||
{ 32, 0, 5, 5}, { 0, 0, 5, 6},
|
||||
{ 0, 0, 5, 8}, { 0, 0, 5, 9},
|
||||
{ 0, 0, 5, 11}, { 0, 0, 6, 13},
|
||||
{ 0, 0, 6, 16}, { 0, 0, 6, 19},
|
||||
{ 0, 0, 6, 22}, { 0, 0, 6, 25},
|
||||
{ 0, 0, 6, 28}, { 0, 0, 6, 31},
|
||||
{ 0, 0, 6, 34}, { 0, 1, 6, 37},
|
||||
{ 0, 1, 6, 41}, { 0, 2, 6, 47},
|
||||
{ 0, 3, 6, 59}, { 0, 4, 6, 83},
|
||||
{ 0, 7, 6, 131}, { 0, 9, 6, 515},
|
||||
{ 16, 0, 4, 4}, { 0, 0, 4, 5},
|
||||
{ 32, 0, 5, 6}, { 0, 0, 5, 7},
|
||||
{ 32, 0, 5, 9}, { 0, 0, 5, 10},
|
||||
{ 0, 0, 6, 12}, { 0, 0, 6, 15},
|
||||
{ 0, 0, 6, 18}, { 0, 0, 6, 21},
|
||||
{ 0, 0, 6, 24}, { 0, 0, 6, 27},
|
||||
{ 0, 0, 6, 30}, { 0, 0, 6, 33},
|
||||
{ 0, 1, 6, 35}, { 0, 1, 6, 39},
|
||||
{ 0, 2, 6, 43}, { 0, 3, 6, 51},
|
||||
{ 0, 4, 6, 67}, { 0, 5, 6, 99},
|
||||
{ 0, 8, 6, 259}, { 32, 0, 4, 4},
|
||||
{ 48, 0, 4, 4}, { 16, 0, 4, 5},
|
||||
{ 32, 0, 5, 7}, { 32, 0, 5, 8},
|
||||
{ 32, 0, 5, 10}, { 32, 0, 5, 11},
|
||||
{ 0, 0, 6, 14}, { 0, 0, 6, 17},
|
||||
{ 0, 0, 6, 20}, { 0, 0, 6, 23},
|
||||
{ 0, 0, 6, 26}, { 0, 0, 6, 29},
|
||||
{ 0, 0, 6, 32}, { 0, 16, 6,65539},
|
||||
{ 0, 15, 6,32771}, { 0, 14, 6,16387},
|
||||
{ 0, 13, 6, 8195}, { 0, 12, 6, 4099},
|
||||
{ 0, 11, 6, 2051}, { 0, 10, 6, 1027},
|
||||
}; /* ML_defaultDTable */
|
||||
|
||||
/* Default FSE distribution table for Offset Codes */
|
||||
static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
|
||||
{ { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
|
||||
/* base, symbol, bits */
|
||||
{ { 0, 0, 5 } }, { { 0, 6, 4 } },
|
||||
{ { 0, 9, 5 } }, { { 0, 15, 5 } },
|
||||
{ { 0, 21, 5 } }, { { 0, 3, 5 } },
|
||||
{ { 0, 7, 4 } }, { { 0, 12, 5 } },
|
||||
{ { 0, 18, 5 } }, { { 0, 23, 5 } },
|
||||
{ { 0, 5, 5 } }, { { 0, 8, 4 } },
|
||||
{ { 0, 14, 5 } }, { { 0, 20, 5 } },
|
||||
{ { 0, 2, 5 } }, { { 16, 7, 4 } },
|
||||
{ { 0, 11, 5 } }, { { 0, 17, 5 } },
|
||||
{ { 0, 22, 5 } }, { { 0, 4, 5 } },
|
||||
{ { 16, 8, 4 } }, { { 0, 13, 5 } },
|
||||
{ { 0, 19, 5 } }, { { 0, 1, 5 } },
|
||||
{ { 16, 6, 4 } }, { { 0, 10, 5 } },
|
||||
{ { 0, 16, 5 } }, { { 0, 28, 5 } },
|
||||
{ { 0, 27, 5 } }, { { 0, 26, 5 } },
|
||||
{ { 0, 25, 5 } }, { { 0, 24, 5 } },
|
||||
}; /* OF_defaultDTable */
|
||||
|
||||
static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddBits)
|
||||
{
|
||||
void* ptr = dt;
|
||||
ZSTD_seqSymbol_header* const DTableH = (ZSTD_seqSymbol_header*)ptr;
|
||||
ZSTD_seqSymbol* const cell = dt + 1;
|
||||
|
||||
DTableH->tableLog = 0;
|
||||
DTableH->fastMode = 0;
|
||||
|
||||
cell->nbBits = 0;
|
||||
cell->nextState = 0;
|
||||
assert(nbAddBits < 255);
|
||||
cell->nbAdditionalBits = (BYTE)nbAddBits;
|
||||
cell->baseValue = baseValue;
|
||||
}
|
||||
|
||||
|
||||
/* ZSTD_buildFSETable() :
|
||||
* generate FSE decoding table for one symbol (ll, ml or off) */
|
||||
static void
|
||||
ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
|
||||
const short* normalizedCounter, unsigned maxSymbolValue,
|
||||
const U32* baseValue, const U32* nbAdditionalBits,
|
||||
unsigned tableLog)
|
||||
{
|
||||
ZSTD_seqSymbol* const tableDecode = dt+1;
|
||||
U16 symbolNext[MaxSeq+1];
|
||||
|
||||
U32 const maxSV1 = maxSymbolValue + 1;
|
||||
U32 const tableSize = 1 << tableLog;
|
||||
U32 highThreshold = tableSize-1;
|
||||
|
||||
/* Sanity Checks */
|
||||
assert(maxSymbolValue <= MaxSeq);
|
||||
assert(tableLog <= MaxFSELog);
|
||||
|
||||
/* Init, lay down lowprob symbols */
|
||||
{ ZSTD_seqSymbol_header DTableH;
|
||||
DTableH.tableLog = tableLog;
|
||||
DTableH.fastMode = 1;
|
||||
{ S16 const largeLimit= (S16)(1 << (tableLog-1));
|
||||
U32 s;
|
||||
for (s=0; s<maxSV1; s++) {
|
||||
if (normalizedCounter[s]==-1) {
|
||||
tableDecode[highThreshold--].baseValue = s;
|
||||
symbolNext[s] = 1;
|
||||
} else {
|
||||
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
|
||||
symbolNext[s] = normalizedCounter[s];
|
||||
} } }
|
||||
memcpy(dt, &DTableH, sizeof(DTableH));
|
||||
}
|
||||
|
||||
/* Spread symbols */
|
||||
{ U32 const tableMask = tableSize-1;
|
||||
U32 const step = FSE_TABLESTEP(tableSize);
|
||||
U32 s, position = 0;
|
||||
for (s=0; s<maxSV1; s++) {
|
||||
int i;
|
||||
for (i=0; i<normalizedCounter[s]; i++) {
|
||||
tableDecode[position].baseValue = s;
|
||||
position = (position + step) & tableMask;
|
||||
while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
|
||||
} }
|
||||
assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
|
||||
}
|
||||
|
||||
/* Build Decoding table */
|
||||
{ U32 u;
|
||||
for (u=0; u<tableSize; u++) {
|
||||
U32 const symbol = tableDecode[u].baseValue;
|
||||
U32 const nextState = symbolNext[symbol]++;
|
||||
tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) );
|
||||
tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
|
||||
assert(nbAdditionalBits[symbol] < 255);
|
||||
tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol];
|
||||
tableDecode[u].baseValue = baseValue[symbol];
|
||||
} }
|
||||
}
|
||||
|
||||
|
||||
/*! ZSTD_buildSeqTable() :
|
||||
* @return : nb bytes read from src,
|
||||
* or an error code if it fails, testable with ZSTD_isError()
|
||||
*/
|
||||
static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
|
||||
* or an error code if it fails */
|
||||
static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr,
|
||||
symbolEncodingType_e type, U32 max, U32 maxLog,
|
||||
const void* src, size_t srcSize,
|
||||
const FSE_decode_t4* defaultTable, U32 flagRepeatTable)
|
||||
const U32* baseValue, const U32* nbAdditionalBits,
|
||||
const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case set_rle :
|
||||
if (!srcSize) return ERROR(srcSize_wrong);
|
||||
if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
|
||||
FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
|
||||
{ U32 const symbol = *(const BYTE*)src;
|
||||
U32 const baseline = baseValue[symbol];
|
||||
U32 const nbBits = nbAdditionalBits[symbol];
|
||||
ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits);
|
||||
}
|
||||
*DTablePtr = DTableSpace;
|
||||
return 1;
|
||||
case set_basic :
|
||||
*DTablePtr = &defaultTable->dtable;
|
||||
*DTablePtr = defaultTable;
|
||||
return 0;
|
||||
case set_repeat:
|
||||
if (!flagRepeatTable) return ERROR(corruption_detected);
|
||||
@ -755,12 +891,41 @@ static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTa
|
||||
size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
|
||||
if (FSE_isError(headerSize)) return ERROR(corruption_detected);
|
||||
if (tableLog > maxLog) return ERROR(corruption_detected);
|
||||
FSE_buildDTable(DTableSpace, norm, max, tableLog);
|
||||
ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog);
|
||||
*DTablePtr = DTableSpace;
|
||||
return headerSize;
|
||||
} }
|
||||
}
|
||||
|
||||
static const U32 LL_base[MaxLL+1] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 18, 20, 22, 24, 28, 32, 40,
|
||||
48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
|
||||
0x2000, 0x4000, 0x8000, 0x10000 };
|
||||
|
||||
static const U32 OF_base[MaxOff+1] = {
|
||||
0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
|
||||
0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
|
||||
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
|
||||
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
|
||||
|
||||
static const U32 OF_bits[MaxOff+1] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31 };
|
||||
|
||||
static const U32 ML_base[MaxML+1] = {
|
||||
3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 26,
|
||||
27, 28, 29, 30, 31, 32, 33, 34,
|
||||
35, 37, 39, 41, 43, 47, 51, 59,
|
||||
67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
|
||||
0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
|
||||
|
||||
|
||||
size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
||||
const void* src, size_t srcSize)
|
||||
{
|
||||
@ -797,19 +962,27 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
||||
/* Build DTables */
|
||||
{ size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
|
||||
LLtype, MaxLL, LLFSELog,
|
||||
ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
|
||||
ip, iend-ip,
|
||||
LL_base, LL_bits,
|
||||
LL_defaultDTable, dctx->fseEntropy);
|
||||
if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
|
||||
ip += llhSize;
|
||||
}
|
||||
|
||||
{ size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
|
||||
OFtype, MaxOff, OffFSELog,
|
||||
ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
|
||||
ip, iend-ip,
|
||||
OF_base, OF_bits,
|
||||
OF_defaultDTable, dctx->fseEntropy);
|
||||
if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
|
||||
ip += ofhSize;
|
||||
}
|
||||
|
||||
{ size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
|
||||
MLtype, MaxML, MLFSELog,
|
||||
ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
|
||||
ip, iend-ip,
|
||||
ML_base, ML_bits,
|
||||
ML_defaultDTable, dctx->fseEntropy);
|
||||
if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
|
||||
ip += mlhSize;
|
||||
}
|
||||
@ -826,11 +999,16 @@ typedef struct {
|
||||
const BYTE* match;
|
||||
} seq_t;
|
||||
|
||||
typedef struct {
|
||||
size_t state;
|
||||
const ZSTD_seqSymbol* table;
|
||||
} ZSTD_fseState;
|
||||
|
||||
typedef struct {
|
||||
BIT_DStream_t DStream;
|
||||
FSE_DState_t stateLL;
|
||||
FSE_DState_t stateOffb;
|
||||
FSE_DState_t stateML;
|
||||
ZSTD_fseState stateLL;
|
||||
ZSTD_fseState stateOffb;
|
||||
ZSTD_fseState stateML;
|
||||
size_t prevOffset[ZSTD_REP_NUM];
|
||||
const BYTE* prefixStart;
|
||||
const BYTE* dictEnd;
|
||||
@ -885,6 +1063,16 @@ size_t ZSTD_execSequenceLast7(BYTE* op,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD)
|
||||
{
|
||||
ZSTD_seqSymbol const DInfo = DStatePtr->table[DStatePtr->state];
|
||||
U32 const nbBits = DInfo.nbBits;
|
||||
size_t const lowBits = BIT_readBits(bitD, nbBits);
|
||||
DStatePtr->state = DInfo.nextState + lowBits;
|
||||
}
|
||||
|
||||
|
||||
typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
|
||||
|
||||
/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
|
||||
@ -892,49 +1080,25 @@ typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset
|
||||
* bits before reloading. This value is the maximum number of bytes we read
|
||||
* after reloading when we are decoding long offets.
|
||||
*/
|
||||
#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \
|
||||
(ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \
|
||||
? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \
|
||||
#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \
|
||||
(ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \
|
||||
? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \
|
||||
: 0)
|
||||
|
||||
static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
||||
{
|
||||
seq_t seq;
|
||||
|
||||
U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
|
||||
U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
|
||||
U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
|
||||
|
||||
U32 const llBits = LL_bits[llCode];
|
||||
U32 const mlBits = ML_bits[mlCode];
|
||||
U32 const ofBits = ofCode;
|
||||
U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits;
|
||||
U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits;
|
||||
U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits;
|
||||
U32 const totalBits = llBits+mlBits+ofBits;
|
||||
|
||||
static const U32 LL_base[MaxLL+1] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 18, 20, 22, 24, 28, 32, 40,
|
||||
48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
|
||||
0x2000, 0x4000, 0x8000, 0x10000 };
|
||||
|
||||
static const U32 ML_base[MaxML+1] = {
|
||||
3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 26,
|
||||
27, 28, 29, 30, 31, 32, 33, 34,
|
||||
35, 37, 39, 41, 43, 47, 51, 59,
|
||||
67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
|
||||
0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
|
||||
|
||||
static const U32 OF_base[MaxOff+1] = {
|
||||
0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
|
||||
0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
|
||||
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
|
||||
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
|
||||
U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue;
|
||||
U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue;
|
||||
U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue;
|
||||
|
||||
/* sequence */
|
||||
{ size_t offset;
|
||||
if (!ofCode)
|
||||
if (!ofBits)
|
||||
offset = 0;
|
||||
else {
|
||||
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
||||
@ -942,18 +1106,18 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e l
|
||||
assert(ofBits <= MaxOff);
|
||||
if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {
|
||||
U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed);
|
||||
offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
|
||||
offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
|
||||
BIT_reloadDStream(&seqState->DStream);
|
||||
if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
|
||||
assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */
|
||||
} else {
|
||||
offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
||||
offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
||||
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
|
||||
}
|
||||
}
|
||||
|
||||
if (ofCode <= 1) {
|
||||
offset += (llCode==0);
|
||||
if (ofBits <= 1) {
|
||||
offset += (llBase==0);
|
||||
if (offset) {
|
||||
size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
|
||||
temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
|
||||
@ -971,8 +1135,8 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e l
|
||||
seq.offset = offset;
|
||||
}
|
||||
|
||||
seq.matchLength = ML_base[mlCode]
|
||||
+ ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/) : 0); /* <= 16 bits */
|
||||
seq.matchLength = mlBase
|
||||
+ ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/) : 0); /* <= 16 bits */
|
||||
if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
|
||||
BIT_reloadDStream(&seqState->DStream);
|
||||
if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
|
||||
@ -980,8 +1144,8 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e l
|
||||
/* Ensure there are enough bits to read the rest of data in 64-bit mode. */
|
||||
ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
|
||||
|
||||
seq.litLength = LL_base[llCode]
|
||||
+ ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits/*>0*/) : 0); /* <= 16 bits */
|
||||
seq.litLength = llBase
|
||||
+ ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits/*>0*/) : 0); /* <= 16 bits */
|
||||
if (MEM_32bits())
|
||||
BIT_reloadDStream(&seqState->DStream);
|
||||
|
||||
@ -989,10 +1153,10 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e l
|
||||
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
|
||||
|
||||
/* ANS state update */
|
||||
FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
|
||||
FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
|
||||
ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
|
||||
ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
|
||||
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
|
||||
FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
|
||||
ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
|
||||
|
||||
return seq;
|
||||
}
|
||||
@ -1079,6 +1243,18 @@ size_t ZSTD_execSequence(BYTE* op,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt)
|
||||
{
|
||||
const void* ptr = dt;
|
||||
const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr;
|
||||
DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
|
||||
DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits",
|
||||
(U32)DStatePtr->state, DTableH->tableLog);
|
||||
BIT_reloadDStream(bitD);
|
||||
DStatePtr->table = dt + 1;
|
||||
}
|
||||
|
||||
static size_t ZSTD_decompressSequences(
|
||||
ZSTD_DCtx* dctx,
|
||||
void* dst, size_t maxDstSize,
|
||||
@ -1112,9 +1288,9 @@ static size_t ZSTD_decompressSequences(
|
||||
dctx->fseEntropy = 1;
|
||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
||||
CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
|
||||
FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||
FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||
FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
||||
|
||||
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
|
||||
nbSeq--;
|
||||
@ -1126,7 +1302,7 @@ static size_t ZSTD_decompressSequences(
|
||||
} }
|
||||
|
||||
/* check if reached exact end */
|
||||
DEBUGLOG(5, "after decode loop, remaining nbSeq : %i", nbSeq);
|
||||
DEBUGLOG(5, "ZSTD_decompressSequences: after decode loop, remaining nbSeq : %i", nbSeq);
|
||||
if (nbSeq) return ERROR(corruption_detected);
|
||||
/* save reps for next block */
|
||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
|
||||
@ -1143,45 +1319,22 @@ static size_t ZSTD_decompressSequences(
|
||||
}
|
||||
|
||||
|
||||
|
||||
HINT_INLINE
|
||||
seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
|
||||
{
|
||||
seq_t seq;
|
||||
|
||||
U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
|
||||
U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
|
||||
U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
|
||||
|
||||
U32 const llBits = LL_bits[llCode];
|
||||
U32 const mlBits = ML_bits[mlCode];
|
||||
U32 const ofBits = ofCode;
|
||||
U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits;
|
||||
U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits;
|
||||
U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits;
|
||||
U32 const totalBits = llBits+mlBits+ofBits;
|
||||
|
||||
static const U32 LL_base[MaxLL+1] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 18, 20, 22, 24, 28, 32, 40,
|
||||
48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
|
||||
0x2000, 0x4000, 0x8000, 0x10000 };
|
||||
|
||||
static const U32 ML_base[MaxML+1] = {
|
||||
3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 26,
|
||||
27, 28, 29, 30, 31, 32, 33, 34,
|
||||
35, 37, 39, 41, 43, 47, 51, 59,
|
||||
67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
|
||||
0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
|
||||
|
||||
static const U32 OF_base[MaxOff+1] = {
|
||||
0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
|
||||
0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
|
||||
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
|
||||
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
|
||||
U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue;
|
||||
U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue;
|
||||
U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue;
|
||||
|
||||
/* sequence */
|
||||
{ size_t offset;
|
||||
if (!ofCode)
|
||||
if (!ofBits)
|
||||
offset = 0;
|
||||
else {
|
||||
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
||||
@ -1189,17 +1342,17 @@ seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const long
|
||||
assert(ofBits <= MaxOff);
|
||||
if (MEM_32bits() && longOffsets) {
|
||||
U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
|
||||
offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
|
||||
offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
|
||||
if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
|
||||
if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
|
||||
} else {
|
||||
offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
||||
offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
||||
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
|
||||
}
|
||||
}
|
||||
|
||||
if (ofCode <= 1) {
|
||||
offset += (llCode==0);
|
||||
if (ofBits <= 1) {
|
||||
offset += (llBase==0);
|
||||
if (offset) {
|
||||
size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
|
||||
temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
|
||||
@ -1217,7 +1370,7 @@ seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const long
|
||||
seq.offset = offset;
|
||||
}
|
||||
|
||||
seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
|
||||
seq.matchLength = mlBase + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
|
||||
if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
|
||||
BIT_reloadDStream(&seqState->DStream);
|
||||
if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
|
||||
@ -1225,7 +1378,7 @@ seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const long
|
||||
/* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
|
||||
ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
|
||||
|
||||
seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
|
||||
seq.litLength = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
|
||||
if (MEM_32bits())
|
||||
BIT_reloadDStream(&seqState->DStream);
|
||||
|
||||
@ -1237,10 +1390,10 @@ seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const long
|
||||
}
|
||||
|
||||
/* ANS state update */
|
||||
FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
|
||||
FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
|
||||
ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
|
||||
ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
|
||||
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
|
||||
FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
|
||||
ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
|
||||
|
||||
return seq;
|
||||
}
|
||||
@ -1364,9 +1517,9 @@ static size_t ZSTD_decompressSequencesLong(
|
||||
seqState.pos = (size_t)(op-prefixStart);
|
||||
seqState.dictEnd = dictEnd;
|
||||
CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
|
||||
FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||
FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||
FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
||||
|
||||
/* prepare in advance */
|
||||
for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {
|
||||
@ -1430,10 +1583,12 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
||||
ip += litCSize;
|
||||
srcSize -= litCSize;
|
||||
}
|
||||
|
||||
if ( frame /* windowSize exists */
|
||||
&& (dctx->fParams.windowSize > (1<<24))
|
||||
&& MEM_64bits() /* x86 benefits less from long mode than x64 */ )
|
||||
return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
|
||||
|
||||
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
|
||||
}
|
||||
|
||||
@ -1929,8 +2084,12 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, const void* const
|
||||
U32 offcodeMaxValue = MaxOff, offcodeLog;
|
||||
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
||||
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||
if (offcodeMaxValue > MaxOff) return ERROR(dictionary_corrupted);
|
||||
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
||||
CHECK_E(FSE_buildDTable(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
||||
ZSTD_buildFSETable(entropy->OFTable,
|
||||
offcodeNCount, offcodeMaxValue,
|
||||
OF_base, OF_bits,
|
||||
offcodeLog);
|
||||
dictPtr += offcodeHeaderSize;
|
||||
}
|
||||
|
||||
@ -1938,8 +2097,12 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, const void* const
|
||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
||||
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
||||
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||
if (matchlengthMaxValue > MaxML) return ERROR(dictionary_corrupted);
|
||||
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
||||
CHECK_E(FSE_buildDTable(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
||||
ZSTD_buildFSETable(entropy->MLTable,
|
||||
matchlengthNCount, matchlengthMaxValue,
|
||||
ML_base, ML_bits,
|
||||
matchlengthLog);
|
||||
dictPtr += matchlengthHeaderSize;
|
||||
}
|
||||
|
||||
@ -1947,8 +2110,12 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, const void* const
|
||||
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
||||
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
||||
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||
if (litlengthMaxValue > MaxLL) return ERROR(dictionary_corrupted);
|
||||
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
||||
CHECK_E(FSE_buildDTable(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
||||
ZSTD_buildFSETable(entropy->LLTable,
|
||||
litlengthNCount, litlengthMaxValue,
|
||||
LL_base, LL_bits,
|
||||
litlengthLog);
|
||||
dictPtr += litlengthHeaderSize;
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1209,7 @@ static int basicUnitTests(U32 seed, double compressibility)
|
||||
if (strcmp("No error detected", ZSTD_getErrorName(ZSTD_error_GENERIC)) != 0) goto _output_error;
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(4, "test%3i : testing ZSTD dictionary sizes : ", testNb++);
|
||||
DISPLAYLEVEL(3, "test%3i : testing ZSTD dictionary sizes : ", testNb++);
|
||||
RDG_genBuffer(CNBuffer, CNBuffSize, compressibility, 0., seed);
|
||||
{
|
||||
size_t const size = MIN(128 KB, CNBuffSize);
|
||||
@ -1230,6 +1230,7 @@ static int basicUnitTests(U32 seed, double compressibility)
|
||||
ZSTD_freeCDict(lgCDict);
|
||||
ZSTD_freeCCtx(cctx);
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
_end:
|
||||
free(CNBuffer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user