blob: c7722283b1039d6c284402c4ab90f7ac9eed541c [file] [log] [blame]
Debargha Mukherjee47748b52017-03-24 12:20:49 -07001/*
James Zernb7c05bd2024-06-11 19:15:10 -07002 * Copyright (c) 2017, Alliance for Open Media. All rights reserved.
Debargha Mukherjee47748b52017-03-24 12:20:49 -07003 *
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#include "aom_dsp/bitwriter.h"
Sarah Parker3e579a62017-08-23 16:53:20 -070013#include "aom_dsp/binary_codes_writer.h"
Tom Finegan067e9842018-09-28 10:15:09 -070014#include "aom_dsp/recenter.h"
15#include "aom_ports/bitops.h"
Debargha Mukherjee47748b52017-03-24 12:20:49 -070016
Debargha Mukherjee47748b52017-03-24 12:20:49 -070017// 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.
22void aom_write_primitive_symmetric(aom_writer *w, int16_t v,
23 unsigned int abs_bits) {
24 if (v == 0) {
25 aom_write_bit(w, 0);
26 } else {
27 const int x = abs(v);
28 const int s = v < 0;
29 aom_write_bit(w, 1);
30 aom_write_bit(w, s);
31 aom_write_literal(w, x - 1, abs_bits);
32 }
33}
34
35int aom_count_primitive_symmetric(int16_t v, unsigned int abs_bits) {
36 return (v == 0 ? 1 : abs_bits + 2);
37}
38
39// Encodes a value v in [0, n-1] quasi-uniformly
40void aom_write_primitive_quniform(aom_writer *w, uint16_t n, uint16_t v) {
41 if (n <= 1) return;
Wan-Teh Chang15ad38f2018-08-16 10:31:53 -070042 const int l = get_msb(n) + 1;
Debargha Mukherjee47748b52017-03-24 12:20:49 -070043 const int m = (1 << l) - n;
44 if (v < m) {
45 aom_write_literal(w, v, l - 1);
46 } else {
47 aom_write_literal(w, m + ((v - m) >> 1), l - 1);
48 aom_write_bit(w, (v - m) & 1);
49 }
50}
51
52int aom_count_primitive_quniform(uint16_t n, uint16_t v) {
53 if (n <= 1) return 0;
Wan-Teh Chang15ad38f2018-08-16 10:31:53 -070054 const int l = get_msb(n) + 1;
Debargha Mukherjee47748b52017-03-24 12:20:49 -070055 const int m = (1 << l) - n;
56 return v < m ? l - 1 : l;
57}
58
Debargha Mukherjee47748b52017-03-24 12:20:49 -070059// Finite subexponential code that codes a symbol v in [0, n-1] with parameter k
60void aom_write_primitive_subexpfin(aom_writer *w, uint16_t n, uint16_t k,
61 uint16_t v) {
62 int i = 0;
63 int mk = 0;
64 while (1) {
65 int b = (i ? k + i - 1 : k);
66 int a = (1 << b);
67 if (n <= mk + 3 * a) {
68 aom_write_primitive_quniform(w, n - mk, v - mk);
69 break;
70 } else {
71 int t = (v >= mk + a);
72 aom_write_bit(w, t);
73 if (t) {
74 i = i + 1;
75 mk += a;
76 } else {
77 aom_write_literal(w, v - mk, b);
78 break;
79 }
80 }
81 }
82}
83
84int aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v) {
85 int count = 0;
86 int i = 0;
87 int mk = 0;
88 while (1) {
89 int b = (i ? k + i - 1 : k);
90 int a = (1 << b);
91 if (n <= mk + 3 * a) {
92 count += aom_count_primitive_quniform(n - mk, v - mk);
93 break;
94 } else {
95 int t = (v >= mk + a);
96 count++;
97 if (t) {
98 i = i + 1;
99 mk += a;
100 } else {
101 count += b;
102 break;
103 }
104 }
105 }
106 return count;
107}
108
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.
112void aom_write_primitive_refsubexpfin(aom_writer *w, uint16_t n, uint16_t k,
Sarah Parker3e579a62017-08-23 16:53:20 -0700113 uint16_t ref, uint16_t v) {
Debargha Mukherjee47748b52017-03-24 12:20:49 -0700114 aom_write_primitive_subexpfin(w, n, k, recenter_finite_nonneg(n, ref, v));
115}
116
Sarah Parkerf1783292017-04-05 11:55:27 -0700117void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
Sarah Parker3e579a62017-08-23 16:53:20 -0700118 uint16_t k, int16_t ref,
119 int16_t v) {
Sarah Parkerf1783292017-04-05 11:55:27 -0700120 ref += n - 1;
121 v += n - 1;
122 const uint16_t scaled_n = (n << 1) - 1;
123 aom_write_primitive_refsubexpfin(w, scaled_n, k, ref, v);
124}
125
Debargha Mukherjee47748b52017-03-24 12:20:49 -0700126int aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
127 uint16_t v) {
128 return aom_count_primitive_subexpfin(n, k, recenter_finite_nonneg(n, ref, v));
129}
Sarah Parkerf1783292017-04-05 11:55:27 -0700130
131int aom_count_signed_primitive_refsubexpfin(uint16_t n, uint16_t k, int16_t ref,
132 int16_t v) {
133 ref += n - 1;
134 v += n - 1;
135 const uint16_t scaled_n = (n << 1) - 1;
136 return aom_count_primitive_refsubexpfin(scaled_n, k, ref, v);
137}