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