Mercurial > mplayer.hg
annotate tremor/bitwise.c @ 34168:55abe5125482
Make include recursion depth actually have some effect.
Not working yet though, needs another change to really work properly.
author | reimar |
---|---|
date | Tue, 25 Oct 2011 19:22:10 +0000 |
parents | e83eef58b30a |
children |
rev | line source |
---|---|
14280 | 1 /******************************************************************** |
2 * * | |
15250 | 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * |
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |
14280 | 7 * * |
15250 | 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * |
9 * by the Xiph.Org Foundation http://www.xiph.org/ * | |
14280 | 10 * * |
11 ******************************************************************** | |
12 | |
13 function: packing variable sized words into an octet stream | |
15250 | 14 last mod: $Id$ |
14280 | 15 |
16 ********************************************************************/ | |
17 | |
18 /* We're 'LSb' endian; if we write a word but read individual bits, | |
19 then we'll read the lsb first */ | |
20 | |
21 #include <string.h> | |
22 #include <stdlib.h> | |
23 #include "ogg.h" | |
24 | |
25 #define BUFFER_INCREMENT 256 | |
26 | |
15250 | 27 static const unsigned long mask[]= |
14280 | 28 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, |
29 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, | |
30 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, | |
31 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, | |
32 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, | |
33 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, | |
34 0x3fffffff,0x7fffffff,0xffffffff }; | |
35 | |
15250 | 36 static const unsigned int mask8B[]= |
37 {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; | |
38 | |
39 void oggpack_writeinit(oggpack_buffer *b){ | |
40 memset(b,0,sizeof(*b)); | |
41 b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); | |
42 b->buffer[0]='\0'; | |
43 b->storage=BUFFER_INCREMENT; | |
44 } | |
45 | |
46 void oggpackB_writeinit(oggpack_buffer *b){ | |
47 oggpack_writeinit(b); | |
48 } | |
49 | |
50 void oggpack_writetrunc(oggpack_buffer *b,long bits){ | |
51 long bytes=bits>>3; | |
52 bits-=bytes*8; | |
53 b->ptr=b->buffer+bytes; | |
54 b->endbit=bits; | |
55 b->endbyte=bytes; | |
56 *b->ptr&=mask[bits]; | |
57 } | |
58 | |
59 void oggpackB_writetrunc(oggpack_buffer *b,long bits){ | |
60 long bytes=bits>>3; | |
61 bits-=bytes*8; | |
62 b->ptr=b->buffer+bytes; | |
63 b->endbit=bits; | |
64 b->endbyte=bytes; | |
65 *b->ptr&=mask8B[bits]; | |
66 } | |
67 | |
68 /* Takes only up to 32 bits. */ | |
69 void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ | |
70 if(b->endbyte+4>=b->storage){ | |
71 b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); | |
72 b->storage+=BUFFER_INCREMENT; | |
73 b->ptr=b->buffer+b->endbyte; | |
74 } | |
75 | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
76 value&=mask[bits]; |
15250 | 77 bits+=b->endbit; |
78 | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
79 b->ptr[0]|=value<<b->endbit; |
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
80 |
15250 | 81 if(bits>=8){ |
82 b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); | |
83 if(bits>=16){ | |
84 b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); | |
85 if(bits>=24){ | |
86 b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); | |
87 if(bits>=32){ | |
88 if(b->endbit) | |
89 b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); | |
90 else | |
91 b->ptr[4]=0; | |
92 } | |
93 } | |
94 } | |
95 } | |
96 | |
97 b->endbyte+=bits/8; | |
98 b->ptr+=bits/8; | |
99 b->endbit=bits&7; | |
100 } | |
101 | |
102 /* Takes only up to 32 bits. */ | |
103 void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ | |
104 if(b->endbyte+4>=b->storage){ | |
105 b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); | |
106 b->storage+=BUFFER_INCREMENT; | |
107 b->ptr=b->buffer+b->endbyte; | |
108 } | |
109 | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
110 value=(value&mask[bits])<<(32-bits); |
15250 | 111 bits+=b->endbit; |
112 | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
113 b->ptr[0]|=value>>(24+b->endbit); |
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
114 |
15250 | 115 if(bits>=8){ |
116 b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); | |
117 if(bits>=16){ | |
118 b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); | |
119 if(bits>=24){ | |
120 b->ptr[3]=(unsigned char)(value>>(b->endbit)); | |
121 if(bits>=32){ | |
122 if(b->endbit) | |
123 b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); | |
124 else | |
125 b->ptr[4]=0; | |
126 } | |
127 } | |
128 } | |
129 } | |
130 | |
131 b->endbyte+=bits/8; | |
132 b->ptr+=bits/8; | |
133 b->endbit=bits&7; | |
134 } | |
135 | |
136 void oggpack_writealign(oggpack_buffer *b){ | |
137 int bits=8-b->endbit; | |
138 if(bits<8) | |
139 oggpack_write(b,0,bits); | |
140 } | |
141 | |
142 void oggpackB_writealign(oggpack_buffer *b){ | |
143 int bits=8-b->endbit; | |
144 if(bits<8) | |
145 oggpackB_write(b,0,bits); | |
146 } | |
147 | |
148 static void oggpack_writecopy_helper(oggpack_buffer *b, | |
149 void *source, | |
150 long bits, | |
151 void (*w)(oggpack_buffer *, | |
152 unsigned long, | |
153 int), | |
154 int msb){ | |
155 unsigned char *ptr=(unsigned char *)source; | |
156 | |
157 long bytes=bits/8; | |
158 bits-=bytes*8; | |
159 | |
160 if(b->endbit){ | |
161 int i; | |
162 /* unaligned copy. Do it the hard way. */ | |
163 for(i=0;i<bytes;i++) | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
164 w(b,(unsigned long)(ptr[i]),8); |
15250 | 165 }else{ |
166 /* aligned block copy */ | |
167 if(b->endbyte+bytes+1>=b->storage){ | |
168 b->storage=b->endbyte+bytes+BUFFER_INCREMENT; | |
169 b->buffer=_ogg_realloc(b->buffer,b->storage); | |
170 b->ptr=b->buffer+b->endbyte; | |
171 } | |
172 | |
173 memmove(b->ptr,source,bytes); | |
174 b->ptr+=bytes; | |
175 b->endbyte+=bytes; | |
176 *b->ptr=0; | |
177 | |
178 } | |
179 if(bits){ | |
180 if(msb) | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
181 w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); |
15250 | 182 else |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
183 w(b,(unsigned long)(ptr[bytes]),bits); |
15250 | 184 } |
185 } | |
186 | |
187 void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ | |
188 oggpack_writecopy_helper(b,source,bits,oggpack_write,0); | |
189 } | |
190 | |
191 void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ | |
192 oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); | |
193 } | |
194 | |
195 void oggpack_reset(oggpack_buffer *b){ | |
196 b->ptr=b->buffer; | |
197 b->buffer[0]=0; | |
198 b->endbit=b->endbyte=0; | |
199 } | |
200 | |
201 void oggpackB_reset(oggpack_buffer *b){ | |
202 oggpack_reset(b); | |
203 } | |
204 | |
205 void oggpack_writeclear(oggpack_buffer *b){ | |
206 _ogg_free(b->buffer); | |
207 memset(b,0,sizeof(*b)); | |
208 } | |
209 | |
210 void oggpackB_writeclear(oggpack_buffer *b){ | |
211 oggpack_writeclear(b); | |
212 } | |
213 | |
14280 | 214 void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ |
215 memset(b,0,sizeof(*b)); | |
216 b->buffer=b->ptr=buf; | |
217 b->storage=bytes; | |
218 } | |
219 | |
15250 | 220 void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ |
221 oggpack_readinit(b,buf,bytes); | |
222 } | |
223 | |
14280 | 224 /* Read in bits without advancing the bitptr; bits <= 32 */ |
225 long oggpack_look(oggpack_buffer *b,int bits){ | |
226 unsigned long ret; | |
227 unsigned long m=mask[bits]; | |
228 | |
229 bits+=b->endbit; | |
230 | |
231 if(b->endbyte+4>=b->storage){ | |
232 /* not the main path */ | |
233 if(b->endbyte*8+bits>b->storage*8)return(-1); | |
234 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
235 |
14280 | 236 ret=b->ptr[0]>>b->endbit; |
237 if(bits>8){ | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
238 ret|=b->ptr[1]<<(8-b->endbit); |
14280 | 239 if(bits>16){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
240 ret|=b->ptr[2]<<(16-b->endbit); |
14280 | 241 if(bits>24){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
242 ret|=b->ptr[3]<<(24-b->endbit); |
14280 | 243 if(bits>32 && b->endbit) |
244 ret|=b->ptr[4]<<(32-b->endbit); | |
245 } | |
246 } | |
247 } | |
248 return(m&ret); | |
249 } | |
250 | |
15250 | 251 /* Read in bits without advancing the bitptr; bits <= 32 */ |
252 long oggpackB_look(oggpack_buffer *b,int bits){ | |
253 unsigned long ret; | |
254 int m=32-bits; | |
255 | |
256 bits+=b->endbit; | |
257 | |
258 if(b->endbyte+4>=b->storage){ | |
259 /* not the main path */ | |
260 if(b->endbyte*8+bits>b->storage*8)return(-1); | |
261 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
262 |
15250 | 263 ret=b->ptr[0]<<(24+b->endbit); |
264 if(bits>8){ | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
265 ret|=b->ptr[1]<<(16+b->endbit); |
15250 | 266 if(bits>16){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
267 ret|=b->ptr[2]<<(8+b->endbit); |
15250 | 268 if(bits>24){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
269 ret|=b->ptr[3]<<(b->endbit); |
15250 | 270 if(bits>32 && b->endbit) |
271 ret|=b->ptr[4]>>(8-b->endbit); | |
272 } | |
273 } | |
274 } | |
275 return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); | |
276 } | |
277 | |
14280 | 278 long oggpack_look1(oggpack_buffer *b){ |
279 if(b->endbyte>=b->storage)return(-1); | |
280 return((b->ptr[0]>>b->endbit)&1); | |
281 } | |
282 | |
15250 | 283 long oggpackB_look1(oggpack_buffer *b){ |
284 if(b->endbyte>=b->storage)return(-1); | |
285 return((b->ptr[0]>>(7-b->endbit))&1); | |
286 } | |
287 | |
14280 | 288 void oggpack_adv(oggpack_buffer *b,int bits){ |
289 bits+=b->endbit; | |
290 b->ptr+=bits/8; | |
291 b->endbyte+=bits/8; | |
292 b->endbit=bits&7; | |
293 } | |
294 | |
15250 | 295 void oggpackB_adv(oggpack_buffer *b,int bits){ |
296 oggpack_adv(b,bits); | |
297 } | |
298 | |
14280 | 299 void oggpack_adv1(oggpack_buffer *b){ |
300 if(++(b->endbit)>7){ | |
301 b->endbit=0; | |
302 b->ptr++; | |
303 b->endbyte++; | |
304 } | |
305 } | |
306 | |
15250 | 307 void oggpackB_adv1(oggpack_buffer *b){ |
308 oggpack_adv1(b); | |
309 } | |
310 | |
14280 | 311 /* bits <= 32 */ |
312 long oggpack_read(oggpack_buffer *b,int bits){ | |
15250 | 313 long ret; |
14280 | 314 unsigned long m=mask[bits]; |
315 | |
316 bits+=b->endbit; | |
317 | |
318 if(b->endbyte+4>=b->storage){ | |
319 /* not the main path */ | |
15250 | 320 ret=-1L; |
14280 | 321 if(b->endbyte*8+bits>b->storage*8)goto overflow; |
322 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
323 |
14280 | 324 ret=b->ptr[0]>>b->endbit; |
325 if(bits>8){ | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
326 ret|=b->ptr[1]<<(8-b->endbit); |
14280 | 327 if(bits>16){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
328 ret|=b->ptr[2]<<(16-b->endbit); |
14280 | 329 if(bits>24){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
330 ret|=b->ptr[3]<<(24-b->endbit); |
14280 | 331 if(bits>32 && b->endbit){ |
332 ret|=b->ptr[4]<<(32-b->endbit); | |
333 } | |
334 } | |
335 } | |
336 } | |
337 ret&=m; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
338 |
14280 | 339 overflow: |
340 | |
341 b->ptr+=bits/8; | |
342 b->endbyte+=bits/8; | |
343 b->endbit=bits&7; | |
344 return(ret); | |
345 } | |
346 | |
15250 | 347 /* bits <= 32 */ |
348 long oggpackB_read(oggpack_buffer *b,int bits){ | |
349 long ret; | |
350 long m=32-bits; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
351 |
15250 | 352 bits+=b->endbit; |
353 | |
354 if(b->endbyte+4>=b->storage){ | |
355 /* not the main path */ | |
356 ret=-1L; | |
357 if(b->endbyte*8+bits>b->storage*8)goto overflow; | |
358 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
359 |
15250 | 360 ret=b->ptr[0]<<(24+b->endbit); |
361 if(bits>8){ | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
362 ret|=b->ptr[1]<<(16+b->endbit); |
15250 | 363 if(bits>16){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
364 ret|=b->ptr[2]<<(8+b->endbit); |
15250 | 365 if(bits>24){ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
366 ret|=b->ptr[3]<<(b->endbit); |
15250 | 367 if(bits>32 && b->endbit) |
368 ret|=b->ptr[4]>>(8-b->endbit); | |
369 } | |
370 } | |
371 } | |
372 ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
373 |
15250 | 374 overflow: |
375 | |
376 b->ptr+=bits/8; | |
377 b->endbyte+=bits/8; | |
378 b->endbit=bits&7; | |
379 return(ret); | |
380 } | |
381 | |
14280 | 382 long oggpack_read1(oggpack_buffer *b){ |
15250 | 383 long ret; |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
384 |
14280 | 385 if(b->endbyte>=b->storage){ |
386 /* not the main path */ | |
15250 | 387 ret=-1L; |
14280 | 388 goto overflow; |
389 } | |
390 | |
391 ret=(b->ptr[0]>>b->endbit)&1; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
392 |
14280 | 393 overflow: |
394 | |
395 b->endbit++; | |
396 if(b->endbit>7){ | |
397 b->endbit=0; | |
398 b->ptr++; | |
399 b->endbyte++; | |
400 } | |
401 return(ret); | |
402 } | |
403 | |
15250 | 404 long oggpackB_read1(oggpack_buffer *b){ |
405 long ret; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
406 |
15250 | 407 if(b->endbyte>=b->storage){ |
408 /* not the main path */ | |
409 ret=-1L; | |
410 goto overflow; | |
411 } | |
412 | |
413 ret=(b->ptr[0]>>(7-b->endbit))&1; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
414 |
15250 | 415 overflow: |
416 | |
417 b->endbit++; | |
418 if(b->endbit>7){ | |
419 b->endbit=0; | |
420 b->ptr++; | |
421 b->endbyte++; | |
422 } | |
423 return(ret); | |
424 } | |
425 | |
426 long oggpack_bytes(oggpack_buffer *b){ | |
427 return(b->endbyte+(b->endbit+7)/8); | |
428 } | |
429 | |
430 long oggpack_bits(oggpack_buffer *b){ | |
431 return(b->endbyte*8+b->endbit); | |
432 } | |
433 | |
434 long oggpackB_bytes(oggpack_buffer *b){ | |
435 return oggpack_bytes(b); | |
436 } | |
437 | |
438 long oggpackB_bits(oggpack_buffer *b){ | |
439 return oggpack_bits(b); | |
440 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
15250
diff
changeset
|
441 |
15250 | 442 unsigned char *oggpack_get_buffer(oggpack_buffer *b){ |
443 return(b->buffer); | |
444 } | |
445 | |
446 unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ | |
447 return oggpack_get_buffer(b); | |
448 } | |
449 | |
14280 | 450 #undef BUFFER_INCREMENT |