#include "range_common.h"
Data Structures | |
struct | lzma_range_decoder |
Defines | |
#define | rc_to_local(range_decoder, in_pos) |
#define | rc_from_local(range_decoder, in_pos) |
Stores the local copes back to the range decoder structure. | |
#define | rc_reset(range_decoder) |
Resets the range decoder structure. | |
#define | rc_is_finished(range_decoder) ((range_decoder).code == 0) |
#define | rc_normalize(seq) |
#define | rc_if_0(prob, seq) |
#define | rc_update_0(prob) |
#define | rc_update_1(prob) |
#define | rc_bit_last(prob, action0, action1, seq) |
#define | rc_bit(prob, action0, action1, seq) |
#define | rc_bit_case(prob, action0, action1, seq) case seq: rc_bit(prob, action0, action1, seq) |
#define | rc_direct(dest, seq) |
Decode a bit without using a probability. | |
Functions | |
static bool | rc_read_init (lzma_range_decoder *rc, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size) |
Reads the first five bytes to initialize the range decoder. |
#define rc_to_local | ( | range_decoder, | |||
in_pos | ) |
Value:
lzma_range_decoder rc = range_decoder; \
size_t rc_in_pos = (in_pos); \
uint32_t rc_bound
#define rc_from_local | ( | range_decoder, | |||
in_pos | ) |
Value:
do { \ range_decoder = rc; \ in_pos = rc_in_pos; \ } while (0)
#define rc_reset | ( | range_decoder | ) |
Value:
do { \ (range_decoder).range = UINT32_MAX; \ (range_decoder).code = 0; \ (range_decoder).init_bytes_left = 5; \ } while (0)
#define rc_is_finished | ( | range_decoder | ) | ((range_decoder).code == 0) |
When decoding has been properly finished, rc.code is always zero unless the input stream is corrupt. So checking this can catch some corrupt files especially if they don't have any other integrity check.
#define rc_normalize | ( | seq | ) |
Value:
do { \ if (rc.range < RC_TOP_VALUE) { \ if (unlikely(rc_in_pos == in_size)) { \ coder->sequence = seq; \ goto out; \ } \ rc.range <<= RC_SHIFT_BITS; \ rc.code = (rc.code << RC_SHIFT_BITS) | in[rc_in_pos++]; \ } \ } while (0)
#define rc_if_0 | ( | prob, | |||
seq | ) |
Value:
rc_normalize(seq); \ rc_bound = (rc.range >> RC_BIT_MODEL_TOTAL_BITS) * (prob); \ if (rc.code < rc_bound)
rc_if_0(prob, seq) { rc_update_0(prob); Do something } else { rc_update_1(prob); Do something else }
#define rc_update_0 | ( | prob | ) |
Value:
do { \ rc.range = rc_bound; \ prob += (RC_BIT_MODEL_TOTAL - (prob)) >> RC_MOVE_BITS; \ } while (0)
#define rc_update_1 | ( | prob | ) |
Value:
do { \ rc.range -= rc_bound; \ rc.code -= rc_bound; \ prob -= (prob) >> RC_MOVE_BITS; \ } while (0)
#define rc_bit_last | ( | prob, | |||
action0, | |||||
action1, | |||||
seq | ) |
Value:
do { \ rc_if_0(prob, seq) { \ rc_update_0(prob); \ action0; \ } else { \ rc_update_1(prob); \ action1; \ } \ } while (0)
#define rc_bit | ( | prob, | |||
action0, | |||||
action1, | |||||
seq | ) |
Value:
rc_bit_last(prob, \ symbol <<= 1; action0, \ symbol = (symbol << 1) + 1; action1, \ seq);
#define rc_bit_case | ( | prob, | |||
action0, | |||||
action1, | |||||
seq | ) | case seq: rc_bit(prob, action0, action1, seq) |
Like rc_bit() but add "case seq:" as a prefix. This makes the unrolled loops more readable because the code isn't littered with "case" statements. On the other hand this also makes it less readable, since spotting the places where the decoder loop may be restarted is less obvious.
#define rc_direct | ( | dest, | |||
seq | ) |
Value:
do { \ rc_normalize(seq); \ rc.range >>= 1; \ rc.code -= rc.range; \ rc_bound = UINT32_C(0) - (rc.code >> 31); \ rc.code += rc.range & rc_bound; \ dest = (dest << 1) + (rc_bound + 1); \ } while (0)
static bool rc_read_init | ( | lzma_range_decoder * | rc, | |
const uint8_t *restrict | in, | |||
size_t *restrict | in_pos, | |||
size_t | in_size | |||
) | [inline, static] |
Reads the first five bytes to initialize the range decoder.