Moved range decoder initialization (reading the first
authorLasse Collin <lasse.collin@tukaani.org>
Fri, 4 Jan 2008 18:45:05 +0000 (20:45 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Fri, 4 Jan 2008 18:45:05 +0000 (20:45 +0200)
five input bytes) from LZMA decoder to range decoder
header. Did the same for decoding of direct bits.

src/liblzma/lzma/lzma_decoder.c
src/liblzma/rangecoder/range_decoder.h

index 6e2c166..dda9417 100644 (file)
@@ -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);
index 0583faa..f3dcc84 100644 (file)
 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 //
 ///////////////////////