draco/docs/spec/rans.decoding.md
Frank Galligan 4efc3d27cc Update bitstream spec
This PR is associated with #134.
2017-07-22 22:35:54 -07:00

2.5 KiB

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 }