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.
35 #include "speex_bits.h"
38 void speex_bits_init(SpeexBits
*bits
)
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
++)
53 void speex_bits_init_buffer(SpeexBits
*bits
, void *buff
, int buf_size
)
56 bits
->bytes
= (char*)buff
;
57 bits
->buf_size
= buf_size
;
59 for (i
=0;i
<buf_size
;i
++)
68 void speex_bits_destroy(SpeexBits
*bits
)
71 speex_free(bits
->bytes
);
72 /* Will do something once the allocation is dynamic */
75 void speex_bits_reset(SpeexBits
*bits
)
78 for (i
=0;i
<bits
->buf_size
;i
++)
86 void speex_bits_rewind(SpeexBits
*bits
)
93 void speex_bits_read_from(SpeexBits
*bits
, char *bytes
, int len
)
96 if (len
> bits
->buf_size
)
98 speex_warning_int("Packet if larger than allocated buffer: ", len
);
101 char *tmp
= (char*)speex_realloc(bits
->bytes
, len
);
108 speex_warning("Could not resize input buffer: truncating input");
111 speex_warning("Do not own input buffer: truncating input");
116 bits
->bytes
[i
]=bytes
[i
];
123 static void speex_bits_flush(SpeexBits
*bits
)
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;
135 void speex_bits_read_whole_bytes(SpeexBits
*bits
, char *bytes
, int len
)
139 if ((bits
->nbBits
>>3)+len
+1 > bits
->buf_size
)
141 speex_warning_int("Packet if larger than allocated buffer: ", len
);
144 char *tmp
= (char*)speex_realloc(bits
->bytes
, (bits
->nbBits
>>3)+len
+1);
147 bits
->buf_size
=(bits
->nbBits
>>3)+len
+1;
150 len
=bits
->buf_size
-(bits
->nbBits
>>3)-1;
151 speex_warning("Could not resize input buffer: truncating input");
154 speex_warning("Do not own input buffer: truncating input");
159 speex_bits_flush(bits
);
162 bits
->bytes
[pos
+i
]=bytes
[i
];
163 bits
->nbBits
+=len
<<3;
166 int speex_bits_write(SpeexBits
*bits
, char *bytes
, int max_len
)
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
];
176 int speex_bits_write_whole_bytes(SpeexBits
*bits
, char *bytes
, int max_len
)
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
];
185 bits
->bytes
[0]=bits
->bytes
[max_len
];
188 for (i
=1;i
<((bits
->nbBits
)>>3)+1;i
++)
196 void speex_bits_pack(SpeexBits
*bits
, int data
, int nbBits
)
201 if (bits
->bytePtr
+((nbBits
+bits
->bitPtr
)>>3) >= bits
->buf_size
)
203 speex_warning("Buffer too small to pack bits");
206 char *tmp
= (char*)speex_realloc(bits
->bytes
, ((bits
->buf_size
+5)*3)>>1);
209 for (i
=bits
->buf_size
;i
<(((bits
->buf_size
+5)*3)>>1);i
++)
211 bits
->buf_size
=((bits
->buf_size
+5)*3)>>1;
214 speex_warning("Could not resize input buffer: not packing");
218 speex_warning("Do not own input buffer: not packing");
226 bit
= (d
>>(nbBits
-1))&1;
227 bits
->bytes
[bits
->bytePtr
] |= bit
<<(7-bits
->bitPtr
);
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 */
251 unsigned int speex_bits_unpack_unsigned(SpeexBits
*bits
, int nbBits
)
254 if ((bits
->bytePtr
<<3)+bits
->bitPtr
+nbBits
>bits
->nbBits
)
261 d
|= (bits
->bytes
[bits
->bytePtr
]>>(7-bits
->bitPtr
))&1;
273 unsigned int speex_bits_peek_unsigned(SpeexBits
*bits
, int nbBits
)
279 if ((bits
->bytePtr
<<3)+bits
->bitPtr
+nbBits
>bits
->nbBits
)
285 bytePtr
=bits
->bytePtr
;
290 d
|= (bytes
[bytePtr
]>>(7-bitPtr
))&1;
302 int speex_bits_peek(SpeexBits
*bits
)
304 if ((bits
->bytePtr
<<3)+bits
->bitPtr
+1>bits
->nbBits
)
308 return (bits
->bytes
[bits
->bytePtr
]>>(7-bits
->bitPtr
))&1;
311 void speex_bits_advance(SpeexBits
*bits
, int n
)
315 if ((bits
->bytePtr
<<3)+bits
->bitPtr
+n
>bits
->nbBits
)
323 bits
->bytePtr
+= nbytes
;
324 bits
->bitPtr
+= nbits
;
333 int speex_bits_remaining(SpeexBits
*bits
)
338 return bits
->nbBits
-((bits
->bytePtr
<<3)+bits
->bitPtr
);
341 int speex_bits_nbytes(SpeexBits
*bits
)
343 return ((bits
->nbBits
+7)>>3);