~ubuntu-branches/ubuntu/hardy/speex/hardy-security

« back to all changes in this revision

Viewing changes to libspeex/bits.c

  • Committer: Bazaar Package Importer
  • Author(s): A. Maitland Bottoms
  • Date: 2005-02-26 22:33:22 UTC
  • Revision ID: james.westby@ubuntu.com-20050226223322-vc6sdoshrqjxfh9c
Tags: upstream-1.1.6
ImportĀ upstreamĀ versionĀ 1.1.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2002 Jean-Marc Valin 
 
2
   File: speex_bits.c
 
3
 
 
4
   Handles bit packing/unpacking
 
5
 
 
6
   Redistribution and use in source and binary forms, with or without
 
7
   modification, are permitted provided that the following conditions
 
8
   are met:
 
9
   
 
10
   - Redistributions of source code must retain the above copyright
 
11
   notice, this list of conditions and the following disclaimer.
 
12
   
 
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.
 
16
   
 
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.
 
20
   
 
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.
 
32
 
 
33
*/
 
34
 
 
35
#ifdef HAVE_CONFIG_H
 
36
#include "config.h"
 
37
#endif
 
38
 
 
39
#include <speex/speex_bits.h>
 
40
#include "misc.h"
 
41
 
 
42
/** Maximum size of the bit-stream (for fixed-size allocation) */
 
43
#define MAX_BYTES_PER_FRAME 2000
 
44
 
 
45
void speex_bits_init(SpeexBits *bits)
 
46
{
 
47
   int i;
 
48
   bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME);
 
49
   bits->buf_size = MAX_BYTES_PER_FRAME;
 
50
 
 
51
   for (i=0;i<bits->buf_size;i++)
 
52
      bits->bytes[i]=0;
 
53
   bits->nbBits=0;
 
54
   bits->bytePtr=0;
 
55
   bits->bitPtr=0;
 
56
   bits->owner=1;
 
57
   bits->overflow=0;
 
58
}
 
59
 
 
60
void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
 
61
{
 
62
   int i;
 
63
   bits->bytes = (char*)buff;
 
64
   bits->buf_size = buf_size;
 
65
 
 
66
   for (i=0;i<buf_size;i++)
 
67
      bits->bytes[i]=0;
 
68
   bits->nbBits=0;
 
69
   bits->bytePtr=0;
 
70
   bits->bitPtr=0;
 
71
   bits->owner=0;
 
72
   bits->overflow=0;
 
73
}
 
74
 
 
75
void speex_bits_destroy(SpeexBits *bits)
 
76
{
 
77
   if (bits->owner)
 
78
      speex_free(bits->bytes);
 
79
   /* Will do something once the allocation is dynamic */
 
80
}
 
81
 
 
82
void speex_bits_reset(SpeexBits *bits)
 
83
{
 
84
   int i;
 
85
   for (i=0;i<bits->buf_size;i++)
 
86
      bits->bytes[i]=0;
 
87
   bits->nbBits=0;
 
88
   bits->bytePtr=0;
 
89
   bits->bitPtr=0;
 
90
   bits->overflow=0;
 
91
}
 
92
 
 
93
void speex_bits_rewind(SpeexBits *bits)
 
94
{
 
95
   bits->bytePtr=0;
 
96
   bits->bitPtr=0;
 
97
   bits->overflow=0;
 
98
}
 
99
 
 
100
void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
 
101
{
 
102
   int i;
 
103
   if (len > bits->buf_size)
 
104
   {
 
105
      speex_warning_int("Packet if larger than allocated buffer: ", len);
 
106
      if (bits->owner)
 
107
      {
 
108
         char *tmp = (char*)speex_realloc(bits->bytes, len);
 
109
         if (tmp)
 
110
         {
 
111
            bits->buf_size=len;
 
112
            bits->bytes=tmp;
 
113
         } else {
 
114
            len=bits->buf_size;
 
115
            speex_warning("Could not resize input buffer: truncating input");
 
116
         }
 
117
      } else {
 
118
         speex_warning("Do not own input buffer: truncating input");
 
119
         len=bits->buf_size;
 
120
      }
 
121
   }
 
122
   for (i=0;i<len;i++)
 
123
      bits->bytes[i]=bytes[i];
 
124
   bits->nbBits=len<<3;
 
125
   bits->bytePtr=0;
 
126
   bits->bitPtr=0;
 
127
   bits->overflow=0;
 
128
}
 
