bitpack.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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: bitpack.c 16503 2009-08-22 18:14:02Z giles $
  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. window=_b->window;
  31. available=_b->bits;
  32. ptr=_b->ptr;
  33. stop=_b->stop;
  34. while(available<=OC_PB_WINDOW_SIZE-8&&ptr<stop){
  35. available+=8;
  36. window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
  37. }
  38. _b->ptr=ptr;
  39. if(_bits>available){
  40. if(ptr>=stop){
  41. _b->eof=1;
  42. available=OC_LOTS_OF_BITS;
  43. }
  44. else window|=*ptr>>(available&7);
  45. }
  46. _b->bits=available;
  47. return window;
  48. }
  49. int oc_pack_look1(oc_pack_buf *_b){
  50. oc_pb_window window;
  51. int available;
  52. window=_b->window;
  53. available=_b->bits;
  54. if(available<1)_b->window=window=oc_pack_refill(_b,1);
  55. return window>>OC_PB_WINDOW_SIZE-1;
  56. }
  57. void oc_pack_adv1(oc_pack_buf *_b){
  58. _b->window<<=1;
  59. _b->bits--;
  60. }
  61. /*Here we assume that 0<=_bits&&_bits<=32.*/
  62. long oc_pack_read(oc_pack_buf *_b,int _bits){
  63. oc_pb_window window;
  64. int available;
  65. long result;
  66. window=_b->window;
  67. available=_b->bits;
  68. if(_bits==0)return 0;
  69. if(available<_bits){
  70. window=oc_pack_refill(_b,_bits);
  71. available=_b->bits;
  72. }
  73. result=window>>OC_PB_WINDOW_SIZE-_bits;
  74. available-=_bits;
  75. window<<=1;
  76. window<<=_bits-1;
  77. _b->bits=available;
  78. _b->window=window;
  79. return result;
  80. }
  81. int oc_pack_read1(oc_pack_buf *_b){
  82. oc_pb_window window;
  83. int available;
  84. int result;
  85. window=_b->window;
  86. available=_b->bits;
  87. if(available<1){
  88. window=oc_pack_refill(_b,1);
  89. available=_b->bits;
  90. }
  91. result=window>>OC_PB_WINDOW_SIZE-1;
  92. available--;
  93. window<<=1;
  94. _b->bits=available;
  95. _b->window=window;
  96. return result;
  97. }
  98. long oc_pack_bytes_left(oc_pack_buf *_b){
  99. if(_b->eof)return -1;
  100. return _b->stop-_b->ptr+(_b->bits>>3);
  101. }