Rizin
unix-like reverse engineering framework and cli tools
range_decoder.h File Reference

Range Decoder. More...

#include "range_common.h"

Go to the source code of this file.

Classes

struct  lzma_range_decoder
 

Macros

#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. More...
 
#define rc_reset(range_decoder)
 Resets the range decoder structure. More...
 
#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. More...
 

Functions

static lzma_ret 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. More...
 

Detailed Description

Range Decoder.

Definition in file range_decoder.h.

Macro Definition Documentation

◆ rc_bit

#define rc_bit (   prob,
  action0,
  action1,
  seq 
)
Value:
rc_bit_last(prob, \
symbol <<= 1; action0, \
symbol = (symbol << 1) + 1; action1, \
seq);
#define rc_bit_last(prob, action0, action1, seq)

Decodes one bit, updates "symbol", and runs action0 or action1 depending on the decoded bit.

Definition at line 154 of file range_decoder.h.

◆ rc_bit_case

#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.

Definition at line 166 of file range_decoder.h.

◆ rc_bit_last

#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)

Decodes one bit and runs action0 or action1 depending on the decoded bit. This macro is used as the last step in bittree reverse decoders since those don't use "symbol" for anything else than indexing the probability arrays.

Definition at line 140 of file range_decoder.h.

◆ rc_direct

#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)
char * dest
Definition: lz4.h:697
#define UINT32_C(val)

Decode a bit without using a probability.

Definition at line 171 of file range_decoder.h.

◆ rc_from_local

#define rc_from_local (   range_decoder,
  in_pos 
)
Value:
do { \
range_decoder = rc; \
in_pos = rc_in_pos; \
} while (0)

Stores the local copes back to the range decoder structure.

Definition at line 61 of file range_decoder.h.

◆ rc_if_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)
#define RC_BIT_MODEL_TOTAL_BITS
Definition: range_common.h:27
#define rc_normalize(seq)
Definition: range_decoder.h:87

Start decoding a bit. This must be used together with rc_update_0() and rc_update_1():

rc_if_0(prob, seq) {
    rc_update_0(prob);
    // Do something
} else {
    rc_update_1(prob);
    // Do something else
}

Definition at line 111 of file range_decoder.h.

◆ rc_is_finished

#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.

Definition at line 80 of file range_decoder.h.

◆ rc_normalize

#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)
const lzma_allocator const uint8_t size_t in_size
Definition: block.h:527
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define unlikely(expr)
Definition: lz4.c:177
#define RC_SHIFT_BITS
Definition: range_common.h:24
#define RC_TOP_VALUE
Definition: range_common.h:26

Read the next input byte if needed. If more input is needed but there is no more input available, "goto out" is used to jump out of the main decoder loop.

Definition at line 87 of file range_decoder.h.

◆ rc_reset

#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 UINT32_MAX
Definition: inftree9.h:24

Resets the range decoder structure.

Definition at line 69 of file range_decoder.h.

◆ rc_to_local

#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
const lzma_allocator const uint8_t size_t * in_pos
Definition: block.h:579

Makes local copies of range decoder and *in_pos variables. Doing this improves speed significantly. The range decoder macros expect also variables ‘in’ and ‘in_size’ to be defined.

Definition at line 54 of file range_decoder.h.

◆ rc_update_0

#define rc_update_0 (   prob)
Value:
do { \
rc.range = rc_bound; \
prob += (RC_BIT_MODEL_TOTAL - (prob)) >> RC_MOVE_BITS; \
} while (0)
#define RC_MOVE_BITS
Definition: range_common.h:29
#define RC_BIT_MODEL_TOTAL
Definition: range_common.h:28

Update the range decoder state and the used probability variable to match a decoded bit of 0.

Definition at line 119 of file range_decoder.h.

◆ rc_update_1

#define rc_update_1 (   prob)
Value:
do { \
rc.range -= rc_bound; \
rc.code -= rc_bound; \
prob -= (prob) >> RC_MOVE_BITS; \
} while (0)

Update the range decoder state and the used probability variable to match a decoded bit of 1.

Definition at line 128 of file range_decoder.h.

Function Documentation

◆ rc_read_init()

static lzma_ret rc_read_init ( lzma_range_decoder rc,
const uint8_t *restrict  in,
size_t *restrict  in_pos,
size_t  in_size 
)
inlinestatic

Reads the first five bytes to initialize the range decoder.

Definition at line 29 of file range_decoder.h.

31 {
32  while (rc->init_bytes_left > 0) {
33  if (*in_pos == in_size)
34  return LZMA_OK;
35 
36  // The first byte is always 0x00. It could have been omitted
37  // in LZMA2 but it wasn't, so one byte is wasted in every
38  // LZMA2 chunk.
39  if (rc->init_bytes_left == 5 && in[*in_pos] != 0x00)
40  return LZMA_DATA_ERROR;
41 
42  rc->code = (rc->code << 8) | in[*in_pos];
43  ++*in_pos;
44  --rc->init_bytes_left;
45  }
46 
47  return LZMA_STREAM_END;
48 }
uint32_t init_bytes_left
Definition: range_decoder.h:23
@ LZMA_DATA_ERROR
Data is corrupt.
Definition: base.h:172
@ LZMA_STREAM_END
End of stream was reached.
Definition: base.h:63
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58

References lzma_range_decoder::code, in, in_pos, in_size, lzma_range_decoder::init_bytes_left, LZMA_DATA_ERROR, LZMA_OK, and LZMA_STREAM_END.

Referenced by lzma_decode().