129
 
 
130
static void speex_bits_flush(SpeexBits *bits)
 
131
{
 
132
   int i;
 
133
   if (bits->bytePtr>0)
 
134
   {
 
135
      for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++)
 
136
         bits->bytes[i-bits->bytePtr]=bits->bytes[i];
 
137
   }
 
138
   bits->nbBits -= bits->bytePtr<<3;
 
139
   bits->bytePtr=0;
 
140
}
 
141
 
 
142
void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len)
 
143
{
 
144
   int i,pos;
 
145
 
 
146
   if (((bits->nbBits+7)>>3)+len > bits->buf_size)
 
147
   {
 
148
      /* Packet is larger than allocated buffer */
 
149
      if (bits->owner)
 
150
      {
 
151
         char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1);
 
152
         if (tmp)
 
153
         {
 
154
            bits->buf_size=(bits->nbBits>>3)+len+1;
 
155
            bits->bytes=tmp;
 
156
         } else {
 
157
            len=bits->buf_size-(bits->nbBits>>3)-1;
 
158
            speex_warning("Could not resize input buffer: truncating input");
 
159
         }
 
160
      } else {
 
161
         speex_warning("Do not own input buffer: truncating input");
 
162
         len=bits->buf_size;
 
163
      }
 
164
   }
 
165
 
 
166
   speex_bits_flush(bits);
 
167
   pos=bits->nbBits>>3;
 
168
   for (i=0;i<len;i++)
 
169
      bits->bytes[pos+i]=bytes[i];
 
170
   bits->nbBits+=len<<3;
 
171
}
 
172
 
 
173
int speex_bits_write(SpeexBits *bits, char *bytes, int max_len)
 
174
{
 
175
   int i;
 
176
   int bytePtr, bitPtr, nbBits;
 
177
   
 
178
   /* Insert terminator, but save the data so we can put it back after */
 
179
   bitPtr=bits->bitPtr;
 
180
   bytePtr=bits->bytePtr;
 
181
   nbBits=bits->nbBits;
 
182
   speex_bits_insert_terminator(bits);
 
183
   bits->bitPtr=bitPtr;
 
184
   bits->bytePtr=bytePtr;
 
185
   bits->nbBits=nbBits;
 
186
 
 
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];
 
191
   return max_len;
 
192
}
 
193
 
 
194
int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len)
 
195
{
 
196
   int i;
 
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];
 
201
   
 
202
   if (bits->bitPtr>0)
 
203
      bits->bytes[0]=bits->bytes[max_len];
 
204
   else
 
205
      bits->bytes[0]=0;
 
206
   for (i=1;i<((bits->nbBits)>>3)+1;i++)
 
207
      bits->bytes[i]=0;
 
208
   bits->bytePtr=0;
 
209
   bits->nbBits &= 7;
 
210
   return max_len;
 
211
}
 
212
 
 
213
 
 
214
void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
 
215
{
 
216
   int i;
 
217
   unsigned int d=data;
 
218
 
 
219
   if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size)
 
220
   {
 
221
      speex_warning("Buffer too small to pack bits");
 
222
      if (bits->owner)
 
223
      {
 
224
         char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1);
 
225
         if (tmp)
 
226
         {
 
227
            for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++)
 
228
               tmp[i]=0;
 
229
            bits->buf_size=((bits->buf_size+5)*3)>>1;
 
230
            bits->bytes=tmp;
 
231
         } else {
 
232
            speex_warning("Could not resize input buffer: not packing");
 
233
            return;
 
234
         }
 
