vrshoot
diff libs/ogg/bitwise.c @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/ogg/bitwise.c Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,857 @@ 1.4 +/******************************************************************** 1.5 + * * 1.6 + * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. * 1.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 1.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 1.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 1.10 + * * 1.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * 1.12 + * by the Xiph.Org Foundation http://www.xiph.org/ * 1.13 + * * 1.14 + ******************************************************************** 1.15 + 1.16 + function: packing variable sized words into an octet stream 1.17 + last mod: $Id: bitwise.c 18051 2011-08-04 17:56:39Z giles $ 1.18 + 1.19 + ********************************************************************/ 1.20 + 1.21 +/* We're 'LSb' endian; if we write a word but read individual bits, 1.22 + then we'll read the lsb first */ 1.23 + 1.24 +#include <string.h> 1.25 +#include <stdlib.h> 1.26 +#include <limits.h> 1.27 +#include <ogg/ogg.h> 1.28 + 1.29 +#define BUFFER_INCREMENT 256 1.30 + 1.31 +static const unsigned long mask[]= 1.32 +{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, 1.33 + 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, 1.34 + 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, 1.35 + 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, 1.36 + 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, 1.37 + 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, 1.38 + 0x3fffffff,0x7fffffff,0xffffffff }; 1.39 + 1.40 +static const unsigned int mask8B[]= 1.41 +{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; 1.42 + 1.43 +void oggpack_writeinit(oggpack_buffer *b){ 1.44 + memset(b,0,sizeof(*b)); 1.45 + b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); 1.46 + b->buffer[0]='\0'; 1.47 + b->storage=BUFFER_INCREMENT; 1.48 +} 1.49 + 1.50 +void oggpackB_writeinit(oggpack_buffer *b){ 1.51 + oggpack_writeinit(b); 1.52 +} 1.53 + 1.54 +int oggpack_writecheck(oggpack_buffer *b){ 1.55 + if(!b->ptr || !b->storage)return -1; 1.56 + return 0; 1.57 +} 1.58 + 1.59 +int oggpackB_writecheck(oggpack_buffer *b){ 1.60 + return oggpack_writecheck(b); 1.61 +} 1.62 + 1.63 +void oggpack_writetrunc(oggpack_buffer *b,long bits){ 1.64 + long bytes=bits>>3; 1.65 + if(b->ptr){ 1.66 + bits-=bytes*8; 1.67 + b->ptr=b->buffer+bytes; 1.68 + b->endbit=bits; 1.69 + b->endbyte=bytes; 1.70 + *b->ptr&=mask[bits]; 1.71 + } 1.72 +} 1.73 + 1.74 +void oggpackB_writetrunc(oggpack_buffer *b,long bits){ 1.75 + long bytes=bits>>3; 1.76 + if(b->ptr){ 1.77 + bits-=bytes*8; 1.78 + b->ptr=b->buffer+bytes; 1.79 + b->endbit=bits; 1.80 + b->endbyte=bytes; 1.81 + *b->ptr&=mask8B[bits]; 1.82 + } 1.83 +} 1.84 + 1.85 +/* Takes only up to 32 bits. */ 1.86 +void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ 1.87 + if(bits<0 || bits>32) goto err; 1.88 + if(b->endbyte>=b->storage-4){ 1.89 + void *ret; 1.90 + if(!b->ptr)return; 1.91 + if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; 1.92 + ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); 1.93 + if(!ret) goto err; 1.94 + b->buffer=ret; 1.95 + b->storage+=BUFFER_INCREMENT; 1.96 + b->ptr=b->buffer+b->endbyte; 1.97 + } 1.98 + 1.99 + value&=mask[bits]; 1.100 + bits+=b->endbit; 1.101 + 1.102 + b->ptr[0]|=value<<b->endbit; 1.103 + 1.104 + if(bits>=8){ 1.105 + b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); 1.106 + if(bits>=16){ 1.107 + b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); 1.108 + if(bits>=24){ 1.109 + b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); 1.110 + if(bits>=32){ 1.111 + if(b->endbit) 1.112 + b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); 1.113 + else 1.114 + b->ptr[4]=0; 1.115 + } 1.116 + } 1.117 + } 1.118 + } 1.119 + 1.120 + b->endbyte+=bits/8; 1.121 + b->ptr+=bits/8; 1.122 + b->endbit=bits&7; 1.123 + return; 1.124 + err: 1.125 + oggpack_writeclear(b); 1.126 +} 1.127 + 1.128 +/* Takes only up to 32 bits. */ 1.129 +void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ 1.130 + if(bits<0 || bits>32) goto err; 1.131 + if(b->endbyte>=b->storage-4){ 1.132 + void *ret; 1.133 + if(!b->ptr)return; 1.134 + if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; 1.135 + ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); 1.136 + if(!ret) goto err; 1.137 + b->buffer=ret; 1.138 + b->storage+=BUFFER_INCREMENT; 1.139 + b->ptr=b->buffer+b->endbyte; 1.140 + } 1.141 + 1.142 + value=(value&mask[bits])<<(32-bits); 1.143 + bits+=b->endbit; 1.144 + 1.145 + b->ptr[0]|=value>>(24+b->endbit); 1.146 + 1.147 + if(bits>=8){ 1.148 + b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); 1.149 + if(bits>=16){ 1.150 + b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); 1.151 + if(bits>=24){ 1.152 + b->ptr[3]=(unsigned char)(value>>(b->endbit)); 1.153 + if(bits>=32){ 1.154 + if(b->endbit) 1.155 + b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); 1.156 + else 1.157 + b->ptr[4]=0; 1.158 + } 1.159 + } 1.160 + } 1.161 + } 1.162 + 1.163 + b->endbyte+=bits/8; 1.164 + b->ptr+=bits/8; 1.165 + b->endbit=bits&7; 1.166 + return; 1.167 + err: 1.168 + oggpack_writeclear(b); 1.169 +} 1.170 + 1.171 +void oggpack_writealign(oggpack_buffer *b){ 1.172 + int bits=8-b->endbit; 1.173 + if(bits<8) 1.174 + oggpack_write(b,0,bits); 1.175 +} 1.176 + 1.177 +void oggpackB_writealign(oggpack_buffer *b){ 1.178 + int bits=8-b->endbit; 1.179 + if(bits<8) 1.180 + oggpackB_write(b,0,bits); 1.181 +} 1.182 + 1.183 +static void oggpack_writecopy_helper(oggpack_buffer *b, 1.184 + void *source, 1.185 + long bits, 1.186 + void (*w)(oggpack_buffer *, 1.187 + unsigned long, 1.188 + int), 1.189 + int msb){ 1.190 + unsigned char *ptr=(unsigned char *)source; 1.191 + 1.192 + long bytes=bits/8; 1.193 + bits-=bytes*8; 1.194 + 1.195 + if(b->endbit){ 1.196 + int i; 1.197 + /* unaligned copy. Do it the hard way. */ 1.198 + for(i=0;i<bytes;i++) 1.199 + w(b,(unsigned long)(ptr[i]),8); 1.200 + }else{ 1.201 + /* aligned block copy */ 1.202 + if(b->endbyte+bytes+1>=b->storage){ 1.203 + void *ret; 1.204 + if(!b->ptr) goto err; 1.205 + if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err; 1.206 + b->storage=b->endbyte+bytes+BUFFER_INCREMENT; 1.207 + ret=_ogg_realloc(b->buffer,b->storage); 1.208 + if(!ret) goto err; 1.209 + b->buffer=ret; 1.210 + b->ptr=b->buffer+b->endbyte; 1.211 + } 1.212 + 1.213 + memmove(b->ptr,source,bytes); 1.214 + b->ptr+=bytes; 1.215 + b->endbyte+=bytes; 1.216 + *b->ptr=0; 1.217 + 1.218 + } 1.219 + if(bits){ 1.220 + if(msb) 1.221 + w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); 1.222 + else 1.223 + w(b,(unsigned long)(ptr[bytes]),bits); 1.224 + } 1.225 + return; 1.226 + err: 1.227 + oggpack_writeclear(b); 1.228 +} 1.229 + 1.230 +void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ 1.231 + oggpack_writecopy_helper(b,source,bits,oggpack_write,0); 1.232 +} 1.233 + 1.234 +void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ 1.235 + oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); 1.236 +} 1.237 + 1.238 +void oggpack_reset(oggpack_buffer *b){ 1.239 + if(!b->ptr)return; 1.240 + b->ptr=b->buffer; 1.241 + b->buffer[0]=0; 1.242 + b->endbit=b->endbyte=0; 1.243 +} 1.244 + 1.245 +void oggpackB_reset(oggpack_buffer *b){ 1.246 + oggpack_reset(b); 1.247 +} 1.248 + 1.249 +void oggpack_writeclear(oggpack_buffer *b){ 1.250 + if(b->buffer)_ogg_free(b->buffer); 1.251 + memset(b,0,sizeof(*b)); 1.252 +} 1.253 + 1.254 +void oggpackB_writeclear(oggpack_buffer *b){ 1.255 + oggpack_writeclear(b); 1.256 +} 1.257 + 1.258 +void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ 1.259 + memset(b,0,sizeof(*b)); 1.260 + b->buffer=b->ptr=buf; 1.261 + b->storage=bytes; 1.262 +} 1.263 + 1.264 +void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ 1.265 + oggpack_readinit(b,buf,bytes); 1.266 +} 1.267 + 1.268 +/* Read in bits without advancing the bitptr; bits <= 32 */ 1.269 +long oggpack_look(oggpack_buffer *b,int bits){ 1.270 + unsigned long ret; 1.271 + unsigned long m; 1.272 + 1.273 + if(bits<0 || bits>32) return -1; 1.274 + m=mask[bits]; 1.275 + bits+=b->endbit; 1.276 + 1.277 + if(b->endbyte >= b->storage-4){ 1.278 + /* not the main path */ 1.279 + if(b->endbyte > b->storage-((bits+7)>>3)) return -1; 1.280 + /* special case to avoid reading b->ptr[0], which might be past the end of 1.281 + the buffer; also skips some useless accounting */ 1.282 + else if(!bits)return(0L); 1.283 + } 1.284 + 1.285 + ret=b->ptr[0]>>b->endbit; 1.286 + if(bits>8){ 1.287 + ret|=b->ptr[1]<<(8-b->endbit); 1.288 + if(bits>16){ 1.289 + ret|=b->ptr[2]<<(16-b->endbit); 1.290 + if(bits>24){ 1.291 + ret|=b->ptr[3]<<(24-b->endbit); 1.292 + if(bits>32 && b->endbit) 1.293 + ret|=b->ptr[4]<<(32-b->endbit); 1.294 + } 1.295 + } 1.296 + } 1.297 + return(m&ret); 1.298 +} 1.299 + 1.300 +/* Read in bits without advancing the bitptr; bits <= 32 */ 1.301 +long oggpackB_look(oggpack_buffer *b,int bits){ 1.302 + unsigned long ret; 1.303 + int m=32-bits; 1.304 + 1.305 + if(m<0 || m>32) return -1; 1.306 + bits+=b->endbit; 1.307 + 1.308 + if(b->endbyte >= b->storage-4){ 1.309 + /* not the main path */ 1.310 + if(b->endbyte > b->storage-((bits+7)>>3)) return -1; 1.311 + /* special case to avoid reading b->ptr[0], which might be past the end of 1.312 + the buffer; also skips some useless accounting */ 1.313 + else if(!bits)return(0L); 1.314 + } 1.315 + 1.316 + ret=b->ptr[0]<<(24+b->endbit); 1.317 + if(bits>8){ 1.318 + ret|=b->ptr[1]<<(16+b->endbit); 1.319 + if(bits>16){ 1.320 + ret|=b->ptr[2]<<(8+b->endbit); 1.321 + if(bits>24){ 1.322 + ret|=b->ptr[3]<<(b->endbit); 1.323 + if(bits>32 && b->endbit) 1.324 + ret|=b->ptr[4]>>(8-b->endbit); 1.325 + } 1.326 + } 1.327 + } 1.328 + return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); 1.329 +} 1.330 + 1.331 +long oggpack_look1(oggpack_buffer *b){ 1.332 + if(b->endbyte>=b->storage)return(-1); 1.333 + return((b->ptr[0]>>b->endbit)&1); 1.334 +} 1.335 + 1.336 +long oggpackB_look1(oggpack_buffer *b){ 1.337 + if(b->endbyte>=b->storage)return(-1); 1.338 + return((b->ptr[0]>>(7-b->endbit))&1); 1.339 +} 1.340 + 1.341 +void oggpack_adv(oggpack_buffer *b,int bits){ 1.342 + bits+=b->endbit; 1.343 + 1.344 + if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; 1.345 + 1.346 + b->ptr+=bits/8; 1.347 + b->endbyte+=bits/8; 1.348 + b->endbit=bits&7; 1.349 + return; 1.350 + 1.351 + overflow: 1.352 + b->ptr=NULL; 1.353 + b->endbyte=b->storage; 1.354 + b->endbit=1; 1.355 +} 1.356 + 1.357 +void oggpackB_adv(oggpack_buffer *b,int bits){ 1.358 + oggpack_adv(b,bits); 1.359 +} 1.360 + 1.361 +void oggpack_adv1(oggpack_buffer *b){ 1.362 + if(++(b->endbit)>7){ 1.363 + b->endbit=0; 1.364 + b->ptr++; 1.365 + b->endbyte++; 1.366 + } 1.367 +} 1.368 + 1.369 +void oggpackB_adv1(oggpack_buffer *b){ 1.370 + oggpack_adv1(b); 1.371 +} 1.372 + 1.373 +/* bits <= 32 */ 1.374 +long oggpack_read(oggpack_buffer *b,int bits){ 1.375 + long ret; 1.376 + unsigned long m; 1.377 + 1.378 + if(bits<0 || bits>32) goto err; 1.379 + m=mask[bits]; 1.380 + bits+=b->endbit; 1.381 + 1.382 + if(b->endbyte >= b->storage-4){ 1.383 + /* not the main path */ 1.384 + if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; 1.385 + /* special case to avoid reading b->ptr[0], which might be past the end of 1.386 + the buffer; also skips some useless accounting */ 1.387 + else if(!bits)return(0L); 1.388 + } 1.389 + 1.390 + ret=b->ptr[0]>>b->endbit; 1.391 + if(bits>8){ 1.392 + ret|=b->ptr[1]<<(8-b->endbit); 1.393 + if(bits>16){ 1.394 + ret|=b->ptr[2]<<(16-b->endbit); 1.395 + if(bits>24){ 1.396 + ret|=b->ptr[3]<<(24-b->endbit); 1.397 + if(bits>32 && b->endbit){ 1.398 + ret|=b->ptr[4]<<(32-b->endbit); 1.399 + } 1.400 + } 1.401 + } 1.402 + } 1.403 + ret&=m; 1.404 + b->ptr+=bits/8; 1.405 + b->endbyte+=bits/8; 1.406 + b->endbit=bits&7; 1.407 + return ret; 1.408 + 1.409 + overflow: 1.410 + err: 1.411 + b->ptr=NULL; 1.412 + b->endbyte=b->storage; 1.413 + b->endbit=1; 1.414 + return -1L; 1.415 +} 1.416 + 1.417 +/* bits <= 32 */ 1.418 +long oggpackB_read(oggpack_buffer *b,int bits){ 1.419 + long ret; 1.420 + long m=32-bits; 1.421 + 1.422 + if(m<0 || m>32) goto err; 1.423 + bits+=b->endbit; 1.424 + 1.425 + if(b->endbyte+4>=b->storage){ 1.426 + /* not the main path */ 1.427 + if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; 1.428 + /* special case to avoid reading b->ptr[0], which might be past the end of 1.429 + the buffer; also skips some useless accounting */ 1.430 + else if(!bits)return(0L); 1.431 + } 1.432 + 1.433 + ret=b->ptr[0]<<(24+b->endbit); 1.434 + if(bits>8){ 1.435 + ret|=b->ptr[1]<<(16+b->endbit); 1.436 + if(bits>16){ 1.437 + ret|=b->ptr[2]<<(8+b->endbit); 1.438 + if(bits>24){ 1.439 + ret|=b->ptr[3]<<(b->endbit); 1.440 + if(bits>32 && b->endbit) 1.441 + ret|=b->ptr[4]>>(8-b->endbit); 1.442 + } 1.443 + } 1.444 + } 1.445 + ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); 1.446 + 1.447 + b->ptr+=bits/8; 1.448 + b->endbyte+=bits/8; 1.449 + b->endbit=bits&7; 1.450 + return ret; 1.451 + 1.452 + overflow: 1.453 + err: 1.454 + b->ptr=NULL; 1.455 + b->endbyte=b->storage; 1.456 + b->endbit=1; 1.457 + return -1L; 1.458 +} 1.459 + 1.460 +long oggpack_read1(oggpack_buffer *b){ 1.461 + long ret; 1.462 + 1.463 + if(b->endbyte >= b->storage) goto overflow; 1.464 + ret=(b->ptr[0]>>b->endbit)&1; 1.465 + 1.466 + b->endbit++; 1.467 + if(b->endbit>7){ 1.468 + b->endbit=0; 1.469 + b->ptr++; 1.470 + b->endbyte++; 1.471 + } 1.472 + return ret; 1.473 + 1.474 + overflow: 1.475 + b->ptr=NULL; 1.476 + b->endbyte=b->storage; 1.477 + b->endbit=1; 1.478 + return -1L; 1.479 +} 1.480 + 1.481 +long oggpackB_read1(oggpack_buffer *b){ 1.482 + long ret; 1.483 + 1.484 + if(b->endbyte >= b->storage) goto overflow; 1.485 + ret=(b->ptr[0]>>(7-b->endbit))&1; 1.486 + 1.487 + b->endbit++; 1.488 + if(b->endbit>7){ 1.489 + b->endbit=0; 1.490 + b->ptr++; 1.491 + b->endbyte++; 1.492 + } 1.493 + return ret; 1.494 + 1.495 + overflow: 1.496 + b->ptr=NULL; 1.497 + b->endbyte=b->storage; 1.498 + b->endbit=1; 1.499 + return -1L; 1.500 +} 1.501 + 1.502 +long oggpack_bytes(oggpack_buffer *b){ 1.503 + return(b->endbyte+(b->endbit+7)/8); 1.504 +} 1.505 + 1.506 +long oggpack_bits(oggpack_buffer *b){ 1.507 + return(b->endbyte*8+b->endbit); 1.508 +} 1.509 + 1.510 +long oggpackB_bytes(oggpack_buffer *b){ 1.511 + return oggpack_bytes(b); 1.512 +} 1.513 + 1.514 +long oggpackB_bits(oggpack_buffer *b){ 1.515 + return oggpack_bits(b); 1.516 +} 1.517 + 1.518 +unsigned char *oggpack_get_buffer(oggpack_buffer *b){ 1.519 + return(b->buffer); 1.520 +} 1.521 + 1.522 +unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ 1.523 + return oggpack_get_buffer(b); 1.524 +} 1.525 + 1.526 +/* Self test of the bitwise routines; everything else is based on 1.527 + them, so they damned well better be solid. */ 1.528 + 1.529 +#ifdef _V_SELFTEST 1.530 +#include <stdio.h> 1.531 + 1.532 +static int ilog(unsigned int v){ 1.533 + int ret=0; 1.534 + while(v){ 1.535 + ret++; 1.536 + v>>=1; 1.537 + } 1.538 + return(ret); 1.539 +} 1.540 + 1.541 +oggpack_buffer o; 1.542 +oggpack_buffer r; 1.543 + 1.544 +void report(char *in){ 1.545 + fprintf(stderr,"%s",in); 1.546 + exit(1); 1.547 +} 1.548 + 1.549 +void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ 1.550 + long bytes,i; 1.551 + unsigned char *buffer; 1.552 + 1.553 + oggpack_reset(&o); 1.554 + for(i=0;i<vals;i++) 1.555 + oggpack_write(&o,b[i],bits?bits:ilog(b[i])); 1.556 + buffer=oggpack_get_buffer(&o); 1.557 + bytes=oggpack_bytes(&o); 1.558 + if(bytes!=compsize)report("wrong number of bytes!\n"); 1.559 + for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ 1.560 + for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); 1.561 + report("wrote incorrect value!\n"); 1.562 + } 1.563 + oggpack_readinit(&r,buffer,bytes); 1.564 + for(i=0;i<vals;i++){ 1.565 + int tbit=bits?bits:ilog(b[i]); 1.566 + if(oggpack_look(&r,tbit)==-1) 1.567 + report("out of data!\n"); 1.568 + if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit])) 1.569 + report("looked at incorrect value!\n"); 1.570 + if(tbit==1) 1.571 + if(oggpack_look1(&r)!=(b[i]&mask[tbit])) 1.572 + report("looked at single bit incorrect value!\n"); 1.573 + if(tbit==1){ 1.574 + if(oggpack_read1(&r)!=(b[i]&mask[tbit])) 1.575 + report("read incorrect single bit value!\n"); 1.576 + }else{ 1.577 + if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit])) 1.578 + report("read incorrect value!\n"); 1.579 + } 1.580 + } 1.581 + if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); 1.582 +} 1.583 + 1.584 +void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){ 1.585 + long bytes,i; 1.586 + unsigned char *buffer; 1.587 + 1.588 + oggpackB_reset(&o); 1.589 + for(i=0;i<vals;i++) 1.590 + oggpackB_write(&o,b[i],bits?bits:ilog(b[i])); 1.591 + buffer=oggpackB_get_buffer(&o); 1.592 + bytes=oggpackB_bytes(&o); 1.593 + if(bytes!=compsize)report("wrong number of bytes!\n"); 1.594 + for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ 1.595 + for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); 1.596 + report("wrote incorrect value!\n"); 1.597 + } 1.598 + oggpackB_readinit(&r,buffer,bytes); 1.599 + for(i=0;i<vals;i++){ 1.600 + int tbit=bits?bits:ilog(b[i]); 1.601 + if(oggpackB_look(&r,tbit)==-1) 1.602 + report("out of data!\n"); 1.603 + if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit])) 1.604 + report("looked at incorrect value!\n"); 1.605 + if(tbit==1) 1.606 + if(oggpackB_look1(&r)!=(b[i]&mask[tbit])) 1.607 + report("looked at single bit incorrect value!\n"); 1.608 + if(tbit==1){ 1.609 + if(oggpackB_read1(&r)!=(b[i]&mask[tbit])) 1.610 + report("read incorrect single bit value!\n"); 1.611 + }else{ 1.612 + if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit])) 1.613 + report("read incorrect value!\n"); 1.614 + } 1.615 + } 1.616 + if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); 1.617 +} 1.618 + 1.619 +int main(void){ 1.620 + unsigned char *buffer; 1.621 + long bytes,i; 1.622 + static unsigned long testbuffer1[]= 1.623 + {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7, 1.624 + 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4}; 1.625 + int test1size=43; 1.626 + 1.627 + static unsigned long testbuffer2[]= 1.628 + {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212, 1.629 + 1233432,534,5,346435231,14436467,7869299,76326614,167548585, 1.630 + 85525151,0,12321,1,349528352}; 1.631 + int test2size=21; 1.632 + 1.633 + static unsigned long testbuffer3[]= 1.634 + {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, 1.635 + 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1}; 1.636 + int test3size=56; 1.637 + 1.638 + static unsigned long large[]= 1.639 + {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212, 1.640 + 1233432,534,5,2146435231,14436467,7869299,76326614,167548585, 1.641 + 85525151,0,12321,1,2146528352}; 1.642 + 1.643 + int onesize=33; 1.644 + static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40, 1.645 + 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172, 1.646 + 223,4}; 1.647 + static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222, 1.648 + 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18, 1.649 + 245,251,128}; 1.650 + 1.651 + int twosize=6; 1.652 + static int two[6]={61,255,255,251,231,29}; 1.653 + static int twoB[6]={247,63,255,253,249,120}; 1.654 + 1.655 + int threesize=54; 1.656 + static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254, 1.657 + 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83, 1.658 + 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10, 1.659 + 100,52,4,14,18,86,77,1}; 1.660 + static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183, 1.661 + 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98, 1.662 + 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104, 1.663 + 200,20,254,4,58,106,176,144,0}; 1.664 + 1.665 + int foursize=38; 1.666 + static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72, 1.667 + 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169, 1.668 + 28,2,133,0,1}; 1.669 + static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41, 1.670 + 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67, 1.671 + 129,10,4,32}; 1.672 + 1.673 + int fivesize=45; 1.674 + static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62, 1.675 + 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169, 1.676 + 84,75,159,2,1,0,132,192,8,0,0,18,22}; 1.677 + static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226, 1.678 + 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77, 1.679 + 172,150,169,129,79,128,0,6,4,32,0,27,9,0}; 1.680 + 1.681 + int sixsize=7; 1.682 + static int six[7]={17,177,170,242,169,19,148}; 1.683 + static int sixB[7]={136,141,85,79,149,200,41}; 1.684 + 1.685 + /* Test read/write together */ 1.686 + /* Later we test against pregenerated bitstreams */ 1.687 + oggpack_writeinit(&o); 1.688 + 1.689 + fprintf(stderr,"\nSmall preclipped packing (LSb): "); 1.690 + cliptest(testbuffer1,test1size,0,one,onesize); 1.691 + fprintf(stderr,"ok."); 1.692 + 1.693 + fprintf(stderr,"\nNull bit call (LSb): "); 1.694 + cliptest(testbuffer3,test3size,0,two,twosize); 1.695 + fprintf(stderr,"ok."); 1.696 + 1.697 + fprintf(stderr,"\nLarge preclipped packing (LSb): "); 1.698 + cliptest(testbuffer2,test2size,0,three,threesize); 1.699 + fprintf(stderr,"ok."); 1.700 + 1.701 + fprintf(stderr,"\n32 bit preclipped packing (LSb): "); 1.702 + oggpack_reset(&o); 1.703 + for(i=0;i<test2size;i++) 1.704 + oggpack_write(&o,large[i],32); 1.705 + buffer=oggpack_get_buffer(&o); 1.706 + bytes=oggpack_bytes(&o); 1.707 + oggpack_readinit(&r,buffer,bytes); 1.708 + for(i=0;i<test2size;i++){ 1.709 + if(oggpack_look(&r,32)==-1)report("out of data. failed!"); 1.710 + if(oggpack_look(&r,32)!=large[i]){ 1.711 + fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i], 1.712 + oggpack_look(&r,32),large[i]); 1.713 + report("read incorrect value!\n"); 1.714 + } 1.715 + oggpack_adv(&r,32); 1.716 + } 1.717 + if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); 1.718 + fprintf(stderr,"ok."); 1.719 + 1.720 + fprintf(stderr,"\nSmall unclipped packing (LSb): "); 1.721 + cliptest(testbuffer1,test1size,7,four,foursize); 1.722 + fprintf(stderr,"ok."); 1.723 + 1.724 + fprintf(stderr,"\nLarge unclipped packing (LSb): "); 1.725 + cliptest(testbuffer2,test2size,17,five,fivesize); 1.726 + fprintf(stderr,"ok."); 1.727 + 1.728 + fprintf(stderr,"\nSingle bit unclipped packing (LSb): "); 1.729 + cliptest(testbuffer3,test3size,1,six,sixsize); 1.730 + fprintf(stderr,"ok."); 1.731 + 1.732 + fprintf(stderr,"\nTesting read past end (LSb): "); 1.733 + oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); 1.734 + for(i=0;i<64;i++){ 1.735 + if(oggpack_read(&r,1)!=0){ 1.736 + fprintf(stderr,"failed; got -1 prematurely.\n"); 1.737 + exit(1); 1.738 + } 1.739 + } 1.740 + if(oggpack_look(&r,1)!=-1 || 1.741 + oggpack_read(&r,1)!=-1){ 1.742 + fprintf(stderr,"failed; read past end without -1.\n"); 1.743 + exit(1); 1.744 + } 1.745 + oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); 1.746 + if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){ 1.747 + fprintf(stderr,"failed 2; got -1 prematurely.\n"); 1.748 + exit(1); 1.749 + } 1.750 + 1.751 + if(oggpack_look(&r,18)!=0 || 1.752 + oggpack_look(&r,18)!=0){ 1.753 + fprintf(stderr,"failed 3; got -1 prematurely.\n"); 1.754 + exit(1); 1.755 + } 1.756 + if(oggpack_look(&r,19)!=-1 || 1.757 + oggpack_look(&r,19)!=-1){ 1.758 + fprintf(stderr,"failed; read past end without -1.\n"); 1.759 + exit(1); 1.760 + } 1.761 + if(oggpack_look(&r,32)!=-1 || 1.762 + oggpack_look(&r,32)!=-1){ 1.763 + fprintf(stderr,"failed; read past end without -1.\n"); 1.764 + exit(1); 1.765 + } 1.766 + oggpack_writeclear(&o); 1.767 + fprintf(stderr,"ok.\n"); 1.768 + 1.769 + /********** lazy, cut-n-paste retest with MSb packing ***********/ 1.770 + 1.771 + /* Test read/write together */ 1.772 + /* Later we test against pregenerated bitstreams */ 1.773 + oggpackB_writeinit(&o); 1.774 + 1.775 + fprintf(stderr,"\nSmall preclipped packing (MSb): "); 1.776 + cliptestB(testbuffer1,test1size,0,oneB,onesize); 1.777 + fprintf(stderr,"ok."); 1.778 + 1.779 + fprintf(stderr,"\nNull bit call (MSb): "); 1.780 + cliptestB(testbuffer3,test3size,0,twoB,twosize); 1.781 + fprintf(stderr,"ok."); 1.782 + 1.783 + fprintf(stderr,"\nLarge preclipped packing (MSb): "); 1.784 + cliptestB(testbuffer2,test2size,0,threeB,threesize); 1.785 + fprintf(stderr,"ok."); 1.786 + 1.787 + fprintf(stderr,"\n32 bit preclipped packing (MSb): "); 1.788 + oggpackB_reset(&o); 1.789 + for(i=0;i<test2size;i++) 1.790 + oggpackB_write(&o,large[i],32); 1.791 + buffer=oggpackB_get_buffer(&o); 1.792 + bytes=oggpackB_bytes(&o); 1.793 + oggpackB_readinit(&r,buffer,bytes); 1.794 + for(i=0;i<test2size;i++){ 1.795 + if(oggpackB_look(&r,32)==-1)report("out of data. failed!"); 1.796 + if(oggpackB_look(&r,32)!=large[i]){ 1.797 + fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i], 1.798 + oggpackB_look(&r,32),large[i]); 1.799 + report("read incorrect value!\n"); 1.800 + } 1.801 + oggpackB_adv(&r,32); 1.802 + } 1.803 + if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); 1.804 + fprintf(stderr,"ok."); 1.805 + 1.806 + fprintf(stderr,"\nSmall unclipped packing (MSb): "); 1.807 + cliptestB(testbuffer1,test1size,7,fourB,foursize); 1.808 + fprintf(stderr,"ok."); 1.809 + 1.810 + fprintf(stderr,"\nLarge unclipped packing (MSb): "); 1.811 + cliptestB(testbuffer2,test2size,17,fiveB,fivesize); 1.812 + fprintf(stderr,"ok."); 1.813 + 1.814 + fprintf(stderr,"\nSingle bit unclipped packing (MSb): "); 1.815 + cliptestB(testbuffer3,test3size,1,sixB,sixsize); 1.816 + fprintf(stderr,"ok."); 1.817 + 1.818 + fprintf(stderr,"\nTesting read past end (MSb): "); 1.819 + oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); 1.820 + for(i=0;i<64;i++){ 1.821 + if(oggpackB_read(&r,1)!=0){ 1.822 + fprintf(stderr,"failed; got -1 prematurely.\n"); 1.823 + exit(1); 1.824 + } 1.825 + } 1.826 + if(oggpackB_look(&r,1)!=-1 || 1.827 + oggpackB_read(&r,1)!=-1){ 1.828 + fprintf(stderr,"failed; read past end without -1.\n"); 1.829 + exit(1); 1.830 + } 1.831 + oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); 1.832 + if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){ 1.833 + fprintf(stderr,"failed 2; got -1 prematurely.\n"); 1.834 + exit(1); 1.835 + } 1.836 + 1.837 + if(oggpackB_look(&r,18)!=0 || 1.838 + oggpackB_look(&r,18)!=0){ 1.839 + fprintf(stderr,"failed 3; got -1 prematurely.\n"); 1.840 + exit(1); 1.841 + } 1.842 + if(oggpackB_look(&r,19)!=-1 || 1.843 + oggpackB_look(&r,19)!=-1){ 1.844 + fprintf(stderr,"failed; read past end without -1.\n"); 1.845 + exit(1); 1.846 + } 1.847 + if(oggpackB_look(&r,32)!=-1 || 1.848 + oggpackB_look(&r,32)!=-1){ 1.849 + fprintf(stderr,"failed; read past end without -1.\n"); 1.850 + exit(1); 1.851 + } 1.852 + oggpackB_writeclear(&o); 1.853 + fprintf(stderr,"ok.\n\n"); 1.854 + 1.855 + 1.856 + return(0); 1.857 +} 1.858 +#endif /* _V_SELFTEST */ 1.859 + 1.860 +#undef BUFFER_INCREMENT