From bbfd1f6ab058a7e661545205befcb7f70c5685ab Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 4 Jan 2008 20:45:05 +0200 Subject: [PATCH] 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. --- src/liblzma/lzma/lzma_decoder.c | 42 ++----------- src/liblzma/rangecoder/range_decoder.h | 87 ++++++++++++++++++-------- 2 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/liblzma/lzma/lzma_decoder.c b/src/liblzma/lzma/lzma_decoder.c index 6e2c166d..dda94177 100644 --- a/src/liblzma/lzma/lzma_decoder.c +++ b/src/liblzma/lzma/lzma_decoder.c @@ -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,15 +329,8 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in, // Initialization // //////////////////// - while (coder->init_bytes_left > 0) { - if (*in_pos == in_size) - return false; - - coder->rc.code = (coder->rc.code << 8) | in[*in_pos]; - ++*in_pos; - --coder->init_bytes_left; - } - + if (!rc_read_init(&coder->rc, in, in_pos, in_size)) + return false; /////////////// // 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); diff --git a/src/liblzma/rangecoder/range_decoder.h b/src/liblzma/rangecoder/range_decoder.h index 0583faaf..f3dcc84e 100644 --- a/src/liblzma/rangecoder/range_decoder.h +++ b/src/liblzma/rangecoder/range_decoder.h @@ -27,36 +27,50 @@ 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 +// - 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 // ///////////////////////