mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
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
2 changed files with 66 additions and 63 deletions
|
@ -151,10 +151,6 @@ struct lzma_coder_s {
|
||||||
|
|
||||||
/// Length of a repeated match.
|
/// Length of a repeated match.
|
||||||
lzma_length_decoder rep_match_len_decoder;
|
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))
|
static bool lzma_attribute((pure))
|
||||||
decode_dummy(const lzma_coder *restrict coder,
|
decode_dummy(const lzma_coder *restrict coder,
|
||||||
const uint8_t *restrict in, size_t in_pos_local,
|
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 state, uint32_t rep0, const uint32_t now_pos)
|
||||||
{
|
{
|
||||||
uint32_t rc_bound;
|
uint32_t rc_bound;
|
||||||
|
@ -268,20 +264,11 @@ decode_dummy(const lzma_coder *restrict coder,
|
||||||
coder->pos_decoders + offset,
|
coder->pos_decoders + offset,
|
||||||
direct_bits);
|
direct_bits);
|
||||||
} else {
|
} else {
|
||||||
// Decode direct bits
|
|
||||||
assert(pos_slot >= 14);
|
assert(pos_slot >= 14);
|
||||||
assert(direct_bits >= 6);
|
assert(direct_bits >= 6);
|
||||||
direct_bits -= ALIGN_BITS;
|
direct_bits -= ALIGN_BITS;
|
||||||
assert(direct_bits >= 2);
|
assert(direct_bits >= 2);
|
||||||
do {
|
rc_decode_direct_dummy(direct_bits);
|
||||||
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;
|
|
||||||
|
|
||||||
bittree_reverse_decode_dummy(
|
bittree_reverse_decode_dummy(
|
||||||
coder->pos_align_decoder,
|
coder->pos_align_decoder,
|
||||||
|
@ -342,16 +329,9 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||||
// Initialization //
|
// Initialization //
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
while (coder->init_bytes_left > 0) {
|
if (!rc_read_init(&coder->rc, in, in_pos, in_size))
|
||||||
if (*in_pos == in_size)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
coder->rc.code = (coder->rc.code << 8) | in[*in_pos];
|
|
||||||
++*in_pos;
|
|
||||||
--coder->init_bytes_left;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Variables //
|
// 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
|
while (coder->lz.pos < coder->lz.limit && (in_pos_local < in_limit
|
||||||
|| (has_safe_buffer && decode_dummy(
|
|| (has_safe_buffer && decode_dummy(
|
||||||
coder, in, in_pos_local, in_size,
|
coder, in, in_pos_local, in_size,
|
||||||
rc_range, rc_code, state, rep0, now_pos)))) {
|
rc, state, rep0, now_pos)))) {
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// Actual decoding //
|
// Actual decoding //
|
||||||
|
@ -513,20 +493,11 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||||
coder->pos_decoders + offset,
|
coder->pos_decoders + offset,
|
||||||
direct_bits);
|
direct_bits);
|
||||||
} else {
|
} else {
|
||||||
// Decode direct bits
|
|
||||||
assert(pos_slot >= 14);
|
assert(pos_slot >= 14);
|
||||||
assert(direct_bits >= 6);
|
assert(direct_bits >= 6);
|
||||||
direct_bits -= ALIGN_BITS;
|
direct_bits -= ALIGN_BITS;
|
||||||
assert(direct_bits >= 2);
|
assert(direct_bits >= 2);
|
||||||
do {
|
rc_decode_direct(rep0, direct_bits);
|
||||||
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);
|
|
||||||
rep0 <<= ALIGN_BITS;
|
rep0 <<= ALIGN_BITS;
|
||||||
|
|
||||||
bittree_reverse_decode(rep0,
|
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_bits = options->pos_bits;
|
||||||
next->coder->pos_mask = (1 << next->coder->pos_bits) - 1;
|
next->coder->pos_mask = (1 << next->coder->pos_bits) - 1;
|
||||||
next->coder->now_pos = 0;
|
next->coder->now_pos = 0;
|
||||||
next->coder->init_bytes_left = 5;
|
|
||||||
|
|
||||||
// Range decoder
|
// Range decoder
|
||||||
rc_reset(next->coder->rc);
|
rc_reset(next->coder->rc);
|
||||||
|
|
|
@ -27,33 +27,47 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t range;
|
uint32_t range;
|
||||||
uint32_t code;
|
uint32_t code;
|
||||||
|
uint32_t init_bytes_left;
|
||||||
} lzma_range_decoder;
|
} 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.
|
/// Makes local copies of range decoder variables.
|
||||||
#define rc_to_local(rc) \
|
#define rc_to_local(range_decoder) \
|
||||||
uint32_t rc_range = (rc).range; \
|
lzma_range_decoder rc = range_decoder; \
|
||||||
uint32_t rc_code = (rc).code; \
|
|
||||||
uint32_t rc_bound
|
uint32_t rc_bound
|
||||||
|
|
||||||
/// Stores the local copes back to the range decoder structure.
|
/// Stores the local copes back to the range decoder structure.
|
||||||
#define rc_from_local(rc) \
|
#define rc_from_local(range_decoder) \
|
||||||
do {\
|
range_decoder = rc
|
||||||
(rc).range = rc_range; \
|
|
||||||
(rc).code = rc_code; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/// Resets the range decoder structure.
|
/// Resets the range decoder structure.
|
||||||
#define rc_reset(rc) \
|
#define rc_reset(range_decoder) \
|
||||||
do { \
|
do { \
|
||||||
(rc).range = UINT32_MAX; \
|
(range_decoder).range = UINT32_MAX; \
|
||||||
(rc).code = 0; \
|
(range_decoder).code = 0; \
|
||||||
|
(range_decoder).init_bytes_left = 5; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
// All of the macros in this file expect the following variables being defined:
|
// All of the macros in this file expect the following variables being defined:
|
||||||
// - uint32_t rc_range;
|
// - lzma_range_decoder range_decoder;
|
||||||
// - uint32_t rc_code;
|
|
||||||
// - uint32_t rc_bound; // Temporary variable
|
// - uint32_t rc_bound; // Temporary variable
|
||||||
// - uint8_t *in;
|
// - uint8_t *in;
|
||||||
// - size_t in_pos_local; // Local alias for *in_pos
|
// - 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.
|
// Read the next byte of compressed data from buffer_in, if needed.
|
||||||
#define rc_normalize() \
|
#define rc_normalize() \
|
||||||
do { \
|
do { \
|
||||||
if (rc_range < TOP_VALUE) { \
|
if (rc.range < TOP_VALUE) { \
|
||||||
rc_range <<= SHIFT_BITS; \
|
rc.range <<= SHIFT_BITS; \
|
||||||
rc_code = (rc_code << SHIFT_BITS) | in[in_pos_local++]; \
|
rc.code = (rc.code << SHIFT_BITS) | in[in_pos_local++]; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -88,37 +102,56 @@ do { \
|
||||||
|
|
||||||
#define if_bit_0(prob) \
|
#define if_bit_0(prob) \
|
||||||
rc_normalize(); \
|
rc_normalize(); \
|
||||||
rc_bound = (rc_range >> BIT_MODEL_TOTAL_BITS) * (prob); \
|
rc_bound = (rc.range >> BIT_MODEL_TOTAL_BITS) * (prob); \
|
||||||
if (rc_code < rc_bound)
|
if (rc.code < rc_bound)
|
||||||
|
|
||||||
|
|
||||||
#define update_bit_0(prob) \
|
#define update_bit_0(prob) \
|
||||||
do { \
|
do { \
|
||||||
rc_range = rc_bound; \
|
rc.range = rc_bound; \
|
||||||
prob += (BIT_MODEL_TOTAL - (prob)) >> MOVE_BITS; \
|
prob += (BIT_MODEL_TOTAL - (prob)) >> MOVE_BITS; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
#define update_bit_1(prob) \
|
#define update_bit_1(prob) \
|
||||||
do { \
|
do { \
|
||||||
rc_range -= rc_bound; \
|
rc.range -= rc_bound; \
|
||||||
rc_code -= rc_bound; \
|
rc.code -= rc_bound; \
|
||||||
prob -= (prob) >> MOVE_BITS; \
|
prob -= (prob) >> MOVE_BITS; \
|
||||||
} while (0)
|
} 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() \
|
#define update_bit_0_dummy() \
|
||||||
rc_range = rc_bound
|
rc.range = rc_bound
|
||||||
|
|
||||||
|
|
||||||
#define update_bit_1_dummy() \
|
#define update_bit_1_dummy() \
|
||||||
do { \
|
do { \
|
||||||
rc_range -= rc_bound; \
|
rc.range -= rc_bound; \
|
||||||
rc_code -= rc_bound; \
|
rc.code -= rc_bound; \
|
||||||
} while (0)
|
} 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 //
|
// Bit tree decoding //
|
||||||
///////////////////////
|
///////////////////////
|
||||||
|
|
Loading…
Reference in a new issue