opengl: fix unused variable
[vlc.git] / include / vlc_bits.h
blobb6b222125b52cb00a7cf5ea6691840ac68d36ef4
1 /*****************************************************************************
2 * vlc_bits.h : Bit handling helpers
3 *****************************************************************************
4 * Copyright (C) 2001, 2002, 2003, 2006, 2015 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7 * Gildas Bazin <gbazin at videolan dot org>
8 * Rafaël Carré <funman at videolan dot org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
24 #ifndef VLC_BITS_H
25 #define VLC_BITS_H 1
27 #include <vlc_common.h>
29 /**
30 * \file
31 * This file defines functions, structures for handling streams of bits in vlc
34 typedef struct bs_s bs_t;
36 typedef struct
38 /* forward read modifier (p_start, p_end, p_fwpriv, count, pos, remain) */
39 size_t (*pf_byte_forward)(bs_t *, size_t);
40 size_t (*pf_byte_pos)(const bs_t *);
41 size_t (*pf_byte_remain)(const bs_t *);
42 } bs_byte_callbacks_t;
44 typedef struct bs_s
46 uint8_t *p_start;
47 uint8_t *p; /* points to currently read/written byte */
48 uint8_t *p_end;
50 uint8_t i_left; /* i_count number of available bits */
51 bool b_read_only;
53 bs_byte_callbacks_t cb;
54 void *p_priv;
55 } bs_t;
57 static size_t bs_impl_bytes_forward( bs_t *s, size_t i_count )
59 if( s->p == NULL )
61 s->p = s->p_start;
62 return 1;
65 if( s->p >= s->p_end )
66 return 0;
68 if( (size_t) (s->p_end - s->p) < i_count )
69 i_count = s->p_end - s->p;
70 s->p += i_count;
71 return i_count;
74 static size_t bs_impl_bytes_remain( const bs_t *s )
76 if( s->p )
77 return s->p < s->p_end ? s->p_end - s->p - 1: 0;
78 else
79 return s->p_end - s->p_start;
82 static size_t bs_impl_bytes_pos( const bs_t *s )
84 if( s->p )
85 return s->p < s->p_end ? s->p - s->p_start + 1 : s->p - s->p_start;
86 else
87 return 0;
90 static inline void bs_init_custom( bs_t *s, const void *p_data, size_t i_data,
91 const bs_byte_callbacks_t *cb, void *priv )
93 s->p_start = (uint8_t *)p_data;
94 s->p = NULL;
95 s->p_end = s->p_start + i_data;
96 s->i_left = 0;
97 s->b_read_only = true;
98 s->p_priv = priv;
99 s->cb = *cb;
102 static inline void bs_init( bs_t *s, const void *p_data, size_t i_data )
104 bs_byte_callbacks_t cb = {
105 bs_impl_bytes_forward,
106 bs_impl_bytes_pos,
107 bs_impl_bytes_remain,
109 bs_init_custom( s, p_data, i_data, &cb, NULL );
112 static inline void bs_write_init( bs_t *s, void *p_data, size_t i_data )
114 bs_init( s, (const void *) p_data, i_data );
115 s->b_read_only = false;
118 static inline int bs_refill( bs_t *s )
120 if( s->i_left == 0 )
122 if( s->cb.pf_byte_forward( s, 1 ) != 1 )
123 return -1;
125 if( s->p < s->p_end )
126 s->i_left = 8;
128 return s->i_left > 0 ? 0 : 1;
131 static inline bool bs_eof( bs_t *s )
133 return bs_refill( s ) != 0;
136 static inline size_t bs_pos( const bs_t *s )
138 return 8 * s->cb.pf_byte_pos( s ) - s->i_left;
141 static inline size_t bs_remain( const bs_t *s )
143 return 8 * s->cb.pf_byte_remain( s ) + s->i_left;
146 static inline void bs_skip( bs_t *s, size_t i_count )
148 if( i_count == 0 )
149 return;
151 if( bs_refill( s ) )
152 return;
154 if( i_count > s->i_left )
156 i_count -= s->i_left;
157 s->i_left = 0;
158 if( i_count / 8 )
159 s->cb.pf_byte_forward( s, i_count / 8 );
160 i_count = i_count % 8;
161 if( i_count > 0 && !bs_refill( s ) )
162 s->i_left = 8 - i_count;
164 else s->i_left -= i_count;
167 static inline uint32_t bs_read( bs_t *s, uint8_t i_count )
169 static const uint32_t i_mask[33] =
170 { 0x00,
171 0x01, 0x03, 0x07, 0x0f,
172 0x1f, 0x3f, 0x7f, 0xff,
173 0x1ff, 0x3ff, 0x7ff, 0xfff,
174 0x1fff, 0x3fff, 0x7fff, 0xffff,
175 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
176 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
177 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
178 0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
179 uint8_t i_shr, i_drop = 0;
180 uint32_t i_result = 0;
182 if( i_count > 32 )
184 i_drop = i_count - 32;
185 i_count = 32;
188 while( i_count > 0 )
190 if( bs_refill( s ) )
191 break;
193 if( s->i_left > i_count )
195 i_shr = s->i_left - i_count;
196 /* more in the buffer than requested */
197 i_result |= ( *s->p >> i_shr )&i_mask[i_count];
198 s->i_left -= i_count;
199 break;
201 else
203 i_shr = i_count - s->i_left;
204 /* less in the buffer than requested */
205 if( i_shr >= 32 )
206 i_result = 0;
207 else
208 i_result |= (*s->p&i_mask[s->i_left]) << i_shr;
209 i_count -= s->i_left;
210 s->i_left = 0;
214 if( i_drop )
215 bs_skip( s, i_drop );
217 return( i_result );
220 static inline uint32_t bs_read1( bs_t *s )
222 if( bs_refill( s ) )
223 return 0;
224 s->i_left--;
225 return ( *s->p >> s->i_left )&0x01;
228 static inline void bs_write( bs_t *s, uint8_t i_count, uint32_t i_bits )
230 if( s->b_read_only )
231 return;
233 while( i_count > 0 )
235 if( bs_refill( s ) )
236 break;
238 i_count--;
240 if( ( i_bits >> i_count )&0x01 )
242 *s->p |= 1 << ( s->i_left - 1 );
244 else
246 *s->p &= ~( 1 << ( s->i_left - 1 ) );
248 s->i_left--;
252 static inline bool bs_aligned( bs_t *s )
254 return s->i_left % 8 == 0;
257 static inline void bs_align( bs_t *s )
259 if( s->i_left % 8 )
260 s->i_left = 0;
263 static inline void bs_write_align( bs_t *s, uint8_t v )
265 if( !s->b_read_only && (s->i_left % 8) )
266 bs_write( s, s->i_left, v ? 0xFF : 0 );
269 #define bs_align_0( s ) bs_write_align( s, 0 )
270 #define bs_align_1( s ) bs_write_align( s, 1 )
272 /* Read unsigned Exp-Golomb code */
273 static inline uint_fast32_t bs_read_ue( bs_t * bs )
275 unsigned i = 0;
277 while( bs_read1( bs ) == 0 && bs->p < bs->p_end && i < 31 )
278 i++;
280 return (1U << i) - 1 + bs_read( bs, i );
283 /* Read signed Exp-Golomb code */
284 static inline int_fast32_t bs_read_se( bs_t *s )
286 uint_fast32_t val = bs_read_ue( s );
288 return (val & 0x01) ? (int_fast32_t)((val + 1) / 2)
289 : -(int_fast32_t)(val / 2);
292 #undef bs_forward
294 #endif