]> git.sesse.net Git - x264/blob - common/bs.h
support pkg-config.
[x264] / common / bs.h
1 /*****************************************************************************
2  * bs.h :
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: bs.h,v 1.1 2004/06/03 19:27:06 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #ifdef _BS_H
25 #warning FIXME Multiple inclusion of bs.h
26 #else
27 #define _BS_H
28
29 typedef struct bs_s
30 {
31     uint8_t *p_start;
32     uint8_t *p;
33     uint8_t *p_end;
34
35     int     i_left;    /* i_count number of available bits */
36     int     i_bits_encoded; /* RD only */
37 } bs_t;
38
39 static inline void bs_init( bs_t *s, void *p_data, int i_data )
40 {
41     s->p_start = p_data;
42     s->p       = p_data;
43     s->p_end   = s->p + i_data;
44     s->i_left  = 8;
45 }
46 static inline int bs_pos( bs_t *s )
47 {
48     return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
49 }
50 static inline int bs_eof( bs_t *s )
51 {
52     return( s->p >= s->p_end ? 1: 0 );
53 }
54 static inline uint32_t bs_read( bs_t *s, int i_count )
55 {
56      static uint32_t i_mask[33] ={0x00,
57                                   0x01,      0x03,      0x07,      0x0f,
58                                   0x1f,      0x3f,      0x7f,      0xff,
59                                   0x1ff,     0x3ff,     0x7ff,     0xfff,
60                                   0x1fff,    0x3fff,    0x7fff,    0xffff,
61                                   0x1ffff,   0x3ffff,   0x7ffff,   0xfffff,
62                                   0x1fffff,  0x3fffff,  0x7fffff,  0xffffff,
63                                   0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
64                                   0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
65     int      i_shr;
66     uint32_t i_result = 0;
67
68     while( i_count > 0 )
69     {
70         if( s->p >= s->p_end )
71         {
72             break;
73         }
74
75         if( ( i_shr = s->i_left - i_count ) >= 0 )
76         {
77             /* more in the buffer than requested */
78             i_result |= ( *s->p >> i_shr )&i_mask[i_count];
79             s->i_left -= i_count;
80             if( s->i_left == 0 )
81             {
82                 s->p++;
83                 s->i_left = 8;
84             }
85             return( i_result );
86         }
87         else
88         {
89             /* less in the buffer than requested */
90            i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
91            i_count  -= s->i_left;
92            s->p++;
93            s->i_left = 8;
94         }
95     }
96
97     return( i_result );
98 }
99
100 static inline uint32_t bs_read1( bs_t *s )
101 {
102
103     if( s->p < s->p_end )
104     {
105         unsigned int i_result;
106
107         s->i_left--;
108         i_result = ( *s->p >> s->i_left )&0x01;
109         if( s->i_left == 0 )
110         {
111             s->p++;
112             s->i_left = 8;
113         }
114         return i_result;
115     }
116
117     return 0;
118 }
119 static inline uint32_t bs_show( bs_t *s, int i_count )
120 {
121     if( s->p < s->p_end && i_count > 0 )
122     {
123         uint32_t i_cache = ((s->p[0] << 24)+(s->p[1] << 16)+(s->p[2] << 8)+s->p[3]) << (8-s->i_left);
124         return( i_cache >> ( 32 - i_count) );
125     }
126     return 0;
127 }
128
129 /* TODO optimize */
130 static inline void bs_skip( bs_t *s, int i_count )
131 {
132     s->i_left -= i_count;
133
134     while( s->i_left <= 0 )
135     {
136         s->p++;
137         s->i_left += 8;
138     }
139 }
140
141
142 static inline int bs_read_ue( bs_t *s )
143 {
144     int i = 0;
145
146     while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 )
147     {
148         i++;
149     }
150     return( ( 1 << i) - 1 + bs_read( s, i ) );
151 }
152 static inline int bs_read_se( bs_t *s )
153 {
154     int val = bs_read_ue( s );
155
156     return val&0x01 ? (val+1)/2 : -(val/2);
157 }
158
159 static inline int bs_read_te( bs_t *s, int x )
160 {
161     if( x == 1 )
162     {
163         return 1 - bs_read1( s );
164     }
165     else if( x > 1 )
166     {
167         return bs_read_ue( s );
168     }
169     return 0;
170 }
171
172 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
173 {
174     if( s->p >= s->p_end - 4 )
175         return;
176     while( i_count > 0 )
177     {
178         if( i_count < 32 )
179             i_bits &= (1<<i_count)-1;
180         if( i_count < s->i_left )
181         {
182             *s->p = (*s->p << i_count) | i_bits;
183             s->i_left -= i_count;
184             break;
185         }
186         else
187         {
188             *s->p = (*s->p << s->i_left) | (i_bits >> (i_count - s->i_left));
189             i_count -= s->i_left;
190             s->p++;
191             s->i_left = 8;
192         }
193     }
194 }
195
196 static inline void bs_write1( bs_t *s, uint32_t i_bit )
197 {
198     if( s->p < s->p_end )
199     {
200         *s->p <<= 1;
201         *s->p |= i_bit;
202         s->i_left--;
203         if( s->i_left == 0 )
204         {
205             s->p++;
206             s->i_left = 8;
207         }
208     }
209 }
210
211 static inline void bs_align_0( bs_t *s )
212 {
213     if( s->i_left != 8 )
214     {
215         *s->p <<= s->i_left;
216         s->i_left = 8;
217         s->p++;
218     }
219 }
220 static inline void bs_align_1( bs_t *s )
221 {
222     if( s->i_left != 8 )
223     {
224         *s->p <<= s->i_left;
225         *s->p |= (1 << s->i_left) - 1;
226         s->i_left = 8;
227         s->p++;
228     }
229 }
230 static inline void bs_align( bs_t *s )
231 {
232     bs_align_0( s );
233 }
234
235
236
237 /* golomb functions */
238
239 static inline void bs_write_ue( bs_t *s, unsigned int val )
240 {
241     int i_size = 0;
242     static const int i_size0_255[256] =
243     {
244         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,
245         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,
246         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,
247         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,
248         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,
249         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,
250         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,
251         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
252     };
253
254     if( val == 0 )
255     {
256         bs_write1( s, 1 );
257     }
258     else
259     {
260         unsigned int tmp = ++val;
261
262         if( tmp >= 0x00010000 )
263         {
264             i_size += 16;
265             tmp >>= 16;
266         }
267         if( tmp >= 0x100 )
268         {
269             i_size += 8;
270             tmp >>= 8;
271         }
272         i_size += i_size0_255[tmp];
273
274         bs_write( s, 2 * i_size - 1, val );
275     }
276 }
277
278 static inline void bs_write_se( bs_t *s, int val )
279 {
280     bs_write_ue( s, val <= 0 ? -val * 2 : val * 2 - 1);
281 }
282
283 static inline void bs_write_te( bs_t *s, int x, int val )
284 {
285     if( x == 1 )
286     {
287         bs_write1( s, 1&~val );
288     }
289     else if( x > 1 )
290     {
291         bs_write_ue( s, val );
292     }
293 }
294
295 static inline void bs_rbsp_trailing( bs_t *s )
296 {
297     bs_write1( s, 1 );
298     if( s->i_left != 8 )
299     {
300         bs_write( s, s->i_left, 0x00 );
301     }
302 }
303
304 static inline int bs_size_ue( unsigned int val )
305 {
306     static const int i_size0_254[255] =
307     {
308         1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
309         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
310         11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
311         11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
312         13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
313         13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
314         13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
315         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
316         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
317         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
318         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
319         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
320     };
321
322     if( val < 255 )
323     {
324         return i_size0_254[val];
325     }
326     else
327     {
328         int i_size = 0;
329
330         val++;
331
332         if( val >= 0x10000 )
333         {
334             i_size += 32;
335             val = (val >> 16) - 1;
336         }
337         if( val >= 0x100 )
338         {
339             i_size += 16;
340             val = (val >> 8) - 1;
341         }
342         return i_size0_254[val] + i_size;
343     }
344 }
345
346 static inline int bs_size_se( int val )
347 {
348     return bs_size_ue( val <= 0 ? -val * 2 : val * 2 - 1);
349 }
350
351 static inline int bs_size_te( int x, int val )
352 {
353     if( x == 1 )
354     {
355         return 1;
356     }
357     else if( x > 1 )
358     {
359         return bs_size_ue( val );
360     }
361     return 0;
362 }
363
364
365
366 #endif