15#ifndef DRACO_COMPRESSION_ENTROPY_ANS_H_
16#define DRACO_COMPRESSION_ENTROPY_ANS_H_
23#define DRACO_ANS_DIVIDE_BY_MULTIPLY 1
24#if DRACO_ANS_DIVIDE_BY_MULTIPLY
31#if DRACO_ANS_DIVIDE_BY_MULTIPLY
33#define DRACO_ANS_DIVREM(quotient, remainder, dividend, divisor) \
35 quotient = fastdiv(dividend, divisor); \
36 remainder = dividend - quotient * divisor; \
38#define DRACO_ANS_DIV(dividend, divisor) fastdiv(dividend, divisor)
40#define DRACO_ANS_DIVREM(quotient, remainder, dividend, divisor) \
42 quotient = dividend / divisor; \
43 remainder = dividend % divisor; \
45#define DRACO_ANS_DIV(dividend, divisor) ((dividend) / (divisor))
63#define DRACO_ANS_P8_PRECISION 256u
64#define DRACO_ANS_L_BASE (4096u)
65#define DRACO_ANS_IO_BASE 256
67static uint32_t mem_get_le16(
const void *vmem) {
69 const uint8_t *mem = (
const uint8_t *)vmem;
76static uint32_t mem_get_le24(
const void *vmem) {
78 const uint8_t *mem = (
const uint8_t *)vmem;
86static inline uint32_t mem_get_le32(
const void *vmem) {
88 const uint8_t *mem = (
const uint8_t *)vmem;
97static inline void mem_put_le16(
void *vmem, uint32_t val) {
98 uint8_t *mem =
reinterpret_cast<uint8_t *
>(vmem);
100 mem[0] = (val >> 0) & 0xff;
101 mem[1] = (val >> 8) & 0xff;
104static inline void mem_put_le24(
void *vmem, uint32_t val) {
105 uint8_t *mem =
reinterpret_cast<uint8_t *
>(vmem);
107 mem[0] = (val >> 0) & 0xff;
108 mem[1] = (val >> 8) & 0xff;
109 mem[2] = (val >> 16) & 0xff;
112static inline void mem_put_le32(
void *vmem, uint32_t val) {
113 uint8_t *mem =
reinterpret_cast<uint8_t *
>(vmem);
115 mem[0] = (val >> 0) & 0xff;
116 mem[1] = (val >> 8) & 0xff;
117 mem[2] = (val >> 16) & 0xff;
118 mem[3] = (val >> 24) & 0xff;
121static inline void ans_write_init(
struct AnsCoder *
const ans,
122 uint8_t *
const buf) {
128static inline int ans_write_end(
struct AnsCoder *
const ans) {
133 if (state < (1 << 6)) {
134 ans->buf[ans->buf_offset] = (0x00 << 6) + state;
135 return ans->buf_offset + 1;
136 }
else if (state < (1 << 14)) {
137 mem_put_le16(ans->buf + ans->buf_offset, (0x01 << 14) + state);
138 return ans->buf_offset + 2;
139 }
else if (state < (1 << 22)) {
140 mem_put_le24(ans->buf + ans->buf_offset, (0x02 << 22) + state);
141 return ans->buf_offset + 3;
143 DRACO_DCHECK(0 &&
"State is too large to be serialized");
144 return ans->buf_offset;
151static inline void rabs_desc_write(
struct AnsCoder *ans,
int val,
AnsP8 p0) {
153 const unsigned l_s = val ? p : p0;
164#define DRACO_ANS_IMPL1 0
165#define UNPREDICTABLE(x) x
166static inline int rabs_desc_read(
struct AnsDecoder *ans,
AnsP8 p0) {
171 unsigned quot, rem, x, xn;
189 ans->state = xn + rem;
192 ans->state = x - xn - p;
201static inline void rabs_asc_write(
struct AnsCoder *ans,
int val,
AnsP8 p0) {
203 const unsigned l_s = val ? p : p0;
219 unsigned quot, rem, x, xn;
237 ans->state = xn + rem - p0;
246#define rabs_read rabs_desc_read
247#define rabs_write rabs_desc_write
250static inline void uabs_write(
struct AnsCoder *ans,
int val,
AnsP8 p0) {
252 const unsigned l_s = val ? p : p0;
271 unsigned state = ans->state;
272 while (state < DRACO_ANS_L_BASE && ans->buf_offset > 0) {
279 s = (sp & 0xFF) >= p0;
283 ans->state = state - xp;
288static inline int uabs_read_bit(
struct AnsDecoder *ans) {
290 unsigned state = ans->state;
291 while (state < DRACO_ANS_L_BASE && ans->buf_offset > 0) {
294 s =
static_cast<int>(state & 1);
295 ans->state = state >> 1;
299static inline int ans_read_init(
struct AnsDecoder *
const ans,
300 const uint8_t *
const buf,
int offset) {
306 x = buf[offset - 1] >> 6;
308 ans->buf_offset = offset - 1;
309 ans->state = buf[offset - 1] & 0x3F;
314 ans->buf_offset = offset - 2;
315 ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF;
320 ans->buf_offset = offset - 3;
321 ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
332static inline int ans_read_end(
struct AnsDecoder *
const ans) {
336static inline int ans_reader_has_error(
const struct AnsDecoder *
const ans) {
349template <
int rans_precision_bits_t>
358 ans_.state = l_rans_base;
366 state = ans_.state - l_rans_base;
367 if (state < (1 << 6)) {
368 ans_.buf[ans_.buf_offset] = (0x00 << 6) + state;
369 return ans_.buf_offset + 1;
370 }
else if (state < (1 << 14)) {
371 mem_put_le16(ans_.buf + ans_.buf_offset, (0x01 << 14) + state);
372 return ans_.buf_offset + 2;
373 }
else if (state < (1 << 22)) {
374 mem_put_le24(ans_.buf + ans_.buf_offset, (0x02 << 22) + state);
375 return ans_.buf_offset + 3;
376 }
else if (state < (1 << 30)) {
377 mem_put_le32(ans_.buf + ans_.buf_offset, (0x03u << 30u) + state);
378 return ans_.buf_offset + 4;
380 DRACO_DCHECK(0 &&
"State is too large to be serialized");
381 return ans_.buf_offset;
389 const uint32_t p = sym->
prob;
395 (ans_.state / p) * rans_precision + ans_.state % p + sym->
cum_prob;
399 static constexpr int rans_precision = 1 << rans_precision_bits_t;
400 static constexpr int l_rans_base = rans_precision * 4;
413template <
int rans_precision_bits_t>
421 inline int read_init(
const uint8_t *
const buf,
int offset) {
427 x = buf[offset - 1] >> 6;
429 ans_.buf_offset = offset - 1;
430 ans_.state = buf[offset - 1] & 0x3F;
435 ans_.buf_offset = offset - 2;
436 ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF;
441 ans_.buf_offset = offset - 3;
442 ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
444 ans_.buf_offset = offset - 4;
445 ans_.state = mem_get_le32(buf + offset - 4) & 0x3FFFFFFF;
449 ans_.state += l_rans_base;
456 inline int read_end() {
return ans_.state == l_rans_base; }
459 return ans_.state < l_rans_base && ans_.buf_offset == 0;
466 while (ans_.state < l_rans_base && ans_.buf_offset > 0) {
471 quo = ans_.state / rans_precision;
472 rem = ans_.state % rans_precision;
473 fetch_sym(&sym, rem);
481 uint32_t num_symbols) {
482 lut_table_.resize(rans_precision);
483 probability_table_.resize(num_symbols);
484 uint32_t cum_prob = 0;
485 uint32_t act_prob = 0;
486 for (uint32_t i = 0; i < num_symbols; ++i) {
487 probability_table_[i].prob = token_probs[i];
488 probability_table_[i].cum_prob = cum_prob;
489 cum_prob += token_probs[i];
490 if (cum_prob > rans_precision) {
493 for (uint32_t j = act_prob; j < cum_prob; ++j) {
498 if (cum_prob != rans_precision) {
505 inline void fetch_sym(
struct rans_dec_sym *out, uint32_t rem) {
506 uint32_t symbol = lut_table_[rem];
508 out->
prob = probability_table_[symbol].prob;
509 out->
cum_prob = probability_table_[symbol].cum_prob;
512 static constexpr int rans_precision = 1 << rans_precision_bits_t;
513 static constexpr int l_rans_base = rans_precision * 4;
514 std::vector<uint32_t> lut_table_;
515 std::vector<rans_sym> probability_table_;
519#undef DRACO_ANS_DIVREM
520#undef DRACO_ANS_P8_PRECISION
521#undef DRACO_ANS_L_BASE
522#undef DRACO_ANS_IO_BASE
#define UNPREDICTABLE(x)
Definition ans.h:165
#define DRACO_ANS_DIVREM(quotient, remainder, dividend, divisor)
Definition ans.h:33
#define DRACO_ANS_DIV(dividend, divisor)
Definition ans.h:38
#define DRACO_ANS_IO_BASE
Definition ans.h:65
#define DRACO_ANS_P8_PRECISION
Definition ans.h:63
#define DRACO_ANS_L_BASE
Definition ans.h:64
bool rans_build_look_up_table(const uint32_t token_probs[], uint32_t num_symbols)
Definition ans.h:480
int read_init(const uint8_t *const buf, int offset)
Definition ans.h:421
int read_end()
Definition ans.h:456
RAnsDecoder()
Definition ans.h:416
int rans_read()
Definition ans.h:462
int reader_has_error()
Definition ans.h:458
void rans_write(const struct rans_sym *const sym)
Definition ans.h:388
RAnsEncoder()
Definition ans.h:352
void write_init(uint8_t *const buf)
Definition ans.h:355
int write_end()
Definition ans.h:362
#define DRACO_DCHECK_LT(a, b)
Definition macros.h:86
#define DRACO_DCHECK(x)
Definition macros.h:80
#define DRACO_DCHECK_GE(a, b)
Definition macros.h:83
Definition attribute_octahedron_transform.cc:21
uint8_t AnsP8
Definition ans.h:62
int buf_offset
Definition ans.h:51
uint32_t state
Definition ans.h:52
AnsCoder()
Definition ans.h:49
uint8_t * buf
Definition ans.h:50
uint32_t state
Definition ans.h:59
const uint8_t * buf
Definition ans.h:57
int buf_offset
Definition ans.h:58
AnsDecoder()
Definition ans.h:56
uint32_t prob
Definition ans.h:406
uint32_t val
Definition ans.h:405
uint32_t cum_prob
Definition ans.h:407
uint32_t cum_prob
Definition ans.h:342
uint32_t prob
Definition ans.h:341