1
0
Fork 0
mirror of https://git.tukaani.org/xz.git synced 2024-04-04 12:36:23 +02:00

More fixes to LZMA decoder's flush marker handling.

This commit is contained in:
Lasse Collin 2008-01-14 11:54:56 +02:00
parent f73c2ab607
commit 3599dba957

View file

@ -425,13 +425,7 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
// Not a repeated match // Not a repeated match
// //
// We will decode a new distance and store // We will decode a new distance and store
// the value to rep0. // the value to distance.
// The latest three match distances are kept in
// memory in case there are repeated matches.
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
// Decode the length of the match. // Decode the length of the match.
length_decode(len, coder->len_decoder, pos_state); length_decode(len, coder->len_decoder, pos_state);
@ -447,36 +441,36 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
if (pos_slot >= START_POS_MODEL_INDEX) { if (pos_slot >= START_POS_MODEL_INDEX) {
uint32_t direct_bits = (pos_slot >> 1) - 1; uint32_t direct_bits = (pos_slot >> 1) - 1;
assert(direct_bits >= 1 && direct_bits <= 30); assert(direct_bits >= 1 && direct_bits <= 30);
rep0 = 2 | (pos_slot & 1); uint32_t distance = 2 | (pos_slot & 1);
if (pos_slot < END_POS_MODEL_INDEX) { if (pos_slot < END_POS_MODEL_INDEX) {
assert(direct_bits <= 5); assert(direct_bits <= 5);
rep0 <<= direct_bits; distance <<= direct_bits;
assert(rep0 <= 96); assert(distance <= 96);
// -1 is fine, because // -1 is fine, because
// bittree_reverse_decode() // bittree_reverse_decode()
// starts from table index [1] // starts from table index [1]
// (not [0]). // (not [0]).
assert((int32_t)(rep0 - pos_slot - 1) >= -1); assert((int32_t)(distance - pos_slot - 1) >= -1);
assert((int32_t)(rep0 - pos_slot - 1) <= 82); assert((int32_t)(distance - pos_slot - 1) <= 82);
// We add the result to rep0, so rep0 // We add the result to distance, so distance
// must not be part of second argument // must not be part of second argument
// of the macro. // of the macro.
const int32_t offset = rep0 - pos_slot - 1; const int32_t offset = distance - pos_slot - 1;
bittree_reverse_decode(rep0, coder->pos_decoders + offset, bittree_reverse_decode(distance, coder->pos_decoders + offset,
direct_bits); direct_bits);
} else { } else {
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);
rc_decode_direct(rep0, direct_bits); rc_decode_direct(distance, direct_bits);
rep0 <<= ALIGN_BITS; distance <<= ALIGN_BITS;
bittree_reverse_decode(rep0, coder->pos_align_decoder, bittree_reverse_decode(distance, coder->pos_align_decoder,
ALIGN_BITS); ALIGN_BITS);
if (rep0 == UINT32_MAX) { if (distance == UINT32_MAX) {
if (len == LEN_SPECIAL_EOPM) { if (len == LEN_SPECIAL_EOPM) {
// End of Payload Marker found. // End of Payload Marker found.
coder->lz.eopm_detected = true; coder->lz.eopm_detected = true;
@ -501,16 +495,31 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
rc_reset(rc); rc_reset(rc);
// If we don't have enough input here, we jump // If we don't have enough input here, we jump
// out of the loop without calling rc_normalize(). // out of the loop. Note that while there is a
// useless call to rc_normalize(), it does nothing
// since we have just reset the range decoder.
if (!rc_read_init(&rc, in, &in_pos_local, in_size)) if (!rc_read_init(&rc, in, &in_pos_local, in_size))
goto out; break;
continue;
} else { } else {
return true; return true;
} }
} }
} }
// The latest three match distances are kept in
// memory in case there are repeated matches.
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
rep0 = distance;
} else { } else {
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
rep0 = pos_slot; rep0 = pos_slot;
} }
@ -630,7 +639,6 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
// Update the *data structure. // // Update the *data structure. //
///////////////////////////////// /////////////////////////////////
out:
// Range decoder // Range decoder
rc_from_local(coder->rc); rc_from_local(coder->rc);