Coverage Report

Created: 2022-08-24 06:11

/src/aom/aom_dsp/binary_codes_writer.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2017, 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
#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"
16
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
0
                                   unsigned int abs_bits) {
24
0
  if (v == 0) {
25
0
    aom_write_bit(w, 0);
26
0
  } else {
27
0
    const int x = abs(v);
28
0
    const int s = v < 0;
29
0
    aom_write_bit(w, 1);
30
0
    aom_write_bit(w, s);
31
0
    aom_write_literal(w, x - 1, abs_bits);
32
0
  }
33
0
}
34
35
0
int aom_count_primitive_symmetric(int16_t v, unsigned int abs_bits) {
36
0
  return (v == 0 ? 1 : abs_bits + 2);
37
0
}
38
39
// Encodes a value v in [0, n-1] quasi-uniformly
40
0
void aom_write_primitive_quniform(aom_writer *w, uint16_t n, uint16_t v) {
41
0
  if (n <= 1) return;
42
0
  const int l = get_msb(n) + 1;
43
0
  const int m = (1 << l) - n;
44
0
  if (v < m) {
45
0
    aom_write_literal(w, v, l - 1);
46
0
  } else {
47
0
    aom_write_literal(w, m + ((v - m) >> 1), l - 1);
48
0
    aom_write_bit(w, (v - m) & 1);
49
0
  }
50
0
}
51
52
0
int aom_count_primitive_quniform(uint16_t n, uint16_t v) {
53
0
  if (n <= 1) return 0;
54
0
  const int l = get_msb(n) + 1;
55
0
  const int m = (1 << l) - n;
56
0
  return v < m ? l - 1 : l;
57
0
}
58
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,
61
0
                                   uint16_t v) {
62
0
  int i = 0;
63
0
  int mk = 0;
64
0
  while (1) {
65
0
    int b = (i ? k + i - 1 : k);
66
0
    int a = (1 << b);
67
0
    if (n <= mk + 3 * a) {
68
0
      aom_write_primitive_quniform(w, n - mk, v - mk);
69
0
      break;
70
0
    } else {
71
0
      int t = (v >= mk + a);
72
0
      aom_write_bit(w, t);
73
0
      if (t) {
74
0
        i = i + 1;
75
0
        mk += a;
76
0
      } else {
77
0
        aom_write_literal(w, v - mk, b);
78
0
        break;
79
0
      }
80
0
    }
81
0
  }
82
0
}
83
84
0
int aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v) {
85
0
  int count = 0;
86
0
  int i = 0;
87
0
  int mk = 0;
88
0
  while (1) {
89
0
    int b = (i ? k + i - 1 : k);
90
0
    int a = (1 << b);
91
0
    if (n <= mk + 3 * a) {
92
0
      count += aom_count_primitive_quniform(n - mk, v - mk);
93
0
      break;
94
0
    } else {
95
0
      int t = (v >= mk + a);
96
0
      count++;
97
0
      if (t) {
98
0
        i = i + 1;
99
0
        mk += a;
100
0
      } else {
101
0
        count += b;
102
0
        break;
103
0
      }
104
0
    }
105
0
  }
106
0
  return count;
107
0
}
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.
112
void aom_write_primitive_refsubexpfin(aom_writer *w, uint16_t n, uint16_t k,
113
0
                                      uint16_t ref, uint16_t v) {
114
0
  aom_write_primitive_subexpfin(w, n, k, recenter_finite_nonneg(n, ref, v));
115
0
}
116
117
void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
118
                                             uint16_t k, int16_t ref,
119
0
                                             int16_t v) {
120
0
  ref += n - 1;
121
0
  v += n - 1;
122
0
  const uint16_t scaled_n = (n << 1) - 1;
123
0
  aom_write_primitive_refsubexpfin(w, scaled_n, k, ref, v);
124
0
}
125
126
int aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
127
0
                                     uint16_t v) {
128
0
  return aom_count_primitive_subexpfin(n, k, recenter_finite_nonneg(n, ref, v));
129
0
}
130
131
int aom_count_signed_primitive_refsubexpfin(uint16_t n, uint16_t k, int16_t ref,
132
0
                                            int16_t v) {
133
0
  ref += n - 1;
134
0
  v += n - 1;
135
0
  const uint16_t scaled_n = (n << 1) - 1;
136
0
  return aom_count_primitive_refsubexpfin(scaled_n, k, ref, v);
137
0
}