~arkadini/fogg/trunk

« back to all changes in this revision

Viewing changes to reference/tremor/bitwise.c

  • Committer: Arek Korbik
  • Date: 2008-10-03 00:34:01 UTC
  • Revision ID: arkadini@gmail.com-20081003003401-9eahru9hcz3o2qht
Remove the Tremor reference files for now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/********************************************************************
2
 
 *                                                                  *
3
 
 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
4
 
 *                                                                  *
5
 
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
6
 
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7
 
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
8
 
 *                                                                  *
9
 
 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
10
 
 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
11
 
 *                                                                  *
12
 
 ********************************************************************
13
 
 
14
 
  function: packing variable sized words into an octet stream
15
 
 
16
 
 ********************************************************************/
17
 
 
18
 
/* We're 'LSb' endian; if we write a word but read individual bits,
19
 
   then we'll read the lsb first */
20
 
 
21
 
#include <string.h>
22
 
#include <stdlib.h>
23
 
#include "ogg.h"
24
 
 
25
 
static unsigned long mask[]=
26
 
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
27
 
 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
28
 
 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
29
 
 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
30
 
 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
31
 
 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
32
 
 0x3fffffff,0x7fffffff,0xffffffff };
33
 
 
34
 
/* mark read process as having run off the end */
35
 
static void _adv_halt(oggpack_buffer *b){
36
 
  b->headptr=b->head->buffer->data+b->head->begin+b->head->length;
37
 
  b->headend=-1;
38
 
  b->headbit=0;
39
 
}
40
 
 
41
 
/* spans forward, skipping as many bytes as headend is negative; if
42
 
   headend is zero, simply finds next byte.  If we're up to the end
43
 
   of the buffer, leaves headend at zero.  If we've read past the end,
44
 
   halt the decode process. */
45
 
static void _span(oggpack_buffer *b){
46
 
  while(b->headend<1){
47
 
    if(b->head->next){
48
 
      b->count+=b->head->length;
49
 
      b->head=b->head->next;
50
 
      b->headptr=b->head->buffer->data+b->head->begin-b->headend; 
51
 
      b->headend+=b->head->length;      
52
 
    }else{
53
 
      /* we've either met the end of decode, or gone past it. halt
54
 
         only if we're past */
55
 
      if(b->headend<0 || b->headbit)
56
 
        /* read has fallen off the end */
57
 
        _adv_halt(b);
58
 
 
59
 
      break;
60
 
    }
61
 
  }
62
 
}
63
 
 
64
 
void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
65
 
  memset(b,0,sizeof(*b));
66
 
 
67
 
  b->tail=b->head=r;
68
 
  b->count=0;
69
 
  b->headptr=b->head->buffer->data+b->head->begin;
70
 
  b->headend=b->head->length;
71
 
  _span(b);
72
 
}
73
 
 
74
 
#define _lookspan()   while(!end){\
75
 
                        head=head->next;\
76
 
                        if(!head) return -1;\
77
 
                        ptr=head->buffer->data + head->begin;\
78
 
                        end=head->length;\
79
 
                      }
80
 
 
81
 
/* Read in bits without advancing the bitptr; bits <= 32 */
82
 
long oggpack_look(oggpack_buffer *b,int bits){
83
 
  unsigned long m=mask[bits];
84
 
  unsigned long ret=-1;
85
 
 
86
 
  bits+=b->headbit;
87
 
 
88
 
  if(bits >= b->headend<<3){
89
 
    int            end=b->headend;
90
 
    unsigned char *ptr=b->headptr;
91
 
    ogg_reference *head=b->head;
92
 
 
93
 
    if(end<0)return -1;
94
 
    
95
 
    if(bits){
96
 
      _lookspan();
97
 
      ret=*ptr++>>b->headbit;
98
 
      if(bits>8){
99
 
        --end;
100
 
        _lookspan();
101
 
        ret|=*ptr++<<(8-b->headbit);  
102
 
        if(bits>16){
103
 
          --end;
104
 
          _lookspan();
105
 
          ret|=*ptr++<<(16-b->headbit);  
106
 
          if(bits>24){
107
 
            --end;
108
 
            _lookspan();
109
 
            ret|=*ptr++<<(24-b->headbit);  
110
 
            if(bits>32 && b->headbit){
111
 
              --end;
112
 
              _lookspan();
113
 
              ret|=*ptr<<(32-b->headbit);
114
 
            }
115
 
          }
116
 
        }
117
 
      }
118
 
    }
119
 
 
120
 
  }else{
121
 
 
122
 
    /* make this a switch jump-table */
123
 
    ret=b->headptr[0]>>b->headbit;
124
 
    if(bits>8){
125
 
      ret|=b->headptr[1]<<(8-b->headbit);  
126
 
      if(bits>16){
127
 
        ret|=b->headptr[2]<<(16-b->headbit);  
128
 
        if(bits>24){
129
 
          ret|=b->headptr[3]<<(24-b->headbit);  
130
 
          if(bits>32 && b->headbit)
131
 
            ret|=b->headptr[4]<<(32-b->headbit);
132
 
        }
133
 
      }
134
 
    }
135
 
  }
136
 
 
137
 
  ret&=m;
138
 
  return ret;
139
 
}
140
 
 
141
 
