xref: /aosp_15_r20/external/libgav1/src/utils/bit_reader.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1*09537850SAkhilesh Sanikop // Copyright 2019 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop //      http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop 
15*09537850SAkhilesh Sanikop #include "src/utils/bit_reader.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <cassert>
18*09537850SAkhilesh Sanikop #include <cstdint>
19*09537850SAkhilesh Sanikop 
20*09537850SAkhilesh Sanikop #include "src/utils/common.h"
21*09537850SAkhilesh Sanikop 
22*09537850SAkhilesh Sanikop namespace libgav1 {
23*09537850SAkhilesh Sanikop namespace {
24*09537850SAkhilesh Sanikop 
Assign(int * const value,int assignment,bool return_value)25*09537850SAkhilesh Sanikop bool Assign(int* const value, int assignment, bool return_value) {
26*09537850SAkhilesh Sanikop   *value = assignment;
27*09537850SAkhilesh Sanikop   return return_value;
28*09537850SAkhilesh Sanikop }
29*09537850SAkhilesh Sanikop 
30*09537850SAkhilesh Sanikop // 5.9.29.
InverseRecenter(int r,int v)31*09537850SAkhilesh Sanikop int InverseRecenter(int r, int v) {
32*09537850SAkhilesh Sanikop   if (v > (r << 1)) {
33*09537850SAkhilesh Sanikop     return v;
34*09537850SAkhilesh Sanikop   }
35*09537850SAkhilesh Sanikop   if ((v & 1) != 0) {
36*09537850SAkhilesh Sanikop     return r - ((v + 1) >> 1);
37*09537850SAkhilesh Sanikop   }
38*09537850SAkhilesh Sanikop   return r + (v >> 1);
39*09537850SAkhilesh Sanikop }
40*09537850SAkhilesh Sanikop 
41*09537850SAkhilesh Sanikop }  // namespace
42*09537850SAkhilesh Sanikop 
DecodeSignedSubexpWithReference(int low,int high,int reference,int control,int * const value)43*09537850SAkhilesh Sanikop bool BitReader::DecodeSignedSubexpWithReference(int low, int high,
44*09537850SAkhilesh Sanikop                                                 int reference, int control,
45*09537850SAkhilesh Sanikop                                                 int* const value) {
46*09537850SAkhilesh Sanikop   if (!DecodeUnsignedSubexpWithReference(high - low, reference - low, control,
47*09537850SAkhilesh Sanikop                                          value)) {
48*09537850SAkhilesh Sanikop     return false;
49*09537850SAkhilesh Sanikop   }
50*09537850SAkhilesh Sanikop   *value += low;
51*09537850SAkhilesh Sanikop   return true;
52*09537850SAkhilesh Sanikop }
53*09537850SAkhilesh Sanikop 
DecodeUniform(int n,int * const value)54*09537850SAkhilesh Sanikop bool BitReader::DecodeUniform(int n, int* const value) {
55*09537850SAkhilesh Sanikop   if (n <= 1) {
56*09537850SAkhilesh Sanikop     return Assign(value, 0, true);
57*09537850SAkhilesh Sanikop   }
58*09537850SAkhilesh Sanikop   const int w = FloorLog2(n) + 1;
59*09537850SAkhilesh Sanikop   const int m = (1 << w) - n;
60*09537850SAkhilesh Sanikop   assert(w - 1 < 32);
61*09537850SAkhilesh Sanikop   const int v = static_cast<int>(ReadLiteral(w - 1));
62*09537850SAkhilesh Sanikop   if (v == -1) {
63*09537850SAkhilesh Sanikop     return Assign(value, 0, false);
64*09537850SAkhilesh Sanikop   }
65*09537850SAkhilesh Sanikop   if (v < m) {
66*09537850SAkhilesh Sanikop     return Assign(value, v, true);
67*09537850SAkhilesh Sanikop   }
68*09537850SAkhilesh Sanikop   const int extra_bit = ReadBit();
69*09537850SAkhilesh Sanikop   if (extra_bit == -1) {
70*09537850SAkhilesh Sanikop     return Assign(value, 0, false);
71*09537850SAkhilesh Sanikop   }
72*09537850SAkhilesh Sanikop   return Assign(value, (v << 1) - m + extra_bit, true);
73*09537850SAkhilesh Sanikop }
74*09537850SAkhilesh Sanikop 
DecodeUnsignedSubexpWithReference(int mx,int reference,int control,int * const value)75*09537850SAkhilesh Sanikop bool BitReader::DecodeUnsignedSubexpWithReference(int mx, int reference,
76*09537850SAkhilesh Sanikop                                                   int control,
77*09537850SAkhilesh Sanikop                                                   int* const value) {
78*09537850SAkhilesh Sanikop   int v;
79*09537850SAkhilesh Sanikop   if (!DecodeSubexp(mx, control, &v)) return false;
80*09537850SAkhilesh Sanikop   if ((reference << 1) <= mx) {
81*09537850SAkhilesh Sanikop     *value = InverseRecenter(reference, v);
82*09537850SAkhilesh Sanikop   } else {
83*09537850SAkhilesh Sanikop     *value = mx - 1 - InverseRecenter(mx - 1 - reference, v);
84*09537850SAkhilesh Sanikop   }
85*09537850SAkhilesh Sanikop   return true;
86*09537850SAkhilesh Sanikop }
87*09537850SAkhilesh Sanikop 
DecodeSubexp(int num_symbols,int control,int * const value)88*09537850SAkhilesh Sanikop bool BitReader::DecodeSubexp(int num_symbols, int control, int* const value) {
89*09537850SAkhilesh Sanikop   int i = 0;
90*09537850SAkhilesh Sanikop   int mk = 0;
91*09537850SAkhilesh Sanikop   while (true) {
92*09537850SAkhilesh Sanikop     const int b = (i != 0) ? control + i - 1 : control;
93*09537850SAkhilesh Sanikop     if (b >= 32) {
94*09537850SAkhilesh Sanikop       return Assign(value, 0, false);
95*09537850SAkhilesh Sanikop     }
96*09537850SAkhilesh Sanikop     const int a = 1 << b;
97*09537850SAkhilesh Sanikop     if (num_symbols <= mk + 3 * a) {
98*09537850SAkhilesh Sanikop       if (!DecodeUniform(num_symbols - mk, value)) return false;
99*09537850SAkhilesh Sanikop       *value += mk;
100*09537850SAkhilesh Sanikop       return true;
101*09537850SAkhilesh Sanikop     }
102*09537850SAkhilesh Sanikop     const int8_t subexp_more_bits = ReadBit();
103*09537850SAkhilesh Sanikop     if (subexp_more_bits == -1) return false;
104*09537850SAkhilesh Sanikop     if (subexp_more_bits != 0) {
105*09537850SAkhilesh Sanikop       ++i;
106*09537850SAkhilesh Sanikop       mk += a;
107*09537850SAkhilesh Sanikop     } else {
108*09537850SAkhilesh Sanikop       const int subexp_bits = static_cast<int>(ReadLiteral(b));
109*09537850SAkhilesh Sanikop       if (subexp_bits == -1) {
110*09537850SAkhilesh Sanikop         return Assign(value, 0, false);
111*09537850SAkhilesh Sanikop       }
112*09537850SAkhilesh Sanikop       return Assign(value, subexp_bits + mk, true);
113*09537850SAkhilesh Sanikop     }
114*09537850SAkhilesh Sanikop   }
115*09537850SAkhilesh Sanikop }
116*09537850SAkhilesh Sanikop 
117*09537850SAkhilesh Sanikop }  // namespace libgav1
118