bitpack.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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-2009 *
  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$
  14. ********************************************************************/
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "bitpack.h"
  18. /*We're 'MSb' endian; if we write a word but read individual bits,
  19. then we'll read the MSb first.*/
  20. void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){
  21. memset(_b,0,sizeof(*_b));
  22. _b->ptr=_buf;
  23. _b->stop=_buf+_bytes;
  24. }
  25. static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
  26. const unsigned char *ptr;
  27. const unsigned char *stop;
  28. oc_pb_window window;
  29. int available;
  30. unsigned shift;
  31. stop=_b->stop;
  32. ptr=_b->ptr;
  33. window=_b->window;
  34. available=_b->bits;
  35. shift=OC_PB_WINDOW_SIZE-available;
  36. while(7<shift&&ptr<stop){
  37. shift-=8;
  38. window|=(oc_pb_window)*ptr++<<shift;
  39. }
  40. _b->ptr=ptr;
  41. available=OC_PB_WINDOW_SIZE-shift;
  42. if(_bits>available){
  43. if(ptr>=stop){
  44. _b->eof=1;
  45. available=OC_LOTS_OF_BITS;
  46. }
  47. else window|=*ptr>>(available&7);
  48. }
  49. _b->bits=available;
  50. return window;
  51. }
  52. int oc_pack_look1(oc_pack_buf *_b){
  53. oc_pb_window window;
  54. int available;
  55. window=_b->window;
  56. available=_b->bits;
  57. if(available<1)_b->window=window=oc_pack_refill(_b,1);
  58. return window>>OC_PB_WINDOW_SIZE-1;
  59. }
  60. void oc_pack_adv1(oc_pack_buf *_b){
  61. _b->window<<=1;
  62. _b->bits--;
  63. }
  64. /*Here we assume that 0<=_bits&&_bits<=32.*/
  65. long oc_pack_read_c(oc_pack_buf *_b,int _bits){
  66. oc_pb_window window;
  67. int available;
  68. long result;
  69. window=_b->window;
  70. available=_b->bits;
  71. if(_bits==0)return 0;
  72. if(available<_bits){
  73. window=oc_pack_refill(_b,_bits);
  74. available=_b->bits;
  75. }
  76. result=window>>OC_PB_WINDOW_SIZE-_bits;
  77. available-=_bits;
  78. window<<=1;
  79. window<<=_bits-1;
  80. _b->window=window;
  81. _b->bits=available;
  82. return result;
  83. }
  84. int oc_pack_read1_c(oc_pack_buf *_b){
  85. oc_pb_window window;
  86. int available;
  87. int result;
  88. window=_b->window;
  89. available=_b->bits;
  90. if(available<1){
  91. window=oc_pack_refill(_b,1);
  92. available=_b->bits;
  93. }
  94. result=window>>OC_PB_WINDOW_SIZE-1;
  95. available--;
  96. window<<=1;
  97. _b->window=window;
  98. _b->bits=available;
  99. return result;
  100. }
  101. long oc_pack_bytes_left(oc_pack_buf *_b){
  102. if(_b->eof)return -1;
  103. return _b->stop-_b->ptr+(_b->bits>>3);
  104. }