]> git.sesse.net Git - x264/blob - common/bs.h
Update file headers throughout x264
[x264] / common / bs.h
1 /*****************************************************************************
2  * bs.h :
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar <fenrir@via.ecp.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
19  *****************************************************************************/
20
21 #ifndef X264_BS_H
22 #define X264_BS_H
23
24 typedef struct bs_s
25 {
26     uint8_t *p_start;
27     uint8_t *p;
28     uint8_t *p_end;
29
30     int     i_left;    /* i_count number of available bits */
31     int     i_bits_encoded; /* RD only */
32 } bs_t;
33
34 static inline void bs_init( bs_t *s, void *p_data, int i_data )
35 {
36     s->p_start = p_data;
37     s->p       = p_data;
38     s->p_end   = s->p + i_data;
39     s->i_left  = 8;
40 }
41 static inline int bs_pos( bs_t *s )
42 {
43     return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
44 }
45
46 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
47 {
48     while( i_count > 0 )
49     {
50         if( i_count < 32 )
51             i_bits &= (1<<i_count)-1;
52         if( i_count < s->i_left )
53         {
54             *s->p = (*s->p << i_count) | i_bits;
55             s->i_left -= i_count;
56             break;
57         }
58         else
59         {
60             *s->p = (*s->p << s->i_left) | (i_bits >> (i_count - s->i_left));
61             i_count -= s->i_left;
62             s->p++;
63             s->i_left = 8;
64         }
65     }
66 }
67
68 static inline void bs_write1( bs_t *s, uint32_t i_bit )
69 {
70     *s->p <<= 1;
71     *s->p |= i_bit;
72     s->i_left--;
73     if( s->i_left == 0 )
74     {
75         s->p++;
76         s->i_left = 8;
77     }
78 }
79
80 static inline void bs_align_0( bs_t *s )
81 {
82     if( s->i_left != 8 )
83     {
84         *s->p <<= s->i_left;
85         s->i_left = 8;
86         s->p++;
87     }
88 }
89 static inline void bs_align_1( bs_t *s )
90 {
91     if( s->i_left != 8 )
92     {
93         *s->p <<= s->i_left;
94         *s->p |= (1 << s->i_left) - 1;
95         s->i_left = 8;
96         s->p++;
97     }
98 }
99 static inline void bs_align( bs_t *s )
100 {
101     bs_align_0( s );
102 }
103
104
105
106 /* golomb functions */
107
108 static inline void bs_write_ue( bs_t *s, unsigned int val )
109 {
110     int i_size = 0;
111     static const uint8_t i_size0_255[256] =
112     {
113         1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
114         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
115         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
116         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
117         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
118         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
119         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
120         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
121     };
122
123     if( val == 0 )
124     {
125         bs_write1( s, 1 );
126     }
127     else
128     {
129         unsigned int tmp = ++val;
130
131         if( tmp >= 0x00010000 )
132         {
133             i_size += 16;
134             tmp >>= 16;
135         }
136         if( tmp >= 0x100 )
137         {
138             i_size += 8;
139             tmp >>= 8;
140         }
141         i_size += i_size0_255[tmp];
142
143         bs_write( s, 2 * i_size - 1, val );
144     }
145 }
146
147 static inline void bs_write_se( bs_t *s, int val )
148 {
149     bs_write_ue( s, val <= 0 ? -val * 2 : val * 2 - 1);
150 }
151
152 static inline void bs_write_te( bs_t *s, int x, int val )
153 {
154     if( x == 1 )
155     {
156         bs_write1( s, 1&~val );
157     }
158     else if( x > 1 )
159     {
160         bs_write_ue( s, val );
161     }
162 }
163
164 static inline void bs_rbsp_trailing( bs_t *s )
165 {
166     bs_write1( s, 1 );
167     if( s->i_left != 8 )
168     {
169         bs_write( s, s->i_left, 0x00 );
170     }
171 }
172
173 static inline int bs_size_ue( unsigned int val )
174 {
175     static const uint8_t i_size0_254[255] =
176     {
177         1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
178         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
179         11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
180         11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
181         13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
182         13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
183         13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
184         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
185         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
186         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
187         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
188         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
189     };
190
191     if( val < 255 )
192     {
193         return i_size0_254[val];
194     }
195     else
196     {
197         int i_size = 0;
198
199         val++;
200
201         if( val >= 0x10000 )
202         {
203             i_size += 32;
204             val = (val >> 16) - 1;
205         }
206         if( val >= 0x100 )
207         {
208             i_size += 16;
209             val = (val >> 8) - 1;
210         }
211         return i_size0_254[val] + i_size;
212     }
213 }
214
215 static inline int bs_size_se( int val )
216 {
217     return bs_size_ue( val <= 0 ? -val * 2 : val * 2 - 1);
218 }
219
220 static inline int bs_size_te( int x, int val )
221 {
222     if( x == 1 )
223     {
224         return 1;
225     }
226     else if( x > 1 )
227     {
228         return bs_size_ue( val );
229     }
230     return 0;
231 }
232
233 #endif