ogg_bitwise.c (30633B)
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 #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 void oggpack_writeinit(oggpack_buffer *b){ 40 memset(b,0,sizeof(*b)); 41 b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); 42 if (!b->buffer) 43 return; 44 b->buffer[0]='\0'; 45 b->storage=BUFFER_INCREMENT; 46 } 47 48 void oggpackB_writeinit(oggpack_buffer *b){ 49 oggpack_writeinit(b); 50 } 51 52 int oggpack_writecheck(oggpack_buffer *b){ 53 if(!b->ptr || !b->storage)return -1; 54 return 0; 55 } 56 57 int oggpackB_writecheck(oggpack_buffer *b){ 58 return oggpack_writecheck(b); 59 } 60 61 void oggpack_writetrunc(oggpack_buffer *b,long bits){ 62 long bytes=bits>>3; 63 if(b->ptr){ 64 bits-=bytes*8; 65 b->ptr=b->buffer+bytes; 66 b->endbit=bits; 67 b->endbyte=bytes; 68 *b->ptr&=mask[bits]; 69 } 70 } 71 72 void oggpackB_writetrunc(oggpack_buffer *b,long bits){ 73 long bytes=bits>>3; 74 if(b->ptr){ 75 bits-=bytes*8; 76 b->ptr=b->buffer+bytes; 77 b->endbit=bits; 78 b->endbyte=bytes; 79 *b->ptr&=mask8B[bits]; 80 } 81 } 82 83 /* Takes only up to 32 bits. */ 84 void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ 85 if(bits<0 || bits>32) goto err; 86 if(b->endbyte>=b->storage-4){ 87 void *ret; 88 if(!b->ptr)return; 89 if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; 90 ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); 91 if(!ret) goto err; 92 b->buffer=ret; 93 b->storage+=BUFFER_INCREMENT; 94 b->ptr=b->buffer+b->endbyte; 95 } 96 97 value&=mask[bits]; 98 bits+=b->endbit; 99 100 b->ptr[0]|=value<<b->endbit; 101 102 if(bits>=8){ 103 b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); 104 if(bits>=16){ 105 b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); 106 if(bits>=24){ 107 b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); 108 if(bits>=32){ 109 if(b->endbit) 110 b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); 111 else 112 b->ptr[4]=0; 113 } 114 } 115 } 116 } 117 118 b->endbyte+=bits/8; 119 b->ptr+=bits/8; 120 b->endbit=bits&7; 121 return; 122 err: 123 oggpack_writeclear(b); 124 } 125 126 /* Takes only up to 32 bits. */ 127 void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ 128 if(bits<0 || bits>32) goto err; 129 if(b->endbyte>=b->storage-4){ 130 void *ret; 131 if(!b->ptr)return; 132 if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err; 133 ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); 134 if(!ret) goto err; 135 b->buffer=ret; 136 b->storage+=BUFFER_INCREMENT; 137 b->ptr=b->buffer+b->endbyte; 138 } 139 140 value=(value&mask[bits])<<(32-bits); 141 bits+=b->endbit; 142 143 b->ptr[0]|=value>>(24+b->endbit); 144 145 if(bits>=8){ 146 b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); 147 if(bits>=16){ 148 b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); 149 if(bits>=24){ 150 b->ptr[3]=(unsigned char)(value>>(b->endbit)); 151 if(bits>=32){ 152 if(b->endbit) 153 b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); 154 else 155 b->ptr[4]=0; 156 } 157 } 158 } 159 } 160 161 b->endbyte+=bits/8; 162 b->ptr+=bits/8; 163 b->endbit=bits&7; 164 return; 165 err: 166 oggpack_writeclear(b); 167 } 168 169 void oggpack_writealign(oggpack_buffer *b){ 170 int bits=8-b->endbit; 171 if(bits<8) 172 oggpack_write(b,0,bits); 173 } 174 175 void oggpackB_writealign(oggpack_buffer *b){ 176 int bits=8-b->endbit; 177 if(bits<8) 178 oggpackB_write(b,0,bits); 179 } 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 int msb){ 188 unsigned char *ptr=(unsigned char *)source; 189 190 long bytes=bits/8; 191 long pbytes=(b->endbit+bits)/8; 192 bits-=bytes*8; 193 194 /* expand storage up-front */ 195 if(b->endbyte+pbytes>=b->storage){ 196 void *ret; 197 if(!b->ptr) goto err; 198 if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err; 199 b->storage=b->endbyte+pbytes+BUFFER_INCREMENT; 200 ret=_ogg_realloc(b->buffer,b->storage); 201 if(!ret) goto err; 202 b->buffer=ret; 203 b->ptr=b->buffer+b->endbyte; 204 } 205 206 /* copy whole octets */ 207 if(b->endbit){ 208 int i; 209 /* unaligned copy. Do it the hard way. */ 210 for(i=0;i<bytes;i++) 211 w(b,(unsigned long)(ptr[i]),8); 212 }else{ 213 /* aligned block copy */ 214 memmove(b->ptr,source,bytes); 215 b->ptr+=bytes; 216 b->endbyte+=bytes; 217 *b->ptr=0; 218 } 219 220 /* copy trailing bits */ 221 if(bits){ 222 if(msb) 223 w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); 224 else 225 w(b,(unsigned long)(ptr[bytes]),bits); 226 } 227 return; 228 err: 229 oggpack_writeclear(b); 230 } 231 232 void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ 233 oggpack_writecopy_helper(b,source,bits,oggpack_write,0); 234 } 235 236 void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ 237 oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); 238 } 239 240 void oggpack_reset(oggpack_buffer *b){ 241 if(!b->ptr)return; 242 b->ptr=b->buffer; 243 b->buffer[0]=0; 244 b->endbit=b->endbyte=0; 245 } 246 247 void oggpackB_reset(oggpack_buffer *b){ 248 oggpack_reset(b); 249 } 250 251 void oggpack_writeclear(oggpack_buffer *b){ 252 if(b->buffer)_ogg_free(b->buffer); 253 memset(b,0,sizeof(*b)); 254 } 255 256 void oggpackB_writeclear(oggpack_buffer *b){ 257 oggpack_writeclear(b); 258 } 259 260 void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ 261 memset(b,0,sizeof(*b)); 262 b->buffer=b->ptr=buf; 263 b->storage=bytes; 264 } 265 266 void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ 267 oggpack_readinit(b,buf,bytes); 268 } 269 270 /* Read in bits without advancing the bitptr; bits <= 32 */ 271 long oggpack_look(oggpack_buffer *b,int bits){ 272 unsigned long ret; 273 unsigned long m; 274 275 if(bits<0 || bits>32) return -1; 276 m=mask[bits]; 277 bits+=b->endbit; 278 279 if(b->endbyte >= b->storage-4){ 280 /* not the main path */ 281 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 else if(!bits)return(0L); 285 } 286 287 ret=b->ptr[0]>>b->endbit; 288 if(bits>8){ 289 ret|=(unsigned long)b->ptr[1]<<(8-b->endbit); 290 if(bits>16){ 291 ret|=(unsigned long)b->ptr[2]<<(16-b->endbit); 292 if(bits>24){ 293 ret|=(unsigned long)b->ptr[3]<<(24-b->endbit); 294 if(bits>32 && b->endbit) 295 ret|=(unsigned long)b->ptr[4]<<(32-b->endbit); 296 } 297 } 298 } 299 return(m&ret); 300 } 301 302 /* Read in bits without advancing the bitptr; bits <= 32 */ 303 long oggpackB_look(oggpack_buffer *b,int bits){ 304 unsigned long ret; 305 int m=32-bits; 306 307 if(m<0 || m>32) return -1; 308 bits+=b->endbit; 309 310 if(b->endbyte >= b->storage-4){ 311 /* not the main path */ 312 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 else if(!bits)return(0L); 316 } 317 318 ret=(unsigned long)b->ptr[0]<<(24+b->endbit); 319 if(bits>8){ 320 ret|=(unsigned long)b->ptr[1]<<(16+b->endbit); 321 if(bits>16){ 322 ret|=(unsigned long)b->ptr[2]<<(8+b->endbit); 323 if(bits>24){ 324 ret|=(unsigned long)b->ptr[3]<<(b->endbit); 325 if(bits>32 && b->endbit) 326 ret|=b->ptr[4]>>(8-b->endbit); 327 } 328 } 329 } 330 return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); 331 } 332 333 long oggpack_look1(oggpack_buffer *b){ 334 if(b->endbyte>=b->storage)return(-1); 335 return((b->ptr[0]>>b->endbit)&1); 336 } 337 338 long oggpackB_look1(oggpack_buffer *b){ 339 if(b->endbyte>=b->storage)return(-1); 340 return((b->ptr[0]>>(7-b->endbit))&1); 341 } 342 343 void oggpack_adv(oggpack_buffer *b,int bits){ 344 bits+=b->endbit; 345 346 if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; 347 348 b->ptr+=bits/8; 349 b->endbyte+=bits/8; 350 b->endbit=bits&7; 351 return; 352 353 overflow: 354 b->ptr=NULL; 355 b->endbyte=b->storage; 356 b->endbit=1; 357 } 358 359 void oggpackB_adv(oggpack_buffer *b,int bits){ 360 oggpack_adv(b,bits); 361 } 362 363 void oggpack_adv1(oggpack_buffer *b){ 364 if(++(b->endbit)>7){ 365 b->endbit=0; 366 b->ptr++; 367 b->endbyte++; 368 } 369 } 370 371 void oggpackB_adv1(oggpack_buffer *b){ 372 oggpack_adv1(b); 373 } 374 375 /* bits <= 32 */ 376 long oggpack_read(oggpack_buffer *b,int bits){ 377 long ret; 378 unsigned long m; 379 380 if(bits<0 || bits>32) goto err; 381 m=mask[bits]; 382 bits+=b->endbit; 383 384 if(b->endbyte >= b->storage-4){ 385 /* not the main path */ 386 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 else if(!bits)return(0L); 390 } 391 392 ret=b->ptr[0]>>b->endbit; 393 if(bits>8){ 394 ret|=(unsigned long)b->ptr[1]<<(8-b->endbit); 395 if(bits>16){ 396 ret|=(unsigned long)b->ptr[2]<<(16-b->endbit); 397 if(bits>24){ 398 ret|=(unsigned long)b->ptr[3]<<(24-b->endbit); 399 if(bits>32 && b->endbit){ 400 ret|=(unsigned long)b->ptr[4]<<(32-b->endbit); 401 } 402 } 403 } 404 } 405 ret&=m; 406 b->ptr+=bits/8; 407 b->endbyte+=bits/8; 408 b->endbit=bits&7; 409 return ret; 410 411 overflow: 412 err: 413 b->ptr=NULL; 414 b->endbyte=b->storage; 415 b->endbit=1; 416 return -1L; 417 } 418 419 /* bits <= 32 */ 420 long oggpackB_read(oggpack_buffer *b,int bits){ 421 long ret; 422 long m=32-bits; 423 424 if(m<0 || m>32) goto err; 425 bits+=b->endbit; 426 427 if(b->endbyte+4>=b->storage){ 428 /* not the main path */ 429 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 else if(!bits)return(0L); 433 } 434 435 ret=(unsigned long)b->ptr[0]<<(24+b->endbit); 436 if(bits>8){ 437 ret|=(unsigned long)b->ptr[1]<<(16+b->endbit); 438 if(bits>16){ 439 ret|=(unsigned long)b->ptr[2]<<(8+b->endbit); 440 if(bits>24){ 441 ret|=(unsigned long)b->ptr[3]<<(b->endbit); 442 if(bits>32 && b->endbit) 443 ret|=b->ptr[4]>>(8-b->endbit); 444 } 445 } 446 } 447 ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); 448 449 b->ptr+=bits/8; 450 b->endbyte+=bits/8; 451 b->endbit=bits&7; 452 return ret; 453 454 overflow: 455 err: 456 b->ptr=NULL; 457 b->endbyte=b->storage; 458 b->endbit=1; 459 return -1L; 460 } 461 462 long oggpack_read1(oggpack_buffer *b){ 463 long ret; 464 465 if(b->endbyte >= b->storage) goto overflow; 466 ret=(b->ptr[0]>>b->endbit)&1; 467 468 b->endbit++; 469 if(b->endbit>7){ 470 b->endbit=0; 471 b->ptr++; 472 b->endbyte++; 473 } 474 return ret; 475 476 overflow: 477 b->ptr=NULL; 478 b->endbyte=b->storage; 479 b->endbit=1; 480 return -1L; 481 } 482 483 long oggpackB_read1(oggpack_buffer *b){ 484 long ret; 485 486 if(b->endbyte >= b->storage) goto overflow; 487 ret=(b->ptr[0]>>(7-b->endbit))&1; 488 489 b->endbit++; 490 if(b->endbit>7){ 491 b->endbit=0; 492 b->ptr++; 493 b->endbyte++; 494 } 495 return ret; 496 497 overflow: 498 b->ptr=NULL; 499 b->endbyte=b->storage; 500 b->endbit=1; 501 return -1L; 502 } 503 504 long oggpack_bytes(oggpack_buffer *b){ 505 return(b->endbyte+(b->endbit+7)/8); 506 } 507 508 long oggpack_bits(oggpack_buffer *b){ 509 return(b->endbyte*8+b->endbit); 510 } 511 512 long oggpackB_bytes(oggpack_buffer *b){ 513 return oggpack_bytes(b); 514 } 515 516 long oggpackB_bits(oggpack_buffer *b){ 517 return oggpack_bits(b); 518 } 519 520 unsigned char *oggpack_get_buffer(oggpack_buffer *b){ 521 return(b->buffer); 522 } 523 524 unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ 525 return oggpack_get_buffer(b); 526 } 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