xref: /aosp_15_r20/external/libaom/aom_dsp/entenc.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1 /*
2  * Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved.
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #ifndef AOM_AOM_DSP_ENTENC_H_
13 #define AOM_AOM_DSP_ENTENC_H_
14 #include <stddef.h>
15 #include "aom_dsp/entcode.h"
16 #include "aom_util/endian_inl.h"
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 typedef uint64_t od_ec_enc_window;
23 
24 typedef struct od_ec_enc od_ec_enc;
25 
26 #define OD_MEASURE_EC_OVERHEAD (0)
27 
28 /*The entropy encoder context.*/
29 struct od_ec_enc {
30   /*Buffered output.
31     This contains only the raw bits until the final call to od_ec_enc_done(),
32      where all the arithmetic-coded data gets prepended to it.*/
33   unsigned char *buf;
34   /*The size of the buffer.*/
35   uint32_t storage;
36   /*The offset at which the next entropy-coded byte will be written.*/
37   uint32_t offs;
38   /*The low end of the current range.*/
39   od_ec_enc_window low;
40   /*The number of values in the current range.*/
41   uint16_t rng;
42   /*The number of bits of data in the current value.*/
43   int16_t cnt;
44   /*Nonzero if an error occurred.*/
45   int error;
46 #if OD_MEASURE_EC_OVERHEAD
47   double entropy;
48   int nb_symbols;
49 #endif
50 };
51 
52 /*See entenc.c for further documentation.*/
53 
54 void od_ec_enc_init(od_ec_enc *enc, uint32_t size) OD_ARG_NONNULL(1);
55 void od_ec_enc_reset(od_ec_enc *enc) OD_ARG_NONNULL(1);
56 void od_ec_enc_clear(od_ec_enc *enc) OD_ARG_NONNULL(1);
57 
58 void od_ec_encode_bool_q15(od_ec_enc *enc, int val, unsigned f_q15)
59     OD_ARG_NONNULL(1);
60 void od_ec_encode_cdf_q15(od_ec_enc *enc, int s, const uint16_t *cdf, int nsyms)
61     OD_ARG_NONNULL(1) OD_ARG_NONNULL(3);
62 
63 void od_ec_enc_bits(od_ec_enc *enc, uint32_t fl, unsigned ftb)
64     OD_ARG_NONNULL(1);
65 
66 void od_ec_enc_patch_initial_bits(od_ec_enc *enc, unsigned val, int nbits)
67     OD_ARG_NONNULL(1);
68 OD_WARN_UNUSED_RESULT unsigned char *od_ec_enc_done(od_ec_enc *enc,
69                                                     uint32_t *nbytes)
70     OD_ARG_NONNULL(1) OD_ARG_NONNULL(2);
71 
72 OD_WARN_UNUSED_RESULT int od_ec_enc_tell(const od_ec_enc *enc)
73     OD_ARG_NONNULL(1);
74 OD_WARN_UNUSED_RESULT uint32_t od_ec_enc_tell_frac(const od_ec_enc *enc)
75     OD_ARG_NONNULL(1);
76 
77 // buf is the frame bitbuffer, offs is where carry to be added
propagate_carry_bwd(unsigned char * buf,uint32_t offs)78 static inline void propagate_carry_bwd(unsigned char *buf, uint32_t offs) {
79   uint16_t sum, carry = 1;
80   do {
81     sum = (uint16_t)buf[offs] + 1;
82     buf[offs--] = (unsigned char)sum;
83     carry = sum >> 8;
84   } while (carry);
85 }
86 
87 // Convert to big-endian byte order and write data to buffer adding the
88 // carry-bit
write_enc_data_to_out_buf(unsigned char * out,uint32_t offs,uint64_t output,uint64_t carry,uint32_t * enc_offs,uint8_t num_bytes_ready)89 static inline void write_enc_data_to_out_buf(unsigned char *out, uint32_t offs,
90                                              uint64_t output, uint64_t carry,
91                                              uint32_t *enc_offs,
92                                              uint8_t num_bytes_ready) {
93   const uint64_t reg = HToBE64(output << ((8 - num_bytes_ready) << 3));
94   memcpy(&out[offs], &reg, 8);
95   // Propagate carry backwards if exists
96   if (carry) {
97     assert(offs > 0);
98     propagate_carry_bwd(out, offs - 1);
99   }
100   *enc_offs = offs + num_bytes_ready;
101 }
102 
103 #ifdef __cplusplus
104 }  // extern "C"
105 #endif
106 
107 #endif  // AOM_AOM_DSP_ENTENC_H_
108