123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- /********************************************************************
- * *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2008 *
- * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
- * *
- ********************************************************************
- function: packing variable sized words into an octet stream
- last mod: $Id: bitpack.c 15400 2008-10-15 12:10:58Z tterribe $
- ********************************************************************/
- /*We're 'MSb' endian; if we write a word but read individual bits,
- then we'll read the MSb first.*/
- #include <string.h>
- #include <stdlib.h>
- #include "bitpack.h"
- void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes){
- memset(_b,0,sizeof(*_b));
- _b->buffer=_b->ptr=_buf;
- _b->storage=_bytes;
- }
- int theorapackB_look1(oggpack_buffer *_b,long *_ret){
- if(_b->endbyte>=_b->storage){
- *_ret=0L;
- return -1;
- }
- *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
- return 0;
- }
- void theorapackB_adv1(oggpack_buffer *_b){
- if(++(_b->endbit)>7){
- _b->endbit=0;
- _b->ptr++;
- _b->endbyte++;
- }
- }
- /*Here we assume that 0<=_bits&&_bits<=32.*/
- int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret){
- long ret;
- long m;
- long d;
- int fail;
- m=32-_bits;
- _bits+=_b->endbit;
- d=_b->storage-_b->endbyte;
- if(d<=4){
- /*Not the main path.*/
- if(d*8<_bits){
- *_ret=0L;
- fail=-1;
- goto overflow;
- }
- /*Special case to avoid reading _b->ptr[0], which might be past the end of
- the buffer; also skips some useless accounting.*/
- else if(!_bits){
- *_ret=0L;
- return 0;
- }
- }
- ret=_b->ptr[0]<<24+_b->endbit;
- if(_bits>8){
- ret|=_b->ptr[1]<<16+_b->endbit;
- if(_bits>16){
- ret|=_b->ptr[2]<<8+_b->endbit;
- if(_bits>24){
- ret|=_b->ptr[3]<<_b->endbit;
- if(_bits>32)ret|=_b->ptr[4]>>8-_b->endbit;
- }
- }
- }
- *_ret=((ret&0xFFFFFFFFUL)>>(m>>1))>>(m+1>>1);
- fail=0;
- overflow:
- _b->ptr+=_bits>>3;
- _b->endbyte+=_bits>>3;
- _b->endbit=_bits&7;
- return fail;
- }
- int theorapackB_read1(oggpack_buffer *_b,long *_ret){
- int fail;
- if(_b->endbyte>=_b->storage){
- /*Not the main path.*/
- *_ret=0L;
- fail=-1;
- }
- else{
- *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
- fail=0;
- }
- _b->endbit++;
- if(_b->endbit>7){
- _b->endbit=0;
- _b->ptr++;
- _b->endbyte++;
- }
- return fail;
- }
- long theorapackB_bytes(oggpack_buffer *_b){
- return _b->endbyte+(_b->endbit+7>>3);
- }
- long theorapackB_bits(oggpack_buffer *_b){
- return _b->endbyte*8+_b->endbit;
- }
- unsigned char *theorapackB_get_buffer(oggpack_buffer *_b){
- return _b->buffer;
- }
|