/* limited to 32 at a time */
142
 
void oggpack_adv(oggpack_buffer *b,int bits){
143
 
  bits+=b->headbit;
144
 
  b->headbit=bits&7;
145
 
  b->headptr+=bits/8;
146
 
  if((b->headend-=bits/8)<1)_span(b);
147
 
}
148
 
 
149
 
/* spans forward and finds next byte.  Never halts */
150
 
static void _span_one(oggpack_buffer *b){
151
 
  while(b->headend<1){
152
 
    if(b->head->next){
153
 
      b->count+=b->head->length;
154
 
      b->head=b->head->next;
155
 
      b->headptr=b->head->buffer->data+b->head->begin; 
156
 
      b->headend=b->head->length;      
157
 
    }else
158
 
      break;
159
 
  }
160
 
}
161
 
 
162
 
static int _halt_one(oggpack_buffer *b){
163
 
  if(b->headend<1){
164
 
    _adv_halt(b);
165
 
    return -1;
166
 
  }
167
 
  return 0;
168
 
}
169
 
 
170
 
int oggpack_eop(oggpack_buffer *b){
171
 
  if(b->headend<0)return -1;
172
 
  return 0;
173
 
}
174
 
 
175
 
/* bits <= 32 */
176
 
long oggpack_read(oggpack_buffer *b,int bits){
177
 
  unsigned long m=mask[bits];
178
 
  ogg_uint32_t ret=-1;
179
 
 
180
 
  bits+=b->headbit;
181
 
 
182
 
  if(bits >= b->headend<<3){
183
 
 
184
 
    if(b->headend<0)return -1;
185
 
    
186
 
    if(bits){
187
 
      if (_halt_one(b)) return -1;
188
 
      ret=*b->headptr>>b->headbit;
189
 
      
190
 
      if(bits>=8){
191
 
        ++b->headptr;
192
 
        --b->headend;
193
 
        _span_one(b);
194
 
        if(bits>8){
195
 
          if (_halt_one(b)) return -1;
196
 
          ret|=*b->headptr<<(8-b->headbit);   
197
 
          
198
 
          if(bits>=16){
199
 
            ++b->headptr;
200
 
            --b->headend;
201
 
            _span_one(b);
202
 
            if(bits>16){
203
 
              if (_halt_one(b)) return -1;
204
 
              ret|=*b->headptr<<(16-b->headbit);  
205
 
              
206
 
              if(bits>=24){
207
 
                ++b->headptr;
208
 
                --b->headend;
209
 
                _span_one(b);
210
 
                if(bits>24){
211
 
                  if (_halt_one(b)) return -1;
212
 
                  ret|=*b->headptr<<(24-b->headbit);
213
 
                  
214
 
                  if(bits>=32){
215
 
                    ++b->headptr;
216
 
                    --b->headend;
217
 
                    _span_one(b);
218
 
                    if(bits>32){
219
 
                      if (_halt_one(b)) return -1;
220
 
                      if(b->headbit)ret|=*b->headptr<<(32-b->headbit);
221
 
                      
222
 
                    }
223
 
                  }
224
 
                }
225
 
              }
226
 
            }
227
 
          }
228
 
        }
229
 
      }
230
 
    }
231
 
  }else{
232
 
  
233
 
    ret=b->headptr[0]>>b->headbit;
234
 
    if(bits>8){
235
 
      ret|=b->headptr[1]<<(8-b->headbit);  
236
 
      if(bits>16){
237
 
        ret|=b->headptr[2]<<(16-b->headbit);  
238
 
        if(bits>24){
239
 
          ret|=b->headptr[3]<<(24-b->headbit);  
240
 
          if(bits>32 && b->headbit){
241
 
            ret|=b->headptr[4]<<(32-b->headbit);
242
 
          }
243
 
        }
244
 
      }
245
 
    }
246
 
    
247
 
    b->headptr+=bits/8;
248
 
    b->headend-=bits/8;
249
 
  }
250
 
 
251
 
  ret&=m;
252
 
  b->headbit=bits&7;   
253
 
  return ret;
254
 
}
255
 
 
256
 
long oggpack_bytes(oggpack_buffer *b){
257
 
  return(b->count+b->headptr-b->head->buffer->data-b->head->begin+
258
 
         (b->headbit+7)/8);
259
 
}
260
 
 
261
 
long oggpack_bits(oggpack_buffer *b){
262
 
  return((b->count+b->headptr-b->head->buffer->data-b->head->begin)*8+
263
 
         b->headbit);
264
 
}
265