2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
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.
12 #include "aom_dsp/bitwriter.h"
13 #include "aom_dsp/binary_codes_writer.h"
14 #include "aom_dsp/recenter.h"
15 #include "aom_ports/bitops.h"
17 // Codes a symbol v in [-2^mag_bits, 2^mag_bits].
18 // mag_bits is number of bits for magnitude. The alphabet is of size
19 // 2 * 2^mag_bits + 1, symmetric around 0, where one bit is used to
20 // indicate 0 or non-zero, mag_bits bits are used to indicate magnitide
21 // and 1 more bit for the sign if non-zero.
22 void aom_write_primitive_symmetric(aom_writer
*w
, int16_t v
,
23 unsigned int abs_bits
) {
31 aom_write_literal(w
, x
- 1, abs_bits
);
35 int aom_count_primitive_symmetric(int16_t v
, unsigned int abs_bits
) {
36 return (v
== 0 ? 1 : abs_bits
+ 2);
39 // Encodes a value v in [0, n-1] quasi-uniformly
40 void aom_write_primitive_quniform(aom_writer
*w
, uint16_t n
, uint16_t v
) {
42 const int l
= get_msb(n
) + 1;
43 const int m
= (1 << l
) - n
;
45 aom_write_literal(w
, v
, l
- 1);
47 aom_write_literal(w
, m
+ ((v
- m
) >> 1), l
- 1);
48 aom_write_bit(w
, (v
- m
) & 1);
52 int aom_count_primitive_quniform(uint16_t n
, uint16_t v
) {
54 const int l
= get_msb(n
) + 1;
55 const int m
= (1 << l
) - n
;
56 return v
< m
? l
- 1 : l
;
59 // Finite subexponential code that codes a symbol v in [0, n-1] with parameter k
60 void aom_write_primitive_subexpfin(aom_writer
*w
, uint16_t n
, uint16_t k
,
65 int b
= (i
? k
+ i
- 1 : k
);
67 if (n
<= mk
+ 3 * a
) {
68 aom_write_primitive_quniform(w
, n
- mk
, v
- mk
);
71 int t
= (v
>= mk
+ a
);
77 aom_write_literal(w
, v
- mk
, b
);
84 int aom_count_primitive_subexpfin(uint16_t n
, uint16_t k
, uint16_t v
) {
89 int b
= (i
? k
+ i
- 1 : k
);
91 if (n
<= mk
+ 3 * a
) {
92 count
+= aom_count_primitive_quniform(n
- mk
, v
- mk
);
95 int t
= (v
>= mk
+ a
);
109 // Finite subexponential code that codes a symbol v in [0, n-1] with parameter k
110 // based on a reference ref also in [0, n-1].
111 // Recenters symbol around r first and then uses a finite subexponential code.
112 void aom_write_primitive_refsubexpfin(aom_writer
*w
, uint16_t n
, uint16_t k
,
113 uint16_t ref
, uint16_t v
) {
114 aom_write_primitive_subexpfin(w
, n
, k
, recenter_finite_nonneg(n
, ref
, v
));
117 void aom_write_signed_primitive_refsubexpfin(aom_writer
*w
, uint16_t n
,
118 uint16_t k
, int16_t ref
,
122 const uint16_t scaled_n
= (n
<< 1) - 1;
123 aom_write_primitive_refsubexpfin(w
, scaled_n
, k
, ref
, v
);
126 int aom_count_primitive_refsubexpfin(uint16_t n
, uint16_t k
, uint16_t ref
,
128 return aom_count_primitive_subexpfin(n
, k
, recenter_finite_nonneg(n
, ref
, v
));
131 int aom_count_signed_primitive_refsubexpfin(uint16_t n
, uint16_t k
, int16_t ref
,
135 const uint16_t scaled_n
= (n
<< 1) - 1;
136 return aom_count_primitive_refsubexpfin(scaled_n
, k
, ref
, v
);