dbf-halloween2015

annotate libs/ogg/bitwise.c @ 1:c3f5c32cb210

barfed all the libraries in the source tree to make porting easier
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 01 Nov 2015 00:36:56 +0200
parents
children
rev   line source
nuclear@1 1 /********************************************************************
nuclear@1 2 * *
nuclear@1 3 * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. *
nuclear@1 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
nuclear@1 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
nuclear@1 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
nuclear@1 7 * *
nuclear@1 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
nuclear@1 9 * by the Xiph.Org Foundation http://www.xiph.org/ *
nuclear@1 10 * *
nuclear@1 11 ********************************************************************
nuclear@1 12
nuclear@1 13 function: packing variable sized words into an octet stream
nuclear@1 14 last mod: $Id: bitwise.c 18051 2011-08-04 17:56:39Z giles $
nuclear@1 15
nuclear@1 16 ********************************************************************/
nuclear@1 17
nuclear@1 18 /* We're 'LSb' endian; if we write a word but read individual bits,
nuclear@1 19 then we'll read the lsb first */
nuclear@1 20
nuclear@1 21 #include <string.h>
nuclear@1 22 #include <stdlib.h>
nuclear@1 23 #include <limits.h>
nuclear@1 24 #include <ogg/ogg.h>
nuclear@1 25
nuclear@1 26 #define BUFFER_INCREMENT 256
nuclear@1 27
nuclear@1 28 static const unsigned long mask[]=
nuclear@1 29 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
nuclear@1 30 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
nuclear@1 31 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
nuclear@1 32 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
nuclear@1 33 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
nuclear@1 34 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
nuclear@1 35 0x3fffffff,0x7fffffff,0xffffffff };
nuclear@1 36
nuclear@1 37 static const unsigned int mask8B[]=
nuclear@1 38 {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
nuclear@1 39
nuclear@1 40 void oggpack_writeinit(oggpack_buffer *b){
nuclear@1 41 memset(b,0,sizeof(*b));
nuclear@1 42 b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT);
nuclear@1 43 b->buffer[0]='\0';
nuclear@1 44 b->storage=BUFFER_INCREMENT;
nuclear@1 45 }
nuclear@1 46
nuclear@1 47 void oggpackB_writeinit(oggpack_buffer *b){
nuclear@1 48 oggpack_writeinit(b);
nuclear@1 49 }
nuclear@1 50
nuclear@1 51 int oggpack_writecheck(oggpack_buffer *b){
nuclear@1 52 if(!b->ptr || !b->storage)return -1;
nuclear@1 53 return 0;
nuclear@1 54 }
nuclear@1 55
nuclear@1 56 int oggpackB_writecheck(oggpack_buffer *b){
nuclear@1 57 return oggpack_writecheck(b);
nuclear@1 58 }
nuclear@1 59
nuclear@1 60 void oggpack_writetrunc(oggpack_buffer *b,long bits){
nuclear@1 61 long bytes=bits>>3;
nuclear@1 62 if(b->ptr){
nuclear@1 63 bits-=bytes*8;
nuclear@1 64 b->ptr=b->buffer+bytes;
nuclear@1 65 b->endbit=bits;
nuclear@1 66 b->endbyte=bytes;
nuclear@1 67 *b->ptr&=mask[bits];
nuclear@1 68 }
nuclear@1 69 }
nuclear@1 70
nuclear@1 71 void oggpackB_writetrunc(oggpack_buffer *b,long bits){
nuclear@1 72 long bytes=bits>>3;
nuclear@1 73 if(b->ptr){
nuclear@1 74 bits-=bytes*8;
nuclear@1 75 b->ptr=b->buffer+bytes;
nuclear@1 76 b->endbit=bits;
nuclear@1 77 b->endbyte=bytes;
nuclear@1 78 *b->ptr&=mask8B[bits];
nuclear@1 79 }
nuclear@1 80 }
nuclear@1 81
nuclear@1 82 /* Takes only up to 32 bits. */
nuclear@1 83 void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
nuclear@1 84 if(bits<0 || bits>32) goto err;
nuclear@1 85 if(b->endbyte>=b->storage-4){
nuclear@1 86 void *ret;
nuclear@1 87 if(!b->ptr)return;
nuclear@1 88 if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
nuclear@1 89 ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
nuclear@1 90 if(!ret) goto err;
nuclear@1 91 b->buffer=ret;
nuclear@1 92 b->storage+=BUFFER_INCREMENT;
nuclear@1 93 b->ptr=b->buffer+b->endbyte;
nuclear@1 94 }
nuclear@1 95
nuclear@1 96 value&=mask[bits];
nuclear@1 97 bits+=b->endbit;
nuclear@1 98
nuclear@1 99 b->ptr[0]|=value<<b->endbit;
nuclear@1 100
nuclear@1 101 if(bits>=8){
nuclear@1 102 b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
nuclear@1 103 if(bits>=16){
nuclear@1 104 b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
nuclear@1 105 if(bits>=24){
nuclear@1 106 b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
nuclear@1 107 if(bits>=32){
nuclear@1 108 if(b->endbit)
nuclear@1 109 b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
nuclear@1 110 else
nuclear@1 111 b->ptr[4]=0;
nuclear@1 112 }
nuclear@1 113 }
nuclear@1 114 }
nuclear@1 115 }
nuclear@1 116
nuclear@1 117 b->endbyte+=bits/8;
nuclear@1 118 b->ptr+=bits/8;
nuclear@1 119 b->endbit=bits&7;
nuclear@1 120 return;
nuclear@1 121 err:
nuclear@1 122 oggpack_writeclear(b);
nuclear@1 123 }
nuclear@1 124
nuclear@1 125 /* Takes only up to 32 bits. */
nuclear@1 126 void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
nuclear@1 127 if(bits<0 || bits>32) goto err;
nuclear@1 128 if(b->endbyte>=b->storage-4){
nuclear@1 129 void *ret;
nuclear@1 130 if(!b->ptr)return;
nuclear@1 131 if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
nuclear@1 132 ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
nuclear@1 133 if(!ret) goto err;
nuclear@1 134 b->buffer=ret;
nuclear@1 135 b->storage+=BUFFER_INCREMENT;
nuclear@1 136 b->ptr=b->buffer+b->endbyte;
nuclear@1 137 }
nuclear@1 138
nuclear@1 139 value=(value&mask[bits])<<(32-bits);
nuclear@1 140 bits+=b->endbit;
nuclear@1 141
nuclear@1 142 b->ptr[0]|=value>>(24+b->endbit);
nuclear@1 143
nuclear@1 144 if(bits>=8){
nuclear@1 145 b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
nuclear@1 146 if(bits>=16){
nuclear@1 147 b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
nuclear@1 148 if(bits>=24){
nuclear@1 149 b->ptr[3]=(unsigned char)(value>>(b->endbit));
nuclear@1 150 if(bits>=32){
nuclear@1 151 if(b->endbit)
nuclear@1 152 b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
nuclear@1 153 else
nuclear@1 154 b->ptr[4]=0;
nuclear@1 155 }
nuclear@1 156 }
nuclear@1 157 }
nuclear@1 158 }
nuclear@1 159
nuclear@1 160 b->endbyte+=bits/8;
nuclear@1 161 b->ptr+=bits/8;
nuclear@1 162 b->endbit=bits&7;
nuclear@1 163 return;
nuclear@1 164 err:
nuclear@1 165 oggpack_writeclear(b);
nuclear@1 166 }
nuclear@1 167
nuclear@1 168 void oggpack_writealign(oggpack_buffer *b){
nuclear@1 169 int bits=8-b->endbit;
nuclear@1 170 if(bits<8)
nuclear@1 171 oggpack_write(b,0,bits);
nuclear@1 172 }
nuclear@1 173
nuclear@1 174 void oggpackB_writealign(oggpack_buffer *b){
nuclear@1 175 int bits=8-b->endbit;
nuclear@1 176 if(bits<8)
nuclear@1 177 oggpackB_write(b,0,bits);
nuclear@1 178 }
nuclear@1 179
nuclear@1 180 static void oggpack_writecopy_helper(oggpack_buffer *b,
nuclear@1 181 void *source,
nuclear@1 182 long bits,
nuclear@1 183 void (*w)(oggpack_buffer *,
nuclear@1 184 unsigned long,
nuclear@1 185 int),
nuclear@1 186 int msb){
nuclear@1 187 unsigned char *ptr=(unsigned char *)source;
nuclear@1 188
nuclear@1 189 long bytes=bits/8;
nuclear@1 190 bits-=bytes*8;
nuclear@1 191
nuclear@1 192 if(b->endbit){
nuclear@1 193 int i;
nuclear@1 194 /* unaligned copy. Do it the hard way. */
nuclear@1 195 for(i=0;i<bytes;i++)
nuclear@1 196 w(b,(unsigned long)(ptr[i]),8);
nuclear@1 197 }else{
nuclear@1 198 /* aligned block copy */
nuclear@1 199 if(b->endbyte+bytes+1>=b->storage){
nuclear@1 200 void *ret;
nuclear@1 201 if(!b->ptr) goto err;
nuclear@1 202 if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err;
nuclear@1 203 b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
nuclear@1 204 ret=_ogg_realloc(b->buffer,b->storage);
nuclear@1 205 if(!ret) goto err;
nuclear@1 206 b->buffer=ret;
nuclear@1 207 b->ptr=b->buffer+b->endbyte;
nuclear@1 208 }
nuclear@1 209
nuclear@1 210 memmove(b->ptr,source,bytes);
nuclear@1 211 b->ptr+=bytes;
nuclear@1 212 b->endbyte+=bytes;
nuclear@1 213 *b->ptr=0;
nuclear@1 214
nuclear@1 215 }
nuclear@1 216 if(bits){
nuclear@1 217 if(msb)
nuclear@1 218 w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
nuclear@1 219 else
nuclear@1 220 w(b,(unsigned long)(ptr[bytes]),bits);
nuclear@1 221 }
nuclear@1 222 return;
nuclear@1 223 err:
nuclear@1 224 oggpack_writeclear(b);
nuclear@1 225 }
nuclear@1 226
nuclear@1 227 void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
nuclear@1 228 oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
nuclear@1 229 }
nuclear@1 230
nuclear@1 231 void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
nuclear@1 232 oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
nuclear@1 233 }
nuclear@1 234
nuclear@1 235 void oggpack_reset(oggpack_buffer *b){
nuclear@1 236 if(!b->ptr)return;
nuclear@1 237 b->ptr=b->buffer;
nuclear@1 238 b->buffer[0]=0;
nuclear@1 239 b->endbit=b->endbyte=0;
nuclear@1 240 }
nuclear@1 241
nuclear@1 242 void oggpackB_reset(oggpack_buffer *b){
nuclear@1 243 oggpack_reset(b);
nuclear@1 244 }
nuclear@1 245
nuclear@1 246 void oggpack_writeclear(oggpack_buffer *b){
nuclear@1 247 if(b->buffer)_ogg_free(b->buffer);
nuclear@1 248 memset(b,0,sizeof(*b));
nuclear@1 249 }
nuclear@1 250
nuclear@1 251 void oggpackB_writeclear(oggpack_buffer *b){
nuclear@1 252 oggpack_writeclear(b);
nuclear@1 253 }
nuclear@1 254
nuclear@1 255 void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
nuclear@1 256 memset(b,0,sizeof(*b));
nuclear@1 257 b->buffer=b->ptr=buf;
nuclear@1 258 b->storage=bytes;
nuclear@1 259 }
nuclear@1 260
nuclear@1 261 void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
nuclear@1 262 oggpack_readinit(b,buf,bytes);
nuclear@1 263 }
nuclear@1 264
nuclear@1 265 /* Read in bits without advancing the bitptr; bits <= 32 */
nuclear@1 266 long oggpack_look(oggpack_buffer *b,int bits){
nuclear@1 267 unsigned long ret;
nuclear@1 268 unsigned long m;
nuclear@1 269
nuclear@1 270 if(bits<0 || bits>32) return -1;
nuclear@1 271 m=mask[bits];
nuclear@1 272 bits+=b->endbit;
nuclear@1 273
nuclear@1 274 if(b->endbyte >= b->storage-4){
nuclear@1 275 /* not the main path */
nuclear@1 276 if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
nuclear@1 277 /* special case to avoid reading b->ptr[0], which might be past the end of
nuclear@1 278 the buffer; also skips some useless accounting */
nuclear@1 279 else if(!bits)return(0L);
nuclear@1 280 }
nuclear@1 281
nuclear@1 282 ret=b->ptr[0]>>b->endbit;
nuclear@1 283 if(bits>8){
nuclear@1 284 ret|=b->ptr[1]<<(8-b->endbit);
nuclear@1 285 if(bits>16){
nuclear@1 286 ret|=b->ptr[2]<<(16-b->endbit);
nuclear@1 287 if(bits>24){
nuclear@1 288 ret|=b->ptr[3]<<(24-b->endbit);
nuclear@1 289 if(bits>32 && b->endbit)
nuclear@1 290 ret|=b->ptr[4]<<(32-b->endbit);
nuclear@1 291 }
nuclear@1 292 }
nuclear@1 293 }
nuclear@1 294 return(m&ret);
nuclear@1 295 }
nuclear@1 296
nuclear@1 297 /* Read in bits without advancing the bitptr; bits <= 32 */
nuclear@1 298 long oggpackB_look(oggpack_buffer *b,int bits){
nuclear@1 299 unsigned long ret;
nuclear@1 300 int m=32-bits;
nuclear@1 301
nuclear@1 302 if(m<0 || m>32) return -1;
nuclear@1 303 bits+=b->endbit;
nuclear@1 304
nuclear@1 305 if(b->endbyte >= b->storage-4){
nuclear@1 306 /* not the main path */
nuclear@1 307 if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
nuclear@1 308 /* special case to avoid reading b->ptr[0], which might be past the end of
nuclear@1 309 the buffer; also skips some useless accounting */
nuclear@1 310 else if(!bits)return(0L);
nuclear@1 311 }
nuclear@1 312
nuclear@1 313 ret=b->ptr[0]<<(24+b->endbit);
nuclear@1 314 if(bits>8){
nuclear@1 315 ret|=b->ptr[1]<<(16+b->endbit);
nuclear@1 316 if(bits>16){
nuclear@1 317 ret|=b->ptr[2]<<(8+b->endbit);
nuclear@1 318 if(bits>24){
nuclear@1 319 ret|=b->ptr[3]<<(b->endbit);
nuclear@1 320 if(bits>32 && b->endbit)
nuclear@1 321 ret|=b->ptr[4]>>(8-b->endbit);
nuclear@1 322 }
nuclear@1 323 }
nuclear@1 324 }
nuclear@1 325 return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
nuclear@1 326 }
nuclear@1 327
nuclear@1 328 long oggpack_look1(oggpack_buffer *b){
nuclear@1 329 if(b->endbyte>=b->storage)return(-1);
nuclear@1 330 return((b->ptr[0]>>b->endbit)&1);
nuclear@1 331 }
nuclear@1 332
nuclear@1 333 long oggpackB_look1(oggpack_buffer *b){
nuclear@1 334 if(b->endbyte>=b->storage)return(-1);
nuclear@1 335 return((b->ptr[0]>>(7-b->endbit))&1);
nuclear@1 336 }
nuclear@1 337
nuclear@1 338 void oggpack_adv(oggpack_buffer *b,int bits){
nuclear@1 339 bits+=b->endbit;
nuclear@1 340
nuclear@1 341 if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
nuclear@1 342
nuclear@1 343 b->ptr+=bits/8;
nuclear@1 344 b->endbyte+=bits/8;
nuclear@1 345 b->endbit=bits&7;
nuclear@1 346 return;
nuclear@1 347
nuclear@1 348 overflow:
nuclear@1 349 b->ptr=NULL;
nuclear@1 350 b->endbyte=b->storage;
nuclear@1 351 b->endbit=1;
nuclear@1 352 }
nuclear@1 353
nuclear@1 354 void oggpackB_adv(oggpack_buffer *b,int bits){
nuclear@1 355 oggpack_adv(b,bits);
nuclear@1 356 }
nuclear@1 357
nuclear@1 358 void oggpack_adv1(oggpack_buffer *b){
nuclear@1 359 if(++(b->endbit)>7){
nuclear@1 360 b->endbit=0;
nuclear@1 361 b->ptr++;
nuclear@1 362 b->endbyte++;
nuclear@1 363 }
nuclear@1 364 }
nuclear@1 365
nuclear@1 366 void oggpackB_adv1(oggpack_buffer *b){
nuclear@1 367 oggpack_adv1(b);
nuclear@1 368 }
nuclear@1 369
nuclear@1 370 /* bits <= 32 */
nuclear@1 371 long oggpack_read(oggpack_buffer *b,int bits){
nuclear@1 372 long ret;
nuclear@1 373 unsigned long m;
nuclear@1 374
nuclear@1 375 if(bits<0 || bits>32) goto err;
nuclear@1 376 m=mask[bits];
nuclear@1 377 bits+=b->endbit;
nuclear@1 378
nuclear@1 379 if(b->endbyte >= b->storage-4){
nuclear@1 380 /* not the main path */
nuclear@1 381 if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
nuclear@1 382 /* special case to avoid reading b->ptr[0], which might be past the end of
nuclear@1 383 the buffer; also skips some useless accounting */
nuclear@1 384 else if(!bits)return(0L);
nuclear@1 385 }
nuclear@1 386
nuclear@1 387 ret=b->ptr[0]>>b->endbit;
nuclear@1 388 if(bits>8){
nuclear@1 389 ret|=b->ptr[1]<<(8-b->endbit);
nuclear@1 390 if(bits>16){
nuclear@1 391 ret|=b->ptr[2]<<(16-b->endbit);
nuclear@1 392 if(bits>24){
nuclear@1 393 ret|=b->ptr[3]<<(24-b->endbit);
nuclear@1 394 if(bits>32 && b->endbit){
nuclear@1 395 ret|=b->ptr[4]<<(32-b->endbit);
nuclear@1 396 }
nuclear@1 397 }
nuclear@1 398 }
nuclear@1 399 }
nuclear@1 400 ret&=m;
nuclear@1 401 b->ptr+=bits/8;
nuclear@1 402 b->endbyte+=bits/8;
nuclear@1 403 b->endbit=bits&7;
nuclear@1 404 return ret;
nuclear@1 405
nuclear@1 406 overflow:
nuclear@1 407 err:
nuclear@1 408 b->ptr=NULL;
nuclear@1 409 b->endbyte=b->storage;
nuclear@1 410 b->endbit=1;
nuclear@1 411 return -1L;
nuclear@1 412 }
nuclear@1 413
nuclear@1 414 /* bits <= 32 */
nuclear@1 415 long oggpackB_read(oggpack_buffer *b,int bits){
nuclear@1 416 long ret;
nuclear@1 417 long m=32-bits;
nuclear@1 418
nuclear@1 419 if(m<0 || m>32) goto err;
nuclear@1 420 bits+=b->endbit;
nuclear@1 421
nuclear@1 422 if(b->endbyte+4>=b->storage){
nuclear@1 423 /* not the main path */
nuclear@1 424 if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
nuclear@1 425 /* special case to avoid reading b->ptr[0], which might be past the end of
nuclear@1 426 the buffer; also skips some useless accounting */
nuclear@1 427 else if(!bits)return(0L);
nuclear@1 428 }
nuclear@1 429
nuclear@1 430 ret=b->ptr[0]<<(24+b->endbit);
nuclear@1 431 if(bits>8){
nuclear@1 432 ret|=b->ptr[1]<<(16+b->endbit);
nuclear@1 433 if(bits>16){
nuclear@1 434 ret|=b->ptr[2]<<(8+b->endbit);
nuclear@1 435 if(bits>24){
nuclear@1 436 ret|=b->ptr[3]<<(b->endbit);
nuclear@1 437 if(bits>32 && b->endbit)
nuclear@1 438 ret|=b->ptr[4]>>(8-b->endbit);
nuclear@1 439 }
nuclear@1 440 }
nuclear@1 441 }
nuclear@1 442 ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
nuclear@1 443
nuclear@1 444 b->ptr+=bits/8;
nuclear@1 445 b->endbyte+=bits/8;
nuclear@1 446 b->endbit=bits&7;
nuclear@1 447 return ret;
nuclear@1 448
nuclear@1 449 overflow:
nuclear@1 450 err:
nuclear@1 451 b->ptr=NULL;
nuclear@1 452 b->endbyte=b->storage;
nuclear@1 453 b->endbit=1;
nuclear@1 454 return -1L;
nuclear@1 455 }
nuclear@1 456
nuclear@1 457 long oggpack_read1(oggpack_buffer *b){
nuclear@1 458 long ret;
nuclear@1 459
nuclear@1 460 if(b->endbyte >= b->storage) goto overflow;
nuclear@1 461 ret=(b->ptr[0]>>b->endbit)&1;
nuclear@1 462
nuclear@1 463 b->endbit++;
nuclear@1 464 if(b->endbit>7){
nuclear@1 465 b->endbit=0;
nuclear@1 466 b->ptr++;
nuclear@1 467 b->endbyte++;
nuclear@1 468 }
nuclear@1 469 return ret;
nuclear@1 470
nuclear@1 471 overflow:
nuclear@1 472 b->ptr=NULL;
nuclear@1 473 b->endbyte=b->storage;
nuclear@1 474 b->endbit=1;
nuclear@1 475 return -1L;
nuclear@1 476 }
nuclear@1 477
nuclear@1 478 long oggpackB_read1(oggpack_buffer *b){
nuclear@1 479 long ret;
nuclear@1 480
nuclear@1 481 if(b->endbyte >= b->storage) goto overflow;
nuclear@1 482 ret=(b->ptr[0]>>(7-b->endbit))&1;
nuclear@1 483
nuclear@1 484 b->endbit++;
nuclear@1 485 if(b->endbit>7){
nuclear@1 486 b->endbit=0;
nuclear@1 487 b->ptr++;
nuclear@1 488 b->endbyte++;
nuclear@1 489 }
nuclear@1 490 return ret;
nuclear@1 491
nuclear@1 492 overflow:
nuclear@1 493 b->ptr=NULL;
nuclear@1 494 b->endbyte=b->storage;
nuclear@1 495 b->endbit=1;
nuclear@1 496 return -1L;
nuclear@1 497 }
nuclear@1 498
nuclear@1 499 long oggpack_bytes(oggpack_buffer *b){
nuclear@1 500 return(b->endbyte+(b->endbit+7)/8);
nuclear@1 501 }
nuclear@1 502
nuclear@1 503 long oggpack_bits(oggpack_buffer *b){
nuclear@1 504 return(b->endbyte*8+b->endbit);
nuclear@1 505 }
nuclear@1 506
nuclear@1 507 long oggpackB_bytes(oggpack_buffer *b){
nuclear@1 508 return oggpack_bytes(b);
nuclear@1 509 }
nuclear@1 510
nuclear@1 511 long oggpackB_bits(oggpack_buffer *b){
nuclear@1 512 return oggpack_bits(b);
nuclear@1 513 }
nuclear@1 514
nuclear@1 515 unsigned char *oggpack_get_buffer(oggpack_buffer *b){
nuclear@1 516 return(b->buffer);
nuclear@1 517 }
nuclear@1 518
nuclear@1 519 unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
nuclear@1 520 return oggpack_get_buffer(b);
nuclear@1 521 }
nuclear@1 522
nuclear@1 523 /* Self test of the bitwise routines; everything else is based on
nuclear@1 524 them, so they damned well better be solid. */
nuclear@1 525
nuclear@1 526 #ifdef _V_SELFTEST
nuclear@1 527 #include <stdio.h>
nuclear@1 528
nuclear@1 529 static int ilog(unsigned int v){
nuclear@1 530 int ret=0;
nuclear@1 531 while(v){
nuclear@1 532 ret++;
nuclear@1 533 v>>=1;
nuclear@1 534 }
nuclear@1 535 return(ret);
nuclear@1 536 }
nuclear@1 537
nuclear@1 538 oggpack_buffer o;
nuclear@1 539 oggpack_buffer r;
nuclear@1 540
nuclear@1 541 void report(char *in){
nuclear@1 542 fprintf(stderr,"%s",in);
nuclear@1 543 exit(1);
nuclear@1 544 }
nuclear@1 545
nuclear@1 546 void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
nuclear@1 547 long bytes,i;
nuclear@1 548 unsigned char *buffer;
nuclear@1 549
nuclear@1 550 oggpack_reset(&o);
nuclear@1 551 for(i=0;i<vals;i++)
nuclear@1 552 oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
nuclear@1 553 buffer=oggpack_get_buffer(&o);
nuclear@1 554 bytes=oggpack_bytes(&o);
nuclear@1 555 if(bytes!=compsize)report("wrong number of bytes!\n");
nuclear@1 556 for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
nuclear@1 557 for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
nuclear@1 558 report("wrote incorrect value!\n");
nuclear@1 559 }
nuclear@1 560 oggpack_readinit(&r,buffer,bytes);
nuclear@1 561 for(i=0;i<vals;i++){
nuclear@1 562 int tbit=bits?bits:ilog(b[i]);
nuclear@1 563 if(oggpack_look(&r,tbit)==-1)
nuclear@1 564 report("out of data!\n");
nuclear@1 565 if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit]))
nuclear@1 566 report("looked at incorrect value!\n");
nuclear@1 567 if(tbit==1)
nuclear@1 568 if(oggpack_look1(&r)!=(b[i]&mask[tbit]))
nuclear@1 569 report("looked at single bit incorrect value!\n");
nuclear@1 570 if(tbit==1){
nuclear@1 571 if(oggpack_read1(&r)!=(b[i]&mask[tbit]))
nuclear@1 572 report("read incorrect single bit value!\n");
nuclear@1 573 }else{
nuclear@1 574 if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
nuclear@1 575 report("read incorrect value!\n");
nuclear@1 576 }
nuclear@1 577 }
nuclear@1 578 if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
nuclear@1 579 }
nuclear@1 580
nuclear@1 581 void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
nuclear@1 582 long bytes,i;
nuclear@1 583 unsigned char *buffer;
nuclear@1 584
nuclear@1 585 oggpackB_reset(&o);
nuclear@1 586 for(i=0;i<vals;i++)
nuclear@1 587 oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
nuclear@1 588 buffer=oggpackB_get_buffer(&o);
nuclear@1 589 bytes=oggpackB_bytes(&o);
nuclear@1 590 if(bytes!=compsize)report("wrong number of bytes!\n");
nuclear@1 591 for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
nuclear@1 592 for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
nuclear@1 593 report("wrote incorrect value!\n");
nuclear@1 594 }
nuclear@1 595 oggpackB_readinit(&r,buffer,bytes);
nuclear@1 596 for(i=0;i<vals;i++){
nuclear@1 597 int tbit=bits?bits:ilog(b[i]);
nuclear@1 598 if(oggpackB_look(&r,tbit)==-1)
nuclear@1 599 report("out of data!\n");
nuclear@1 600 if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
nuclear@1 601 report("looked at incorrect value!\n");
nuclear@1 602 if(tbit==1)
nuclear@1 603 if(oggpackB_look1(&r)!=(b[i]&mask[tbit]))
nuclear@1 604 report("looked at single bit incorrect value!\n");
nuclear@1 605 if(tbit==1){
nuclear@1 606 if(oggpackB_read1(&r)!=(b[i]&mask[tbit]))
nuclear@1 607 report("read incorrect single bit value!\n");
nuclear@1 608 }else{
nuclear@1 609 if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
nuclear@1 610 report("read incorrect value!\n");
nuclear@1 611 }
nuclear@1 612 }
nuclear@1 613 if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
nuclear@1 614 }
nuclear@1 615
nuclear@1 616 int main(void){
nuclear@1 617 unsigned char *buffer;
nuclear@1 618 long bytes,i;
nuclear@1 619 static unsigned long testbuffer1[]=
nuclear@1 620 {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
nuclear@1 621 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
nuclear@1 622 int test1size=43;
nuclear@1 623
nuclear@1 624 static unsigned long testbuffer2[]=
nuclear@1 625 {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
nuclear@1 626 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
nuclear@1 627 85525151,0,12321,1,349528352};
nuclear@1 628 int test2size=21;
nuclear@1 629
nuclear@1 630 static unsigned long testbuffer3[]=
nuclear@1 631 {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,
nuclear@1 632 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
nuclear@1 633 int test3size=56;
nuclear@1 634
nuclear@1 635 static unsigned long large[]=
nuclear@1 636 {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
nuclear@1 637 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
nuclear@1 638 85525151,0,12321,1,2146528352};
nuclear@1 639
nuclear@1 640 int onesize=33;
nuclear@1 641 static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
nuclear@1 642 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
nuclear@1 643 223,4};
nuclear@1 644 static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
nuclear@1 645 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
nuclear@1 646 245,251,128};
nuclear@1 647
nuclear@1 648 int twosize=6;
nuclear@1 649 static int two[6]={61,255,255,251,231,29};
nuclear@1 650 static int twoB[6]={247,63,255,253,249,120};
nuclear@1 651
nuclear@1 652 int threesize=54;
nuclear@1 653 static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
nuclear@1 654 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
nuclear@1 655 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
nuclear@1 656 100,52,4,14,18,86,77,1};
nuclear@1 657 static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
nuclear@1 658 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
nuclear@1 659 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
nuclear@1 660 200,20,254,4,58,106,176,144,0};
nuclear@1 661
nuclear@1 662 int foursize=38;
nuclear@1 663 static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
nuclear@1 664 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
nuclear@1 665 28,2,133,0,1};
nuclear@1 666 static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
nuclear@1 667 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
nuclear@1 668 129,10,4,32};
nuclear@1 669
nuclear@1 670 int fivesize=45;
nuclear@1 671 static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
nuclear@1 672 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
nuclear@1 673 84,75,159,2,1,0,132,192,8,0,0,18,22};
nuclear@1 674 static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
nuclear@1 675 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
nuclear@1 676 172,150,169,129,79,128,0,6,4,32,0,27,9,0};
nuclear@1 677
nuclear@1 678 int sixsize=7;
nuclear@1 679 static int six[7]={17,177,170,242,169,19,148};
nuclear@1 680 static int sixB[7]={136,141,85,79,149,200,41};
nuclear@1 681
nuclear@1 682 /* Test read/write together */
nuclear@1 683 /* Later we test against pregenerated bitstreams */
nuclear@1 684 oggpack_writeinit(&o);
nuclear@1 685
nuclear@1 686 fprintf(stderr,"\nSmall preclipped packing (LSb): ");
nuclear@1 687 cliptest(testbuffer1,test1size,0,one,onesize);
nuclear@1 688 fprintf(stderr,"ok.");
nuclear@1 689
nuclear@1 690 fprintf(stderr,"\nNull bit call (LSb): ");
nuclear@1 691 cliptest(testbuffer3,test3size,0,two,twosize);
nuclear@1 692 fprintf(stderr,"ok.");
nuclear@1 693
nuclear@1 694 fprintf(stderr,"\nLarge preclipped packing (LSb): ");
nuclear@1 695 cliptest(testbuffer2,test2size,0,three,threesize);
nuclear@1 696 fprintf(stderr,"ok.");
nuclear@1 697
nuclear@1 698 fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
nuclear@1 699 oggpack_reset(&o);
nuclear@1 700 for(i=0;i<test2size;i++)
nuclear@1 701 oggpack_write(&o,large[i],32);
nuclear@1 702 buffer=oggpack_get_buffer(&o);
nuclear@1 703 bytes=oggpack_bytes(&o);
nuclear@1 704 oggpack_readinit(&r,buffer,bytes);
nuclear@1 705 for(i=0;i<test2size;i++){
nuclear@1 706 if(oggpack_look(&r,32)==-1)report("out of data. failed!");
nuclear@1 707 if(oggpack_look(&r,32)!=large[i]){
nuclear@1 708 fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i],
nuclear@1 709 oggpack_look(&r,32),large[i]);
nuclear@1 710 report("read incorrect value!\n");
nuclear@1 711 }
nuclear@1 712 oggpack_adv(&r,32);
nuclear@1 713 }
nuclear@1 714 if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
nuclear@1 715 fprintf(stderr,"ok.");
nuclear@1 716
nuclear@1 717 fprintf(stderr,"\nSmall unclipped packing (LSb): ");
nuclear@1 718 cliptest(testbuffer1,test1size,7,four,foursize);
nuclear@1 719 fprintf(stderr,"ok.");
nuclear@1 720
nuclear@1 721 fprintf(stderr,"\nLarge unclipped packing (LSb): ");
nuclear@1 722 cliptest(testbuffer2,test2size,17,five,fivesize);
nuclear@1 723 fprintf(stderr,"ok.");
nuclear@1 724
nuclear@1 725 fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
nuclear@1 726 cliptest(testbuffer3,test3size,1,six,sixsize);
nuclear@1 727 fprintf(stderr,"ok.");
nuclear@1 728
nuclear@1 729 fprintf(stderr,"\nTesting read past end (LSb): ");
nuclear@1 730 oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
nuclear@1 731 for(i=0;i<64;i++){
nuclear@1 732 if(oggpack_read(&r,1)!=0){
nuclear@1 733 fprintf(stderr,"failed; got -1 prematurely.\n");
nuclear@1 734 exit(1);
nuclear@1 735 }
nuclear@1 736 }
nuclear@1 737 if(oggpack_look(&r,1)!=-1 ||
nuclear@1 738 oggpack_read(&r,1)!=-1){
nuclear@1 739 fprintf(stderr,"failed; read past end without -1.\n");
nuclear@1 740 exit(1);
nuclear@1 741 }
nuclear@1 742 oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
nuclear@1 743 if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
nuclear@1 744 fprintf(stderr,"failed 2; got -1 prematurely.\n");
nuclear@1 745 exit(1);
nuclear@1 746 }
nuclear@1 747
nuclear@1 748 if(oggpack_look(&r,18)!=0 ||
nuclear@1 749 oggpack_look(&r,18)!=0){
nuclear@1 750 fprintf(stderr,"failed 3; got -1 prematurely.\n");
nuclear@1 751 exit(1);
nuclear@1 752 }
nuclear@1 753 if(oggpack_look(&r,19)!=-1 ||
nuclear@1 754 oggpack_look(&r,19)!=-1){
nuclear@1 755 fprintf(stderr,"failed; read past end without -1.\n");
nuclear@1 756 exit(1);
nuclear@1 757 }
nuclear@1 758 if(oggpack_look(&r,32)!=-1 ||
nuclear@1 759 oggpack_look(&r,32)!=-1){
nuclear@1 760 fprintf(stderr,"failed; read past end without -1.\n");
nuclear@1 761 exit(1);
nuclear@1 762 }
nuclear@1 763 oggpack_writeclear(&o);
nuclear@1 764 fprintf(stderr,"ok.\n");
nuclear@1 765
nuclear@1 766 /********** lazy, cut-n-paste retest with MSb packing ***********/
nuclear@1 767
nuclear@1 768 /* Test read/write together */
nuclear@1 769 /* Later we test against pregenerated bitstreams */
nuclear@1 770 oggpackB_writeinit(&o);
nuclear@1 771
nuclear@1 772 fprintf(stderr,"\nSmall preclipped packing (MSb): ");
nuclear@1 773 cliptestB(testbuffer1,test1size,0,oneB,onesize);
nuclear@1 774 fprintf(stderr,"ok.");
nuclear@1 775
nuclear@1 776 fprintf(stderr,"\nNull bit call (MSb): ");
nuclear@1 777 cliptestB(testbuffer3,test3size,0,twoB,twosize);
nuclear@1 778 fprintf(stderr,"ok.");
nuclear@1 779
nuclear@1 780 fprintf(stderr,"\nLarge preclipped packing (MSb): ");
nuclear@1 781 cliptestB(testbuffer2,test2size,0,threeB,threesize);
nuclear@1 782 fprintf(stderr,"ok.");
nuclear@1 783
nuclear@1 784 fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
nuclear@1 785 oggpackB_reset(&o);
nuclear@1 786 for(i=0;i<test2size;i++)
nuclear@1 787 oggpackB_write(&o,large[i],32);
nuclear@1 788 buffer=oggpackB_get_buffer(&o);
nuclear@1 789 bytes=oggpackB_bytes(&o);
nuclear@1 790 oggpackB_readinit(&r,buffer,bytes);
nuclear@1 791 for(i=0;i<test2size;i++){
nuclear@1 792 if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
nuclear@1 793 if(oggpackB_look(&r,32)!=large[i]){
nuclear@1 794 fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i],
nuclear@1 795 oggpackB_look(&r,32),large[i]);
nuclear@1 796 report("read incorrect value!\n");
nuclear@1 797 }
nuclear@1 798 oggpackB_adv(&r,32);
nuclear@1 799 }
nuclear@1 800 if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
nuclear@1 801 fprintf(stderr,"ok.");
nuclear@1 802
nuclear@1 803 fprintf(stderr,"\nSmall unclipped packing (MSb): ");
nuclear@1 804 cliptestB(testbuffer1,test1size,7,fourB,foursize);
nuclear@1 805 fprintf(stderr,"ok.");
nuclear@1 806
nuclear@1 807 fprintf(stderr,"\nLarge unclipped packing (MSb): ");
nuclear@1 808 cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
nuclear@1 809 fprintf(stderr,"ok.");
nuclear@1 810
nuclear@1 811 fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
nuclear@1 812 cliptestB(testbuffer3,test3size,1,sixB,sixsize);
nuclear@1 813 fprintf(stderr,"ok.");
nuclear@1 814
nuclear@1 815 fprintf(stderr,"\nTesting read past end (MSb): ");
nuclear@1 816 oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
nuclear@1 817 for(i=0;i<64;i++){
nuclear@1 818 if(oggpackB_read(&r,1)!=0){
nuclear@1 819 fprintf(stderr,"failed; got -1 prematurely.\n");
nuclear@1 820 exit(1);
nuclear@1 821 }
nuclear@1 822 }
nuclear@1 823 if(oggpackB_look(&r,1)!=-1 ||
nuclear@1 824 oggpackB_read(&r,1)!=-1){
nuclear@1 825 fprintf(stderr,"failed; read past end without -1.\n");
nuclear@1 826 exit(1);
nuclear@1 827 }
nuclear@1 828 oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
nuclear@1 829 if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
nuclear@1 830 fprintf(stderr,"failed 2; got -1 prematurely.\n");
nuclear@1 831 exit(1);
nuclear@1 832 }
nuclear@1 833
nuclear@1 834 if(oggpackB_look(&r,18)!=0 ||
nuclear@1 835 oggpackB_look(&r,18)!=0){
nuclear@1 836 fprintf(stderr,"failed 3; got -1 prematurely.\n");
nuclear@1 837 exit(1);
nuclear@1 838 }
nuclear@1 839 if(oggpackB_look(&r,19)!=-1 ||
nuclear@1 840 oggpackB_look(&r,19)!=-1){
nuclear@1 841 fprintf(stderr,"failed; read past end without -1.\n");
nuclear@1 842 exit(1);
nuclear@1 843 }
nuclear@1 844 if(oggpackB_look(&r,32)!=-1 ||
nuclear@1 845 oggpackB_look(&r,32)!=-1){
nuclear@1 846 fprintf(stderr,"failed; read past end without -1.\n");
nuclear@1 847 exit(1);
nuclear@1 848 }
nuclear@1 849 oggpackB_writeclear(&o);
nuclear@1 850 fprintf(stderr,"ok.\n\n");
nuclear@1 851
nuclear@1 852
nuclear@1 853 return(0);
nuclear@1 854 }
nuclear@1 855 #endif /* _V_SELFTEST */
nuclear@1 856
nuclear@1 857 #undef BUFFER_INCREMENT