mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-06-21 15:58:51 +08:00
123 lines
2.5 KiB
Markdown
123 lines
2.5 KiB
Markdown
|
|
## Rans Decoding
|
|
|
|
### ans_read_init()
|
|
|
|
~~~~~
|
|
ans_read_init(AnsDecoder ans, buf, int offset) {
|
|
x = buf[offset - 1] >> 6
|
|
If (x == 0) {
|
|
ans->buf_offset = offset - 1;
|
|
ans->state = buf[offset - 1] & 0x3F;
|
|
} else if (x == 1) {
|
|
ans->buf_offset = offset - 2;
|
|
ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF;
|
|
} else if (x == 2) {
|
|
ans->buf_offset = offset - 3;
|
|
ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
|
|
} else if (x == 3) {
|
|
// ERROR
|
|
}
|
|
ans->state += l_base;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### int rabs_desc_read()
|
|
|
|
~~~~~
|
|
int rabs_desc_read(struct AnsDecoder *ans, AnsP8 p0) {
|
|
AnsP8 p = ans_p8_precision - p0;
|
|
if (ans->state < l_base) {
|
|
ans->state = ans->state * io_base + ans->buf[--ans->buf_offset];
|
|
}
|
|
x = ans->state;
|
|
quot = x / ans_p8_precision;
|
|
rem = x % ans_p8_precision;
|
|
xn = quot * p;
|
|
val = rem < p;
|
|
if (val) {
|
|
ans->state = xn + rem;
|
|
} else {
|
|
ans->state = x - xn - p;
|
|
}
|
|
return val;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### rans_read_init()
|
|
|
|
~~~~~
|
|
rans_read_init(UI8 *buf, int offset) {
|
|
ans_.buf = buf;
|
|
x = buf[offset - 1] >> 6
|
|
If (x == 0) {
|
|
ans_.buf_offset = offset - 1;
|
|
ans_.state = buf[offset - 1] & 0x3F;
|
|
} else if (x == 1) {
|
|
ans_.buf_offset = offset - 2;
|
|
ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF;
|
|
} else if (x == 2) {
|
|
ans_.buf_offset = offset - 3;
|
|
ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
|
|
} else if (x == 3) {
|
|
ans_.buf_offset = offset - 4;
|
|
ans_.state = mem_get_le32(buf + offset - 4) & 0x3FFFFFFF;
|
|
}
|
|
ans_.state += l_rans_base;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### rans_build_look_up_table()
|
|
|
|
~~~~~
|
|
rans_build_look_up_table() {
|
|
cum_prob = 0
|
|
act_prob = 0
|
|
for (i = 0; i < num_symbols; ++i) {
|
|
probability_table_[i].prob = token_probs[i];
|
|
probability_table_[i].cum_prob = cum_prob;
|
|
cum_prob += token_probs[i];
|
|
for (j = act_prob; j < cum_prob; ++j) {
|
|
Lut_table_[j] = i
|
|
}
|
|
act_prob = cum_prob
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### rans_read()
|
|
|
|
~~~~~
|
|
rans_read() {
|
|
while (ans_.state < l_rans_base) {
|
|
ans_.state = ans_.state * io_base + ans_.buf[--ans_.buf_offset];
|
|
}
|
|
quo = ans_.state / rans_precision;
|
|
rem = ans_.state % rans_precision;
|
|
sym = fetch_sym()
|
|
ans_.state = quo * sym.prob + rem - sym.cum_prob;
|
|
return sym.val;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|
|
|
|
|
|
### fetch_sym()
|
|
|
|
~~~~~
|
|
fetch_sym() {
|
|
symbol = lut_table[rem]
|
|
out->val = symbol
|
|
out->prob = probability_table_[symbol].prob;
|
|
out->cum_prob = probability_table_[symbol].cum_prob;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax }
|