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