235
      } else {
 
236
         speex_warning("Do not own input buffer: not packing");
 
237
         return;
 
238
      }
 
239
   }
 
240
 
 
241
   while(nbBits)
 
242
   {
 
243
      int bit;
 
244
      bit = (d>>(nbBits-1))&1;
 
245
      bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr);
 
246
      bits->bitPtr++;
 
247
 
 
248
      if (bits->bitPtr==8)
 
249
      {
 
250
         bits->bitPtr=0;
 
251
         bits->bytePtr++;
 
252
      }
 
253
      bits->nbBits++;
 
254
      nbBits--;
 
255
   }
 
256
}
 
257
 
 
258
int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
 
259
{
 
260
   unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
 
261
   /* If number is negative */
 
262
   if (d>>(nbBits-1))
 
263
   {
 
264
      d |= (-1)<<nbBits;
 
265
   }
 
266
   return d;
 
267
}
 
268
 
 
269
unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
 
270
{
 
271
   unsigned int d=0;
 
272
   if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
 
273
      bits->overflow=1;
 
274
   if (bits->overflow)
 
275
      return 0;
 
276
   while(nbBits)
 
277
   {
 
278
      d<<=1;
 
279
      d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
 
280
      bits->bitPtr++;
 
281
      if (bits->bitPtr==8)
 
282
      {
 
283
         bits->bitPtr=0;
 
284
         bits->bytePtr++;
 
285
      }
 
286
      nbBits--;
 
287
   }
 
288
   return d;
 
289
}
 
290
 
 
291
unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
 
292
{
 
293
   unsigned int d=0;
 
294
   int bitPtr, bytePtr;
 
295
   char *bytes;
 
296
 
 
297
   if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
 
298
     bits->overflow=1;
 
299
   if (bits->overflow)
 
300
      return 0;
 
301
 
 
302
   bitPtr=bits->bitPtr;
 
303
   bytePtr=bits->bytePtr;
 
304
   bytes = bits->bytes;
 
305
   while(nbBits)
 
306
   {
 
307
      d<<=1;
 
308
      d |= (bytes[bytePtr]>>(7-bitPtr))&1;
 
309
      bitPtr++;
 
310
      if (bitPtr==8)
 
311
      {
 
312
         bitPtr=0;
 
313
         bytePtr++;
 
314
      }
 
315
      nbBits--;
 
316
   }
 
317
   return d;
 
318
}
 
319
 
 
320
int speex_bits_peek(SpeexBits *bits)
 
321
{
 
322
   if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits)
 
323
      bits->overflow=1;
 
324
   if (bits->overflow)
 
325
      return 0;
 
326
   return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
 
327
}
 
328
 
 
329
void speex_bits_advance(SpeexBits *bits, int n)
 
330
{
 
331
    if (((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
 
332
      bits->overflow=1;
 
333
      return;
 
334
    }
 
335
   bits->bytePtr += (bits->bitPtr+n) >> 3; /*divide by 8*/
 
336
   bits->bitPtr = (bits->bitPtr+n) & 7;    /* modulo by 8*/
 
337
}
 
338
 
 
339
int speex_bits_remaining(SpeexBits *bits)
 
340
{
 
341
   if (bits->overflow)
 
342
      return -1;
 
343
   else
 
344
      return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr);
 
345
}
 
346
 
 
347
int speex_bits_nbytes(SpeexBits *bits)
 
348
{
 
349
   return ((bits->nbBits+7)>>3);
 
350
}
 
351
 
 
352
void speex_bits_insert_terminator(SpeexBits *bits)
 
353
{
 
354
   if (bits->bitPtr<7)
 
355
      speex_bits_pack(bits, 0, 1);
 
356
   while (bits->bitPtr<7)
 
357
      speex_bits_pack(bits, 1, 1);
 
358
}