00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022 #include <stdlib.h>
00023 #include "ogg.h"
00024
00025 const static unsigned long mask[]=
00026 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
00027 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
00028 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
00029 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
00030 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
00031 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
00032 0x3fffffff,0x7fffffff,0xffffffff };
00033
00034
00035 static void _adv_halt(oggpack_buffer *b){
00036 b->headptr=b->head->buffer->data+b->head->begin+b->head->length;
00037 b->headend=-1;
00038 b->headbit=0;
00039 }
00040
00041
00042
00043
00044
00045 static void _span(oggpack_buffer *b){
00046 while(b->headend<1){
00047 if(b->head->next){
00048 b->count+=b->head->length;
00049 b->head=b->head->next;
00050 b->headptr=b->head->buffer->data+b->head->begin-b->headend;
00051 b->headend+=b->head->length;
00052 }else{
00053
00054
00055 if(b->headend<0 || b->headbit)
00056
00057 _adv_halt(b);
00058
00059 break;
00060 }
00061 }
00062 }
00063
00064 void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
00065 memset(b,0,sizeof(*b));
00066
00067 b->tail=b->head=r;
00068 b->count=0;
00069 b->headptr=b->head->buffer->data+b->head->begin;
00070 b->headend=b->head->length;
00071 _span(b);
00072 }
00073
00074 #define _lookspan() while(!end){\
00075 head=head->next;\
00076 if(!head) return -1;\
00077 ptr=head->buffer->data + head->begin;\
00078 end=head->length;\
00079 }
00080
00081
00082 long oggpack_look(oggpack_buffer *b,int bits){
00083 unsigned long m=mask[bits];
00084 unsigned long ret=0;
00085
00086 bits+=b->headbit;
00087
00088 if(bits >= b->headend<<3){
00089 int end=b->headend;
00090 unsigned char *ptr=b->headptr;
00091 ogg_reference *head=b->head;
00092
00093 if(end<0)return -1;
00094
00095 if(bits){
00096 _lookspan();
00097 ret=*ptr++>>b->headbit;
00098 if(bits>8){
00099 --end;
00100 _lookspan();
00101 ret|=*ptr++<<(8-b->headbit);
00102 if(bits>16){
00103 --end;
00104 _lookspan();
00105 ret|=*ptr++<<(16-b->headbit);
00106 if(bits>24){
00107 --end;
00108 _lookspan();
00109 ret|=*ptr++<<(24-b->headbit);
00110 if(bits>32 && b->headbit){
00111 --end;
00112 _lookspan();
00113 ret|=*ptr<<(32-b->headbit);
00114 }
00115 }
00116 }
00117 }
00118 }
00119
00120 }else{
00121
00122
00123 ret=b->headptr[0]>>b->headbit;
00124 if(bits>8){
00125 ret|=b->headptr[1]<<(8-b->headbit);
00126 if(bits>16){
00127 ret|=b->headptr[2]<<(16-b->headbit);
00128 if(bits>24){
00129 ret|=b->headptr[3]<<(24-b->headbit);
00130 if(bits>32 && b->headbit)
00131 ret|=b->headptr[4]<<(32-b->headbit);
00132 }
00133 }
00134 }
00135 }
00136
00137 ret&=m;
00138 return ret;
00139 }
00140
00141
00142 void oggpack_adv(oggpack_buffer *b,int bits){
00143 bits+=b->headbit;
00144 b->headbit=bits&7;
00145 b->headptr+=bits/8;
00146 if((b->headend-=bits/8)<1)_span(b);
00147 }
00148
00149
00150 static void _span_one(oggpack_buffer *b){
00151 while(b->headend<1){
00152 if(b->head->next){
00153 b->count+=b->head->length;
00154 b->head=b->head->next;
00155 b->headptr=b->head->buffer->data+b->head->begin;
00156 b->headend=b->head->length;
00157 }else
00158 break;
00159 }
00160 }
00161
00162 static int _halt_one(oggpack_buffer *b){
00163 if(b->headend<1){
00164 _adv_halt(b);
00165 return -1;
00166 }
00167 return 0;
00168 }
00169
00170 int oggpack_eop(oggpack_buffer *b){
00171 if(b->headend<0)return -1;
00172 return 0;
00173 }
00174
00175
00176 long oggpack_read(oggpack_buffer *b,int bits){
00177 unsigned long m=mask[bits];
00178 ogg_uint32_t ret=0;
00179
00180 bits+=b->headbit;
00181
00182 if(bits >= b->headend<<3){
00183
00184 if(b->headend<0)return -1;
00185
00186 if(bits){
00187 if (_halt_one(b)) return -1;
00188 ret=*b->headptr>>b->headbit;
00189
00190 if(bits>=8){
00191 ++b->headptr;
00192 --b->headend;
00193 _span_one(b);
00194 if(bits>8){
00195 if (_halt_one(b)) return -1;
00196 ret|=*b->headptr<<(8-b->headbit);
00197
00198 if(bits>=16){
00199 ++b->headptr;
00200 --b->headend;
00201 _span_one(b);
00202 if(bits>16){
00203 if (_halt_one(b)) return -1;
00204 ret|=*b->headptr<<(16-b->headbit);
00205
00206 if(bits>=24){
00207 ++b->headptr;
00208 --b->headend;
00209 _span_one(b);
00210 if(bits>24){
00211 if (_halt_one(b)) return -1;
00212 ret|=*b->headptr<<(24-b->headbit);
00213
00214 if(bits>=32){
00215 ++b->headptr;
00216 --b->headend;
00217 _span_one(b);
00218 if(bits>32){
00219 if (_halt_one(b)) return -1;
00220 if(b->headbit)ret|=*b->headptr<<(32-b->headbit);
00221
00222 }
00223 }
00224 }
00225 }
00226 }
00227 }
00228 }
00229 }
00230 }
00231 }else{
00232
00233 ret=b->headptr[0]>>b->headbit;
00234 if(bits>8){
00235 ret|=b->headptr[1]<<(8-b->headbit);
00236 if(bits>16){
00237 ret|=b->headptr[2]<<(16-b->headbit);
00238 if(bits>24){
00239 ret|=b->headptr[3]<<(24-b->headbit);
00240 if(bits>32 && b->headbit){
00241 ret|=b->headptr[4]<<(32-b->headbit);
00242 }
00243 }
00244 }
00245 }
00246
00247 b->headptr+=bits/8;
00248 b->headend-=bits/8;
00249 }
00250
00251 ret&=m;
00252 b->headbit=bits&7;
00253 return ret;
00254 }
00255
00256 long oggpack_bytes(oggpack_buffer *b){
00257 return(b->count+b->headptr-b->head->buffer->data-b->head->begin+
00258 (b->headbit+7)/8);
00259 }
00260
00261 long oggpack_bits(oggpack_buffer *b){
00262 return((b->count+b->headptr-b->head->buffer->data-b->head->begin)*8+
00263 b->headbit);
00264 }
00265