VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gbitstream.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gbitstream.h
19 ///
20 
21 #ifndef G_BIT_STREAM__H
22 #define G_BIT_STREAM__H
23 
24 #include "gdef.h"
25 #include "gbititerator.h"
26 #include "gexpgolomb.h"
27 #include <stdexcept>
28 
29 namespace G
30 {
31 
32 /// \class G::bit_stream
33 /// A class for pulling integer values of various widths out of a bit stream.
34 /// Also supports exp-golomb encoding.
35 ///
36 /// The template parameter must be G::bit_iterator<X>, for some underlying
37 /// byte-wise forward iterator type X.
38 ///
39 /// Eg:
40 /// \code
41 /// typedef G::ExpGolomb::value<unsigned> uev_t ;
42 /// typedef G::ExpGolomb::value<signed> sev_t ;
43 /// bit_stream<bit_iterator<char*>> bs( data.begin() , data.end() ) ;
44 /// g_uint16_t w ;
45 /// g_uint32_t dw ;
46 /// uev_t uev ;
47 /// sev_t uev ;
48 /// bs >> w >> dw >> uev >> sev ;
49 /// bs.check() ; // throw on underflow
50 /// \endcode
51 ///
52 /// \see G::bit_iterator
53 ///
54 template <typename T>
56 {
57 public:
58  typedef T bit_iterator_type ;
59  typedef typename T::byte_iterator_type static_assert_T_is_bit_iterator ;
60 
61  bit_stream( T begin , T end ) ;
62  ///< Constructor taking a G::bit_iterator<X> pair where the underlying
63  ///< byte source has a well-defined end.
64  ///<
65  ///< Prefer the other overload if the bit iterator is based on an underlying
66  ///< stream, because the underlying byte stream will be left at a poorly-defined
67  ///< read position after the bit_stream goes away.
68 
69  explicit bit_stream( T begin ) ;
70  ///< Constructor overload for an G::bit_iterator that has no well-defined
71  ///< end; typically bit iterators that are already based on a stream,
72  ///< such as G::bit_stream<std::istream_iterator<char>>.
73 
74  bool get_bool() ;
75  ///< Extracts a boolean. Sets the fail state on underflow.
76 
77  unsigned char get( int bits ) ;
78  ///< Gets a number of bits, returned in a byte. Sets the fail state on underflow.
79  ///< Precondition: bits <= 8
80 
81  unsigned char get() ;
82  ///< Gets a byte. Sets the fail state on underflow.
83  ///< This is matches std::istream::get().
84 
85  unsigned char get_byte() ;
86  ///< Gets a byte. Sets the fail state on underflow.
87 
88  g_uint16_t get_word() ;
89  ///< Gets a word. Sets the fail state on underflow.
90 
91  g_uint32_t get_dword() ;
92  ///< Gets a dword. Sets the fail state on underflow.
93 
94  int get_signed_golomb() ;
95  ///< Gets an exp-golomb encoded signed value. Sets the fail state on underflow.
96 
97  unsigned int get_unsigned_golomb() ;
98  ///< Gets an exp-golomb encoded unsigned value. Sets the fail state on underflow.
99 
100  bool at_end( bool default_ = false ) const ;
101  ///< Returns true if the bit iterator is equal to the end iterator.
102  ///< Returns the default if the end iterator was not supplied in the ctor.
103 
104  bool fail() const ;
105  ///< Returns the fail state.
106 
107  bool good() const ;
108  ///< Returns !fail().
109 
110  void check() ;
111  ///< Checks for a failed state and throws if failed.
112 
113  size_t tellg() const ;
114  ///< Returns the current bit offset.
115 
116 private:
117  template <typename U> U get_imp( int nbits = sizeof(U) * 8 ) ;
118 
119 private:
120  T m_begin ;
121  T m_p ;
122  T m_end ;
123  bool m_end_defined ;
124  bool m_failbit ;
125 } ;
126 
127 template <typename T>
128 bit_stream<T>::bit_stream( T begin , T end ) :
129  m_begin(begin) ,
130  m_p(begin) ,
131  m_end(end) ,
132  m_end_defined(true) ,
133  m_failbit(false)
134 {
135 }
136 
137 template <typename T>
139  m_begin(begin) ,
140  m_p(begin) ,
141  m_end(begin) ,
142  m_end_defined(false) ,
143  m_failbit(false)
144 {
145 }
146 
147 template <typename T>
148 template <typename U> U bit_stream<T>::get_imp( int nbits )
149 {
150  U result = 0U ;
151  for( int i = 0 ; i < nbits ; i++ )
152  {
153  if( m_end_defined && m_p == m_end )
154  {
155  m_failbit = true ;
156  return 0U ;
157  }
158  result <<= 1 ;
159  result += *m_p++ ;
160  }
161  return result ;
162 }
163 
164 template <typename T>
166 {
167  return get_imp<unsigned char>( 1 ) == 1U ;
168 }
169 
170 template <typename T>
171 unsigned char bit_stream<T>::get()
172 {
173  return get_imp<unsigned char>( 8 ) ;
174 }
175 
176 template <typename T>
177 unsigned char bit_stream<T>::get( int n )
178 {
179  return get_imp<unsigned char>( n ) ;
180 }
181 
182 template <typename T>
183 unsigned char bit_stream<T>::get_byte()
184 {
185  return get_imp<unsigned char>( 8 ) ;
186 }
187 
188 template <typename T>
190 {
191  return get_imp<g_uint16_t>( 16 ) ;
192 }
193 
194 template <typename T>
196 {
197  return get_imp<g_uint32_t>( 32 ) ;
198 }
199 
200 template <typename T>
202 {
203  unsigned int u = ExpGolomb::decode<unsigned int>( m_p , m_end , &m_failbit ) ;
204  return ExpGolomb::make_signed<int>( u ) ;
205 }
206 
207 template <typename T>
209 {
210  return ExpGolomb::decode<unsigned int>( m_p , m_end , &m_failbit ) ;
211 }
212 
213 template <typename T>
214 bool bit_stream<T>::at_end( bool default_ ) const
215 {
216  return m_end_defined ? ( m_p == m_end ) : default_ ;
217 }
218 
219 template <typename T>
221 {
222  return !fail() ;
223 }
224 
225 template <typename T>
227 {
228  return m_failbit ;
229 }
230 
231 template <typename T>
233 {
234  if( m_failbit )
235  throw std::underflow_error("bitstream underflow") ;
236 }
237 
238 template <typename T>
239 size_t bit_stream<T>::tellg() const
240 {
241  return m_p - m_begin ;
242 }
243 
244 template <typename T>
245 bit_stream<T> & operator>>( bit_stream<T> & stream , bool & value )
246 {
247  value = stream.get_bool() ;
248  return stream ;
249 }
250 
251 template <typename T>
252 bit_stream<T> & operator>>( bit_stream<T> & stream , unsigned char & value )
253 {
254  value = stream.get_byte() ;
255  return stream ;
256 }
257 
258 template <typename T>
259 bit_stream<T> & operator>>( bit_stream<T> & stream , g_uint16_t & value )
260 {
261  value = stream.get_word() ;
262  return stream ;
263 }
264 
265 template <typename T>
266 bit_stream<T> & operator>>( bit_stream<T> & stream , g_uint32_t & value )
267 {
268  value = stream.get_dword() ;
269  return stream ;
270 }
271 
272 template <typename T>
273 bit_stream<T> & operator>>( bit_stream<T> & stream , ExpGolomb::value<unsigned int> & value )
274 {
275  value.n = stream.get_unsigned_golomb() ;
276  return stream ;
277 }
278 
279 template <typename T>
280 bit_stream<T> & operator>>( bit_stream<T> & stream , ExpGolomb::value<int> & value )
281 {
282  value.n = stream.get_signed_golomb() ;
283  return stream ;
284 }
285 
286 }
287 
288 #endif
void check()
Checks for a failed state and throws if failed.
Definition: gbitstream.h:232
g_uint16_t get_word()
Gets a word. Sets the fail state on underflow.
Definition: gbitstream.h:189
bit_stream(T begin, T end)
Constructor taking a G::bit_iterator<X> pair where the underlying byte source has a well-defined end...
Definition: gbitstream.h:128
bool good() const
Returns !fail().
Definition: gbitstream.h:220
unsigned int get_unsigned_golomb()
Gets an exp-golomb encoded unsigned value. Sets the fail state on underflow.
Definition: gbitstream.h:208
unsigned char get_byte()
Gets a byte. Sets the fail state on underflow.
Definition: gbitstream.h:183
bool at_end(bool default_=false) const
Returns true if the bit iterator is equal to the end iterator.
Definition: gbitstream.h:214
int get_signed_golomb()
Gets an exp-golomb encoded signed value. Sets the fail state on underflow.
Definition: gbitstream.h:201
A class for pulling integer values of various widths out of a bit stream.
Definition: gbitstream.h:55
bool fail() const
Returns the fail state.
Definition: gbitstream.h:226
size_t tellg() const
Returns the current bit offset.
Definition: gbitstream.h:239
bool get_bool()
Extracts a boolean. Sets the fail state on underflow.
Definition: gbitstream.h:165
unsigned char get()
Gets a byte.
Definition: gbitstream.h:171
g_uint32_t get_dword()
Gets a dword. Sets the fail state on underflow.
Definition: gbitstream.h:195