• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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