1
/* Copyright (C) 2002 Jean-Marc Valin
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
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.
39
#include <speex/speex_bits.h>
42
/** Maximum size of the bit-stream (for fixed-size allocation) */
43
#define MAX_BYTES_PER_FRAME 2000
45
void speex_bits_init(SpeexBits *bits)
48
bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME);
49
bits->buf_size = MAX_BYTES_PER_FRAME;
51
for (i=0;i<bits->buf_size;i++)
60
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
63
bits->bytes = (char*)buff;
64
bits->buf_size = buf_size;
66
for (i=0;i<buf_size;i++)
75
void speex_bits_destroy(SpeexBits *bits)
78
speex_free(bits->bytes);
79
/* Will do something once the allocation is dynamic */
82
void speex_bits_reset(SpeexBits *bits)
85
for (i=0;i<bits->buf_size;i++)
93
void speex_bits_rewind(SpeexBits *bits)
100
void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
103
if (len > bits->buf_size)
105
speex_warning_int("Packet if larger than allocated buffer: ", len);
108
char *tmp = (char*)speex_realloc(bits->bytes, len);
115
speex_warning("Could not resize input buffer: truncating input");
118
speex_warning("Do not own input buffer: truncating input");
123
bits->bytes[i]=bytes[i];
130
static void speex_bits_flush(SpeexBits *bits)
135
for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++)
136
bits->bytes[i-bits->bytePtr]=bits->bytes[i];
138
bits->nbBits -= bits->bytePtr<<3;
142
void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len)
146
if (((bits->nbBits+7)>>3)+len > bits->buf_size)
148
/* Packet is larger than allocated buffer */
151
char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1);
154
bits->buf_size=(bits->nbBits>>3)+len+1;
157
len=bits->buf_size-(bits->nbBits>>3)-1;
158
speex_warning("Could not resize input buffer: truncating input");
161
speex_warning("Do not own input buffer: truncating input");
166
speex_bits_flush(bits);
169
bits->bytes[pos+i]=bytes[i];
170
bits->nbBits+=len<<3;
173
int speex_bits_write(SpeexBits *bits, char *bytes, int max_len)
176
int bytePtr, bitPtr, nbBits;
178
/* Insert terminator, but save the data so we can put it back after */
180
bytePtr=bits->bytePtr;
182
speex_bits_insert_terminator(bits);
184
bits->bytePtr=bytePtr;
187
if (max_len > ((bits->nbBits+7)>>3))
188
max_len = ((bits->nbBits+7)>>3);
189
for (i=0;i<max_len;i++)
190
bytes[i]=bits->bytes[i];
194
int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len)
197
if (max_len > ((bits->nbBits)>>3))
198
max_len = ((bits->nbBits)>>3);
199
for (i=0;i<max_len;i++)
200
bytes[i]=bits->bytes[i];
203
bits->bytes[0]=bits->bytes[max_len];
206
for (i=1;i<((bits->nbBits)>>3)+1;i++)
214
void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
219
if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size)
221
speex_warning("Buffer too small to pack bits");
224
char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1);
227
for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++)
229
bits->buf_size=((bits->buf_size+5)*3)>>1;
232
speex_warning("Could not resize input buffer: not packing");
236
speex_warning("Do not own input buffer: not packing");
244
bit = (d>>(nbBits-1))&1;
245
bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr);
258
int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
260
unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
261
/* If number is negative */
269
unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
272
if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
279
d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
291
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
297
if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
303
bytePtr=bits->bytePtr;
308
d |= (bytes[bytePtr]>>(7-bitPtr))&1;
320
int speex_bits_peek(SpeexBits *bits)
322
if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits)
326
return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
329
void speex_bits_advance(SpeexBits *bits, int n)
331
if (((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
335
bits->bytePtr += (bits->bitPtr+n) >> 3; /*divide by 8*/
336
bits->bitPtr = (bits->bitPtr+n) & 7; /* modulo by 8*/
339
int speex_bits_remaining(SpeexBits *bits)
344
return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr);
347
int speex_bits_nbytes(SpeexBits *bits)
349
return ((bits->nbBits+7)>>3);
352
void speex_bits_insert_terminator(SpeexBits *bits)
355
speex_bits_pack(bits, 0, 1);
356
while (bits->bitPtr<7)
357
speex_bits_pack(bits, 1, 1);