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