r1003: BlueDot theme is usable again thanks to Miha Kitic who finished off
[cinelerra_cv/mob.git] / toolame-02l / bitstream.c
blob71e8bb6df437de576f6d8c5a1328aec56287587c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "common.h"
4 #include "mem.h"
5 #include "bitstream.h"
7 /*****************************************************************************
9 * bit_stream.c package
10 * Author: Jean-Georges Fritsch, C-Cube Microsystems
11 * Changes
12 * Apr 2000 - removed all the file input routines. MFC
13 *****************************************************************************/
15 /********************************************************************
16 This package provides functions to write (exclusive or read)
17 information from (exclusive or to) the bit stream.
19 If the bit stream is opened in read mode only the get functions are
20 available. If the bit stream is opened in write mode only the put
21 functions are available.
22 ********************************************************************/
24 /*open_bit_stream_w(); open the device to write the bit stream into it */
25 /*close_bit_stream(); close the device containing the bit stream */
26 /*alloc_buffer(); open and initialize the buffer; */
27 /*desalloc_buffer(); empty and close the buffer */
28 /*back_track_buffer(); goes back N bits in the buffer */
29 /*put1bit(); write 1 bit from the bit stream */
30 /*put1bit(); write 1 bit from the bit stream */
31 /*putbits(); write N bits from the bit stream */
32 /*byte_ali_putbits(); write byte aligned the next N bits into the bit stream*/
33 /*unsigned long sstell(); return the current bit stream length (in bits) */
34 /*int end_bs(); return 1 if the end of bit stream reached otherwise 0 */
35 /*int seek_sync(); return 1 if a sync word was found in the bit stream */
36 /* otherwise returns 0 */
38 /* refill the buffer from the input device when the buffer becomes empty */
40 /* You must have one frame in memory if you are in DAB mode */
41 /* in conformity of the norme ETS 300 401 http://www.etsi.org */
42 /* see toollame.c */
43 int minimum = MINIMUM;
44 int refill_buffer (Bit_stream_struc * bs)
46 register int i = bs->buf_size - 2 - bs->buf_byte_idx;
47 register unsigned long n = 1;
48 register int index = 0;
49 char val[2];
51 while ((i >= 0) && (!bs->eob)) {
53 if (bs->format == BINARY)
54 n = fread (&bs->buf[i--], sizeof (unsigned char), 1, bs->pt);
56 else {
57 while ((index < 2) && n) {
58 n = fread (&val[index], sizeof (char), 1, bs->pt);
59 switch (val[index]) {
60 case 0x30:
61 case 0x31:
62 case 0x32:
63 case 0x33:
64 case 0x34:
65 case 0x35:
66 case 0x36:
67 case 0x37:
68 case 0x38:
69 case 0x39:
70 case 0x41:
71 case 0x42:
72 case 0x43:
73 case 0x44:
74 case 0x45:
75 case 0x46:
76 index++;
77 break;
78 default:
79 break;
83 if (val[0] <= 0x39)
84 bs->buf[i] = (val[0] - 0x30) << 4;
85 else
86 bs->buf[i] = (val[0] - 0x37) << 4;
87 if (val[1] <= 0x39)
88 bs->buf[i--] |= (val[1] - 0x30);
89 else
90 bs->buf[i--] |= (val[1] - 0x37);
91 index = 0;
94 if (!n) {
95 bs->eob = i + 1;
99 return 0;
102 /* empty the buffer to the output device when the buffer becomes full */
103 void empty_buffer (Bit_stream_struc * bs, int minimum)
105 register int i;
107 for (i = bs->buf_size - 1; i >= minimum; i--)
108 fwrite (&bs->buf[i], sizeof (unsigned char), 1, bs->pt);
110 fflush (bs->pt); /* NEW SS to assist in debugging */
112 for (i = minimum - 1; i >= 0; i--)
113 bs->buf[bs->buf_size - minimum + i] = bs->buf[i];
115 bs->buf_byte_idx = bs->buf_size - 1 - minimum;
116 bs->buf_bit_idx = 8;
119 /* open the device to write the bit stream into it */
120 void open_bit_stream_w (Bit_stream_struc * bs, char *bs_filenam, int size)
122 if (bs_filenam[0] == '-')
123 bs->pt = stdout;
124 else if ((bs->pt = fopen (bs_filenam, "wb")) == NULL) {
125 fprintf (stderr, "Could not create \"%s\".\n", bs_filenam);
126 exit (1);
128 alloc_buffer (bs, size);
129 bs->buf_byte_idx = size - 1;
130 bs->buf_bit_idx = 8;
131 bs->totbit = 0;
132 bs->mode = WRITE_MODE;
133 bs->eob = FALSE;
134 bs->eobs = FALSE;
137 /*close the device containing the bit stream after a write process*/
138 void close_bit_stream_w (Bit_stream_struc * bs)
140 putbits (bs, 0, 7);
141 empty_buffer (bs, bs->buf_byte_idx + 1);
142 fclose (bs->pt);
143 desalloc_buffer (bs);
146 /*open and initialize the buffer; */
147 void alloc_buffer (Bit_stream_struc * bs, int size)
149 bs->buf =
150 (unsigned char *) mem_alloc (size * sizeof (unsigned char), "buffer");
151 bs->buf_size = size;
154 /*empty and close the buffer */
155 void desalloc_buffer (Bit_stream_struc * bs)
157 free (bs->buf);
160 int putmask[9] = { 0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
161 int clearmask[9] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x0 };
163 void back_track_buffer (Bit_stream_struc * bs, int N)
164 /* goes back N bits in the buffer */
166 int tmp = N - (N / 8) * 8;
167 register int i;
169 bs->totbit -= N;
170 for (i = bs->buf_byte_idx; i < bs->buf_byte_idx + N / 8 - 1; i++)
171 bs->buf[i] = 0;
172 bs->buf_byte_idx += N / 8;
173 if ((tmp + bs->buf_bit_idx) <= 8) {
174 bs->buf_bit_idx += tmp;
175 } else {
176 bs->buf_byte_idx++;
177 bs->buf_bit_idx += (tmp - 8);
179 bs->buf[bs->buf_byte_idx] &= clearmask[bs->buf_bit_idx];
182 int mask[8] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
184 /*write 1 bit from the bit stream */
185 void put1bit (Bit_stream_struc * bs, int bit)
187 bs->totbit++;
189 bs->buf[bs->buf_byte_idx] |= (bit & 0x1) << (bs->buf_bit_idx - 1);
190 bs->buf_bit_idx--;
191 if (!bs->buf_bit_idx) {
192 bs->buf_bit_idx = 8;
193 bs->buf_byte_idx--;
194 if (bs->buf_byte_idx < 0)
195 empty_buffer (bs, minimum);
196 bs->buf[bs->buf_byte_idx] = 0;
200 /*write N bits into the bit stream */
201 INLINE void putbits (Bit_stream_struc * bs, unsigned int val, int N)
203 register int j = N;
204 register int k, tmp;
206 /* if (N > MAX_LENGTH)
207 fprintf(stderr, "Cannot read or write more than %d bits at a time.\n", MAX_LENGTH); ignore check!! MFC Apr 00 */
209 bs->totbit += N;
210 while (j > 0) {
211 k = MIN (j, bs->buf_bit_idx);
212 tmp = val >> (j - k);
213 bs->buf[bs->buf_byte_idx] |= (tmp & putmask[k]) << (bs->buf_bit_idx - k);
214 bs->buf_bit_idx -= k;
215 if (!bs->buf_bit_idx) {
216 bs->buf_bit_idx = 8;
217 bs->buf_byte_idx--;
218 if (bs->buf_byte_idx < 0)
219 empty_buffer (bs, minimum);
220 bs->buf[bs->buf_byte_idx] = 0;
222 j -= k;
226 /*write N bits byte aligned into the bit stream */
227 void byte_ali_putbits (Bit_stream_struc * bs, unsigned int val, int N)
229 unsigned long aligning;
231 if (N > MAX_LENGTH)
232 fprintf (stderr, "Cannot read or write more than %d bits at a time.\n",
233 MAX_LENGTH);
234 aligning = sstell (bs) % 8;
235 if (aligning)
236 putbits (bs, (unsigned int) 0, (int) (8 - aligning));
238 putbits (bs, val, N);
241 /*return the current bit stream length (in bits)*/
242 unsigned long sstell (Bit_stream_struc * bs)
244 return (bs->totbit);
247 /*return the status of the bit stream*/
248 /* returns 1 if end of bit stream was reached */
249 /* returns 0 if end of bit stream was not reached */
250 int end_bs (Bit_stream_struc * bs)
252 return (bs->eobs);
255 /*****************************************************************************
257 * End of bit_stream.c package
259 *****************************************************************************/
261 #define BUFSIZE 4096
262 static unsigned long offset, totbit = 0;
263 static unsigned int buf[BUFSIZE];
265 /*return the current bit stream length (in bits)*/
266 unsigned long hsstell ()
268 return (totbit);
271 /* int putmask[9]={0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff}; */
272 //extern int putmask[9]; MFC Feb 2003 Redundant redeclaration
274 /*write N bits into the bit stream */
275 void hputbuf (unsigned int val, int N)
277 if (N != 8) {
278 fprintf (stderr, "Not Supported yet!!\n");
279 exit (-3);
281 buf[offset % BUFSIZE] = val;
282 offset++;