bitpack.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC 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 OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2008 *
  9. * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function: packing variable sized words into an octet stream
  13. last mod: $Id: bitpack.c 15400 2008-10-15 12:10:58Z tterribe $
  14. ********************************************************************/
  15. /*We're 'MSb' endian; if we write a word but read individual bits,
  16. then we'll read the MSb first.*/
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include "bitpack.h"
  20. void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes){
  21. memset(_b,0,sizeof(*_b));
  22. _b->buffer=_b->ptr=_buf;
  23. _b->storage=_bytes;
  24. }
  25. int theorapackB_look1(oggpack_buffer *_b,long *_ret){
  26. if(_b->endbyte>=_b->storage){
  27. *_ret=0L;
  28. return -1;
  29. }
  30. *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
  31. return 0;
  32. }
  33. void theorapackB_adv1(oggpack_buffer *_b){
  34. if(++(_b->endbit)>7){
  35. _b->endbit=0;
  36. _b->ptr++;
  37. _b->endbyte++;
  38. }
  39. }
  40. /*Here we assume that 0<=_bits&&_bits<=32.*/
  41. int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret){
  42. long ret;
  43. long m;
  44. long d;
  45. int fail;
  46. m=32-_bits;
  47. _bits+=_b->endbit;
  48. d=_b->storage-_b->endbyte;
  49. if(d<=4){
  50. /*Not the main path.*/
  51. if(d*8<_bits){
  52. *_ret=0L;
  53. fail=-1;
  54. goto overflow;
  55. }
  56. /*Special case to avoid reading _b->ptr[0], which might be past the end of
  57. the buffer; also skips some useless accounting.*/
  58. else if(!_bits){
  59. *_ret=0L;
  60. return 0;
  61. }
  62. }
  63. ret=_b->ptr[0]<<24+_b->endbit;
  64. if(_bits>8){
  65. ret|=_b->ptr[1]<<16+_b->endbit;
  66. if(_bits>16){
  67. ret|=_b->ptr[2]<<8+_b->endbit;
  68. if(_bits>24){
  69. ret|=_b->ptr[3]<<_b->endbit;
  70. if(_bits>32)ret|=_b->ptr[4]>>8-_b->endbit;
  71. }
  72. }
  73. }
  74. *_ret=((ret&0xFFFFFFFFUL)>>(m>>1))>>(m+1>>1);
  75. fail=0;
  76. overflow:
  77. _b->ptr+=_bits>>3;
  78. _b->endbyte+=_bits>>3;
  79. _b->endbit=_bits&7;
  80. return fail;
  81. }
  82. int theorapackB_read1(oggpack_buffer *_b,long *_ret){
  83. int fail;
  84. if(_b->endbyte>=_b->storage){
  85. /*Not the main path.*/
  86. *_ret=0L;
  87. fail=-1;
  88. }
  89. else{
  90. *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
  91. fail=0;
  92. }
  93. _b->endbit++;
  94. if(_b->endbit>7){
  95. _b->endbit=0;
  96. _b->ptr++;
  97. _b->endbyte++;
  98. }
  99. return fail;
  100. }
  101. long theorapackB_bytes(oggpack_buffer *_b){
  102. return _b->endbyte+(_b->endbit+7>>3);
  103. }
  104. long theorapackB_bits(oggpack_buffer *_b){
  105. return _b->endbyte*8+_b->endbit;
  106. }
  107. unsigned char *theorapackB_get_buffer(oggpack_buffer *_b){
  108. return _b->buffer;
  109. }