incorporate ZSTD_decodeSequenceLong() within zstd_decompress.c
This commit is contained in:
@@ -1333,6 +1333,90 @@ ZSTD_decodeSequence_default(seqState_t* seqState, const ZSTD_longOffset_e longOf
|
|||||||
return ZSTD_decodeSequence_body(seqState, longOffsets);
|
return ZSTD_decodeSequence_body(seqState, longOffsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_TEMPLATE seq_t
|
||||||
|
ZSTD_decodeSequenceLong_body(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
|
||||||
|
{
|
||||||
|
seq_t seq;
|
||||||
|
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;
|
||||||
|
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 (!ofBits)
|
||||||
|
offset = 0;
|
||||||
|
else {
|
||||||
|
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
||||||
|
ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
|
||||||
|
assert(ofBits <= MaxOff);
|
||||||
|
if (MEM_32bits() && longOffsets) {
|
||||||
|
U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
|
||||||
|
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 = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
||||||
|
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
|
||||||
|
seqState->prevOffset[1] = seqState->prevOffset[0];
|
||||||
|
seqState->prevOffset[0] = offset = temp;
|
||||||
|
} else {
|
||||||
|
offset = seqState->prevOffset[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
seqState->prevOffset[2] = seqState->prevOffset[1];
|
||||||
|
seqState->prevOffset[1] = seqState->prevOffset[0];
|
||||||
|
seqState->prevOffset[0] = offset;
|
||||||
|
}
|
||||||
|
seq.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)))
|
||||||
|
BIT_reloadDStream(&seqState->DStream);
|
||||||
|
/* 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 = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
|
||||||
|
if (MEM_32bits())
|
||||||
|
BIT_reloadDStream(&seqState->DStream);
|
||||||
|
|
||||||
|
{ size_t const pos = seqState->pos + seq.litLength;
|
||||||
|
const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart;
|
||||||
|
seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
|
||||||
|
* No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */
|
||||||
|
seqState->pos = pos + seq.matchLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ANS state update */
|
||||||
|
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 */
|
||||||
|
ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
|
||||||
|
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static seq_t
|
||||||
|
ZSTD_decodeSequenceLong_default(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
|
||||||
|
{
|
||||||
|
return ZSTD_decodeSequenceLong_body(seqState, longOffsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define FUNCTION(fn) fn##_default
|
#define FUNCTION(fn) fn##_default
|
||||||
#define TARGET
|
#define TARGET
|
||||||
@@ -1348,6 +1432,12 @@ ZSTD_decodeSequence_bmi2(seqState_t* seqState, const ZSTD_longOffset_e longOffse
|
|||||||
return ZSTD_decodeSequence_body(seqState, longOffsets);
|
return ZSTD_decodeSequence_body(seqState, longOffsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TARGET_ATTRIBUTE("bmi2") seq_t
|
||||||
|
ZSTD_decodeSequenceLong_bmi2(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
|
||||||
|
{
|
||||||
|
return ZSTD_decodeSequenceLong_body(seqState, longOffsets);
|
||||||
|
}
|
||||||
|
|
||||||
#define FUNCTION(fn) fn##_bmi2
|
#define FUNCTION(fn) fn##_bmi2
|
||||||
#define TARGET TARGET_ATTRIBUTE("bmi2")
|
#define TARGET TARGET_ATTRIBUTE("bmi2")
|
||||||
#include "zstd_decompress_impl.h"
|
#include "zstd_decompress_impl.h"
|
||||||
|
|||||||
@@ -18,85 +18,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
HINT_INLINE seq_t
|
|
||||||
FUNCTION(ZSTD_decodeSequenceLong)(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
|
|
||||||
{
|
|
||||||
seq_t seq;
|
|
||||||
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;
|
|
||||||
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 (!ofBits)
|
|
||||||
offset = 0;
|
|
||||||
else {
|
|
||||||
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
|
||||||
ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
|
|
||||||
assert(ofBits <= MaxOff);
|
|
||||||
if (MEM_32bits() && longOffsets) {
|
|
||||||
U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
|
|
||||||
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 = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
|
||||||
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 */
|
|
||||||
if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
|
|
||||||
seqState->prevOffset[1] = seqState->prevOffset[0];
|
|
||||||
seqState->prevOffset[0] = offset = temp;
|
|
||||||
} else {
|
|
||||||
offset = seqState->prevOffset[0];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
seqState->prevOffset[2] = seqState->prevOffset[1];
|
|
||||||
seqState->prevOffset[1] = seqState->prevOffset[0];
|
|
||||||
seqState->prevOffset[0] = offset;
|
|
||||||
}
|
|
||||||
seq.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)))
|
|
||||||
BIT_reloadDStream(&seqState->DStream);
|
|
||||||
/* 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 = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
|
|
||||||
if (MEM_32bits())
|
|
||||||
BIT_reloadDStream(&seqState->DStream);
|
|
||||||
|
|
||||||
{ size_t const pos = seqState->pos + seq.litLength;
|
|
||||||
const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart;
|
|
||||||
seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
|
|
||||||
* No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */
|
|
||||||
seqState->pos = pos + seq.matchLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ANS state update */
|
|
||||||
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 */
|
|
||||||
ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
|
|
||||||
|
|
||||||
return seq;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static TARGET void
|
static TARGET void
|
||||||
FUNCTION(ZSTD_initFseState)(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt)
|
FUNCTION(ZSTD_initFseState)(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user