mirror of https://git.tukaani.org/xz.git
Moved range decoder initialization (reading the first
five input bytes) from LZMA decoder to range decoder header. Did the same for decoding of direct bits.
This commit is contained in:
parent
5db745cd2a
commit
bbfd1f6ab0
|
@ -151,10 +151,6 @@ struct lzma_coder_s {
|
|||
|
||||
/// Length of a repeated match.
|
||||
lzma_length_decoder rep_match_len_decoder;
|
||||
|
||||
/// The first five bytes of LZMA compressed data are treated
|
||||
/// specially. Once they are read, this stays at zero.
|
||||
size_t init_bytes_left;
|
||||
};
|
||||
|
||||
|
||||
|
@ -166,7 +162,7 @@ struct lzma_coder_s {
|
|||
static bool lzma_attribute((pure))
|
||||
decode_dummy(const lzma_coder *restrict coder,
|
||||
const uint8_t *restrict in, size_t in_pos_local,
|
||||
const size_t in_size, uint32_t rc_range, uint32_t rc_code,
|
||||
const size_t in_size, lzma_range_decoder rc,
|
||||
uint32_t state, uint32_t rep0, const uint32_t now_pos)
|
||||
{
|
||||
uint32_t rc_bound;
|
||||
|
@ -268,20 +264,11 @@ decode_dummy(const lzma_coder *restrict coder,
|
|||
coder->pos_decoders + offset,
|
||||
direct_bits);
|
||||
} else {
|
||||
// Decode direct bits
|
||||
assert(pos_slot >= 14);
|
||||
assert(direct_bits >= 6);
|
||||
direct_bits -= ALIGN_BITS;
|
||||
assert(direct_bits >= 2);
|
||||
do {
|
||||
rc_normalize();
|
||||
rc_range >>= 1;
|
||||
const uint32_t t
|
||||
= (rc_code - rc_range)
|
||||
>> 31;
|
||||
rc_code -= rc_range & (t - 1);
|
||||
} while (--direct_bits > 0);
|
||||
rep0 <<= ALIGN_BITS;
|
||||
rc_decode_direct_dummy(direct_bits);
|
||||
|
||||
bittree_reverse_decode_dummy(
|
||||
coder->pos_align_decoder,
|
||||
|
@ -342,16 +329,9 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
|||
// Initialization //
|
||||
////////////////////
|
||||
|
||||
while (coder->init_bytes_left > 0) {
|
||||
if (*in_pos == in_size)
|
||||
if (!rc_read_init(&coder->rc, in, in_pos, in_size))
|
||||
return false;
|
||||
|
||||
coder->rc.code = (coder->rc.code << 8) | in[*in_pos];
|
||||
++*in_pos;
|
||||
--coder->init_bytes_left;
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
// Variables //
|
||||
///////////////
|
||||
|
@ -386,7 +366,7 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
|||
while (coder->lz.pos < coder->lz.limit && (in_pos_local < in_limit
|
||||
|| (has_safe_buffer && decode_dummy(
|
||||
coder, in, in_pos_local, in_size,
|
||||
rc_range, rc_code, state, rep0, now_pos)))) {
|
||||
rc, state, rep0, now_pos)))) {
|
||||
|
||||
/////////////////////
|
||||
// Actual decoding //
|
||||
|
@ -513,20 +493,11 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
|||
coder->pos_decoders + offset,
|
||||
direct_bits);
|
||||
} else {
|
||||
// Decode direct bits
|
||||
assert(pos_slot >= 14);
|
||||
assert(direct_bits >= 6);
|
||||
direct_bits -= ALIGN_BITS;
|
||||
assert(direct_bits >= 2);
|
||||
do {
|
||||
rc_normalize();
|
||||
rc_range >>= 1;
|
||||
const uint32_t t
|
||||
= (rc_code - rc_range)
|
||||
>> 31;
|
||||
rc_code -= rc_range & (t - 1);
|
||||
rep0 = (rep0 << 1) | (1 - t);
|
||||
} while (--direct_bits > 0);
|
||||
rc_decode_direct(rep0, direct_bits);
|
||||
rep0 <<= ALIGN_BITS;
|
||||
|
||||
bittree_reverse_decode(rep0,
|
||||
|
@ -762,7 +733,6 @@ lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
|||
next->coder->pos_bits = options->pos_bits;
|
||||
next->coder->pos_mask = (1 << next->coder->pos_bits) - 1;
|
||||
next->coder->now_pos = 0;
|
||||
next->coder->init_bytes_left = 5;
|
||||
|
||||
// Range decoder
|
||||
rc_reset(next->coder->rc);
|
||||
|
|
|
@ -27,33 +27,47 @@
|
|||
typedef struct {
|
||||
uint32_t range;
|
||||
uint32_t code;
|
||||
uint32_t init_bytes_left;
|
||||
} lzma_range_decoder;
|
||||
|
||||
|
||||
static inline bool
|
||||
rc_read_init(lzma_range_decoder *rc, const uint8_t *restrict in,
|
||||
size_t *restrict in_pos, size_t in_size)
|
||||
{
|
||||
while (rc->init_bytes_left > 0) {
|
||||
if (*in_pos == in_size)
|
||||
return false;
|
||||
|
||||
rc->code = (rc->code << 8) | in[*in_pos];
|
||||
++*in_pos;
|
||||
--rc->init_bytes_left;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Makes local copies of range decoder variables.
|
||||
#define rc_to_local(rc) \
|
||||
uint32_t rc_range = (rc).range; \
|
||||
uint32_t rc_code = (rc).code; \
|
||||
#define rc_to_local(range_decoder) \
|
||||
lzma_range_decoder rc = range_decoder; \
|
||||
uint32_t rc_bound
|
||||
|
||||
/// Stores the local copes back to the range decoder structure.
|
||||
#define rc_from_local(rc) \
|
||||
do {\
|
||||
(rc).range = rc_range; \
|
||||
(rc).code = rc_code; \
|
||||
} while (0)
|
||||
#define rc_from_local(range_decoder) \
|
||||
range_decoder = rc
|
||||
|
||||
/// Resets the range decoder structure.
|
||||
#define rc_reset(rc) \
|
||||
#define rc_reset(range_decoder) \
|
||||
do { \
|
||||
(rc).range = UINT32_MAX; \
|
||||
(rc).code = 0; \
|
||||
(range_decoder).range = UINT32_MAX; \
|
||||
(range_decoder).code = 0; \
|
||||
(range_decoder).init_bytes_left = 5; \
|
||||
} while (0)
|
||||
|
||||
|
||||
// All of the macros in this file expect the following variables being defined:
|
||||
// - uint32_t rc_range;
|
||||
// - uint32_t rc_code;
|
||||
// - lzma_range_decoder range_decoder;
|
||||
// - uint32_t rc_bound; // Temporary variable
|
||||
// - uint8_t *in;
|
||||
// - size_t in_pos_local; // Local alias for *in_pos
|
||||
|
@ -66,9 +80,9 @@ do { \
|
|||
// Read the next byte of compressed data from buffer_in, if needed.
|
||||
#define rc_normalize() \
|
||||
do { \
|
||||
if (rc_range < TOP_VALUE) { \
|
||||
rc_range <<= SHIFT_BITS; \
|
||||
rc_code = (rc_code << SHIFT_BITS) | in[in_pos_local++]; \
|
||||
if (rc.range < TOP_VALUE) { \
|
||||
rc.range <<= SHIFT_BITS; \
|
||||
rc.code = (rc.code << SHIFT_BITS) | in[in_pos_local++]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -88,37 +102,56 @@ do { \
|
|||
|
||||
#define if_bit_0(prob) \
|
||||
rc_normalize(); \
|
||||
rc_bound = (rc_range >> BIT_MODEL_TOTAL_BITS) * (prob); \
|
||||
if (rc_code < rc_bound)
|
||||
rc_bound = (rc.range >> BIT_MODEL_TOTAL_BITS) * (prob); \
|
||||
if (rc.code < rc_bound)
|
||||
|
||||
|
||||
#define update_bit_0(prob) \
|
||||
do { \
|
||||
rc_range = rc_bound; \
|
||||
rc.range = rc_bound; \
|
||||
prob += (BIT_MODEL_TOTAL - (prob)) >> MOVE_BITS; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define update_bit_1(prob) \
|
||||
do { \
|
||||
rc_range -= rc_bound; \
|
||||
rc_code -= rc_bound; \
|
||||
rc.range -= rc_bound; \
|
||||
rc.code -= rc_bound; \
|
||||
prob -= (prob) >> MOVE_BITS; \
|
||||
} while (0)
|
||||
|
||||
|
||||
// Dummy versions don't update prob.
|
||||
#define rc_decode_direct(dest, count) \
|
||||
do { \
|
||||
rc_normalize(); \
|
||||
rc.range >>= 1; \
|
||||
rc_bound = (rc.code - rc.range) >> 31; \
|
||||
rc.code -= rc.range & (rc_bound - 1); \
|
||||
dest = ((dest) << 1) | (1 - rc_bound);\
|
||||
} while (--count > 0)
|
||||
|
||||
|
||||
// Dummy versions don't update prob or dest.
|
||||
#define update_bit_0_dummy() \
|
||||
rc_range = rc_bound
|
||||
rc.range = rc_bound
|
||||
|
||||
|
||||
#define update_bit_1_dummy() \
|
||||
do { \
|
||||
rc_range -= rc_bound; \
|
||||
rc_code -= rc_bound; \
|
||||
rc.range -= rc_bound; \
|
||||
rc.code -= rc_bound; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define rc_decode_direct_dummy(count) \
|
||||
do { \
|
||||
rc_normalize(); \
|
||||
rc.range >>= 1; \
|
||||
rc_bound = (rc.code - rc.range) >> 31; \
|
||||
rc.code -= rc.range & (rc_bound - 1); \
|
||||
} while (--count > 0)
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Bit tree decoding //
|
||||
///////////////////////
|
||||
|
|
Loading…
Reference in New Issue