VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gexpgolomb.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 gexpgolomb.h
19 ///
20 
21 #ifndef G_EXP_GOLOMB__H
22 #define G_EXP_GOLOMB__H
23 
24 #include "gdef.h"
25 #include "gbititerator.h"
26 #include "gexception.h"
27 #include <string>
28 #include <stdexcept>
29 #include <limits>
30 
31 namespace G
32 {
33  class ExpGolomb ;
34 }
35 
36 /// \class G::ExpGolomb
37 /// Does exp-golomb decoding, as used in H.264 "ue(v)" syntax elements. The
38 /// encoding is bit-oriented, so byte boundaries have no significance. The
39 /// number of leading zero bits indicates the number of relevant trailing bits
40 /// following the first '1' (eg. 0 0 0 0 1 x x x x), starting with zero encoded
41 /// as '1' on its own, so 010 maps to 1, 011 to 2, 00100 to 3, 00101 to 4,
42 /// 00110 to 5, 00111 to 6 etc.
43 ///
44 /// \see H.264 spec (ISO/IEC 14496 part 10) section 9.1
45 ///
47 {
48 public:
49  G_EXCEPTION( Error , "exp-golomb bitstream underflow" ) ;
50  template <typename V> struct value /// Syntactic sugar for extracting ExpGolomb-encoded values.
51  { V n ; } ;
52 
53  template <typename U, typename T>
54  static U decode( T & begin , T end , U underflow_value ) ;
55  ///< Decodes the bitstream data provided by the bit iterator.
56  ///< Returns the underflow value on underflow.
57 
58  template <typename U, typename T>
59  static U decode( T & begin , T end , bool * underflow_p ) ;
60  ///< Overload that sets a flag on underflow.
61 
62  template <typename U,typename T>
63  static U decode( T & begin , T end ) ;
64  ///< Overload that throws on underflow.
65 
66  template <typename S, typename U>
67  static S make_signed( U ) ;
68  ///< Makes a signed value from the result of decode()
69  ///< so 0 maps to 0, 1 maps to 1, 2 maps to -1,
70  ///< 3 maps to 2, 4 maps to -2 etc.
71 
72 private:
73  template <typename U,typename T>
74  static U decode_imp( T & begin , T end , bool * , U ) ;
75 } ;
76 
77 template <typename U,typename T>
78 inline
79 U G::ExpGolomb::decode_imp( T & p , T end , bool * underflow_p , U underflow_value )
80 {
81  U result = 0U ;
82  int scale = 0 ;
83  bool counting = true ;
84  while( p != end )
85  {
86  int b = *p++ ;
87  if( counting && b == 0 )
88  scale++ ;
89  else if( counting )
90  result = 1 , counting = false ;
91  else if( b == 0 )
92  scale-- , result <<= 1 ;
93  else
94  scale-- , result <<= 1 , result++ ;
95 
96  if( !counting && scale == 0 )
97  return result-1U ;
98  }
99  if( underflow_p ) *underflow_p = true ;
100  return underflow_value ;
101 }
102 
103 template <typename U,typename T>
104 inline
105 U G::ExpGolomb::decode( T & p , T end , U underflow_value )
106 {
107  return decode_imp<U,T>( p , end , nullptr , underflow_value ) ;
108 }
109 
110 template <typename U,typename T>
111 inline
112 U G::ExpGolomb::decode( T & p , T end , bool * underflow_p )
113 {
114  return decode_imp<U,T>( p , end , underflow_p , 0 ) ;
115 }
116 
117 template <typename U,typename T>
118 inline
119 U G::ExpGolomb::decode( T & p , T end )
120 {
121  bool underflow = false ;
122  U result = decode_imp<U,T>( p , end , &underflow , 0 ) ;
123  if( underflow ) throw Error() ;
124  return result ;
125 }
126 
127 template <typename S, typename U>
128 inline
130 {
131  return u == 0U ? S(0) : ( (u & 1U) ? S((u+1U)/2U) : -S(u/2U) ) ;
132 }
133 
134 #endif
static S make_signed(U)
Makes a signed value from the result of decode() so 0 maps to 0, 1 maps to 1, 2 maps to -1...
Definition: gexpgolomb.h:129
Syntactic sugar for extracting ExpGolomb-encoded values.
Definition: gexpgolomb.h:50
Does exp-golomb decoding, as used in H.264 "ue(v)" syntax elements.
Definition: gexpgolomb.h:46
static U decode(T &begin, T end, U underflow_value)
Decodes the bitstream data provided by the bit iterator.
Definition: gexpgolomb.h:105