Checkin of validated codec used during development
[opal.git] / plugins / audio / Speex / libspeex / bits.c
bloba5c4d47231ecb1dca54353cf3fd7f1c435e22fbd
1 /* Copyright (C) 2002 Jean-Marc Valin
2 File: speex_bits.c
4 Handles bit packing/unpacking
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "speex_bits.h"
36 #include "misc.h"
38 void speex_bits_init(SpeexBits *bits)
40 int i;
41 bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME);
42 bits->buf_size = MAX_BYTES_PER_FRAME;
44 for (i=0;i<bits->buf_size;i++)
45 bits->bytes[i]=0;
46 bits->nbBits=0;
47 bits->bytePtr=0;
48 bits->bitPtr=0;
49 bits->owner=1;
50 bits->overflow=0;
53 void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
55 int i;
56 bits->bytes = (char*)buff;
57 bits->buf_size = buf_size;
59 for (i=0;i<buf_size;i++)
60 bits->bytes[i]=0;
61 bits->nbBits=0;
62 bits->bytePtr=0;
63 bits->bitPtr=0;
64 bits->owner=0;
65 bits->overflow=0;
68 void speex_bits_destroy(SpeexBits *bits)
70 if (bits->owner)
71 speex_free(bits->bytes);
72 /* Will do something once the allocation is dynamic */
75 void speex_bits_reset(SpeexBits *bits)
77 int i;
78 for (i=0;i<bits->buf_size;i++)
79 bits->bytes[i]=0;
80 bits->nbBits=0;
81 bits->bytePtr=0;
82 bits->bitPtr=0;
83 bits->overflow=0;
86 void speex_bits_rewind(SpeexBits *bits)
88 bits->bytePtr=0;
89 bits->bitPtr=0;
90 bits->overflow=0;
93 void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
95 int i;
96 if (len > bits->buf_size)
98 speex_warning_int("Packet if larger than allocated buffer: ", len);
99 if (bits->owner)
101 char *tmp = (char*)speex_realloc(bits->bytes, len);
102 if (tmp)
104 bits->buf_size=len;
105 bits->bytes=tmp;
106 } else {
107 len=bits->buf_size;
108 speex_warning("Could not resize input buffer: truncating input");
110 } else {
111 speex_warning("Do not own input buffer: truncating input");
112 len=bits->buf_size;
115 for (i=0;i<len;i++)
116 bits->bytes[i]=bytes[i];
117 bits->nbBits=len<<3;
118 bits->bytePtr=0;
119 bits->bitPtr=0;
120 bits->overflow=0;
123 static void speex_bits_flush(SpeexBits *bits)
125 int i;
126 if (bits->bytePtr>0)
128 for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++)
129 bits->bytes[i-bits->bytePtr]=bits->bytes[i];
131 bits->nbBits -= bits->bytePtr<<3;
132 bits->bytePtr=0;
135 void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len)
137 int i,pos;
139 if ((bits->nbBits>>3)+len+1 > bits->buf_size)
141 speex_warning_int("Packet if larger than allocated buffer: ", len);
142 if (bits->owner)
144 char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1);
145 if (tmp)
147 bits->buf_size=(bits->nbBits>>3)+len+1;
148 bits->bytes=tmp;
149 } else {
150 len=bits->buf_size-(bits->nbBits>>3)-1;
151 speex_warning("Could not resize input buffer: truncating input");
153 } else {
154 speex_warning("Do not own input buffer: truncating input");
155 len=bits->buf_size;
159 speex_bits_flush(bits);
160 pos=bits->nbBits>>3;
161 for (i=0;i<len;i++)
162 bits->bytes[pos+i]=bytes[i];
163 bits->nbBits+=len<<3;
166 int speex_bits_write(SpeexBits *bits, char *bytes, int max_len)
168 int i;
169 if (max_len > ((bits->nbBits+7)>>3))
170 max_len = ((bits->nbBits+7)>>3);
171 for (i=0;i<max_len;i++)
172 bytes[i]=bits->bytes[i];
173 return max_len;
176 int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len)
178 int i;
179 if (max_len > ((bits->nbBits)>>3))
180 max_len = ((bits->nbBits)>>3);
181 for (i=0;i<max_len;i++)
182 bytes[i]=bits->bytes[i];
184 if (bits->bitPtr>0)
185 bits->bytes[0]=bits->bytes[max_len];
186 else
187 bits->bytes[0]=0;
188 for (i=1;i<((bits->nbBits)>>3)+1;i++)
189 bits->bytes[i]=0;
190 bits->bytePtr=0;
191 bits->nbBits &= 7;
192 return max_len;
196 void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
198 int i;
199 unsigned int d=data;
201 if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size)
203 speex_warning("Buffer too small to pack bits");
204 if (bits->owner)
206 char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1);
207 if (tmp)
209 for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++)
210 tmp[i]=0;
211 bits->buf_size=((bits->buf_size+5)*3)>>1;
212 bits->bytes=tmp;
213 } else {
214 speex_warning("Could not resize input buffer: not packing");
215 return;
217 } else {
218 speex_warning("Do not own input buffer: not packing");
219 return;
223 while(nbBits)
225 int bit;
226 bit = (d>>(nbBits-1))&1;
227 bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr);
228 bits->bitPtr++;
230 if (bits->bitPtr==8)
232 bits->bitPtr=0;
233 bits->bytePtr++;
235 bits->nbBits++;
236 nbBits--;
240 int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
242 unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
243 /* If number is negative */
244 if (d>>(nbBits-1))
246 d |= (-1)<<nbBits;
248 return d;
251 unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
253 unsigned int d=0;
254 if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
255 bits->overflow=1;
256 if (bits->overflow)
257 return 0;
258 while(nbBits)
260 d<<=1;
261 d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
262 bits->bitPtr++;
263 if (bits->bitPtr==8)
265 bits->bitPtr=0;
266 bits->bytePtr++;
268 nbBits--;
270 return d;
273 unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
275 unsigned int d=0;
276 int bitPtr, bytePtr;
277 char *bytes;
279 if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
280 bits->overflow=1;
281 if (bits->overflow)
282 return 0;
284 bitPtr=bits->bitPtr;
285 bytePtr=bits->bytePtr;
286 bytes = bits->bytes;
287 while(nbBits)
289 d<<=1;
290 d |= (bytes[bytePtr]>>(7-bitPtr))&1;
291 bitPtr++;
292 if (bitPtr==8)
294 bitPtr=0;
295 bytePtr++;
297 nbBits--;
299 return d;
302 int speex_bits_peek(SpeexBits *bits)
304 if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits)
305 bits->overflow=1;
306 if (bits->overflow)
307 return 0;
308 return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
311 void speex_bits_advance(SpeexBits *bits, int n)
313 int nbytes, nbits;
315 if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits)
316 bits->overflow=1;
317 if (bits->overflow)
318 return;
320 nbytes = n >> 3;
321 nbits = n & 7;
323 bits->bytePtr += nbytes;
324 bits->bitPtr += nbits;
326 if (bits->bitPtr>7)
328 bits->bitPtr-=8;
329 bits->bytePtr++;
333 int speex_bits_remaining(SpeexBits *bits)
335 if (bits->overflow)
336 return -1;
337 else
338 return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr);
341 int speex_bits_nbytes(SpeexBits *bits)
343 return ((bits->nbBits+7)>>3);