17e7046724d08bb7046e3ff6b43452f8770725dd
[speexdsp.git] / libspeex / bits.c
1 /* Copyright (C) 2002 Jean-Marc Valin 
2    File: speex_bits.c
3
4    Handles bit packing/unpacking
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10    
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15    
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 */
21
22 #include "speex_bits.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 void frame_bits_init(FrameBits *bits)
27 {
28    int i;
29    for (i=0;i<MAX_BYTES_PER_FRAME;i++)
30       bits->bytes[i]=0;
31    bits->nbBits=0;
32    bits->bytePtr=0;
33    bits->bitPtr=0;
34 }
35
36 void frame_bits_destroy(FrameBits *bits)
37 {
38    /* Will do something once the allocation is dynamic */
39 }
40
41 void frame_bits_reset(FrameBits *bits)
42 {
43    int i;
44    for (i=0;i<MAX_BYTES_PER_FRAME;i++)
45       bits->bytes[i]=0;
46    bits->nbBits=0;
47    bits->bytePtr=0;
48    bits->bitPtr=0;
49 }
50
51 void frame_bits_rewind(FrameBits *bits)
52 {
53    bits->bytePtr=0;
54    bits->bitPtr=0;
55 }
56
57 void frame_bits_init_from(FrameBits *bits, char *bytes, int len)
58 {
59    int i;
60    if (len > MAX_BYTES_PER_FRAME)
61    {
62       fprintf (stderr, "Trying to init frame with too many bits");
63       exit(1);
64    }
65    for (i=0;i<len;i++)
66       bits->bytes[i]=bytes[i];
67    bits->nbBits=len<<3;
68    bits->bytePtr=0;
69    bits->bitPtr=0;
70 }
71
72 void frame_bits_flush(FrameBits *bits)
73 {
74    int i;
75    if (bits->bytePtr>0)
76    {
77       for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++)
78          bits->bytes[i-bits->bytePtr]=bits->bytes[i];
79    }
80    bits->nbBits -= bits->bytePtr<<3;
81    bits->bytePtr=0;
82 }
83
84 void frame_bits_read_whole_bytes(FrameBits *bits, char *bytes, int len)
85 {
86    int i,pos;
87    frame_bits_flush(bits);
88    pos=bits->nbBits>>3;
89    for (i=0;i<len;i++)
90       bits->bytes[pos+i]=bytes[i];
91    bits->nbBits+=len<<3;
92 }
93
94 int frame_bits_write(FrameBits *bits, char *bytes, int max_len)
95 {
96    int i;
97    if (max_len > ((bits->nbBits+7)>>3))
98       max_len = ((bits->nbBits+7)>>3);
99    for (i=0;i<max_len;i++)
100       bytes[i]=bits->bytes[i];
101    return max_len;
102 }
103
104 int frame_bits_write_whole_bytes(FrameBits *bits, char *bytes, int max_len)
105 {
106    int i;
107    if (max_len > ((bits->nbBits)>>3))
108       max_len = ((bits->nbBits)>>3);
109    for (i=0;i<max_len;i++)
110       bytes[i]=bits->bytes[i];
111    
112    if (bits->bitPtr>0)
113       bits->bytes[0]=bits->bytes[max_len];
114    else
115       bits->bytes[0]=0;
116    for (i=1;i<((bits->nbBits)>>3)+1;i++)
117       bits->bytes[i]=0;
118    bits->bytePtr=0;
119    bits->nbBits &= 7;
120    return max_len;
121 }
122
123
124 void frame_bits_pack(FrameBits *bits, int data, int nbBits)
125 {
126    unsigned int d=data;
127    while(nbBits)
128    {
129       int bit;
130       bit = (d>>(nbBits-1))&1;
131       bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr);
132       bits->bitPtr++;
133       /*fprintf(stderr, "%d %d\n", nbBits, bit);*/
134       if (bits->bitPtr==8)
135       {
136          bits->bitPtr=0;
137          bits->bytePtr++;
138       }
139       bits->nbBits++;
140       nbBits--;
141    }
142 }
143
144 int frame_bits_unpack_signed(FrameBits *bits, int nbBits)
145 {
146    unsigned int d=frame_bits_unpack_unsigned(bits,nbBits);
147    /* If number is negative */
148    if (d>>(nbBits-1))
149    {
150       d |= (-1)<<nbBits;
151    }
152    return d;
153 }
154
155 unsigned int frame_bits_unpack_unsigned(FrameBits *bits, int nbBits)
156 {
157    unsigned int d=0;
158    while(nbBits)
159    {
160       d<<=1;
161       d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
162       bits->bitPtr++;
163       if (bits->bitPtr==8)
164       {
165          bits->bitPtr=0;
166          bits->bytePtr++;
167       }
168       nbBits--;
169    }
170    return d;
171 }