mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 14:07:11 -06:00
Update fast-lzma2 to version 1.0.1
This commit is contained in:
@@ -55,7 +55,7 @@ Introduction
|
||||
/*------ Version ------*/
|
||||
#define FL2_VERSION_MAJOR 1
|
||||
#define FL2_VERSION_MINOR 0
|
||||
#define FL2_VERSION_RELEASE 0
|
||||
#define FL2_VERSION_RELEASE 1
|
||||
|
||||
#define FL2_VERSION_NUMBER (FL2_VERSION_MAJOR *100*100 + FL2_VERSION_MINOR *100 + FL2_VERSION_RELEASE)
|
||||
FL2LIB_API unsigned FL2LIB_CALL FL2_versionNumber(void); /**< useful to check dll version */
|
||||
|
||||
@@ -294,7 +294,7 @@ static size_t FL2_compressCurBlock_blocking(FL2_CCtx* const cctx, int const stre
|
||||
cctx->jobs[nbThreads - 1].block.end = cctx->curBlock.end;
|
||||
|
||||
/* initialize to length 2 */
|
||||
cctx->matchTable->progress = RMF_initTable(cctx->matchTable, cctx->curBlock.data, cctx->curBlock.end);
|
||||
RMF_initTable(cctx->matchTable, cctx->curBlock.data, cctx->curBlock.end);
|
||||
|
||||
if (cctx->canceled) {
|
||||
RMF_resetIncompleteBuild(cctx->matchTable);
|
||||
@@ -666,7 +666,7 @@ FL2LIB_API size_t FL2LIB_CALL FL2_CCtx_setParameter(FL2_CCtx* cctx, FL2_cParamet
|
||||
case FL2_p_dictionarySize:
|
||||
CLAMPCHECK(value, FL2_DICTSIZE_MIN, FL2_DICTSIZE_MAX);
|
||||
cctx->params.rParams.dictionary_size = value;
|
||||
break;
|
||||
break;
|
||||
|
||||
case FL2_p_overlapFraction:
|
||||
MAXCHECK(value, FL2_BLOCK_OVERLAP_MAX);
|
||||
@@ -960,7 +960,7 @@ FL2LIB_API size_t FL2LIB_CALL FL2_copyCStreamOutput(FL2_CStream* fcs, FL2_outBuf
|
||||
|
||||
fcs->outPos = 0;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t FL2_compressStream_input(FL2_CStream* fcs, FL2_inBuffer* input)
|
||||
@@ -1066,7 +1066,7 @@ FL2LIB_API size_t FL2LIB_CALL FL2_getNextCompressedBuffer(FL2_CStream* fcs, FL2_
|
||||
cbuf->size = 0;
|
||||
|
||||
#ifndef FL2_SINGLETHREAD
|
||||
CHECK_F(FL2_waitCStream(fcs));
|
||||
CHECK_F(FL2_waitCStream(fcs));
|
||||
#endif
|
||||
|
||||
if (fcs->outThread < fcs->threadCount) {
|
||||
|
||||
@@ -133,10 +133,10 @@ typedef struct
|
||||
{
|
||||
size_t table_size;
|
||||
unsigned prices[kNumPositionStatesMax][kLenNumSymbolsTotal];
|
||||
Probability choice; /* low[0] is choice_2. Must be consecutive for speed */
|
||||
Probability low[kNumPositionStatesMax << (kLenNumLowBits + 1)];
|
||||
Probability high[kLenNumHighSymbols];
|
||||
} LengthStates;
|
||||
LZMA2_prob choice; /* low[0] is choice_2. Must be consecutive for speed */
|
||||
LZMA2_prob low[kNumPositionStatesMax << (kLenNumLowBits + 1)];
|
||||
LZMA2_prob high[kLenNumHighSymbols];
|
||||
} LZMA2_lenStates;
|
||||
|
||||
/* All probabilities for the encoder. This is a separate from the encoder object
|
||||
* so the state can be saved and restored in case a chunk is not compressible.
|
||||
@@ -144,26 +144,26 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/* Fields are ordered for speed */
|
||||
LengthStates rep_len_states;
|
||||
Probability is_rep0_long[kNumStates][kNumPositionStatesMax];
|
||||
LZMA2_lenStates rep_len_states;
|
||||
LZMA2_prob is_rep0_long[kNumStates][kNumPositionStatesMax];
|
||||
|
||||
size_t state;
|
||||
U32 reps[kNumReps];
|
||||
|
||||
Probability is_match[kNumStates][kNumPositionStatesMax];
|
||||
Probability is_rep[kNumStates];
|
||||
Probability is_rep_G0[kNumStates];
|
||||
Probability is_rep_G1[kNumStates];
|
||||
Probability is_rep_G2[kNumStates];
|
||||
LZMA2_prob is_match[kNumStates][kNumPositionStatesMax];
|
||||
LZMA2_prob is_rep[kNumStates];
|
||||
LZMA2_prob is_rep_G0[kNumStates];
|
||||
LZMA2_prob is_rep_G1[kNumStates];
|
||||
LZMA2_prob is_rep_G2[kNumStates];
|
||||
|
||||
LengthStates len_states;
|
||||
LZMA2_lenStates len_states;
|
||||
|
||||
Probability dist_slot_encoders[kNumLenToPosStates][1 << kNumPosSlotBits];
|
||||
Probability dist_align_encoders[1 << kNumAlignBits];
|
||||
Probability dist_encoders[kNumFullDistances - kEndPosModelIndex];
|
||||
LZMA2_prob dist_slot_encoders[kNumLenToPosStates][1 << kNumPosSlotBits];
|
||||
LZMA2_prob dist_align_encoders[1 << kNumAlignBits];
|
||||
LZMA2_prob dist_encoders[kNumFullDistances - kEndPosModelIndex];
|
||||
|
||||
Probability literal_probs[(kNumLiterals * kNumLitTables) << kLcLpMax];
|
||||
} EncoderStates;
|
||||
LZMA2_prob literal_probs[(kNumLiterals * kNumLitTables) << kLcLpMax];
|
||||
} LZMA2_encStates;
|
||||
|
||||
/*
|
||||
* Linked list item for optimal parsing
|
||||
@@ -178,7 +178,7 @@ typedef struct
|
||||
unsigned len;
|
||||
U32 dist;
|
||||
U32 reps[kNumReps];
|
||||
} OptimalNode;
|
||||
} LZMA2_node;
|
||||
|
||||
#define MARK_LITERAL(node) (node).dist = kNullDist; (node).extra = 0;
|
||||
#define MARK_SHORT_REP(node) (node).dist = 0; (node).extra = 0;
|
||||
@@ -189,7 +189,7 @@ typedef struct
|
||||
typedef struct {
|
||||
S32 table_3[1 << kHash3Bits];
|
||||
S32 hash_chain_3[1];
|
||||
} HashChains;
|
||||
} LZMA2_hc3;
|
||||
|
||||
/*
|
||||
* LZMA2 encoder.
|
||||
@@ -206,13 +206,13 @@ struct LZMA2_ECtx_s
|
||||
unsigned match_cycles;
|
||||
FL2_strategy strategy;
|
||||
|
||||
RangeEncoder rc;
|
||||
RC_encoder rc;
|
||||
/* Finish writing the chunk at this size */
|
||||
size_t chunk_size;
|
||||
/* Don't encode a symbol beyond this limit (used by fast mode) */
|
||||
size_t chunk_limit;
|
||||
|
||||
EncoderStates states;
|
||||
LZMA2_encStates states;
|
||||
|
||||
unsigned match_price_count;
|
||||
unsigned rep_len_price_count;
|
||||
@@ -225,9 +225,9 @@ struct LZMA2_ECtx_s
|
||||
RMF_match matches[kMatchesMax];
|
||||
size_t match_count;
|
||||
|
||||
OptimalNode opt_buf[kOptimizerBufferSize];
|
||||
LZMA2_node opt_buf[kOptimizerBufferSize];
|
||||
|
||||
HashChains* hash_buf;
|
||||
LZMA2_hc3* hash_buf;
|
||||
ptrdiff_t chain_mask_2;
|
||||
ptrdiff_t chain_mask_3;
|
||||
ptrdiff_t hash_dict_3;
|
||||
@@ -319,7 +319,7 @@ static unsigned LZMA_getRepMatch0Price(LZMA2_ECtx *const enc, size_t const len,
|
||||
+ GET_PRICE_1(rep0_long_prob);
|
||||
}
|
||||
|
||||
static unsigned LZMA_getLiteralPriceMatched(const Probability *const prob_table, U32 symbol, unsigned match_byte)
|
||||
static unsigned LZMA_getLiteralPriceMatched(const LZMA2_prob *const prob_table, U32 symbol, unsigned match_byte)
|
||||
{
|
||||
unsigned price = 0;
|
||||
unsigned offs = 0x100;
|
||||
@@ -334,12 +334,12 @@ static unsigned LZMA_getLiteralPriceMatched(const Probability *const prob_table,
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
void LZMA_encodeLiteral(LZMA2_ECtx *const enc, size_t const index, U32 symbol, unsigned const prev_symbol)
|
||||
void LZMA_encodeLiteral(LZMA2_ECtx *const enc, size_t const pos, U32 symbol, unsigned const prev_symbol)
|
||||
{
|
||||
RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][index & enc->pos_mask]);
|
||||
RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][pos & enc->pos_mask]);
|
||||
enc->states.state = LIT_NEXT_STATE(enc->states.state);
|
||||
|
||||
Probability* const prob_table = LITERAL_PROBS(enc, index, prev_symbol);
|
||||
LZMA2_prob* const prob_table = LITERAL_PROBS(enc, pos, prev_symbol);
|
||||
symbol |= 0x100;
|
||||
do {
|
||||
RC_encodeBit(&enc->rc, prob_table + (symbol >> 8), symbol & (1 << 7));
|
||||
@@ -348,13 +348,13 @@ void LZMA_encodeLiteral(LZMA2_ECtx *const enc, size_t const index, U32 symbol, u
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
void LZMA_encodeLiteralMatched(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const index, U32 symbol)
|
||||
void LZMA_encodeLiteralMatched(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const pos, U32 symbol)
|
||||
{
|
||||
RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][index & enc->pos_mask]);
|
||||
RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][pos & enc->pos_mask]);
|
||||
enc->states.state = LIT_NEXT_STATE(enc->states.state);
|
||||
|
||||
unsigned match_symbol = data_block[index - enc->states.reps[0] - 1];
|
||||
Probability* const prob_table = LITERAL_PROBS(enc, index, data_block[index - 1]);
|
||||
unsigned match_symbol = data_block[pos - enc->states.reps[0] - 1];
|
||||
LZMA2_prob* const prob_table = LITERAL_PROBS(enc, pos, data_block[pos - 1]);
|
||||
unsigned offset = 0x100;
|
||||
symbol |= 0x100;
|
||||
do {
|
||||
@@ -367,19 +367,19 @@ void LZMA_encodeLiteralMatched(LZMA2_ECtx *const enc, const BYTE* const data_blo
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
void LZMA_encodeLiteralBuf(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const index)
|
||||
void LZMA_encodeLiteralBuf(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const pos)
|
||||
{
|
||||
U32 const symbol = data_block[index];
|
||||
U32 const symbol = data_block[pos];
|
||||
if (IS_LIT_STATE(enc->states.state)) {
|
||||
unsigned const prev_symbol = data_block[index - 1];
|
||||
LZMA_encodeLiteral(enc, index, symbol, prev_symbol);
|
||||
unsigned const prev_symbol = data_block[pos - 1];
|
||||
LZMA_encodeLiteral(enc, pos, symbol, prev_symbol);
|
||||
}
|
||||
else {
|
||||
LZMA_encodeLiteralMatched(enc, data_block, index, symbol);
|
||||
LZMA_encodeLiteralMatched(enc, data_block, pos, symbol);
|
||||
}
|
||||
}
|
||||
|
||||
static void LZMA_lengthStates_SetPrices(const Probability *probs, U32 start_price, unsigned *prices)
|
||||
static void LZMA_lengthStates_SetPrices(const LZMA2_prob *probs, U32 start_price, unsigned *prices)
|
||||
{
|
||||
for (size_t i = 0; i < 8; i += 2) {
|
||||
U32 prob = probs[4 + (i >> 1)];
|
||||
@@ -391,7 +391,7 @@ static void LZMA_lengthStates_SetPrices(const Probability *probs, U32 start_pric
|
||||
}
|
||||
|
||||
FORCE_NOINLINE
|
||||
static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates* const ls)
|
||||
static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LZMA2_lenStates* const ls)
|
||||
{
|
||||
U32 b;
|
||||
|
||||
@@ -403,7 +403,7 @@ static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates*
|
||||
c = b + GET_PRICE_0(ls->low[0]);
|
||||
for (size_t pos_state = 0; pos_state <= enc->pos_mask; pos_state++) {
|
||||
unsigned *const prices = ls->prices[pos_state];
|
||||
const Probability *const probs = ls->low + (pos_state << (1 + kLenNumLowBits));
|
||||
const LZMA2_prob *const probs = ls->low + (pos_state << (1 + kLenNumLowBits));
|
||||
LZMA_lengthStates_SetPrices(probs, a, prices);
|
||||
LZMA_lengthStates_SetPrices(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols);
|
||||
}
|
||||
@@ -412,7 +412,7 @@ static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates*
|
||||
size_t i = ls->table_size;
|
||||
|
||||
if (i > kLenNumLowSymbols * 2) {
|
||||
const Probability *const probs = ls->high;
|
||||
const LZMA2_prob *const probs = ls->high;
|
||||
unsigned *const prices = ls->prices[0] + kLenNumLowSymbols * 2;
|
||||
i = (i - (kLenNumLowSymbols * 2 - 1)) >> 1;
|
||||
b += GET_PRICE_1(ls->low[0]);
|
||||
@@ -439,7 +439,7 @@ static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates*
|
||||
|
||||
/* Rare enough that not inlining is faster overall */
|
||||
FORCE_NOINLINE
|
||||
static void LZMA_encodeLength_MidHigh(LZMA2_ECtx *const enc, LengthStates* const len_prob_table, unsigned const len, size_t const pos_state)
|
||||
static void LZMA_encodeLength_MidHigh(LZMA2_ECtx *const enc, LZMA2_lenStates* const len_prob_table, unsigned const len, size_t const pos_state)
|
||||
{
|
||||
RC_encodeBit1(&enc->rc, &len_prob_table->choice);
|
||||
if (len < kLenNumLowSymbols * 2) {
|
||||
@@ -453,7 +453,7 @@ static void LZMA_encodeLength_MidHigh(LZMA2_ECtx *const enc, LengthStates* const
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
void LZMA_encodeLength(LZMA2_ECtx *const enc, LengthStates* const len_prob_table, unsigned len, size_t const pos_state)
|
||||
void LZMA_encodeLength(LZMA2_ECtx *const enc, LZMA2_lenStates* const len_prob_table, unsigned len, size_t const pos_state)
|
||||
{
|
||||
len -= kMatchLenMin;
|
||||
if (len < kLenNumLowSymbols) {
|
||||
@@ -580,22 +580,22 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
FL2_dataBlock const block,
|
||||
FL2_matchTable* const tbl,
|
||||
int const struct_tbl,
|
||||
size_t index,
|
||||
size_t pos,
|
||||
size_t const uncompressed_end)
|
||||
{
|
||||
size_t const pos_mask = enc->pos_mask;
|
||||
size_t prev = index;
|
||||
size_t prev = pos;
|
||||
unsigned const search_depth = tbl->params.depth;
|
||||
|
||||
while (index < uncompressed_end && enc->rc.out_index < enc->chunk_size) {
|
||||
while (pos < uncompressed_end && enc->rc.out_index < enc->chunk_size) {
|
||||
size_t max_len;
|
||||
const BYTE* data;
|
||||
/* Table of distance restrictions for short matches */
|
||||
static const U32 max_dist_table[] = { 0, 0, 0, 1 << 6, 1 << 14 };
|
||||
/* Get a match from the table, extended to its full length */
|
||||
RMF_match best_match = RMF_getMatch(block, tbl, search_depth, struct_tbl, index);
|
||||
RMF_match best_match = RMF_getMatch(block, tbl, search_depth, struct_tbl, pos);
|
||||
if (best_match.length < kMatchLenMin) {
|
||||
++index;
|
||||
++pos;
|
||||
continue;
|
||||
}
|
||||
/* Use if near enough */
|
||||
@@ -604,8 +604,8 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
else
|
||||
best_match.length = 0;
|
||||
|
||||
max_len = MIN(kMatchLenMax, block.end - index);
|
||||
data = block.data + index;
|
||||
max_len = MIN(kMatchLenMax, block.end - pos);
|
||||
data = block.data + pos;
|
||||
|
||||
RMF_match best_rep = { 0, 0 };
|
||||
RMF_match rep_match;
|
||||
@@ -643,11 +643,11 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
}
|
||||
|
||||
if (best_match.length < kMatchLenMin) {
|
||||
++index;
|
||||
++pos;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t next = index + 1; best_match.length < kMatchLenMax && next < uncompressed_end; ++next) {
|
||||
for (size_t next = pos + 1; best_match.length < kMatchLenMax && next < uncompressed_end; ++next) {
|
||||
/* lazy matching scheme from ZSTD */
|
||||
RMF_match next_match = RMF_getNextMatch(block, tbl, search_depth, struct_tbl, next);
|
||||
if (next_match.length >= kMatchLenMin) {
|
||||
@@ -669,7 +669,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
if (gain2 > gain1) {
|
||||
DEBUGLOG(7, "Replace match (%u, %u) with rep (%u, %u)", best_match.length, best_match.dist, best_rep.length, best_rep.dist);
|
||||
best_match = best_rep;
|
||||
index = next;
|
||||
pos = next;
|
||||
}
|
||||
}
|
||||
if (next_match.length >= 3 && next_match.dist != best_match.dist) {
|
||||
@@ -679,7 +679,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
DEBUGLOG(7, "Replace match (%u, %u) with match (%u, %u)", best_match.length, best_match.dist, next_match.length, next_match.dist + kNumReps);
|
||||
best_match = next_match;
|
||||
best_match.dist += kNumReps;
|
||||
index = next;
|
||||
pos = next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -712,7 +712,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
if (gain2 > gain1) {
|
||||
DEBUGLOG(7, "Replace match (%u, %u) with rep (%u, %u)", best_match.length, best_match.dist, best_rep.length, best_rep.dist);
|
||||
best_match = best_rep;
|
||||
index = next;
|
||||
pos = next;
|
||||
}
|
||||
}
|
||||
if (next_match.dist != best_match.dist) {
|
||||
@@ -722,7 +722,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
DEBUGLOG(7, "Replace match (%u, %u) with match (%u, %u)", best_match.length, best_match.dist, next_match.length, next_match.dist + kNumReps);
|
||||
best_match = next_match;
|
||||
best_match.dist += kNumReps;
|
||||
index = next;
|
||||
pos = next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -730,9 +730,9 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
|
||||
break;
|
||||
}
|
||||
_encode:
|
||||
assert(index + best_match.length <= block.end);
|
||||
assert(pos + best_match.length <= block.end);
|
||||
|
||||
while (prev < index) {
|
||||
while (prev < pos) {
|
||||
if (enc->rc.out_index >= enc->chunk_limit)
|
||||
return prev;
|
||||
|
||||
@@ -748,18 +748,18 @@ _encode:
|
||||
|
||||
if(best_match.length >= kMatchLenMin) {
|
||||
if (best_match.dist >= kNumReps) {
|
||||
LZMA_encodeNormalMatch(enc, best_match.length, best_match.dist - kNumReps, index & pos_mask);
|
||||
index += best_match.length;
|
||||
prev = index;
|
||||
LZMA_encodeNormalMatch(enc, best_match.length, best_match.dist - kNumReps, pos & pos_mask);
|
||||
pos += best_match.length;
|
||||
prev = pos;
|
||||
}
|
||||
else {
|
||||
LZMA_encodeRepMatchLong(enc, best_match.length, best_match.dist, index & pos_mask);
|
||||
index += best_match.length;
|
||||
prev = index;
|
||||
LZMA_encodeRepMatchLong(enc, best_match.length, best_match.dist, pos & pos_mask);
|
||||
pos += best_match.length;
|
||||
prev = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (prev < index && enc->rc.out_index < enc->chunk_limit) {
|
||||
while (prev < pos && enc->rc.out_index < enc->chunk_limit) {
|
||||
if (block.data[prev] != block.data[prev - enc->states.reps[0] - 1])
|
||||
LZMA_encodeLiteralBuf(enc, block.data, prev);
|
||||
else
|
||||
@@ -773,7 +773,7 @@ _encode:
|
||||
* Reverse the direction of the linked list generated by the optimal parser
|
||||
*/
|
||||
FORCE_NOINLINE
|
||||
static void LZMA_reverseOptimalChain(OptimalNode* const opt_buf, size_t cur)
|
||||
static void LZMA_reverseOptimalChain(LZMA2_node* const opt_buf, size_t cur)
|
||||
{
|
||||
unsigned len = (unsigned)opt_buf[cur].len;
|
||||
U32 dist = opt_buf[cur].dist;
|
||||
@@ -814,9 +814,9 @@ static void LZMA_reverseOptimalChain(OptimalNode* const opt_buf, size_t cur)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned LZMA_getLiteralPrice(LZMA2_ECtx *const enc, size_t const index, size_t const state, unsigned const prev_symbol, U32 symbol, unsigned const match_byte)
|
||||
static unsigned LZMA_getLiteralPrice(LZMA2_ECtx *const enc, size_t const pos, size_t const state, unsigned const prev_symbol, U32 symbol, unsigned const match_byte)
|
||||
{
|
||||
const Probability* const prob_table = LITERAL_PROBS(enc, index, prev_symbol);
|
||||
const LZMA2_prob* const prob_table = LITERAL_PROBS(enc, pos, prev_symbol);
|
||||
if (IS_LIT_STATE(state)) {
|
||||
unsigned price = 0;
|
||||
symbol |= 0x100;
|
||||
@@ -850,7 +850,7 @@ static int LZMA_hashCreate(LZMA2_ECtx *const enc, unsigned const dictionary_bits
|
||||
free(enc->hash_buf);
|
||||
|
||||
enc->hash_alloc_3 = (ptrdiff_t)1 << dictionary_bits_3;
|
||||
enc->hash_buf = malloc(sizeof(HashChains) + (enc->hash_alloc_3 - 1) * sizeof(S32));
|
||||
enc->hash_buf = malloc(sizeof(LZMA2_hc3) + (enc->hash_alloc_3 - 1) * sizeof(S32));
|
||||
|
||||
if (enc->hash_buf == NULL)
|
||||
return 1;
|
||||
@@ -879,34 +879,34 @@ int LZMA2_hashAlloc(LZMA2_ECtx *const enc, const FL2_lzma2Parameters* const opti
|
||||
*/
|
||||
HINT_INLINE
|
||||
size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
ptrdiff_t const index,
|
||||
ptrdiff_t const pos,
|
||||
size_t const length_limit,
|
||||
RMF_match const match)
|
||||
{
|
||||
ptrdiff_t const hash_dict_3 = enc->hash_dict_3;
|
||||
const BYTE* data = block.data;
|
||||
HashChains* const tbl = enc->hash_buf;
|
||||
LZMA2_hc3* const tbl = enc->hash_buf;
|
||||
ptrdiff_t const chain_mask_3 = enc->chain_mask_3;
|
||||
|
||||
enc->match_count = 0;
|
||||
enc->hash_prev_index = MAX(enc->hash_prev_index, index - hash_dict_3);
|
||||
enc->hash_prev_index = MAX(enc->hash_prev_index, pos - hash_dict_3);
|
||||
/* Update hash tables and chains for any positions that were skipped */
|
||||
while (++enc->hash_prev_index < index) {
|
||||
while (++enc->hash_prev_index < pos) {
|
||||
size_t hash = GET_HASH_3(data + enc->hash_prev_index);
|
||||
tbl->hash_chain_3[enc->hash_prev_index & chain_mask_3] = tbl->table_3[hash];
|
||||
tbl->table_3[hash] = (S32)enc->hash_prev_index;
|
||||
}
|
||||
data += index;
|
||||
data += pos;
|
||||
|
||||
size_t const hash = GET_HASH_3(data);
|
||||
ptrdiff_t const first_3 = tbl->table_3[hash];
|
||||
tbl->table_3[hash] = (S32)index;
|
||||
tbl->table_3[hash] = (S32)pos;
|
||||
|
||||
size_t max_len = 2;
|
||||
|
||||
if (first_3 >= 0) {
|
||||
int cycles = enc->match_cycles;
|
||||
ptrdiff_t const end_index = index - (((ptrdiff_t)match.dist < hash_dict_3) ? match.dist : hash_dict_3);
|
||||
ptrdiff_t const end_index = pos - (((ptrdiff_t)match.dist < hash_dict_3) ? match.dist : hash_dict_3);
|
||||
ptrdiff_t match_3 = first_3;
|
||||
if (match_3 >= end_index) {
|
||||
do {
|
||||
@@ -915,7 +915,7 @@ size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
size_t len_test = ZSTD_count(data + 1, data_2 + 1, data + length_limit) + 1;
|
||||
if (len_test > max_len) {
|
||||
enc->matches[enc->match_count].length = (U32)len_test;
|
||||
enc->matches[enc->match_count].dist = (U32)(index - match_3 - 1);
|
||||
enc->matches[enc->match_count].dist = (U32)(pos - match_3 - 1);
|
||||
++enc->match_count;
|
||||
max_len = len_test;
|
||||
if (len_test >= length_limit)
|
||||
@@ -927,7 +927,7 @@ size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
} while (match_3 >= end_index);
|
||||
}
|
||||
}
|
||||
tbl->hash_chain_3[index & chain_mask_3] = (S32)first_3;
|
||||
tbl->hash_chain_3[pos & chain_mask_3] = (S32)first_3;
|
||||
if ((unsigned)max_len < match.length) {
|
||||
/* Insert the match from the RMF */
|
||||
enc->matches[enc->match_count] = match;
|
||||
@@ -948,16 +948,16 @@ size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
FORCE_INLINE_TEMPLATE
|
||||
size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
RMF_match match,
|
||||
size_t const index,
|
||||
size_t const pos,
|
||||
size_t const cur,
|
||||
size_t len_end,
|
||||
int const is_hybrid,
|
||||
U32* const reps)
|
||||
{
|
||||
OptimalNode* const cur_opt = &enc->opt_buf[cur];
|
||||
LZMA2_node* const cur_opt = &enc->opt_buf[cur];
|
||||
size_t const pos_mask = enc->pos_mask;
|
||||
size_t const pos_state = (index & pos_mask);
|
||||
const BYTE* const data = block.data + index;
|
||||
size_t const pos_state = (pos & pos_mask);
|
||||
const BYTE* const data = block.data + pos;
|
||||
size_t const fast_length = enc->fast_length;
|
||||
size_t prev_index = cur - cur_opt->len;
|
||||
size_t state;
|
||||
@@ -983,7 +983,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
state = enc->opt_buf[prev_index].state;
|
||||
state = MATCH_NEXT_STATE(state) + (dist < kNumReps);
|
||||
}
|
||||
const OptimalNode *const prev_opt = &enc->opt_buf[prev_index];
|
||||
const LZMA2_node *const prev_opt = &enc->opt_buf[prev_index];
|
||||
if (dist < kNumReps) {
|
||||
/* Move the chosen rep to the front.
|
||||
* The table is hideous but faster than branching :D */
|
||||
@@ -1008,12 +1008,12 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
}
|
||||
cur_opt->state = state;
|
||||
memcpy(cur_opt->reps, reps, sizeof(cur_opt->reps));
|
||||
Probability const is_rep_prob = enc->states.is_rep[state];
|
||||
LZMA2_prob const is_rep_prob = enc->states.is_rep[state];
|
||||
|
||||
{ OptimalNode *const next_opt = &enc->opt_buf[cur + 1];
|
||||
{ LZMA2_node *const next_opt = &enc->opt_buf[cur + 1];
|
||||
U32 const cur_price = cur_opt->price;
|
||||
U32 const next_price = next_opt->price;
|
||||
Probability const is_match_prob = enc->states.is_match[state][pos_state];
|
||||
LZMA2_prob const is_match_prob = enc->states.is_match[state][pos_state];
|
||||
unsigned const cur_byte = *data;
|
||||
unsigned const match_byte = *(data - reps[0] - 1);
|
||||
|
||||
@@ -1022,7 +1022,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
BYTE try_lit = cur_and_lit_price + kMinLitPrice / 2U <= next_price;
|
||||
if (try_lit) {
|
||||
/* cur_and_lit_price is used later for the literal + rep0 test */
|
||||
cur_and_lit_price += LZMA_getLiteralPrice(enc, index, state, data[-1], cur_byte, match_byte);
|
||||
cur_and_lit_price += LZMA_getLiteralPrice(enc, pos, state, data[-1], cur_byte, match_byte);
|
||||
/* Try literal */
|
||||
if (cur_and_lit_price < next_price) {
|
||||
next_opt->price = cur_and_lit_price;
|
||||
@@ -1043,7 +1043,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
MARK_SHORT_REP(*next_opt);
|
||||
}
|
||||
}
|
||||
bytes_avail = MIN(block.end - index, kOptimizerBufferSize - 1 - cur);
|
||||
bytes_avail = MIN(block.end - pos, kOptimizerBufferSize - 1 - cur);
|
||||
if (bytes_avail < 2)
|
||||
return len_end;
|
||||
|
||||
@@ -1055,7 +1055,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
size_t len_test_2 = ZSTD_count(data + 1, data_2, data + 1 + limit);
|
||||
if (len_test_2 >= 2) {
|
||||
size_t const state_2 = LIT_NEXT_STATE(state);
|
||||
size_t const pos_state_next = (index + 1) & pos_mask;
|
||||
size_t const pos_state_next = (pos + 1) & pos_mask;
|
||||
U32 const next_rep_match_price = cur_and_lit_price +
|
||||
GET_PRICE_1(enc->states.is_match[state_2][pos_state_next]) +
|
||||
GET_PRICE_1(enc->states.is_rep[state_2]);
|
||||
@@ -1092,7 +1092,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
/* Try rep match */
|
||||
do {
|
||||
U32 const cur_and_len_price = cur_rep_price + enc->states.rep_len_states.prices[pos_state][len - kMatchLenMin];
|
||||
OptimalNode *const opt = &enc->opt_buf[cur + len];
|
||||
LZMA2_node *const opt = &enc->opt_buf[cur + len];
|
||||
if (cur_and_len_price < opt->price) {
|
||||
opt->price = cur_and_len_price;
|
||||
opt->len = (unsigned)len;
|
||||
@@ -1114,15 +1114,15 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
data_2 + len_test + 3,
|
||||
data + MIN(len_test + 1 + fast_length, bytes_avail)) + 2;
|
||||
size_t state_2 = REP_NEXT_STATE(state);
|
||||
size_t pos_state_next = (index + len_test) & pos_mask;
|
||||
size_t pos_state_next = (pos + len_test) & pos_mask;
|
||||
U32 rep_lit_rep_total_price =
|
||||
cur_rep_price + enc->states.rep_len_states.prices[pos_state][len_test - kMatchLenMin]
|
||||
+ GET_PRICE_0(enc->states.is_match[state_2][pos_state_next])
|
||||
+ LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, index + len_test, data[len_test - 1]),
|
||||
+ LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, pos + len_test, data[len_test - 1]),
|
||||
data[len_test], data_2[len_test]);
|
||||
|
||||
state_2 = kState_LitAfterRep;
|
||||
pos_state_next = (index + len_test + 1) & pos_mask;
|
||||
pos_state_next = (pos + len_test + 1) & pos_mask;
|
||||
rep_lit_rep_total_price +=
|
||||
GET_PRICE_1(enc->states.is_match[state_2][pos_state_next]) +
|
||||
GET_PRICE_1(enc->states.is_rep[state_2]);
|
||||
@@ -1157,7 +1157,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
else
|
||||
cur_and_len_price += enc->dist_slot_prices[len_to_dist_state][dist_slot] + enc->align_prices[cur_dist & kAlignMask];
|
||||
|
||||
OptimalNode *const opt = &enc->opt_buf[cur + len_test];
|
||||
LZMA2_node *const opt = &enc->opt_buf[cur + len_test];
|
||||
if (cur_and_len_price < opt->price) {
|
||||
opt->price = cur_and_len_price;
|
||||
opt->len = (unsigned)len_test;
|
||||
@@ -1179,7 +1179,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
main_len = match.length;
|
||||
}
|
||||
else {
|
||||
main_len = LZMA_hashGetMatches(enc, block, index, max_length, match);
|
||||
main_len = LZMA_hashGetMatches(enc, block, pos, max_length, match);
|
||||
}
|
||||
ptrdiff_t match_index = enc->match_count - 1;
|
||||
len_end = MAX(len_end, cur + main_len);
|
||||
@@ -1210,7 +1210,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
|
||||
BYTE const sub_len = len_test < enc->matches[match_index].length;
|
||||
|
||||
OptimalNode *const opt = &enc->opt_buf[cur + len_test];
|
||||
LZMA2_node *const opt = &enc->opt_buf[cur + len_test];
|
||||
if (cur_and_len_price < opt->price) {
|
||||
opt->price = cur_and_len_price;
|
||||
opt->len = (unsigned)len_test;
|
||||
@@ -1225,10 +1225,10 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
|
||||
size_t const limit = MIN(rep_0_pos + fast_length, bytes_avail);
|
||||
size_t const len_test_2 = ZSTD_count(data + rep_0_pos + 2, data_2 + rep_0_pos + 2, data + limit) + 2;
|
||||
size_t state_2 = MATCH_NEXT_STATE(state);
|
||||
size_t pos_state_next = (index + len_test) & pos_mask;
|
||||
size_t pos_state_next = (pos + len_test) & pos_mask;
|
||||
U32 match_lit_rep_total_price = cur_and_len_price +
|
||||
GET_PRICE_0(enc->states.is_match[state_2][pos_state_next]) +
|
||||
LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, index + len_test, data[len_test - 1]),
|
||||
LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, pos + len_test, data[len_test - 1]),
|
||||
data[len_test], data_2[len_test]);
|
||||
|
||||
state_2 = kState_LitAfterMatch;
|
||||
@@ -1287,19 +1287,19 @@ static void LZMA_initMatchesPos0(LZMA2_ECtx *const enc,
|
||||
FORCE_NOINLINE
|
||||
static size_t LZMA_initMatchesPos0Best(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
RMF_match const match,
|
||||
size_t const index,
|
||||
size_t const pos,
|
||||
size_t start_len,
|
||||
unsigned const normal_match_price)
|
||||
{
|
||||
if (start_len <= match.length) {
|
||||
size_t main_len;
|
||||
if (match.length < 3 || block.end - index < 4) {
|
||||
if (match.length < 3 || block.end - pos < 4) {
|
||||
enc->matches[0] = match;
|
||||
enc->match_count = 1;
|
||||
main_len = match.length;
|
||||
}
|
||||
else {
|
||||
main_len = LZMA_hashGetMatches(enc, block, index, MIN(block.end - index, enc->fast_length), match);
|
||||
main_len = LZMA_hashGetMatches(enc, block, pos, MIN(block.end - pos, enc->fast_length), match);
|
||||
}
|
||||
|
||||
ptrdiff_t start_match = 0;
|
||||
@@ -1308,7 +1308,7 @@ static size_t LZMA_initMatchesPos0Best(LZMA2_ECtx *const enc, FL2_dataBlock cons
|
||||
|
||||
enc->matches[start_match - 1].length = (U32)start_len - 1; /* Avoids an if..else branch in the loop. [-1] is ok */
|
||||
|
||||
size_t pos_state = index & enc->pos_mask;
|
||||
size_t pos_state = pos & enc->pos_mask;
|
||||
|
||||
for (ptrdiff_t match_index = enc->match_count - 1; match_index >= start_match; --match_index) {
|
||||
size_t len_test = enc->matches[match_index].length;
|
||||
@@ -1348,12 +1348,12 @@ static size_t LZMA_initMatchesPos0Best(LZMA2_ECtx *const enc, FL2_dataBlock cons
|
||||
FORCE_INLINE_TEMPLATE
|
||||
size_t LZMA_initOptimizerPos0(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
RMF_match const match,
|
||||
size_t const index,
|
||||
size_t const pos,
|
||||
int const is_hybrid,
|
||||
U32* const reps)
|
||||
{
|
||||
size_t const max_length = MIN(block.end - index, kMatchLenMax);
|
||||
const BYTE *const data = block.data + index;
|
||||
size_t const max_length = MIN(block.end - pos, kMatchLenMax);
|
||||
const BYTE *const data = block.data + pos;
|
||||
const BYTE *data_2;
|
||||
size_t rep_max_index = 0;
|
||||
size_t rep_lens[kNumReps];
|
||||
@@ -1384,14 +1384,14 @@ size_t LZMA_initOptimizerPos0(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
unsigned const cur_byte = *data;
|
||||
unsigned const match_byte = *(data - reps[0] - 1);
|
||||
size_t const state = enc->states.state;
|
||||
size_t const pos_state = index & enc->pos_mask;
|
||||
Probability const is_match_prob = enc->states.is_match[state][pos_state];
|
||||
Probability const is_rep_prob = enc->states.is_rep[state];
|
||||
size_t const pos_state = pos & enc->pos_mask;
|
||||
LZMA2_prob const is_match_prob = enc->states.is_match[state][pos_state];
|
||||
LZMA2_prob const is_rep_prob = enc->states.is_rep[state];
|
||||
|
||||
enc->opt_buf[0].state = state;
|
||||
/* Set the price for literal */
|
||||
enc->opt_buf[1].price = GET_PRICE_0(is_match_prob) +
|
||||
LZMA_getLiteralPrice(enc, index, state, data[-1], cur_byte, match_byte);
|
||||
LZMA_getLiteralPrice(enc, pos, state, data[-1], cur_byte, match_byte);
|
||||
MARK_LITERAL(enc->opt_buf[1]);
|
||||
|
||||
unsigned const match_price = GET_PRICE_1(is_match_prob);
|
||||
@@ -1434,7 +1434,7 @@ size_t LZMA_initOptimizerPos0(LZMA2_ECtx *const enc, FL2_dataBlock const block,
|
||||
}
|
||||
else {
|
||||
/* Hybrid mode */
|
||||
size_t main_len = LZMA_initMatchesPos0Best(enc, block, match, index, len, normal_match_price);
|
||||
size_t main_len = LZMA_initMatchesPos0Best(enc, block, match, pos, len, normal_match_price);
|
||||
return MAX(main_len, rep_lens[rep_max_index]);
|
||||
}
|
||||
}
|
||||
@@ -1464,16 +1464,16 @@ size_t LZMA_encodeOptimumSequence(LZMA2_ECtx *const enc, FL2_dataBlock const blo
|
||||
}
|
||||
|
||||
/* Set everything up at position 0 */
|
||||
size_t index = start_index;
|
||||
size_t pos = start_index;
|
||||
U32 reps[kNumReps];
|
||||
len_end = LZMA_initOptimizerPos0(enc, block, match, index, is_hybrid, reps);
|
||||
len_end = LZMA_initOptimizerPos0(enc, block, match, pos, is_hybrid, reps);
|
||||
match.length = 0;
|
||||
size_t cur = 1;
|
||||
|
||||
/* len_end == 0 if a match of fast_length was found */
|
||||
if (len_end > 0) {
|
||||
++index;
|
||||
for (; cur < len_end; ++cur, ++index) {
|
||||
++pos;
|
||||
for (; cur < len_end; ++cur, ++pos) {
|
||||
/* Terminate if the farthest calculated price is too near the buffer end */
|
||||
if (len_end >= kOptimizerBufferSize - kOptimizerEndSize) {
|
||||
U32 price = enc->opt_buf[cur].price;
|
||||
@@ -1498,18 +1498,18 @@ size_t LZMA_encodeOptimumSequence(LZMA2_ECtx *const enc, FL2_dataBlock const blo
|
||||
U32 const price2 = enc->opt_buf[j].price;
|
||||
if (price >= price2) {
|
||||
price = price2;
|
||||
index += j - cur;
|
||||
pos += j - cur;
|
||||
cur = j;
|
||||
if (cur == len_end)
|
||||
goto reverse;
|
||||
}
|
||||
}
|
||||
|
||||
match = RMF_getMatch(block, tbl, search_depth, struct_tbl, index);
|
||||
match = RMF_getMatch(block, tbl, search_depth, struct_tbl, pos);
|
||||
if (match.length >= enc->fast_length)
|
||||
break;
|
||||
|
||||
len_end = LZMA_optimalParse(enc, block, match, index, cur, len_end, is_hybrid, reps);
|
||||
len_end = LZMA_optimalParse(enc, block, match, pos, cur, len_end, is_hybrid, reps);
|
||||
}
|
||||
reverse:
|
||||
DEBUGLOG(6, "End optimal parse at %u", (U32)cur);
|
||||
@@ -1555,7 +1555,7 @@ reverse:
|
||||
static void FORCE_NOINLINE LZMA_fillAlignPrices(LZMA2_ECtx *const enc)
|
||||
{
|
||||
unsigned i;
|
||||
const Probability *const probs = enc->states.dist_align_encoders;
|
||||
const LZMA2_prob *const probs = enc->states.dist_align_encoders;
|
||||
for (i = 0; i < kAlignTableSize / 2; i++) {
|
||||
U32 price = 0;
|
||||
unsigned sym = i;
|
||||
@@ -1580,7 +1580,7 @@ static void FORCE_NOINLINE LZMA_fillDistancesPrices(LZMA2_ECtx *const enc)
|
||||
unsigned const dist_slot = distance_table[i];
|
||||
unsigned footer_bits = (dist_slot >> 1) - 1;
|
||||
size_t base = ((2 | (dist_slot & 1)) << footer_bits);
|
||||
const Probability *probs = enc->states.dist_encoders + base * 2U;
|
||||
const LZMA2_prob *probs = enc->states.dist_encoders + base * 2U;
|
||||
base += i;
|
||||
probs = probs - distance_table[base] - 1;
|
||||
U32 price = 0;
|
||||
@@ -1604,7 +1604,7 @@ static void FORCE_NOINLINE LZMA_fillDistancesPrices(LZMA2_ECtx *const enc)
|
||||
size_t slot;
|
||||
size_t const dist_table_size2 = (enc->dist_price_table_size + 1) >> 1;
|
||||
U32 *const dist_slot_prices = enc->dist_slot_prices[lps];
|
||||
const Probability *const probs = enc->states.dist_slot_encoders[lps];
|
||||
const LZMA2_prob *const probs = enc->states.dist_slot_encoders[lps];
|
||||
|
||||
for (slot = 0; slot < dist_table_size2; slot++) {
|
||||
/* dist_slot_prices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices); */
|
||||
@@ -1652,7 +1652,7 @@ size_t LZMA_encodeChunkBest(LZMA2_ECtx *const enc,
|
||||
FL2_dataBlock const block,
|
||||
FL2_matchTable* const tbl,
|
||||
int const struct_tbl,
|
||||
size_t index,
|
||||
size_t pos,
|
||||
size_t const uncompressed_end)
|
||||
{
|
||||
unsigned const search_depth = tbl->params.depth;
|
||||
@@ -1661,16 +1661,16 @@ size_t LZMA_encodeChunkBest(LZMA2_ECtx *const enc,
|
||||
LZMA_lengthStates_updatePrices(enc, &enc->states.len_states);
|
||||
LZMA_lengthStates_updatePrices(enc, &enc->states.rep_len_states);
|
||||
|
||||
while (index < uncompressed_end && enc->rc.out_index < enc->chunk_size)
|
||||
while (pos < uncompressed_end && enc->rc.out_index < enc->chunk_size)
|
||||
{
|
||||
RMF_match const match = RMF_getMatch(block, tbl, search_depth, struct_tbl, index);
|
||||
RMF_match const match = RMF_getMatch(block, tbl, search_depth, struct_tbl, pos);
|
||||
if (match.length > 1) {
|
||||
/* Template-like inline function */
|
||||
if (enc->strategy == FL2_ultra) {
|
||||
index = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 1, index, uncompressed_end, match);
|
||||
pos = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 1, pos, uncompressed_end, match);
|
||||
}
|
||||
else {
|
||||
index = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 0, index, uncompressed_end, match);
|
||||
pos = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 0, pos, uncompressed_end, match);
|
||||
}
|
||||
if (enc->match_price_count >= kMatchRepriceFrequency) {
|
||||
LZMA_fillAlignPrices(enc);
|
||||
@@ -1683,20 +1683,20 @@ size_t LZMA_encodeChunkBest(LZMA2_ECtx *const enc,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (block.data[index] != block.data[index - enc->states.reps[0] - 1]) {
|
||||
LZMA_encodeLiteralBuf(enc, block.data, index);
|
||||
++index;
|
||||
if (block.data[pos] != block.data[pos - enc->states.reps[0] - 1]) {
|
||||
LZMA_encodeLiteralBuf(enc, block.data, pos);
|
||||
++pos;
|
||||
}
|
||||
else {
|
||||
LZMA_encodeRepMatchShort(enc, index & enc->pos_mask);
|
||||
++index;
|
||||
LZMA_encodeRepMatchShort(enc, pos & enc->pos_mask);
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return index;
|
||||
return pos;
|
||||
}
|
||||
|
||||
static void LZMA_lengthStates_Reset(LengthStates* const ls, unsigned const fast_length)
|
||||
static void LZMA_lengthStates_Reset(LZMA2_lenStates* const ls, unsigned const fast_length)
|
||||
{
|
||||
ls->choice = kProbInitValue;
|
||||
|
||||
@@ -1709,7 +1709,7 @@ static void LZMA_lengthStates_Reset(LengthStates* const ls, unsigned const fast_
|
||||
ls->table_size = fast_length + 1 - kMatchLenMin;
|
||||
}
|
||||
|
||||
static void LZMA_encoderStates_Reset(EncoderStates* const es, unsigned const lc, unsigned const lp, unsigned fast_length)
|
||||
static void LZMA_encoderStates_Reset(LZMA2_encStates* const es, unsigned const lc, unsigned const lp, unsigned fast_length)
|
||||
{
|
||||
es->state = 0;
|
||||
|
||||
@@ -1731,7 +1731,7 @@ static void LZMA_encoderStates_Reset(EncoderStates* const es, unsigned const lc,
|
||||
es->literal_probs[i] = kProbInitValue;
|
||||
|
||||
for (size_t i = 0; i < kNumLenToPosStates; ++i) {
|
||||
Probability *probs = es->dist_slot_encoders[i];
|
||||
LZMA2_prob *probs = es->dist_slot_encoders[i];
|
||||
for (size_t j = 0; j < (1 << kNumPosSlotBits); ++j)
|
||||
probs[j] = kProbInitValue;
|
||||
}
|
||||
@@ -1775,7 +1775,7 @@ size_t LZMA2_encMemoryUsage(unsigned const chain_log, FL2_strategy const strateg
|
||||
{
|
||||
size_t size = sizeof(LZMA2_ECtx);
|
||||
if(strategy == FL2_ultra)
|
||||
size += sizeof(HashChains) + (sizeof(U32) << chain_log) - sizeof(U32);
|
||||
size += sizeof(LZMA2_hc3) + (sizeof(U32) << chain_log) - sizeof(U32);
|
||||
return size * thread_count;
|
||||
}
|
||||
|
||||
@@ -1837,16 +1837,16 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
|
||||
|
||||
if (tbl->is_struct) {
|
||||
size_t prev_dist = 0;
|
||||
for (size_t index = start; index < end; ) {
|
||||
U32 const link = GetMatchLink(tbl->table, index);
|
||||
for (size_t pos = start; pos < end; ) {
|
||||
U32 const link = GetMatchLink(tbl->table, pos);
|
||||
if (link == RADIX_NULL_LINK) {
|
||||
++index;
|
||||
++pos;
|
||||
++count;
|
||||
prev_dist = 0;
|
||||
}
|
||||
else {
|
||||
size_t const length = GetMatchLength(tbl->table, index);
|
||||
size_t const dist = index - GetMatchLink(tbl->table, index);
|
||||
size_t const length = GetMatchLength(tbl->table, pos);
|
||||
size_t const dist = pos - GetMatchLink(tbl->table, pos);
|
||||
if (length > 4) {
|
||||
/* Increase the cost if it's not the same match */
|
||||
count += dist != prev_dist;
|
||||
@@ -1855,33 +1855,33 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
|
||||
/* Increment the cost for a short match. The cost is the entire length if it's too far */
|
||||
count += (dist < max_dist_table[strategy][length]) ? 1 : length;
|
||||
}
|
||||
index += length;
|
||||
pos += length;
|
||||
prev_dist = dist;
|
||||
}
|
||||
if (count + terminator <= index)
|
||||
if (count + terminator <= pos)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
size_t prev_dist = 0;
|
||||
for (size_t index = start; index < end; ) {
|
||||
U32 const link = tbl->table[index];
|
||||
for (size_t pos = start; pos < end; ) {
|
||||
U32 const link = tbl->table[pos];
|
||||
if (link == RADIX_NULL_LINK) {
|
||||
++index;
|
||||
++pos;
|
||||
++count;
|
||||
prev_dist = 0;
|
||||
}
|
||||
else {
|
||||
size_t const length = link >> RADIX_LINK_BITS;
|
||||
size_t const dist = index - (link & RADIX_LINK_MASK);
|
||||
size_t const dist = pos - (link & RADIX_LINK_MASK);
|
||||
if (length > 4)
|
||||
count += dist != prev_dist;
|
||||
else
|
||||
count += (dist < max_dist_table[strategy][length]) ? 1 : length;
|
||||
index += length;
|
||||
pos += length;
|
||||
prev_dist = dist;
|
||||
}
|
||||
if (count + terminator <= index)
|
||||
if (count + terminator <= pos)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1892,8 +1892,8 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
|
||||
U32 const avg = (U32)(chunk_size / 64U);
|
||||
|
||||
memset(char_count, 0, sizeof(char_count));
|
||||
for (size_t index = start; index < end; ++index)
|
||||
char_count[block.data[index]] += 4;
|
||||
for (size_t pos = start; pos < end; ++pos)
|
||||
char_count[block.data[pos]] += 4;
|
||||
/* Sum the deviations */
|
||||
for (size_t i = 0; i < 256; ++i) {
|
||||
S32 delta = char_count[i] - avg;
|
||||
@@ -1909,27 +1909,27 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
|
||||
static size_t LZMA2_encodeChunk(LZMA2_ECtx *const enc,
|
||||
FL2_matchTable* const tbl,
|
||||
FL2_dataBlock const block,
|
||||
size_t const index, size_t const uncompressed_end)
|
||||
size_t const pos, size_t const uncompressed_end)
|
||||
{
|
||||
/* Template-like inline functions */
|
||||
if (enc->strategy == FL2_fast) {
|
||||
if (tbl->is_struct) {
|
||||
return LZMA_encodeChunkFast(enc, block, tbl, 1,
|
||||
index, uncompressed_end);
|
||||
pos, uncompressed_end);
|
||||
}
|
||||
else {
|
||||
return LZMA_encodeChunkFast(enc, block, tbl, 0,
|
||||
index, uncompressed_end);
|
||||
pos, uncompressed_end);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tbl->is_struct) {
|
||||
return LZMA_encodeChunkBest(enc, block, tbl, 1,
|
||||
index, uncompressed_end);
|
||||
pos, uncompressed_end);
|
||||
}
|
||||
else {
|
||||
return LZMA_encodeChunkBest(enc, block, tbl, 0,
|
||||
index, uncompressed_end);
|
||||
pos, uncompressed_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1987,28 +1987,28 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
|
||||
/* Limit the matches near the end of this slice to not exceed block.end */
|
||||
RMF_limitLengths(tbl, block.end);
|
||||
|
||||
for (size_t index = start; index < block.end;) {
|
||||
for (size_t pos = start; pos < block.end;) {
|
||||
size_t header_size = (stream_prop >= 0) + (encode_properties ? kChunkHeaderSize + 1 : kChunkHeaderSize);
|
||||
EncoderStates saved_states;
|
||||
LZMA2_encStates saved_states;
|
||||
size_t next_index;
|
||||
|
||||
RC_reset(&enc->rc);
|
||||
RC_setOutputBuffer(&enc->rc, out_dest + header_size);
|
||||
|
||||
if (!incompressible) {
|
||||
size_t cur = index;
|
||||
size_t const end = (enc->strategy == FL2_fast) ? MIN(block.end, index + kMaxChunkUncompressedSize - kMatchLenMax + 1)
|
||||
: MIN(block.end, index + kMaxChunkUncompressedSize - kOptimizerBufferSize + 2); /* last byte of opt_buf unused */
|
||||
size_t cur = pos;
|
||||
size_t const end = (enc->strategy == FL2_fast) ? MIN(block.end, pos + kMaxChunkUncompressedSize - kMatchLenMax + 1)
|
||||
: MIN(block.end, pos + kMaxChunkUncompressedSize - kOptimizerBufferSize + 2); /* last byte of opt_buf unused */
|
||||
|
||||
/* Copy states in case chunk is incompressible */
|
||||
saved_states = enc->states;
|
||||
|
||||
if (index == 0) {
|
||||
if (pos == 0) {
|
||||
/* First byte of the dictionary */
|
||||
LZMA_encodeLiteral(enc, 0, block.data[0], 0);
|
||||
++cur;
|
||||
}
|
||||
if (index == start) {
|
||||
if (pos == start) {
|
||||
/* After kTempMinOutput bytes we can write data to the match table because the */
|
||||
/* compressed data will never catch up with the table position being read. */
|
||||
cur = LZMA2_encodeChunk(enc, tbl, block, cur, end);
|
||||
@@ -2029,10 +2029,10 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
|
||||
RC_flush(&enc->rc);
|
||||
}
|
||||
else {
|
||||
next_index = MIN(index + kChunkSize, block.end);
|
||||
next_index = MIN(pos + kChunkSize, block.end);
|
||||
}
|
||||
size_t compressed_size = enc->rc.out_index;
|
||||
size_t uncompressed_size = next_index - index;
|
||||
size_t uncompressed_size = next_index - pos;
|
||||
|
||||
if (compressed_size > kMaxChunkCompressedSize || uncompressed_size > kMaxChunkUncompressedSize)
|
||||
return FL2_ERROR(internal);
|
||||
@@ -2050,10 +2050,10 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
|
||||
if (incompressible || uncompressed_size + 3 <= compressed_size + header_size) {
|
||||
DEBUGLOG(6, "Storing chunk : was %u => %u", (unsigned)uncompressed_size, (unsigned)compressed_size);
|
||||
|
||||
header[0] = (index == 0) ? kChunkUncompressedDictReset : kChunkUncompressed;
|
||||
header[0] = (pos == 0) ? kChunkUncompressedDictReset : kChunkUncompressed;
|
||||
|
||||
/* Copy uncompressed data into the output */
|
||||
memcpy(header + 3, block.data + index, uncompressed_size);
|
||||
memcpy(header + 3, block.data + pos, uncompressed_size);
|
||||
|
||||
compressed_size = uncompressed_size;
|
||||
header_size = 3 + (header - out_dest);
|
||||
@@ -2065,7 +2065,7 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
|
||||
else {
|
||||
DEBUGLOG(6, "Compressed chunk : %u => %u", (unsigned)uncompressed_size, (unsigned)compressed_size);
|
||||
|
||||
if (index == 0)
|
||||
if (pos == 0)
|
||||
header[0] = kChunkCompressedFlag | kChunkAllReset;
|
||||
else if (encode_properties)
|
||||
header[0] = kChunkCompressedFlag | kChunkStatePropertiesReset;
|
||||
@@ -2087,10 +2087,10 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
|
||||
out_dest += compressed_size + header_size;
|
||||
|
||||
/* Update progress concurrently with other encoder threads */
|
||||
FL2_atomic_add(*progress_in, (long)(next_index - index));
|
||||
FL2_atomic_add(*progress_in, (long)(next_index - pos));
|
||||
FL2_atomic_add(*progress_out, (long)(compressed_size + header_size));
|
||||
|
||||
index = next_index;
|
||||
pos = next_index;
|
||||
|
||||
if (*canceled)
|
||||
return FL2_ERROR(canceled);
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "fl2_internal.h"
|
||||
#include "radix_internal.h"
|
||||
|
||||
typedef struct FL2_matchTable_s FL2_matchTable;
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
@@ -22,38 +20,38 @@ typedef struct FL2_matchTable_s FL2_matchTable;
|
||||
|
||||
#define RADIX_MAX_LENGTH BITPACK_MAX_LENGTH
|
||||
|
||||
#define InitMatchLink(index, link) tbl->table[index] = link
|
||||
#define InitMatchLink(pos, link) tbl->table[pos] = link
|
||||
|
||||
#define GetMatchLink(link) (tbl->table[link] & RADIX_LINK_MASK)
|
||||
|
||||
#define GetInitialMatchLink(index) tbl->table[index]
|
||||
#define GetInitialMatchLink(pos) tbl->table[pos]
|
||||
|
||||
#define GetMatchLength(index) (tbl->table[index] >> RADIX_LINK_BITS)
|
||||
#define GetMatchLength(pos) (tbl->table[pos] >> RADIX_LINK_BITS)
|
||||
|
||||
#define SetMatchLink(index, link, length) tbl->table[index] = (link) | ((U32)(length) << RADIX_LINK_BITS)
|
||||
#define SetMatchLink(pos, link, length) tbl->table[pos] = (link) | ((U32)(length) << RADIX_LINK_BITS)
|
||||
|
||||
#define SetMatchLength(index, link, length) tbl->table[index] = (link) | ((U32)(length) << RADIX_LINK_BITS)
|
||||
#define SetMatchLength(pos, link, length) tbl->table[pos] = (link) | ((U32)(length) << RADIX_LINK_BITS)
|
||||
|
||||
#define SetMatchLinkAndLength(index, link, length) tbl->table[index] = (link) | ((U32)(length) << RADIX_LINK_BITS)
|
||||
#define SetMatchLinkAndLength(pos, link, length) tbl->table[pos] = (link) | ((U32)(length) << RADIX_LINK_BITS)
|
||||
|
||||
#define SetNull(index) tbl->table[index] = RADIX_NULL_LINK
|
||||
#define SetNull(pos) tbl->table[pos] = RADIX_NULL_LINK
|
||||
|
||||
#define IsNull(index) (tbl->table[index] == RADIX_NULL_LINK)
|
||||
#define IsNull(pos) (tbl->table[pos] == RADIX_NULL_LINK)
|
||||
|
||||
BYTE* RMF_bitpackAsOutputBuffer(FL2_matchTable* const tbl, size_t const index)
|
||||
BYTE* RMF_bitpackAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos)
|
||||
{
|
||||
return (BYTE*)(tbl->table + index);
|
||||
return (BYTE*)(tbl->table + pos);
|
||||
}
|
||||
|
||||
/* Restrict the match lengths so that they don't reach beyond index */
|
||||
void RMF_bitpackLimitLengths(FL2_matchTable* const tbl, size_t const index)
|
||||
/* Restrict the match lengths so that they don't reach beyond pos */
|
||||
void RMF_bitpackLimitLengths(FL2_matchTable* const tbl, size_t const pos)
|
||||
{
|
||||
DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)index, RADIX_MAX_LENGTH);
|
||||
SetNull(index - 1);
|
||||
for (U32 length = 2; length < RADIX_MAX_LENGTH && length <= index; ++length) {
|
||||
U32 const link = tbl->table[index - length];
|
||||
DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)pos, RADIX_MAX_LENGTH);
|
||||
SetNull(pos - 1);
|
||||
for (U32 length = 2; length < RADIX_MAX_LENGTH && length <= pos; ++length) {
|
||||
U32 const link = tbl->table[pos - length];
|
||||
if (link != RADIX_NULL_LINK)
|
||||
tbl->table[index - length] = (MIN(length, link >> RADIX_LINK_BITS) << RADIX_LINK_BITS) | (link & RADIX_LINK_MASK);
|
||||
tbl->table[pos - length] = (MIN(length, link >> RADIX_LINK_BITS) << RADIX_LINK_BITS) | (link & RADIX_LINK_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ static void RMF_initReference(FL2_matchTable* const tbl, const void* const data,
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t
|
||||
void
|
||||
#ifdef RMF_BITPACK
|
||||
RMF_bitpackInit
|
||||
#else
|
||||
@@ -115,12 +115,12 @@ RMF_structuredInit
|
||||
for (size_t i = 0; i < end; ++i)
|
||||
SetNull(i);
|
||||
tbl->end_index = 0;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
#ifdef RMF_REFERENCE
|
||||
if (tbl->params.use_ref_mf) {
|
||||
RMF_initReference(tbl, data, end);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -136,7 +136,6 @@ RMF_structuredInit
|
||||
|
||||
radix_16 = ((size_t)((BYTE)radix_16) << 8) | data_block[2];
|
||||
|
||||
ptrdiff_t rpt_total = 0;
|
||||
ptrdiff_t i = 1;
|
||||
ptrdiff_t const block_size = end - 2;
|
||||
for (; i < block_size; ++i) {
|
||||
@@ -170,8 +169,6 @@ RMF_structuredInit
|
||||
SetNull(end - 1);
|
||||
|
||||
tbl->end_index = (U32)st_index;
|
||||
|
||||
return rpt_total;
|
||||
}
|
||||
|
||||
/* Copy the list into a buffer and recurse it there. This decreases cache misses and allows */
|
||||
@@ -264,23 +261,23 @@ static void RMF_recurseListsBuffered(RMF_builder* const tbl,
|
||||
/* Copy everything back, except the last link which never changes, and any extra overlap */
|
||||
count -= overlap + (overlap == 0);
|
||||
#ifdef RMF_BITPACK
|
||||
if (max_depth > RADIX_MAX_LENGTH) for (size_t index = 0; index < count; ++index) {
|
||||
size_t const from = tbl->match_buffer[index].from;
|
||||
if (max_depth > RADIX_MAX_LENGTH) for (size_t pos = 0; pos < count; ++pos) {
|
||||
size_t const from = tbl->match_buffer[pos].from;
|
||||
if (from < block_start)
|
||||
return;
|
||||
U32 length = tbl->match_buffer[index].next >> 24;
|
||||
U32 length = tbl->match_buffer[pos].next >> 24;
|
||||
length = (length > RADIX_MAX_LENGTH) ? RADIX_MAX_LENGTH : length;
|
||||
size_t const next = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
size_t const next = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
for (size_t index = 0; index < count; ++index) {
|
||||
size_t const from = tbl->match_buffer[index].from;
|
||||
for (size_t pos = 0; pos < count; ++pos) {
|
||||
size_t const from = tbl->match_buffer[pos].from;
|
||||
if (from < block_start)
|
||||
return;
|
||||
U32 const length = tbl->match_buffer[index].next >> 24;
|
||||
size_t const next = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
U32 const length = tbl->match_buffer[pos].next >> 24;
|
||||
size_t const next = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length);
|
||||
}
|
||||
start = 0;
|
||||
@@ -338,32 +335,32 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
|
||||
/* Create an offset data buffer pointer for reading the next bytes */
|
||||
const BYTE* data_src = data_block + 2;
|
||||
U32 depth = 3;
|
||||
size_t index = 0;
|
||||
size_t pos = 0;
|
||||
size_t st_index = 0;
|
||||
RMF_listTail* const tails_8 = tbl->tails_8;
|
||||
do {
|
||||
link = tbl->match_buffer[index].from;
|
||||
link = tbl->match_buffer[pos].from;
|
||||
if (link < limit) {
|
||||
size_t const radix_8 = data_src[link];
|
||||
/* Seen this char before? */
|
||||
U32 const prev = tails_8[radix_8].prev_index;
|
||||
tails_8[radix_8].prev_index = (U32)index;
|
||||
tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
++tails_8[radix_8].list_count;
|
||||
/* Link the previous occurrence to this one and record the new length */
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
tails_8[radix_8].list_count = 1;
|
||||
/* Add the new sub list to the stack */
|
||||
tbl->stack[st_index].head = (U32)index;
|
||||
tbl->stack[st_index].head = (U32)pos;
|
||||
/* This will be converted to a count at the end */
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
}
|
||||
++index;
|
||||
} while (index < list_count);
|
||||
++pos;
|
||||
} while (pos < list_count);
|
||||
/* Convert radix values on the stack to counts and reset any used tail slots */
|
||||
for (size_t j = 0; j < st_index; ++j) {
|
||||
tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
|
||||
@@ -378,11 +375,11 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
|
||||
if (list_count < 2) /* Nothing to match with */
|
||||
continue;
|
||||
|
||||
index = tbl->stack[st_index].head;
|
||||
depth = (tbl->match_buffer[index].next >> 24);
|
||||
pos = tbl->stack[st_index].head;
|
||||
depth = (tbl->match_buffer[pos].next >> 24);
|
||||
if (depth >= max_depth)
|
||||
continue;
|
||||
link = tbl->match_buffer[index].from;
|
||||
link = tbl->match_buffer[pos].from;
|
||||
if (link < bounded_start) {
|
||||
/* Chain starts before the bounded region */
|
||||
continue;
|
||||
@@ -392,23 +389,23 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
|
||||
++depth;
|
||||
prev_st_index = st_index;
|
||||
do {
|
||||
link = tbl->match_buffer[index].from;
|
||||
link = tbl->match_buffer[pos].from;
|
||||
if (link < limit) {
|
||||
size_t const radix_8 = data_src[link];
|
||||
U32 const prev = tails_8[radix_8].prev_index;
|
||||
tails_8[radix_8].prev_index = (U32)index;
|
||||
tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
++tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
tails_8[radix_8].list_count = 1;
|
||||
tbl->stack[st_index].head = (U32)index;
|
||||
tbl->stack[st_index].head = (U32)pos;
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
}
|
||||
index = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
pos = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
} while (--list_count != 0);
|
||||
for (size_t j = prev_st_index; j < st_index; ++j) {
|
||||
tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
|
||||
@@ -417,16 +414,16 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
|
||||
}
|
||||
/* Copy everything back above the bound */
|
||||
--count;
|
||||
for (index = 0; index < count; ++index) {
|
||||
ptrdiff_t const from = tbl->match_buffer[index].from;
|
||||
for (pos = 0; pos < count; ++pos) {
|
||||
ptrdiff_t const from = tbl->match_buffer[pos].from;
|
||||
if (from < bounded_start)
|
||||
break;
|
||||
|
||||
U32 length = tbl->match_buffer[index].next >> 24;
|
||||
U32 length = tbl->match_buffer[pos].next >> 24;
|
||||
length = MIN(length, (U32)(block_size - from));
|
||||
length = MIN(length, RADIX_MAX_LENGTH);
|
||||
|
||||
size_t const next = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
size_t const next = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length);
|
||||
}
|
||||
}
|
||||
@@ -901,9 +898,9 @@ static void RMF_recurseListsReference(RMF_builder* const tbl,
|
||||
static ptrdiff_t RMF_getNextList_mt(FL2_matchTable* const tbl)
|
||||
{
|
||||
if (tbl->st_index < tbl->end_index) {
|
||||
long index = FL2_atomic_increment(tbl->st_index);
|
||||
if (index < tbl->end_index)
|
||||
return index;
|
||||
long pos = FL2_atomic_increment(tbl->st_index);
|
||||
if (pos < tbl->end_index)
|
||||
return pos;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -912,9 +909,9 @@ static ptrdiff_t RMF_getNextList_mt(FL2_matchTable* const tbl)
|
||||
static ptrdiff_t RMF_getNextList_st(FL2_matchTable* const tbl)
|
||||
{
|
||||
if (tbl->st_index < tbl->end_index) {
|
||||
long index = FL2_nonAtomic_increment(tbl->st_index);
|
||||
if (index < tbl->end_index)
|
||||
return index;
|
||||
long pos = FL2_nonAtomic_increment(tbl->st_index);
|
||||
if (pos < tbl->end_index)
|
||||
return pos;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -927,7 +924,7 @@ RMF_bitpackBuildTable
|
||||
RMF_structuredBuildTable
|
||||
#endif
|
||||
(FL2_matchTable* const tbl,
|
||||
size_t const job,
|
||||
size_t const job,
|
||||
unsigned const multi_thread,
|
||||
FL2_dataBlock const block)
|
||||
{
|
||||
@@ -945,19 +942,19 @@ RMF_structuredBuildTable
|
||||
for (;;)
|
||||
{
|
||||
/* Get the next to process */
|
||||
ptrdiff_t index = getNextList(tbl);
|
||||
ptrdiff_t pos = getNextList(tbl);
|
||||
|
||||
if (index < 0)
|
||||
if (pos < 0)
|
||||
break;
|
||||
|
||||
while (next_progress < index) {
|
||||
while (next_progress < pos) {
|
||||
/* initial value of next_progress ensures only thread 0 executes this */
|
||||
tbl->progress += tbl->list_heads[tbl->stack[next_progress]].count;
|
||||
++next_progress;
|
||||
}
|
||||
index = tbl->stack[index];
|
||||
RMF_tableHead list_head = tbl->list_heads[index];
|
||||
tbl->list_heads[index].head = RADIX_NULL_LINK;
|
||||
pos = tbl->stack[pos];
|
||||
RMF_tableHead list_head = tbl->list_heads[pos];
|
||||
tbl->list_heads[pos].head = RADIX_NULL_LINK;
|
||||
if (list_head.count < 2 || list_head.head < block.start)
|
||||
continue;
|
||||
|
||||
@@ -989,33 +986,33 @@ RMF_bitpackIntegrityCheck
|
||||
#else
|
||||
RMF_structuredIntegrityCheck
|
||||
#endif
|
||||
(const FL2_matchTable* const tbl, const BYTE* const data, size_t index, size_t const end, unsigned max_depth)
|
||||
(const FL2_matchTable* const tbl, const BYTE* const data, size_t pos, size_t const end, unsigned max_depth)
|
||||
{
|
||||
max_depth &= ~1;
|
||||
int err = 0;
|
||||
for (index += !index; index < end; ++index) {
|
||||
if (IsNull(index))
|
||||
for (pos += !pos; pos < end; ++pos) {
|
||||
if (IsNull(pos))
|
||||
continue;
|
||||
U32 const link = GetMatchLink(index);
|
||||
if (link >= index) {
|
||||
printf("Forward link at %X to %u\r\n", (U32)index, link);
|
||||
U32 const link = GetMatchLink(pos);
|
||||
if (link >= pos) {
|
||||
printf("Forward link at %X to %u\r\n", (U32)pos, link);
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
U32 const length = GetMatchLength(index);
|
||||
if (index && length < RADIX_MAX_LENGTH && link - 1 == GetMatchLink(index - 1) && length + 1 == GetMatchLength(index - 1))
|
||||
U32 const length = GetMatchLength(pos);
|
||||
if (pos && length < RADIX_MAX_LENGTH && link - 1 == GetMatchLink(pos - 1) && length + 1 == GetMatchLength(pos - 1))
|
||||
continue;
|
||||
U32 len_test = 0;
|
||||
U32 const limit = MIN((U32)(end - index), RADIX_MAX_LENGTH);
|
||||
for (; len_test < limit && data[link + len_test] == data[index + len_test]; ++len_test) {
|
||||
U32 const limit = MIN((U32)(end - pos), RADIX_MAX_LENGTH);
|
||||
for (; len_test < limit && data[link + len_test] == data[pos + len_test]; ++len_test) {
|
||||
}
|
||||
if (len_test < length) {
|
||||
printf("Failed integrity check: pos %X, length %u, actual %u\r\n", (U32)index, length, len_test);
|
||||
printf("Failed integrity check: pos %X, length %u, actual %u\r\n", (U32)pos, length, len_test);
|
||||
err = 1;
|
||||
}
|
||||
if (length < max_depth && len_test > length)
|
||||
/* These occur occasionally due to splitting of chains in the buffer when long repeats are present */
|
||||
printf("Shortened match at %X: %u of %u\r\n", (U32)index, length, len_test);
|
||||
printf("Shortened match at %X: %u of %u\r\n", (U32)pos, length, len_test);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -49,9 +49,9 @@ static size_t RMF_bitpackExtendMatch(const BYTE* const data,
|
||||
return end_index - start_index;
|
||||
}
|
||||
|
||||
#define GetMatchLink(table, index) ((const RMF_unit*)(table))[(index) >> UNIT_BITS].links[(index) & UNIT_MASK]
|
||||
#define GetMatchLink(table, pos) ((const RMF_unit*)(table))[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK]
|
||||
|
||||
#define GetMatchLength(table, index) ((const RMF_unit*)(table))[(index) >> UNIT_BITS].lengths[(index) & UNIT_MASK]
|
||||
#define GetMatchLength(table, pos) ((const RMF_unit*)(table))[(pos) >> UNIT_BITS].lengths[(pos) & UNIT_MASK]
|
||||
|
||||
static size_t RMF_structuredExtendMatch(const BYTE* const data,
|
||||
const U32* const table,
|
||||
@@ -86,11 +86,11 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
|
||||
FL2_matchTable* tbl,
|
||||
unsigned max_depth,
|
||||
int structTbl,
|
||||
size_t index)
|
||||
size_t pos)
|
||||
{
|
||||
if (structTbl)
|
||||
{
|
||||
U32 const link = GetMatchLink(tbl->table, index);
|
||||
U32 const link = GetMatchLink(tbl->table, pos);
|
||||
|
||||
RMF_match match;
|
||||
match.length = 0;
|
||||
@@ -98,11 +98,11 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
|
||||
if (link == RADIX_NULL_LINK)
|
||||
return match;
|
||||
|
||||
size_t const length = GetMatchLength(tbl->table, index);
|
||||
size_t const dist = index - link - 1;
|
||||
size_t const length = GetMatchLength(tbl->table, pos);
|
||||
size_t const dist = pos - link - 1;
|
||||
|
||||
if (length == max_depth || length == STRUCTURED_MAX_LENGTH /* from HandleRepeat */)
|
||||
match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, index, block.end, link, length);
|
||||
match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, pos, block.end, link, length);
|
||||
else
|
||||
match.length = (U32)length;
|
||||
|
||||
@@ -111,7 +111,7 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
|
||||
return match;
|
||||
}
|
||||
else {
|
||||
U32 link = tbl->table[index];
|
||||
U32 link = tbl->table[pos];
|
||||
|
||||
RMF_match match;
|
||||
match.length = 0;
|
||||
@@ -121,10 +121,10 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
|
||||
|
||||
size_t const length = link >> RADIX_LINK_BITS;
|
||||
link &= RADIX_LINK_MASK;
|
||||
size_t const dist = index - link - 1;
|
||||
size_t const dist = pos - link - 1;
|
||||
|
||||
if (length == max_depth || length == BITPACK_MAX_LENGTH /* from HandleRepeat */)
|
||||
match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, index, block.end, link, length);
|
||||
match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, pos, block.end, link, length);
|
||||
else
|
||||
match.length = (U32)length;
|
||||
|
||||
@@ -139,11 +139,11 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
|
||||
FL2_matchTable* tbl,
|
||||
unsigned max_depth,
|
||||
int structTbl,
|
||||
size_t index)
|
||||
size_t pos)
|
||||
{
|
||||
if (structTbl)
|
||||
{
|
||||
U32 const link = GetMatchLink(tbl->table, index);
|
||||
U32 const link = GetMatchLink(tbl->table, pos);
|
||||
|
||||
RMF_match match;
|
||||
match.length = 0;
|
||||
@@ -151,15 +151,15 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
|
||||
if (link == RADIX_NULL_LINK)
|
||||
return match;
|
||||
|
||||
size_t const length = GetMatchLength(tbl->table, index);
|
||||
size_t const dist = index - link - 1;
|
||||
size_t const length = GetMatchLength(tbl->table, pos);
|
||||
size_t const dist = pos - link - 1;
|
||||
|
||||
/* same distance, one byte shorter */
|
||||
if (link - 1 == GetMatchLink(tbl->table, index - 1))
|
||||
if (link - 1 == GetMatchLink(tbl->table, pos - 1))
|
||||
return match;
|
||||
|
||||
if (length == max_depth || length == STRUCTURED_MAX_LENGTH /* from HandleRepeat */)
|
||||
match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, index, block.end, link, length);
|
||||
match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, pos, block.end, link, length);
|
||||
else
|
||||
match.length = (U32)length;
|
||||
|
||||
@@ -168,7 +168,7 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
|
||||
return match;
|
||||
}
|
||||
else {
|
||||
U32 link = tbl->table[index];
|
||||
U32 link = tbl->table[pos];
|
||||
|
||||
RMF_match match;
|
||||
match.length = 0;
|
||||
@@ -178,14 +178,14 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
|
||||
|
||||
size_t const length = link >> RADIX_LINK_BITS;
|
||||
link &= RADIX_LINK_MASK;
|
||||
size_t const dist = index - link - 1;
|
||||
size_t const dist = pos - link - 1;
|
||||
|
||||
/* same distance, one byte shorter */
|
||||
if (link - 1 == (tbl->table[index - 1] & RADIX_LINK_MASK))
|
||||
if (link - 1 == (tbl->table[pos - 1] & RADIX_LINK_MASK))
|
||||
return match;
|
||||
|
||||
if (length == max_depth || length == BITPACK_MAX_LENGTH /* from HandleRepeat */)
|
||||
match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, index, block.end, link, length);
|
||||
match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, pos, block.end, link, length);
|
||||
else
|
||||
match.length = (U32)length;
|
||||
|
||||
|
||||
@@ -54,14 +54,14 @@ typedef struct
|
||||
} RMF_tableHead;
|
||||
|
||||
union src_data_u {
|
||||
BYTE chars[4];
|
||||
U32 u32;
|
||||
BYTE chars[4];
|
||||
U32 u32;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U32 from;
|
||||
union src_data_u src;
|
||||
union src_data_u src;
|
||||
U32 next;
|
||||
} RMF_buildMatch;
|
||||
|
||||
@@ -105,14 +105,14 @@ struct FL2_matchTable_s
|
||||
U32 table[1];
|
||||
};
|
||||
|
||||
size_t RMF_bitpackInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end);
|
||||
size_t RMF_structuredInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end);
|
||||
void RMF_bitpackInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end);
|
||||
void RMF_structuredInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end);
|
||||
void RMF_bitpackBuildTable(struct FL2_matchTable_s* const tbl,
|
||||
size_t const job,
|
||||
size_t const job,
|
||||
unsigned const multi_thread,
|
||||
FL2_dataBlock const block);
|
||||
void RMF_structuredBuildTable(struct FL2_matchTable_s* const tbl,
|
||||
size_t const job,
|
||||
size_t const job,
|
||||
unsigned const multi_thread,
|
||||
FL2_dataBlock const block);
|
||||
void RMF_recurseListChunk(RMF_builder* const tbl,
|
||||
@@ -122,21 +122,21 @@ void RMF_recurseListChunk(RMF_builder* const tbl,
|
||||
U32 const max_depth,
|
||||
U32 const list_count,
|
||||
size_t const stack_base);
|
||||
int RMF_bitpackIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t index, size_t const end, unsigned max_depth);
|
||||
int RMF_structuredIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t index, size_t const end, unsigned max_depth);
|
||||
void RMF_bitpackLimitLengths(struct FL2_matchTable_s* const tbl, size_t const index);
|
||||
void RMF_structuredLimitLengths(struct FL2_matchTable_s* const tbl, size_t const index);
|
||||
BYTE* RMF_bitpackAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const index);
|
||||
BYTE* RMF_structuredAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const index);
|
||||
int RMF_bitpackIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t pos, size_t const end, unsigned max_depth);
|
||||
int RMF_structuredIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t pos, size_t const end, unsigned max_depth);
|
||||
void RMF_bitpackLimitLengths(struct FL2_matchTable_s* const tbl, size_t const pos);
|
||||
void RMF_structuredLimitLengths(struct FL2_matchTable_s* const tbl, size_t const pos);
|
||||
BYTE* RMF_bitpackAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const pos);
|
||||
BYTE* RMF_structuredAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const pos);
|
||||
size_t RMF_bitpackGetMatch(const struct FL2_matchTable_s* const tbl,
|
||||
const BYTE* const data,
|
||||
size_t const index,
|
||||
size_t const pos,
|
||||
size_t const limit,
|
||||
unsigned const max_depth,
|
||||
size_t* const offset_ptr);
|
||||
size_t RMF_structuredGetMatch(const struct FL2_matchTable_s* const tbl,
|
||||
const BYTE* const data,
|
||||
size_t const index,
|
||||
size_t const pos,
|
||||
size_t const limit,
|
||||
unsigned const max_depth,
|
||||
size_t* const offset_ptr);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "fl2_internal.h"
|
||||
#include "radix_internal.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" /* warning: 'rpt_head_next' may be used uninitialized in this function */
|
||||
#elif defined(_MSC_VER)
|
||||
# pragma warning(disable : 4701) /* warning: 'rpt_head_next' may be used uninitialized in this function */
|
||||
@@ -274,16 +274,16 @@ void RMF_initProgress(FL2_matchTable * const tbl)
|
||||
tbl->progress = 0;
|
||||
}
|
||||
|
||||
size_t RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end)
|
||||
void RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end)
|
||||
{
|
||||
DEBUGLOG(5, "RMF_initTable : size %u", (U32)end);
|
||||
|
||||
tbl->st_index = ATOMIC_INITIAL_VALUE;
|
||||
|
||||
if (tbl->is_struct)
|
||||
return RMF_structuredInit(tbl, data, end);
|
||||
RMF_structuredInit(tbl, data, end);
|
||||
else
|
||||
return RMF_bitpackInit(tbl, data, end);
|
||||
RMF_bitpackInit(tbl, data, end);
|
||||
}
|
||||
|
||||
static void RMF_handleRepeat(RMF_buildMatch* const match_buffer,
|
||||
@@ -294,31 +294,31 @@ static void RMF_handleRepeat(RMF_buildMatch* const match_buffer,
|
||||
U32 const depth,
|
||||
U32 const max_len)
|
||||
{
|
||||
size_t index = next;
|
||||
size_t pos = next;
|
||||
U32 length = depth + rpt_len;
|
||||
|
||||
const BYTE* const data = data_block + match_buffer[index].from;
|
||||
const BYTE* const data = data_block + match_buffer[pos].from;
|
||||
const BYTE* const data_2 = data - rpt_len;
|
||||
|
||||
while (data[length] == data_2[length] && length < max_len)
|
||||
++length;
|
||||
|
||||
for (; length <= max_len && count; --count) {
|
||||
size_t next_i = match_buffer[index].next & 0xFFFFFF;
|
||||
match_buffer[index].next = (U32)next_i | (length << 24);
|
||||
size_t next_i = match_buffer[pos].next & 0xFFFFFF;
|
||||
match_buffer[pos].next = (U32)next_i | (length << 24);
|
||||
length += rpt_len;
|
||||
index = next_i;
|
||||
pos = next_i;
|
||||
}
|
||||
for (; count; --count) {
|
||||
size_t next_i = match_buffer[index].next & 0xFFFFFF;
|
||||
match_buffer[index].next = (U32)next_i | (max_len << 24);
|
||||
index = next_i;
|
||||
size_t next_i = match_buffer[pos].next & 0xFFFFFF;
|
||||
match_buffer[pos].next = (U32)next_i | (max_len << 24);
|
||||
pos = next_i;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t index;
|
||||
size_t pos;
|
||||
const BYTE* data_src;
|
||||
union src_data_u src;
|
||||
} BruteForceMatch;
|
||||
@@ -326,7 +326,7 @@ typedef struct
|
||||
static void RMF_bruteForceBuffered(RMF_builder* const tbl,
|
||||
const BYTE* const data_block,
|
||||
size_t const block_start,
|
||||
size_t index,
|
||||
size_t pos,
|
||||
size_t const list_count,
|
||||
size_t const slot,
|
||||
size_t const depth,
|
||||
@@ -339,14 +339,14 @@ static void RMF_bruteForceBuffered(RMF_builder* const tbl,
|
||||
size_t i = 0;
|
||||
for (;;) {
|
||||
/* Load all locations from the match buffer */
|
||||
buffer[i].index = index;
|
||||
buffer[i].data_src = data_src + tbl->match_buffer[index].from;
|
||||
buffer[i].src.u32 = tbl->match_buffer[index].src.u32;
|
||||
buffer[i].pos = pos;
|
||||
buffer[i].data_src = data_src + tbl->match_buffer[pos].from;
|
||||
buffer[i].src.u32 = tbl->match_buffer[pos].src.u32;
|
||||
|
||||
if (++i >= list_count)
|
||||
break;
|
||||
|
||||
index = tbl->match_buffer[index].next & 0xFFFFFF;
|
||||
pos = tbl->match_buffer[pos].next & 0xFFFFFF;
|
||||
}
|
||||
i = 0;
|
||||
do {
|
||||
@@ -376,8 +376,8 @@ static void RMF_bruteForceBuffered(RMF_builder* const tbl,
|
||||
} while (++j < list_count);
|
||||
if (longest > 0) {
|
||||
/* If the existing match was extended, store the new link and length info in the match buffer */
|
||||
index = buffer[i].index;
|
||||
tbl->match_buffer[index].next = (U32)(buffer[longest_index].index | ((depth + longest) << 24));
|
||||
pos = buffer[i].pos;
|
||||
tbl->match_buffer[pos].next = (U32)(buffer[longest_index].pos | ((depth + longest) << 24));
|
||||
}
|
||||
++i;
|
||||
} while (i < list_count - 1 && buffer[i].data_src >= start);
|
||||
@@ -397,38 +397,38 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
{
|
||||
U32 const base_depth = depth;
|
||||
size_t st_index = stack_base;
|
||||
size_t index = 0;
|
||||
size_t pos = 0;
|
||||
++depth;
|
||||
/* The last element is done separately and won't be copied back at the end */
|
||||
--list_count;
|
||||
do {
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[0];
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[0];
|
||||
/* Seen this char before? */
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
/* Link the previous occurrence to this one and record the new length */
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
tbl->tails_8[radix_8].list_count = 1;
|
||||
/* Add the new sub list to the stack */
|
||||
tbl->stack[st_index].head = (U32)index;
|
||||
tbl->stack[st_index].head = (U32)pos;
|
||||
/* This will be converted to a count at the end */
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
++index;
|
||||
} while (index < list_count);
|
||||
++pos;
|
||||
} while (pos < list_count);
|
||||
|
||||
{ /* Do the last element */
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[0];
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[0];
|
||||
/* Nothing to do if there was no previous */
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
}
|
||||
/* Convert radix values on the stack to counts and reset any used tail slots */
|
||||
@@ -444,8 +444,8 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
/* Nothing to match with */
|
||||
continue;
|
||||
}
|
||||
index = tbl->stack[st_index].head;
|
||||
size_t link = tbl->match_buffer[index].from;
|
||||
pos = tbl->stack[st_index].head;
|
||||
size_t link = tbl->match_buffer[pos].from;
|
||||
if (link < block_start) {
|
||||
/* Chain starts in the overlap region which is already encoded */
|
||||
continue;
|
||||
@@ -457,7 +457,7 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
/* Stack may not be able to fit all possible new items. This is very rare. */
|
||||
continue;
|
||||
}
|
||||
depth = tbl->match_buffer[index].next >> 24;
|
||||
depth = tbl->match_buffer[pos].next >> 24;
|
||||
/* Index into the 4-byte pre-loaded input char cache */
|
||||
size_t slot = (depth - base_depth) & 3;
|
||||
if (list_count <= MAX_BRUTE_FORCE_LIST_SIZE) {
|
||||
@@ -465,7 +465,7 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
RMF_bruteForceBuffered(tbl,
|
||||
data_block,
|
||||
block_start,
|
||||
index,
|
||||
pos,
|
||||
list_count,
|
||||
slot,
|
||||
depth,
|
||||
@@ -486,59 +486,59 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
--list_count;
|
||||
/* If slot is 3 then chars need to be loaded. */
|
||||
if (slot == 3 && max_depth != 6) do {
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[3];
|
||||
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[3];
|
||||
size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
/* Pre-load the next link and data bytes. On some hardware execution can continue
|
||||
* ahead while the data is retrieved if no operations except move are done on the data. */
|
||||
tbl->match_buffer[index].src.u32 = MEM_read32(data_src + link);
|
||||
tbl->match_buffer[pos].src.u32 = MEM_read32(data_src + link);
|
||||
size_t const next_link = tbl->match_buffer[next_index].from;
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
/* This char has occurred before in the chain. Link the previous (> index) occurance with this */
|
||||
/* This char has occurred before in the chain. Link the previous (> pos) occurance with this */
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
/* First occurrence in the chain */
|
||||
tbl->tails_8[radix_8].list_count = 1;
|
||||
tbl->stack[st_index].head = (U32)index;
|
||||
tbl->stack[st_index].head = (U32)pos;
|
||||
/* Save the char as a reference to load the count at the end */
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
index = next_index;
|
||||
pos = next_index;
|
||||
link = next_link;
|
||||
} while (--list_count != 0);
|
||||
else do {
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot];
|
||||
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
|
||||
size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
/* Pre-load the next link to avoid waiting for RAM access */
|
||||
size_t const next_link = tbl->match_buffer[next_index].from;
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
tbl->tails_8[radix_8].list_count = 1;
|
||||
tbl->stack[st_index].head = (U32)index;
|
||||
tbl->stack[st_index].head = (U32)pos;
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
index = next_index;
|
||||
pos = next_index;
|
||||
link = next_link;
|
||||
} while (--list_count != 0);
|
||||
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot];
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
if (slot == 3)
|
||||
tbl->match_buffer[index].src.u32 = MEM_read32(data_src + link);
|
||||
tbl->match_buffer[pos].src.u32 = MEM_read32(data_src + link);
|
||||
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
for (size_t j = prev_st_index; j < st_index; ++j) {
|
||||
tbl->tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
|
||||
@@ -554,8 +554,8 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
/* Last element done separately */
|
||||
--list_count;
|
||||
do {
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot];
|
||||
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
|
||||
size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
size_t const next_link = tbl->match_buffer[next_index].from;
|
||||
if ((link - next_link) > rpt_depth) {
|
||||
if (rpt > 0)
|
||||
@@ -563,18 +563,18 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
|
||||
rpt = -1;
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
tbl->tails_8[radix_8].list_count = 1;
|
||||
tbl->stack[st_index].head = (U32)index;
|
||||
tbl->stack[st_index].head = (U32)pos;
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
index = next_index;
|
||||
pos = next_index;
|
||||
link = next_link;
|
||||
}
|
||||
else {
|
||||
@@ -587,14 +587,14 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
rpt_head_next = next_index;
|
||||
rpt_dist = dist;
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
tbl->tails_8[radix_8].list_count = 1;
|
||||
tbl->stack[st_index].head = (U32)index;
|
||||
tbl->stack[st_index].head = (U32)pos;
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
@@ -602,7 +602,7 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
else {
|
||||
++rpt;
|
||||
}
|
||||
index = next_index;
|
||||
pos = next_index;
|
||||
link = next_link;
|
||||
}
|
||||
} while (--list_count != 0);
|
||||
@@ -610,14 +610,14 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
if (rpt > 0)
|
||||
RMF_handleRepeat(tbl->match_buffer, data_block, rpt_head_next, rpt, rpt_dist, rpt_depth, tbl->max_len);
|
||||
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot];
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
if (slot == 3) {
|
||||
tbl->match_buffer[index].src.u32 = MEM_read32(data_src + link);
|
||||
tbl->match_buffer[pos].src.u32 = MEM_read32(data_src + link);
|
||||
}
|
||||
++tbl->tails_8[radix_8].list_count;
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
for (size_t j = prev_st_index; j < st_index; ++j) {
|
||||
tbl->tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
|
||||
@@ -628,21 +628,21 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
|
||||
size_t const prev_st_index = st_index;
|
||||
/* The last pass at max_depth */
|
||||
do {
|
||||
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot];
|
||||
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK;
|
||||
size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
|
||||
size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
|
||||
/* Pre-load the next link. */
|
||||
/* The last element in tbl->match_buffer is circular so this is never an access violation. */
|
||||
size_t const next_link = tbl->match_buffer[next_index].from;
|
||||
U32 const prev = tbl->tails_8[radix_8].prev_index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)index;
|
||||
tbl->tails_8[radix_8].prev_index = (U32)pos;
|
||||
if (prev != RADIX_NULL_LINK) {
|
||||
tbl->match_buffer[prev].next = (U32)index | (depth << 24);
|
||||
tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
|
||||
}
|
||||
else {
|
||||
tbl->stack[st_index].count = (U32)radix_8;
|
||||
++st_index;
|
||||
}
|
||||
index = next_index;
|
||||
pos = next_index;
|
||||
link = next_link;
|
||||
} while (--list_count != 0);
|
||||
for (size_t j = prev_st_index; j < st_index; ++j) {
|
||||
@@ -703,28 +703,28 @@ void RMF_resetIncompleteBuild(FL2_matchTable * const tbl)
|
||||
RMF_initListHeads(tbl);
|
||||
}
|
||||
|
||||
int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const index, size_t const end, unsigned const max_depth)
|
||||
int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const pos, size_t const end, unsigned const max_depth)
|
||||
{
|
||||
if (tbl->is_struct)
|
||||
return RMF_structuredIntegrityCheck(tbl, data, index, end, max_depth);
|
||||
return RMF_structuredIntegrityCheck(tbl, data, pos, end, max_depth);
|
||||
else
|
||||
return RMF_bitpackIntegrityCheck(tbl, data, index, end, max_depth);
|
||||
return RMF_bitpackIntegrityCheck(tbl, data, pos, end, max_depth);
|
||||
}
|
||||
|
||||
void RMF_limitLengths(FL2_matchTable* const tbl, size_t const index)
|
||||
void RMF_limitLengths(FL2_matchTable* const tbl, size_t const pos)
|
||||
{
|
||||
if (tbl->is_struct)
|
||||
RMF_structuredLimitLengths(tbl, index);
|
||||
RMF_structuredLimitLengths(tbl, pos);
|
||||
else
|
||||
RMF_bitpackLimitLengths(tbl, index);
|
||||
RMF_bitpackLimitLengths(tbl, pos);
|
||||
}
|
||||
|
||||
BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const index)
|
||||
BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos)
|
||||
{
|
||||
if (tbl->is_struct)
|
||||
return RMF_structuredAsOutputBuffer(tbl, index);
|
||||
return RMF_structuredAsOutputBuffer(tbl, pos);
|
||||
else
|
||||
return RMF_bitpackAsOutputBuffer(tbl, index);
|
||||
return RMF_bitpackAsOutputBuffer(tbl, pos);
|
||||
}
|
||||
|
||||
size_t RMF_memoryUsage(size_t const dict_size, unsigned const buffer_resize, unsigned const thread_count)
|
||||
|
||||
@@ -42,16 +42,16 @@ BYTE RMF_compatibleParameters(const FL2_matchTable* const tbl, const RMF_paramet
|
||||
size_t RMF_applyParameters(FL2_matchTable* const tbl, const RMF_parameters* const params, size_t const dict_reduce);
|
||||
size_t RMF_threadCount(const FL2_matchTable * const tbl);
|
||||
void RMF_initProgress(FL2_matchTable * const tbl);
|
||||
size_t RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end);
|
||||
void RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end);
|
||||
int RMF_buildTable(FL2_matchTable* const tbl,
|
||||
size_t const job,
|
||||
size_t const job,
|
||||
unsigned const multi_thread,
|
||||
FL2_dataBlock const block);
|
||||
void RMF_cancelBuild(FL2_matchTable* const tbl);
|
||||
void RMF_resetIncompleteBuild(FL2_matchTable* const tbl);
|
||||
int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const index, size_t const end, unsigned const max_depth);
|
||||
void RMF_limitLengths(FL2_matchTable* const tbl, size_t const index);
|
||||
BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const index);
|
||||
int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const pos, size_t const end, unsigned const max_depth);
|
||||
void RMF_limitLengths(FL2_matchTable* const tbl, size_t const pos);
|
||||
BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos);
|
||||
size_t RMF_memoryUsage(size_t const dict_size, unsigned const buffer_resize, unsigned const thread_count);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "fl2_internal.h"
|
||||
#include "radix_internal.h"
|
||||
|
||||
typedef struct FL2_matchTable_s FL2_matchTable;
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
@@ -22,37 +20,37 @@ typedef struct FL2_matchTable_s FL2_matchTable;
|
||||
|
||||
#define RADIX_MAX_LENGTH STRUCTURED_MAX_LENGTH
|
||||
|
||||
#define InitMatchLink(index, link) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] = (U32)(link)
|
||||
#define InitMatchLink(pos, link) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] = (U32)(link)
|
||||
|
||||
#define GetMatchLink(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK]
|
||||
#define GetMatchLink(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK]
|
||||
|
||||
#define GetInitialMatchLink(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK]
|
||||
#define GetInitialMatchLink(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK]
|
||||
|
||||
#define GetMatchLength(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].lengths[(index) & UNIT_MASK]
|
||||
#define GetMatchLength(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].lengths[(pos) & UNIT_MASK]
|
||||
|
||||
#define SetMatchLink(index, link, length) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] = (U32)(link)
|
||||
#define SetMatchLink(pos, link, length) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] = (U32)(link)
|
||||
|
||||
#define SetMatchLength(index, link, length) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].lengths[(index) & UNIT_MASK] = (BYTE)(length)
|
||||
#define SetMatchLength(pos, link, length) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].lengths[(pos) & UNIT_MASK] = (BYTE)(length)
|
||||
|
||||
#define SetMatchLinkAndLength(index, link, length) do { size_t i_ = (index) >> UNIT_BITS, u_ = (index) & UNIT_MASK; ((RMF_unit*)tbl->table)[i_].links[u_] = (U32)(link); ((RMF_unit*)tbl->table)[i_].lengths[u_] = (BYTE)(length); } while(0)
|
||||
#define SetMatchLinkAndLength(pos, link, length) do { size_t i_ = (pos) >> UNIT_BITS, u_ = (pos) & UNIT_MASK; ((RMF_unit*)tbl->table)[i_].links[u_] = (U32)(link); ((RMF_unit*)tbl->table)[i_].lengths[u_] = (BYTE)(length); } while(0)
|
||||
|
||||
#define SetNull(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] = RADIX_NULL_LINK
|
||||
#define SetNull(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] = RADIX_NULL_LINK
|
||||
|
||||
#define IsNull(index) (((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] == RADIX_NULL_LINK)
|
||||
#define IsNull(pos) (((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] == RADIX_NULL_LINK)
|
||||
|
||||
BYTE* RMF_structuredAsOutputBuffer(FL2_matchTable* const tbl, size_t const index)
|
||||
BYTE* RMF_structuredAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos)
|
||||
{
|
||||
return (BYTE*)((RMF_unit*)tbl->table + (index >> UNIT_BITS) + ((index & UNIT_MASK) != 0));
|
||||
return (BYTE*)((RMF_unit*)tbl->table + (pos >> UNIT_BITS) + ((pos & UNIT_MASK) != 0));
|
||||
}
|
||||
|
||||
/* Restrict the match lengths so that they don't reach beyond index */
|
||||
void RMF_structuredLimitLengths(FL2_matchTable* const tbl, size_t const index)
|
||||
/* Restrict the match lengths so that they don't reach beyond pos */
|
||||
void RMF_structuredLimitLengths(FL2_matchTable* const tbl, size_t const pos)
|
||||
{
|
||||
DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)index, RADIX_MAX_LENGTH);
|
||||
SetNull(index - 1);
|
||||
for (size_t length = 2; length < RADIX_MAX_LENGTH && length <= index; ++length) {
|
||||
size_t const i = (index - length) >> UNIT_BITS;
|
||||
size_t const u = (index - length) & UNIT_MASK;
|
||||
DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)pos, RADIX_MAX_LENGTH);
|
||||
SetNull(pos - 1);
|
||||
for (size_t length = 2; length < RADIX_MAX_LENGTH && length <= pos; ++length) {
|
||||
size_t const i = (pos - length) >> UNIT_BITS;
|
||||
size_t const u = (pos - length) & UNIT_MASK;
|
||||
if (((RMF_unit*)tbl->table)[i].links[u] != RADIX_NULL_LINK) {
|
||||
((RMF_unit*)tbl->table)[i].lengths[u] = MIN((BYTE)length, ((RMF_unit*)tbl->table)[i].lengths[u]);
|
||||
}
|
||||
|
||||
@@ -63,12 +63,12 @@ void RC_printPriceTable()
|
||||
memset(table0, 0, sizeof(table0));
|
||||
memset(table1, 0, sizeof(table1));
|
||||
memset(count, 0, sizeof(count));
|
||||
for (Probability i = 31; i <= kBitModelTotal - 31; ++i) {
|
||||
RangeEncoder rc;
|
||||
for (LZMA2_prob i = 31; i <= kBitModelTotal - 31; ++i) {
|
||||
RC_encoder rc;
|
||||
RC_reset(&rc);
|
||||
RC_setOutputBuffer(&rc, buf);
|
||||
for (unsigned j = 0; j < test_size; ++j) {
|
||||
Probability prob = i;
|
||||
LZMA2_prob prob = i;
|
||||
RC_encodeBit0(&rc, &prob);
|
||||
}
|
||||
RC_flush(&rc);
|
||||
@@ -76,7 +76,7 @@ void RC_printPriceTable()
|
||||
RC_reset(&rc);
|
||||
RC_setOutputBuffer(&rc, buf);
|
||||
for (unsigned j = 0; j < test_size; ++j) {
|
||||
Probability prob = i;
|
||||
LZMA2_prob prob = i;
|
||||
RC_encodeBit1(&rc, &prob);
|
||||
}
|
||||
RC_flush(&rc);
|
||||
@@ -104,13 +104,13 @@ void RC_printPriceTable()
|
||||
|
||||
#endif
|
||||
|
||||
void RC_setOutputBuffer(RangeEncoder* const rc, BYTE *const out_buffer)
|
||||
void RC_setOutputBuffer(RC_encoder* const rc, BYTE *const out_buffer)
|
||||
{
|
||||
rc->out_buffer = out_buffer;
|
||||
rc->out_index = 0;
|
||||
}
|
||||
|
||||
void RC_reset(RangeEncoder* const rc)
|
||||
void RC_reset(RC_encoder* const rc)
|
||||
{
|
||||
rc->low = 0;
|
||||
rc->range = (U32)-1;
|
||||
@@ -120,7 +120,7 @@ void RC_reset(RangeEncoder* const rc)
|
||||
|
||||
#ifdef __64BIT__
|
||||
|
||||
void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc)
|
||||
void FORCE_NOINLINE RC_shiftLow(RC_encoder* const rc)
|
||||
{
|
||||
U64 low = rc->low;
|
||||
rc->low = (U32)(low << 8);
|
||||
@@ -143,7 +143,7 @@ void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc)
|
||||
|
||||
#else
|
||||
|
||||
void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc)
|
||||
void FORCE_NOINLINE RC_shiftLow(RC_encoder* const rc)
|
||||
{
|
||||
U32 low = (U32)rc->low;
|
||||
unsigned high = (unsigned)(rc->low >> 32);
|
||||
@@ -165,7 +165,7 @@ void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc)
|
||||
|
||||
#endif
|
||||
|
||||
void RC_encodeBitTree(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol)
|
||||
void RC_encodeBitTree(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol)
|
||||
{
|
||||
assert(bit_count > 1);
|
||||
--bit_count;
|
||||
@@ -180,7 +180,7 @@ void RC_encodeBitTree(RangeEncoder* const rc, Probability *const probs, unsigned
|
||||
} while (bit_count != 0);
|
||||
}
|
||||
|
||||
void RC_encodeBitTreeReverse(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol)
|
||||
void RC_encodeBitTreeReverse(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol)
|
||||
{
|
||||
assert(bit_count != 0);
|
||||
unsigned bit = symbol & 1;
|
||||
@@ -194,7 +194,7 @@ void RC_encodeBitTreeReverse(RangeEncoder* const rc, Probability *const probs, u
|
||||
}
|
||||
}
|
||||
|
||||
void FORCE_NOINLINE RC_encodeDirect(RangeEncoder* const rc, unsigned value, unsigned bit_count)
|
||||
void FORCE_NOINLINE RC_encodeDirect(RC_encoder* const rc, unsigned value, unsigned bit_count)
|
||||
{
|
||||
assert(bit_count > 0);
|
||||
do {
|
||||
|
||||
@@ -16,9 +16,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef LZMA_ENC_PROB32
|
||||
typedef U32 Probability;
|
||||
typedef U32 LZMA2_prob;
|
||||
#else
|
||||
typedef U16 Probability;
|
||||
typedef U16 LZMA2_prob;
|
||||
#endif
|
||||
|
||||
#define kNumTopBits 24U
|
||||
@@ -44,27 +44,27 @@ typedef struct
|
||||
U64 low;
|
||||
U32 range;
|
||||
BYTE cache;
|
||||
} RangeEncoder;
|
||||
} RC_encoder;
|
||||
|
||||
void RC_reset(RangeEncoder* const rc);
|
||||
void RC_reset(RC_encoder* const rc);
|
||||
|
||||
void RC_setOutputBuffer(RangeEncoder* const rc, BYTE *const out_buffer);
|
||||
void RC_setOutputBuffer(RC_encoder* const rc, BYTE *const out_buffer);
|
||||
|
||||
void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc);
|
||||
void FORCE_NOINLINE RC_shiftLow(RC_encoder* const rc);
|
||||
|
||||
void RC_encodeBitTree(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol);
|
||||
void RC_encodeBitTree(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol);
|
||||
|
||||
void RC_encodeBitTreeReverse(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol);
|
||||
void RC_encodeBitTreeReverse(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol);
|
||||
|
||||
void FORCE_NOINLINE RC_encodeDirect(RangeEncoder* const rc, unsigned value, unsigned bit_count);
|
||||
void FORCE_NOINLINE RC_encodeDirect(RC_encoder* const rc, unsigned value, unsigned bit_count);
|
||||
|
||||
HINT_INLINE
|
||||
void RC_encodeBit0(RangeEncoder* const rc, Probability *const rprob)
|
||||
void RC_encodeBit0(RC_encoder* const rc, LZMA2_prob *const rprob)
|
||||
{
|
||||
unsigned prob = *rprob;
|
||||
rc->range = (rc->range >> kNumBitModelTotalBits) * prob;
|
||||
prob += (kBitModelTotal - prob) >> kNumMoveBits;
|
||||
*rprob = (Probability)prob;
|
||||
*rprob = (LZMA2_prob)prob;
|
||||
if (rc->range < kTopValue) {
|
||||
rc->range <<= 8;
|
||||
RC_shiftLow(rc);
|
||||
@@ -72,14 +72,14 @@ void RC_encodeBit0(RangeEncoder* const rc, Probability *const rprob)
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
void RC_encodeBit1(RangeEncoder* const rc, Probability *const rprob)
|
||||
void RC_encodeBit1(RC_encoder* const rc, LZMA2_prob *const rprob)
|
||||
{
|
||||
unsigned prob = *rprob;
|
||||
U32 new_bound = (rc->range >> kNumBitModelTotalBits) * prob;
|
||||
rc->low += new_bound;
|
||||
rc->range -= new_bound;
|
||||
prob -= prob >> kNumMoveBits;
|
||||
*rprob = (Probability)prob;
|
||||
*rprob = (LZMA2_prob)prob;
|
||||
if (rc->range < kTopValue) {
|
||||
rc->range <<= 8;
|
||||
RC_shiftLow(rc);
|
||||
@@ -87,7 +87,7 @@ void RC_encodeBit1(RangeEncoder* const rc, Probability *const rprob)
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
void RC_encodeBit(RangeEncoder* const rc, Probability *const rprob, unsigned const bit)
|
||||
void RC_encodeBit(RC_encoder* const rc, LZMA2_prob *const rprob, unsigned const bit)
|
||||
{
|
||||
unsigned prob = *rprob;
|
||||
if (bit != 0) {
|
||||
@@ -100,7 +100,7 @@ void RC_encodeBit(RangeEncoder* const rc, Probability *const rprob, unsigned con
|
||||
rc->range = (rc->range >> kNumBitModelTotalBits) * prob;
|
||||
prob += (kBitModelTotal - prob) >> kNumMoveBits;
|
||||
}
|
||||
*rprob = (Probability)prob;
|
||||
*rprob = (LZMA2_prob)prob;
|
||||
if (rc->range < kTopValue) {
|
||||
rc->range <<= 8;
|
||||
RC_shiftLow(rc);
|
||||
@@ -117,7 +117,7 @@ void RC_encodeBit(RangeEncoder* const rc, Probability *const rprob, unsigned con
|
||||
#define kMinLitPrice 8U
|
||||
|
||||
HINT_INLINE
|
||||
unsigned RC_getTreePrice(const Probability* const prob_table, unsigned bit_count, size_t symbol)
|
||||
unsigned RC_getTreePrice(const LZMA2_prob* const prob_table, unsigned bit_count, size_t symbol)
|
||||
{
|
||||
unsigned price = 0;
|
||||
symbol |= ((size_t)1 << bit_count);
|
||||
@@ -132,7 +132,7 @@ unsigned RC_getTreePrice(const Probability* const prob_table, unsigned bit_count
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
unsigned RC_getReverseTreePrice(const Probability* const prob_table, unsigned bit_count, size_t symbol)
|
||||
unsigned RC_getReverseTreePrice(const LZMA2_prob* const prob_table, unsigned bit_count, size_t symbol)
|
||||
{
|
||||
unsigned prob = prob_table[1];
|
||||
size_t bit = symbol & 1;
|
||||
@@ -149,7 +149,7 @@ unsigned RC_getReverseTreePrice(const Probability* const prob_table, unsigned bi
|
||||
}
|
||||
|
||||
HINT_INLINE
|
||||
void RC_flush(RangeEncoder* const rc)
|
||||
void RC_flush(RC_encoder* const rc)
|
||||
{
|
||||
for (int i = 0; i < 5; ++i)
|
||||
RC_shiftLow(rc);
|
||||
|
||||
Reference in New Issue
Block a user