Line | Count | Source |
1 | | /******************************************************************** |
2 | | * * |
3 | | * THIS FILE IS PART OF THE Ogg CONTAINER 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. * |
7 | | * * |
8 | | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014 * |
9 | | * by the Xiph.Org Foundation http://www.xiph.org/ * |
10 | | * * |
11 | | ******************************************************************** |
12 | | |
13 | | function: packing variable sized words into an octet stream |
14 | | |
15 | | ********************************************************************/ |
16 | | |
17 | | /* We're 'LSb' endian; if we write a word but read individual bits, |
18 | | then we'll read the lsb first */ |
19 | | |
20 | | #include <string.h> |
21 | | #include <stdlib.h> |
22 | | #include <limits.h> |
23 | | #include <ogg/ogg.h> |
24 | | |
25 | 0 | #define BUFFER_INCREMENT 256 |
26 | | |
27 | | static const unsigned long mask[]= |
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 | | |
36 | | static const unsigned int mask8B[]= |
37 | | {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; |
38 | | |
39 | 0 | void oggpack_writeinit(oggpack_buffer *b){ |
40 | 0 | memset(b,0,sizeof(*b)); |
41 | 0 | b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); |
42 | 0 | if (!b->buffer) |
43 | 0 | return; |
44 | 0 | b->buffer[0]='\0'; |
45 | 0 | b->storage=BUFFER_INCREMENT; |
46 | 0 | } |
47 | | |
48 | 0 | void oggpackB_writeinit(oggpack_buffer *b){ |
49 | 0 | oggpack_writeinit(b); |
50 | 0 | } |
51 | | |
52 | 0 | int oggpack_writecheck(oggpack_buffer *b){ |
53 | 0 | if(!b->ptr || !b->storage)return -1; |
54 | 0 | return 0; |
55 | 0 | } |
56 | | |
57 | 0 | int oggpackB_writecheck(oggpack_buffer *b){ |
58 | 0 | return oggpack_writecheck(b); |
59 | 0 | } |
60 | | |
61 | 0 | void oggpack_writetrunc(oggpack_buffer *b,long bits){ |
62 | 0 | long bytes=bits>>3; |
63 | 0 | if(b->ptr){ |
64 | 0 | bits-=bytes*8; |
65 | 0 | b->ptr=b->buffer+bytes; |
66 | 0 | b->endbit=bits; |
67 | 0 | b->endbyte=bytes; |
68 | 0 | *b->ptr&=mask[bits]; |
69 | 0 | } |
70 | 0 | } |
71 | | |
72 | 0 | void oggpackB_writetrunc(oggpack_buffer *b,long bits){ |
73 | 0 | long bytes=bits>>3; |
74 | 0 | if(b->ptr){ |
75 | 0 | bits-=bytes*8; |
76 | 0 | b->ptr=b->buffer+bytes; |
77 | 0 | b->endbit=bits; |
78 | 0 | b->endbyte=bytes; |
79 | 0 | *b->ptr&=mask8B[bits]; |
80 | 0 | } |
81 | 0 | } |
82 | | |
83 | | /* Takes only up to 32 bits. */ |
84 | 0 | void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ |
85 | 0 | if(bits<0 || bits>32) goto err; |
86 | 0 | if(b->endbyte>=b->storage-4){ |
87 | 0 | void *ret; |
88 | 0 | if(!b->ptr)return; |
89 | 0 | if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; |
90 | 0 | ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); |
91 | 0 | if(!ret) goto err; |
92 | 0 | b->buffer=ret; |
93 | 0 | b->storage+=BUFFER_INCREMENT; |
94 | 0 | b->ptr=b->buffer+b->endbyte; |
95 | 0 | } |
96 | | |
97 | 0 | value&=mask[bits]; |
98 | 0 | bits+=b->endbit; |
99 | |
|
100 | 0 | b->ptr[0]|=value<<b->endbit; |
101 | |
|
102 | 0 | if(bits>=8){ |
103 | 0 | b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); |
104 | 0 | if(bits>=16){ |
105 | 0 | b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); |
106 | 0 | if(bits>=24){ |
107 | 0 | b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); |
108 | 0 | if(bits>=32){ |
109 | 0 | if(b->endbit) |
110 | 0 | b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); |
111 | 0 | else |
112 | 0 | b->ptr[4]=0; |
113 | 0 | } |
114 | 0 | } |
115 | 0 | } |
116 | 0 | } |
117 | |
|
118 | 0 | b->endbyte+=bits/8; |
119 | 0 | b->ptr+=bits/8; |
120 | 0 | b->endbit=bits&7; |
121 | 0 | return; |
122 | 0 | err: |
123 | 0 | oggpack_writeclear(b); |
124 | 0 | } |
125 | | |
126 | | /* Takes only up to 32 bits. */ |
127 | 0 | void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ |
128 | 0 | if(bits<0 || bits>32) goto err; |
129 | 0 | if(b->endbyte>=b->storage-4){ |
130 | 0 | void *ret; |
131 | 0 | if(!b->ptr)return; |
132 | 0 | if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; |
133 | 0 | ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); |
134 | 0 | if(!ret) goto err; |
135 | 0 | b->buffer=ret; |
136 | 0 | b->storage+=BUFFER_INCREMENT; |
137 | 0 | b->ptr=b->buffer+b->endbyte; |
138 | 0 | } |
139 | | |
140 | 0 | value=(value&mask[bits])<<(32-bits); |
141 | 0 | bits+=b->endbit; |
142 | |
|
143 | 0 | b->ptr[0]|=value>>(24+b->endbit); |
144 | |
|
145 | 0 | if(bits>=8){ |
146 | 0 | b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); |
147 | 0 | if(bits>=16){ |
148 | 0 | b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); |
149 | 0 | if(bits>=24){ |
150 | 0 | b->ptr[3]=(unsigned char)(value>>(b->endbit)); |
151 | 0 | if(bits>=32){ |
152 | 0 | if(b->endbit) |
153 | 0 | b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); |
154 | 0 | else |
155 | 0 | b->ptr[4]=0; |
156 | 0 | } |
157 | 0 | } |
158 | 0 | } |
159 | 0 | } |
160 | |
|
161 | 0 | b->endbyte+=bits/8; |
162 | 0 | b->ptr+=bits/8; |
163 | 0 | b->endbit=bits&7; |
164 | 0 | return; |
165 | 0 | err: |
166 | 0 | oggpack_writeclear(b); |
167 | 0 | } |
168 | | |
169 | 0 | void oggpack_writealign(oggpack_buffer *b){ |
170 | 0 | int bits=8-b->endbit; |
171 | 0 | if(bits<8) |
172 | 0 | oggpack_write(b,0,bits); |
173 | 0 | } |
174 | | |
175 | 0 | void oggpackB_writealign(oggpack_buffer *b){ |
176 | 0 | int bits=8-b->endbit; |
177 | 0 | if(bits<8) |
178 | 0 | oggpackB_write(b,0,bits); |
179 | 0 | } |
180 | | |
181 | | static void oggpack_writecopy_helper(oggpack_buffer *b, |
182 | | void *source, |
183 | | long bits, |
184 | | void (*w)(oggpack_buffer *, |
185 | | unsigned long, |
186 | | int), |
187 | 0 | int msb){ |
188 | 0 | unsigned char *ptr=(unsigned char *)source; |
189 | |
|
190 | 0 | long bytes=bits/8; |
191 | 0 | long pbytes=(b->endbit+bits)/8; |
192 | 0 | bits-=bytes*8; |
193 | | |
194 | | /* expand storage up-front */ |
195 | 0 | if(b->endbyte+pbytes>=b->storage){ |
196 | 0 | void *ret; |
197 | 0 | if(!b->ptr) goto err; |
198 | 0 | if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err; |
199 | 0 | b->storage=b->endbyte+pbytes+BUFFER_INCREMENT; |
200 | 0 | ret=_ogg_realloc(b->buffer,b->storage); |
201 | 0 | if(!ret) goto err; |
202 | 0 | b->buffer=ret; |
203 | 0 | b->ptr=b->buffer+b->endbyte; |
204 | 0 | } |
205 | | |
206 | | /* copy whole octets */ |
207 | 0 | if(b->endbit){ |
208 | 0 | int i; |
209 | | /* unaligned copy. Do it the hard way. */ |
210 | 0 | for(i=0;i<bytes;i++) |
211 | 0 | w(b,(unsigned long)(ptr[i]),8); |
212 | 0 | }else{ |
213 | | /* aligned block copy */ |
214 | 0 | memmove(b->ptr,source,bytes); |
215 | 0 | b->ptr+=bytes; |
216 | 0 | b->endbyte+=bytes; |
217 | 0 | *b->ptr=0; |
218 | 0 | } |
219 | | |
220 | | /* copy trailing bits */ |
221 | 0 | if(bits){ |
222 | 0 | if(msb) |
223 | 0 | w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); |
224 | 0 | else |
225 | 0 | w(b,(unsigned long)(ptr[bytes]),bits); |
226 | 0 | } |
227 | 0 | return; |
228 | 0 | err: |
229 | 0 | oggpack_writeclear(b); |
230 | 0 | } |
231 | | |
232 | 0 | void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ |
233 | 0 | oggpack_writecopy_helper(b,source,bits,oggpack_write,0); |
234 | 0 | } |
235 | | |
236 | 0 | void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ |
237 | 0 | oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); |
238 | 0 | } |
239 | | |
240 | 0 | void oggpack_reset(oggpack_buffer *b){ |
241 | 0 | if(!b->ptr)return; |
242 | 0 | b->ptr=b->buffer; |
243 | 0 | b->buffer[0]=0; |
244 | 0 | b->endbit=b->endbyte=0; |
245 | 0 | } |
246 | | |
247 | 0 | void oggpackB_reset(oggpack_buffer *b){ |
248 | 0 | oggpack_reset(b); |
249 | 0 | } |
250 | | |
251 | 0 | void oggpack_writeclear(oggpack_buffer *b){ |
252 | 0 | if(b->buffer)_ogg_free(b->buffer); |
253 | 0 | memset(b,0,sizeof(*b)); |
254 | 0 | } |
255 | | |
256 | 0 | void oggpackB_writeclear(oggpack_buffer *b){ |
257 | 0 | oggpack_writeclear(b); |
258 | 0 | } |
259 | | |
260 | 2.12M | void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ |
261 | 2.12M | memset(b,0,sizeof(*b)); |
262 | 2.12M | b->buffer=b->ptr=buf; |
263 | 2.12M | b->storage=bytes; |
264 | 2.12M | } |
265 | | |
266 | 0 | void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ |
267 | 0 | oggpack_readinit(b,buf,bytes); |
268 | 0 | } |
269 | | |
270 | | /* Read in bits without advancing the bitptr; bits <= 32 */ |
271 | 1.39M | long oggpack_look(oggpack_buffer *b,int bits){ |
272 | 1.39M | unsigned long ret; |
273 | 1.39M | unsigned long m; |
274 | | |
275 | 1.39M | if(bits<0 || bits>32) return -1; |
276 | 1.39M | m=mask[bits]; |
277 | 1.39M | bits+=b->endbit; |
278 | | |
279 | 1.39M | if(b->endbyte >= b->storage-4){ |
280 | | /* not the main path */ |
281 | 151k | if(b->endbyte > b->storage-((bits+7)>>3)) return -1; |
282 | | /* special case to avoid reading b->ptr[0], which might be past the end of |
283 | | the buffer; also skips some useless accounting */ |
284 | 57.3k | else if(!bits)return(0L); |
285 | 151k | } |
286 | | |
287 | 1.29M | ret=b->ptr[0]>>b->endbit; |
288 | 1.29M | if(bits>8){ |
289 | 420k | ret|=(unsigned long)b->ptr[1]<<(8-b->endbit); |
290 | 420k | if(bits>16){ |
291 | 12.5k | ret|=(unsigned long)b->ptr[2]<<(16-b->endbit); |
292 | 12.5k | if(bits>24){ |
293 | 1.78k | ret|=(unsigned long)b->ptr[3]<<(24-b->endbit); |
294 | 1.78k | if(bits>32 && b->endbit) |
295 | 0 | ret|=(unsigned long)b->ptr[4]<<(32-b->endbit); |
296 | 1.78k | } |
297 | 12.5k | } |
298 | 420k | } |
299 | 1.29M | return(m&ret); |
300 | 1.39M | } |
301 | | |
302 | | /* Read in bits without advancing the bitptr; bits <= 32 */ |
303 | 0 | long oggpackB_look(oggpack_buffer *b,int bits){ |
304 | 0 | unsigned long ret; |
305 | 0 | int m=32-bits; |
306 | |
|
307 | 0 | if(m<0 || m>32) return -1; |
308 | 0 | bits+=b->endbit; |
309 | |
|
310 | 0 | if(b->endbyte >= b->storage-4){ |
311 | | /* not the main path */ |
312 | 0 | if(b->endbyte > b->storage-((bits+7)>>3)) return -1; |
313 | | /* special case to avoid reading b->ptr[0], which might be past the end of |
314 | | the buffer; also skips some useless accounting */ |
315 | 0 | else if(!bits)return(0L); |
316 | 0 | } |
317 | | |
318 | 0 | ret=(unsigned long)b->ptr[0]<<(24+b->endbit); |
319 | 0 | if(bits>8){ |
320 | 0 | ret|=(unsigned long)b->ptr[1]<<(16+b->endbit); |
321 | 0 | if(bits>16){ |
322 | 0 | ret|=(unsigned long)b->ptr[2]<<(8+b->endbit); |
323 | 0 | if(bits>24){ |
324 | 0 | ret|=(unsigned long)b->ptr[3]<<(b->endbit); |
325 | 0 | if(bits>32 && b->endbit) |
326 | 0 | ret|=b->ptr[4]>>(8-b->endbit); |
327 | 0 | } |
328 | 0 | } |
329 | 0 | } |
330 | 0 | return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); |
331 | 0 | } |
332 | | |
333 | 0 | long oggpack_look1(oggpack_buffer *b){ |
334 | 0 | if(b->endbyte>=b->storage)return(-1); |
335 | 0 | return((b->ptr[0]>>b->endbit)&1); |
336 | 0 | } |
337 | | |
338 | 0 | long oggpackB_look1(oggpack_buffer *b){ |
339 | 0 | if(b->endbyte>=b->storage)return(-1); |
340 | 0 | return((b->ptr[0]>>(7-b->endbit))&1); |
341 | 0 | } |
342 | | |
343 | 1.26M | void oggpack_adv(oggpack_buffer *b,int bits){ |
344 | 1.26M | bits+=b->endbit; |
345 | | |
346 | 1.26M | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; |
347 | | |
348 | 1.26M | b->ptr+=bits/8; |
349 | 1.26M | b->endbyte+=bits/8; |
350 | 1.26M | b->endbit=bits&7; |
351 | 1.26M | return; |
352 | | |
353 | 0 | overflow: |
354 | 0 | b->ptr=NULL; |
355 | 0 | b->endbyte=b->storage; |
356 | 0 | b->endbit=1; |
357 | 0 | } |
358 | | |
359 | 0 | void oggpackB_adv(oggpack_buffer *b,int bits){ |
360 | 0 | oggpack_adv(b,bits); |
361 | 0 | } |
362 | | |
363 | 0 | void oggpack_adv1(oggpack_buffer *b){ |
364 | 0 | if(++(b->endbit)>7){ |
365 | 0 | b->endbit=0; |
366 | 0 | b->ptr++; |
367 | 0 | b->endbyte++; |
368 | 0 | } |
369 | 0 | } |
370 | | |
371 | 0 | void oggpackB_adv1(oggpack_buffer *b){ |
372 | 0 | oggpack_adv1(b); |
373 | 0 | } |
374 | | |
375 | | /* bits <= 32 */ |
376 | 8.98M | long oggpack_read(oggpack_buffer *b,int bits){ |
377 | 8.98M | long ret; |
378 | 8.98M | unsigned long m; |
379 | | |
380 | 8.98M | if(bits<0 || bits>32) goto err; |
381 | 8.97M | m=mask[bits]; |
382 | 8.97M | bits+=b->endbit; |
383 | | |
384 | 8.97M | if(b->endbyte >= b->storage-4){ |
385 | | /* not the main path */ |
386 | 4.11M | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; |
387 | | /* special case to avoid reading b->ptr[0], which might be past the end of |
388 | | the buffer; also skips some useless accounting */ |
389 | 423k | else if(!bits)return(0L); |
390 | 4.11M | } |
391 | | |
392 | 5.27M | ret=b->ptr[0]>>b->endbit; |
393 | 5.27M | if(bits>8){ |
394 | 1.23M | ret|=(unsigned long)b->ptr[1]<<(8-b->endbit); |
395 | 1.23M | if(bits>16){ |
396 | 278k | ret|=(unsigned long)b->ptr[2]<<(16-b->endbit); |
397 | 278k | if(bits>24){ |
398 | 158k | ret|=(unsigned long)b->ptr[3]<<(24-b->endbit); |
399 | 158k | if(bits>32 && b->endbit){ |
400 | 23.0k | ret|=(unsigned long)b->ptr[4]<<(32-b->endbit); |
401 | 23.0k | } |
402 | 158k | } |
403 | 278k | } |
404 | 1.23M | } |
405 | 5.27M | ret&=m; |
406 | 5.27M | b->ptr+=bits/8; |
407 | 5.27M | b->endbyte+=bits/8; |
408 | 5.27M | b->endbit=bits&7; |
409 | 5.27M | return ret; |
410 | | |
411 | 3.69M | overflow: |
412 | 3.70M | err: |
413 | 3.70M | b->ptr=NULL; |
414 | 3.70M | b->endbyte=b->storage; |
415 | 3.70M | b->endbit=1; |
416 | 3.70M | return -1L; |
417 | 3.69M | } |
418 | | |
419 | | /* bits <= 32 */ |
420 | 0 | long oggpackB_read(oggpack_buffer *b,int bits){ |
421 | 0 | long ret; |
422 | 0 | long m=32-bits; |
423 | |
|
424 | 0 | if(m<0 || m>32) goto err; |
425 | 0 | bits+=b->endbit; |
426 | |
|
427 | 0 | if(b->endbyte+4>=b->storage){ |
428 | | /* not the main path */ |
429 | 0 | if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; |
430 | | /* special case to avoid reading b->ptr[0], which might be past the end of |
431 | | the buffer; also skips some useless accounting */ |
432 | 0 | else if(!bits)return(0L); |
433 | 0 | } |
434 | | |
435 | 0 | ret=(unsigned long)b->ptr[0]<<(24+b->endbit); |
436 | 0 | if(bits>8){ |
437 | 0 | ret|=(unsigned long)b->ptr[1]<<(16+b->endbit); |
438 | 0 | if(bits>16){ |
439 | 0 | ret|=(unsigned long)b->ptr[2]<<(8+b->endbit); |
440 | 0 | if(bits>24){ |
441 | 0 | ret|=(unsigned long)b->ptr[3]<<(b->endbit); |
442 | 0 | if(bits>32 && b->endbit) |
443 | 0 | ret|=b->ptr[4]>>(8-b->endbit); |
444 | 0 | } |
445 | 0 | } |
446 | 0 | } |
447 | 0 | ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); |
448 | |
|
449 | 0 | b->ptr+=bits/8; |
450 | 0 | b->endbyte+=bits/8; |
451 | 0 | b->endbit=bits&7; |
452 | 0 | return ret; |
453 | | |
454 | 0 | overflow: |
455 | 0 | err: |
456 | 0 | b->ptr=NULL; |
457 | 0 | b->endbyte=b->storage; |
458 | 0 | b->endbit=1; |
459 | 0 | return -1L; |
460 | 0 | } |
461 | | |
462 | 0 | long oggpack_read1(oggpack_buffer *b){ |
463 | 0 | long ret; |
464 | |
|
465 | 0 | if(b->endbyte >= b->storage) goto overflow; |
466 | 0 | ret=(b->ptr[0]>>b->endbit)&1; |
467 | |
|
468 | 0 | b->endbit++; |
469 | 0 | if(b->endbit>7){ |
470 | 0 | b->endbit=0; |
471 | 0 | b->ptr++; |
472 | 0 | b->endbyte++; |
473 | 0 | } |
474 | 0 | return ret; |
475 | | |
476 | 0 | overflow: |
477 | 0 | b->ptr=NULL; |
478 | 0 | b->endbyte=b->storage; |
479 | 0 | b->endbit=1; |
480 | 0 | return -1L; |
481 | 0 | } |
482 | | |
483 | 0 | long oggpackB_read1(oggpack_buffer *b){ |
484 | 0 | long ret; |
485 | |
|
486 | 0 | if(b->endbyte >= b->storage) goto overflow; |
487 | 0 | ret=(b->ptr[0]>>(7-b->endbit))&1; |
488 | |
|
489 | 0 | b->endbit++; |
490 | 0 | if(b->endbit>7){ |
491 | 0 | b->endbit=0; |
492 | 0 | b->ptr++; |
493 | 0 | b->endbyte++; |
494 | 0 | } |
495 | 0 | return ret; |
496 | | |
497 | 0 | overflow: |
498 | 0 | b->ptr=NULL; |
499 | 0 | b->endbyte=b->storage; |
500 | 0 | b->endbit=1; |
501 | 0 | return -1L; |
502 | 0 | } |
503 | | |
504 | 46.8k | long oggpack_bytes(oggpack_buffer *b){ |
505 | 46.8k | return(b->endbyte+(b->endbit+7)/8); |
506 | 46.8k | } |
507 | | |
508 | 0 | long oggpack_bits(oggpack_buffer *b){ |
509 | 0 | return(b->endbyte*8+b->endbit); |
510 | 0 | } |
511 | | |
512 | 0 | long oggpackB_bytes(oggpack_buffer *b){ |
513 | 0 | return oggpack_bytes(b); |
514 | 0 | } |
515 | | |
516 | 0 | long oggpackB_bits(oggpack_buffer *b){ |
517 | 0 | return oggpack_bits(b); |
518 | 0 | } |
519 | | |
520 | 0 | unsigned char *oggpack_get_buffer(oggpack_buffer *b){ |
521 | 0 | return(b->buffer); |
522 | 0 | } |
523 | | |
524 | 0 | unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ |
525 | 0 | return oggpack_get_buffer(b); |
526 | 0 | } |
527 | | |
528 | | /* Self test of the bitwise routines; everything else is based on |
529 | | them, so they damned well better be solid. */ |
530 | | |
531 | | #ifdef _V_SELFTEST |
532 | | #include <stdio.h> |
533 | | |
534 | | static int ilog(unsigned int v){ |
535 | | int ret=0; |
536 | | while(v){ |
537 | | ret++; |
538 | | v>>=1; |
539 | | } |
540 | | return(ret); |
541 | | } |
542 | | |
543 | | oggpack_buffer o; |
544 | | oggpack_buffer r; |
545 | | |
546 | | void report(char *in){ |
547 | | fprintf(stderr,"%s",in); |
548 | | exit(1); |
549 | | } |
550 | | |
551 | | void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ |
552 | | long bytes,i; |
553 | | unsigned char *buffer; |
554 | | |
555 | | oggpack_reset(&o); |
556 | | for(i=0;i<vals;i++) |
557 | | oggpack_write(&o,b[i],bits?bits:ilog(b[i])); |
558 | | buffer=oggpack_get_buffer(&o); |
559 | | bytes=oggpack_bytes(&o); |
560 | | if(bytes!=compsize)report("wrong number of bytes!\n"); |
561 | | for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ |
562 | | for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); |
563 | | report("wrote incorrect value!\n"); |
564 | | } |
565 | | oggpack_readinit(&r,buffer,bytes); |
566 | | for(i=0;i<vals;i++){ |
567 | | int tbit=bits?bits:ilog(b[i]); |
568 | | if(oggpack_look(&r,tbit)==-1) |
569 | | report("out of data!\n"); |
570 | | if((unsigned long)oggpack_look(&r,tbit)!=(b[i]&mask[tbit])) |
571 | | report("looked at incorrect value!\n"); |
572 | | if(tbit==1) |
573 | | if((unsigned long)oggpack_look1(&r)!=(b[i]&mask[tbit])) |
574 | | report("looked at single bit incorrect value!\n"); |
575 | | if(tbit==1){ |
576 | | if((unsigned long)oggpack_read1(&r)!=(b[i]&mask[tbit])) |
577 | | report("read incorrect single bit value!\n"); |
578 | | }else{ |
579 | | if((unsigned long)oggpack_read(&r,tbit)!=(b[i]&mask[tbit])) |
580 | | report("read incorrect value!\n"); |
581 | | } |
582 | | } |
583 | | if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
584 | | } |
585 | | |
586 | | void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){ |
587 | | long bytes,i; |
588 | | unsigned char *buffer; |
589 | | |
590 | | oggpackB_reset(&o); |
591 | | for(i=0;i<vals;i++) |
592 | | oggpackB_write(&o,b[i],bits?bits:ilog(b[i])); |
593 | | buffer=oggpackB_get_buffer(&o); |
594 | | bytes=oggpackB_bytes(&o); |
595 | | if(bytes!=compsize)report("wrong number of bytes!\n"); |
596 | | for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ |
597 | | for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); |
598 | | report("wrote incorrect value!\n"); |
599 | | } |
600 | | oggpackB_readinit(&r,buffer,bytes); |
601 | | for(i=0;i<vals;i++){ |
602 | | int tbit=bits?bits:ilog(b[i]); |
603 | | if(oggpackB_look(&r,tbit)==-1) |
604 | | report("out of data!\n"); |
605 | | if((unsigned long)oggpackB_look(&r,tbit)!=(b[i]&mask[tbit])) |
606 | | report("looked at incorrect value!\n"); |
607 | | if(tbit==1) |
608 | | if((unsigned long)oggpackB_look1(&r)!=(b[i]&mask[tbit])) |
609 | | report("looked at single bit incorrect value!\n"); |
610 | | if(tbit==1){ |
611 | | if((unsigned long)oggpackB_read1(&r)!=(b[i]&mask[tbit])) |
612 | | report("read incorrect single bit value!\n"); |
613 | | }else{ |
614 | | if((unsigned long)oggpackB_read(&r,tbit)!=(b[i]&mask[tbit])) |
615 | | report("read incorrect value!\n"); |
616 | | } |
617 | | } |
618 | | if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
619 | | } |
620 | | |
621 | | void copytest(int prefill, int copy){ |
622 | | oggpack_buffer source_write; |
623 | | oggpack_buffer dest_write; |
624 | | oggpack_buffer source_read; |
625 | | oggpack_buffer dest_read; |
626 | | unsigned char *source; |
627 | | unsigned char *dest; |
628 | | long source_bytes,dest_bytes; |
629 | | int i; |
630 | | |
631 | | oggpack_writeinit(&source_write); |
632 | | oggpack_writeinit(&dest_write); |
633 | | |
634 | | for(i=0;i<(prefill+copy+7)/8;i++) |
635 | | oggpack_write(&source_write,(i^0x5a)&0xff,8); |
636 | | source=oggpack_get_buffer(&source_write); |
637 | | source_bytes=oggpack_bytes(&source_write); |
638 | | |
639 | | /* prefill */ |
640 | | oggpack_writecopy(&dest_write,source,prefill); |
641 | | |
642 | | /* check buffers; verify end byte masking */ |
643 | | dest=oggpack_get_buffer(&dest_write); |
644 | | dest_bytes=oggpack_bytes(&dest_write); |
645 | | if(dest_bytes!=(prefill+7)/8){ |
646 | | fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8); |
647 | | exit(1); |
648 | | } |
649 | | oggpack_readinit(&source_read,source,source_bytes); |
650 | | oggpack_readinit(&dest_read,dest,dest_bytes); |
651 | | |
652 | | for(i=0;i<prefill;i+=8){ |
653 | | int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8); |
654 | | int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8); |
655 | | if(s!=d){ |
656 | | fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); |
657 | | exit(1); |
658 | | } |
659 | | } |
660 | | if(prefill<dest_bytes){ |
661 | | if(oggpack_read(&dest_read,dest_bytes-prefill)!=0){ |
662 | | fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill); |
663 | | exit(1); |
664 | | } |
665 | | } |
666 | | |
667 | | /* second copy */ |
668 | | oggpack_writecopy(&dest_write,source,copy); |
669 | | |
670 | | /* check buffers; verify end byte masking */ |
671 | | dest=oggpack_get_buffer(&dest_write); |
672 | | dest_bytes=oggpack_bytes(&dest_write); |
673 | | if(dest_bytes!=(copy+prefill+7)/8){ |
674 | | fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8); |
675 | | exit(1); |
676 | | } |
677 | | oggpack_readinit(&source_read,source,source_bytes); |
678 | | oggpack_readinit(&dest_read,dest,dest_bytes); |
679 | | |
680 | | for(i=0;i<prefill;i+=8){ |
681 | | int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8); |
682 | | int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8); |
683 | | if(s!=d){ |
684 | | fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); |
685 | | exit(1); |
686 | | } |
687 | | } |
688 | | |
689 | | oggpack_readinit(&source_read,source,source_bytes); |
690 | | for(i=0;i<copy;i+=8){ |
691 | | int s=oggpack_read(&source_read,copy-i<8?copy-i:8); |
692 | | int d=oggpack_read(&dest_read,copy-i<8?copy-i:8); |
693 | | if(s!=d){ |
694 | | fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d); |
695 | | exit(1); |
696 | | } |
697 | | } |
698 | | |
699 | | if(copy+prefill<dest_bytes){ |
700 | | if(oggpack_read(&dest_read,dest_bytes-copy-prefill)!=0){ |
701 | | fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy); |
702 | | exit(1); |
703 | | } |
704 | | } |
705 | | |
706 | | oggpack_writeclear(&source_write); |
707 | | oggpack_writeclear(&dest_write); |
708 | | |
709 | | |
710 | | } |
711 | | |
712 | | void copytestB(int prefill, int copy){ |
713 | | oggpack_buffer source_write; |
714 | | oggpack_buffer dest_write; |
715 | | oggpack_buffer source_read; |
716 | | oggpack_buffer dest_read; |
717 | | unsigned char *source; |
718 | | unsigned char *dest; |
719 | | long source_bytes,dest_bytes; |
720 | | int i; |
721 | | |
722 | | oggpackB_writeinit(&source_write); |
723 | | oggpackB_writeinit(&dest_write); |
724 | | |
725 | | for(i=0;i<(prefill+copy+7)/8;i++) |
726 | | oggpackB_write(&source_write,(i^0x5a)&0xff,8); |
727 | | source=oggpackB_get_buffer(&source_write); |
728 | | source_bytes=oggpackB_bytes(&source_write); |
729 | | |
730 | | /* prefill */ |
731 | | oggpackB_writecopy(&dest_write,source,prefill); |
732 | | |
733 | | /* check buffers; verify end byte masking */ |
734 | | dest=oggpackB_get_buffer(&dest_write); |
735 | | dest_bytes=oggpackB_bytes(&dest_write); |
736 | | if(dest_bytes!=(prefill+7)/8){ |
737 | | fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8); |
738 | | exit(1); |
739 | | } |
740 | | oggpackB_readinit(&source_read,source,source_bytes); |
741 | | oggpackB_readinit(&dest_read,dest,dest_bytes); |
742 | | |
743 | | for(i=0;i<prefill;i+=8){ |
744 | | int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8); |
745 | | int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8); |
746 | | if(s!=d){ |
747 | | fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); |
748 | | exit(1); |
749 | | } |
750 | | } |
751 | | if(prefill<dest_bytes){ |
752 | | if(oggpackB_read(&dest_read,dest_bytes-prefill)!=0){ |
753 | | fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill); |
754 | | exit(1); |
755 | | } |
756 | | } |
757 | | |
758 | | /* second copy */ |
759 | | oggpackB_writecopy(&dest_write,source,copy); |
760 | | |
761 | | /* check buffers; verify end byte masking */ |
762 | | dest=oggpackB_get_buffer(&dest_write); |
763 | | dest_bytes=oggpackB_bytes(&dest_write); |
764 | | if(dest_bytes!=(copy+prefill+7)/8){ |
765 | | fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8); |
766 | | exit(1); |
767 | | } |
768 | | oggpackB_readinit(&source_read,source,source_bytes); |
769 | | oggpackB_readinit(&dest_read,dest,dest_bytes); |
770 | | |
771 | | for(i=0;i<prefill;i+=8){ |
772 | | int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8); |
773 | | int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8); |
774 | | if(s!=d){ |
775 | | fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d); |
776 | | exit(1); |
777 | | } |
778 | | } |
779 | | |
780 | | oggpackB_readinit(&source_read,source,source_bytes); |
781 | | for(i=0;i<copy;i+=8){ |
782 | | int s=oggpackB_read(&source_read,copy-i<8?copy-i:8); |
783 | | int d=oggpackB_read(&dest_read,copy-i<8?copy-i:8); |
784 | | if(s!=d){ |
785 | | fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d); |
786 | | exit(1); |
787 | | } |
788 | | } |
789 | | |
790 | | if(copy+prefill<dest_bytes){ |
791 | | if(oggpackB_read(&dest_read,dest_bytes-copy-prefill)!=0){ |
792 | | fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy); |
793 | | exit(1); |
794 | | } |
795 | | } |
796 | | |
797 | | oggpackB_writeclear(&source_write); |
798 | | oggpackB_writeclear(&dest_write); |
799 | | |
800 | | } |
801 | | |
802 | | int main(void){ |
803 | | unsigned char *buffer; |
804 | | long bytes,i,j; |
805 | | static unsigned long testbuffer1[]= |
806 | | {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7, |
807 | | 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4}; |
808 | | int test1size=43; |
809 | | |
810 | | static unsigned long testbuffer2[]= |
811 | | {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212, |
812 | | 1233432,534,5,346435231,14436467,7869299,76326614,167548585, |
813 | | 85525151,0,12321,1,349528352}; |
814 | | int test2size=21; |
815 | | |
816 | | static unsigned long testbuffer3[]= |
817 | | {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1, |
818 | | 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1}; |
819 | | int test3size=56; |
820 | | |
821 | | static unsigned long large[]= |
822 | | {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212, |
823 | | 1233432,534,5,2146435231,14436467,7869299,76326614,167548585, |
824 | | 85525151,0,12321,1,2146528352}; |
825 | | |
826 | | int onesize=33; |
827 | | static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40, |
828 | | 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172, |
829 | | 223,4}; |
830 | | static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222, |
831 | | 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18, |
832 | | 245,251,128}; |
833 | | |
834 | | int twosize=6; |
835 | | static int two[6]={61,255,255,251,231,29}; |
836 | | static int twoB[6]={247,63,255,253,249,120}; |
837 | | |
838 | | int threesize=54; |
839 | | static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254, |
840 | | 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83, |
841 | | 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10, |
842 | | 100,52,4,14,18,86,77,1}; |
843 | | static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183, |
844 | | 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98, |
845 | | 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104, |
846 | | 200,20,254,4,58,106,176,144,0}; |
847 | | |
848 | | int foursize=38; |
849 | | static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72, |
850 | | 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169, |
851 | | 28,2,133,0,1}; |
852 | | static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41, |
853 | | 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67, |
854 | | 129,10,4,32}; |
855 | | |
856 | | int fivesize=45; |
857 | | static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62, |
858 | | 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169, |
859 | | 84,75,159,2,1,0,132,192,8,0,0,18,22}; |
860 | | static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226, |
861 | | 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77, |
862 | | 172,150,169,129,79,128,0,6,4,32,0,27,9,0}; |
863 | | |
864 | | int sixsize=7; |
865 | | static int six[7]={17,177,170,242,169,19,148}; |
866 | | static int sixB[7]={136,141,85,79,149,200,41}; |
867 | | |
868 | | /* Test read/write together */ |
869 | | /* Later we test against pregenerated bitstreams */ |
870 | | oggpack_writeinit(&o); |
871 | | |
872 | | fprintf(stderr,"\nSmall preclipped packing (LSb): "); |
873 | | cliptest(testbuffer1,test1size,0,one,onesize); |
874 | | fprintf(stderr,"ok."); |
875 | | |
876 | | fprintf(stderr,"\nNull bit call (LSb): "); |
877 | | cliptest(testbuffer3,test3size,0,two,twosize); |
878 | | fprintf(stderr,"ok."); |
879 | | |
880 | | fprintf(stderr,"\nLarge preclipped packing (LSb): "); |
881 | | cliptest(testbuffer2,test2size,0,three,threesize); |
882 | | fprintf(stderr,"ok."); |
883 | | |
884 | | fprintf(stderr,"\n32 bit preclipped packing (LSb): "); |
885 | | oggpack_reset(&o); |
886 | | for(i=0;i<test2size;i++) |
887 | | oggpack_write(&o,large[i],32); |
888 | | buffer=oggpack_get_buffer(&o); |
889 | | bytes=oggpack_bytes(&o); |
890 | | oggpack_readinit(&r,buffer,bytes); |
891 | | for(i=0;i<test2size;i++){ |
892 | | if(oggpack_look(&r,32)==-1)report("out of data. failed!"); |
893 | | if((unsigned long)oggpack_look(&r,32)!=large[i]){ |
894 | | fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpack_look(&r,32),large[i], |
895 | | oggpack_look(&r,32),large[i]); |
896 | | report("read incorrect value!\n"); |
897 | | } |
898 | | oggpack_adv(&r,32); |
899 | | } |
900 | | if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
901 | | fprintf(stderr,"ok."); |
902 | | |
903 | | fprintf(stderr,"\nSmall unclipped packing (LSb): "); |
904 | | cliptest(testbuffer1,test1size,7,four,foursize); |
905 | | fprintf(stderr,"ok."); |
906 | | |
907 | | fprintf(stderr,"\nLarge unclipped packing (LSb): "); |
908 | | cliptest(testbuffer2,test2size,17,five,fivesize); |
909 | | fprintf(stderr,"ok."); |
910 | | |
911 | | fprintf(stderr,"\nSingle bit unclipped packing (LSb): "); |
912 | | cliptest(testbuffer3,test3size,1,six,sixsize); |
913 | | fprintf(stderr,"ok."); |
914 | | |
915 | | fprintf(stderr,"\nTesting read past end (LSb): "); |
916 | | oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
917 | | for(i=0;i<64;i++){ |
918 | | if(oggpack_read(&r,1)!=0){ |
919 | | fprintf(stderr,"failed; got -1 prematurely.\n"); |
920 | | exit(1); |
921 | | } |
922 | | } |
923 | | if(oggpack_look(&r,1)!=-1 || |
924 | | oggpack_read(&r,1)!=-1){ |
925 | | fprintf(stderr,"failed; read past end without -1.\n"); |
926 | | exit(1); |
927 | | } |
928 | | oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
929 | | if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){ |
930 | | fprintf(stderr,"failed 2; got -1 prematurely.\n"); |
931 | | exit(1); |
932 | | } |
933 | | |
934 | | if(oggpack_look(&r,18)!=0 || |
935 | | oggpack_look(&r,18)!=0){ |
936 | | fprintf(stderr,"failed 3; got -1 prematurely.\n"); |
937 | | exit(1); |
938 | | } |
939 | | if(oggpack_look(&r,19)!=-1 || |
940 | | oggpack_look(&r,19)!=-1){ |
941 | | fprintf(stderr,"failed; read past end without -1.\n"); |
942 | | exit(1); |
943 | | } |
944 | | if(oggpack_look(&r,32)!=-1 || |
945 | | oggpack_look(&r,32)!=-1){ |
946 | | fprintf(stderr,"failed; read past end without -1.\n"); |
947 | | exit(1); |
948 | | } |
949 | | oggpack_writeclear(&o); |
950 | | fprintf(stderr,"ok."); |
951 | | |
952 | | /* this is partly glassbox; we're mostly concerned about the allocation boundaries */ |
953 | | |
954 | | fprintf(stderr,"\nTesting aligned writecopies (LSb): "); |
955 | | for(i=0;i<71;i++) |
956 | | for(j=0;j<5;j++) |
957 | | copytest(j*8,i); |
958 | | for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) |
959 | | for(j=0;j<5;j++) |
960 | | copytest(j*8,i); |
961 | | fprintf(stderr,"ok. "); |
962 | | |
963 | | fprintf(stderr,"\nTesting unaligned writecopies (LSb): "); |
964 | | for(i=0;i<71;i++) |
965 | | for(j=1;j<40;j++) |
966 | | if(j&0x7) |
967 | | copytest(j,i); |
968 | | for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) |
969 | | for(j=1;j<40;j++) |
970 | | if(j&0x7) |
971 | | copytest(j,i); |
972 | | |
973 | | fprintf(stderr,"ok. \n"); |
974 | | |
975 | | |
976 | | /********** lazy, cut-n-paste retest with MSb packing ***********/ |
977 | | |
978 | | /* Test read/write together */ |
979 | | /* Later we test against pregenerated bitstreams */ |
980 | | oggpackB_writeinit(&o); |
981 | | |
982 | | fprintf(stderr,"\nSmall preclipped packing (MSb): "); |
983 | | cliptestB(testbuffer1,test1size,0,oneB,onesize); |
984 | | fprintf(stderr,"ok."); |
985 | | |
986 | | fprintf(stderr,"\nNull bit call (MSb): "); |
987 | | cliptestB(testbuffer3,test3size,0,twoB,twosize); |
988 | | fprintf(stderr,"ok."); |
989 | | |
990 | | fprintf(stderr,"\nLarge preclipped packing (MSb): "); |
991 | | cliptestB(testbuffer2,test2size,0,threeB,threesize); |
992 | | fprintf(stderr,"ok."); |
993 | | |
994 | | fprintf(stderr,"\n32 bit preclipped packing (MSb): "); |
995 | | oggpackB_reset(&o); |
996 | | for(i=0;i<test2size;i++) |
997 | | oggpackB_write(&o,large[i],32); |
998 | | buffer=oggpackB_get_buffer(&o); |
999 | | bytes=oggpackB_bytes(&o); |
1000 | | oggpackB_readinit(&r,buffer,bytes); |
1001 | | for(i=0;i<test2size;i++){ |
1002 | | if(oggpackB_look(&r,32)==-1)report("out of data. failed!"); |
1003 | | if((unsigned long)oggpackB_look(&r,32)!=large[i]){ |
1004 | | fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpackB_look(&r,32),large[i], |
1005 | | oggpackB_look(&r,32),large[i]); |
1006 | | report("read incorrect value!\n"); |
1007 | | } |
1008 | | oggpackB_adv(&r,32); |
1009 | | } |
1010 | | if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); |
1011 | | fprintf(stderr,"ok."); |
1012 | | |
1013 | | fprintf(stderr,"\nSmall unclipped packing (MSb): "); |
1014 | | cliptestB(testbuffer1,test1size,7,fourB,foursize); |
1015 | | fprintf(stderr,"ok."); |
1016 | | |
1017 | | fprintf(stderr,"\nLarge unclipped packing (MSb): "); |
1018 | | cliptestB(testbuffer2,test2size,17,fiveB,fivesize); |
1019 | | fprintf(stderr,"ok."); |
1020 | | |
1021 | | fprintf(stderr,"\nSingle bit unclipped packing (MSb): "); |
1022 | | cliptestB(testbuffer3,test3size,1,sixB,sixsize); |
1023 | | fprintf(stderr,"ok."); |
1024 | | |
1025 | | fprintf(stderr,"\nTesting read past end (MSb): "); |
1026 | | oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
1027 | | for(i=0;i<64;i++){ |
1028 | | if(oggpackB_read(&r,1)!=0){ |
1029 | | fprintf(stderr,"failed; got -1 prematurely.\n"); |
1030 | | exit(1); |
1031 | | } |
1032 | | } |
1033 | | if(oggpackB_look(&r,1)!=-1 || |
1034 | | oggpackB_read(&r,1)!=-1){ |
1035 | | fprintf(stderr,"failed; read past end without -1.\n"); |
1036 | | exit(1); |
1037 | | } |
1038 | | oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); |
1039 | | if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){ |
1040 | | fprintf(stderr,"failed 2; got -1 prematurely.\n"); |
1041 | | exit(1); |
1042 | | } |
1043 | | |
1044 | | if(oggpackB_look(&r,18)!=0 || |
1045 | | oggpackB_look(&r,18)!=0){ |
1046 | | fprintf(stderr,"failed 3; got -1 prematurely.\n"); |
1047 | | exit(1); |
1048 | | } |
1049 | | if(oggpackB_look(&r,19)!=-1 || |
1050 | | oggpackB_look(&r,19)!=-1){ |
1051 | | fprintf(stderr,"failed; read past end without -1.\n"); |
1052 | | exit(1); |
1053 | | } |
1054 | | if(oggpackB_look(&r,32)!=-1 || |
1055 | | oggpackB_look(&r,32)!=-1){ |
1056 | | fprintf(stderr,"failed; read past end without -1.\n"); |
1057 | | exit(1); |
1058 | | } |
1059 | | fprintf(stderr,"ok."); |
1060 | | oggpackB_writeclear(&o); |
1061 | | |
1062 | | /* this is partly glassbox; we're mostly concerned about the allocation boundaries */ |
1063 | | |
1064 | | fprintf(stderr,"\nTesting aligned writecopies (MSb): "); |
1065 | | for(i=0;i<71;i++) |
1066 | | for(j=0;j<5;j++) |
1067 | | copytestB(j*8,i); |
1068 | | for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) |
1069 | | for(j=0;j<5;j++) |
1070 | | copytestB(j*8,i); |
1071 | | fprintf(stderr,"ok. "); |
1072 | | |
1073 | | fprintf(stderr,"\nTesting unaligned writecopies (MSb): "); |
1074 | | for(i=0;i<71;i++) |
1075 | | for(j=1;j<40;j++) |
1076 | | if(j&0x7) |
1077 | | copytestB(j,i); |
1078 | | for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++) |
1079 | | for(j=1;j<40;j++) |
1080 | | if(j&0x7) |
1081 | | copytestB(j,i); |
1082 | | |
1083 | | fprintf(stderr,"ok. \n\n"); |
1084 | | |
1085 | | return(0); |
1086 | | } |
1087 | | #endif /* _V_SELFTEST */ |
1088 | | |
1089 | | #undef BUFFER_INCREMENT |