misc/libtremor/tremor/bitwise.c
changeset 7697 767d3c4153a1
parent 6045 9a7cc0f29430
child 7849 a12155461b34
equal deleted inserted replaced
7696:78a00bc68913 7697:767d3c4153a1
    18 /* We're 'LSb' endian; if we write a word but read individual bits,
    18 /* We're 'LSb' endian; if we write a word but read individual bits,
    19    then we'll read the lsb first */
    19    then we'll read the lsb first */
    20 
    20 
    21 #include <string.h>
    21 #include <string.h>
    22 #include <stdlib.h>
    22 #include <stdlib.h>
       
    23 #include "misc.h"
    23 #include "ogg.h"
    24 #include "ogg.h"
    24 
    25 
    25 static unsigned long mask[]=
    26 static unsigned long mask[]=
    26 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
    27 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
    27  0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
    28  0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
    45 static void _span(oggpack_buffer *b){
    46 static void _span(oggpack_buffer *b){
    46   while(b->headend<1){
    47   while(b->headend<1){
    47     if(b->head->next){
    48     if(b->head->next){
    48       b->count+=b->head->length;
    49       b->count+=b->head->length;
    49       b->head=b->head->next;
    50       b->head=b->head->next;
    50       b->headptr=b->head->buffer->data+b->head->begin-b->headend;
    51       b->headptr=b->head->buffer->data+b->head->begin-b->headend; 
    51       b->headend+=b->head->length;
    52       b->headend+=b->head->length;      
    52     }else{
    53     }else{
    53       /* we've either met the end of decode, or gone past it. halt
    54       /* we've either met the end of decode, or gone past it. halt
    54          only if we're past */
    55          only if we're past */
    55       if(b->headend<0 || b->headbit)
    56       if(b->headend<0 || b->headbit)
    56         /* read has fallen off the end */
    57         /* read has fallen off the end */
    79                       }
    80                       }
    80 
    81 
    81 /* Read in bits without advancing the bitptr; bits <= 32 */
    82 /* Read in bits without advancing the bitptr; bits <= 32 */
    82 long oggpack_look(oggpack_buffer *b,int bits){
    83 long oggpack_look(oggpack_buffer *b,int bits){
    83   unsigned long m=mask[bits];
    84   unsigned long m=mask[bits];
    84   unsigned long ret=-1;
    85   unsigned long ret;
    85 
    86 
    86   bits+=b->headbit;
    87   bits+=b->headbit;
    87 
    88 
    88   if(bits >= b->headend<<3){
    89   if(bits >= b->headend<<3){
    89     int            end=b->headend;
    90     int            end=b->headend;
    90     unsigned char *ptr=b->headptr;
    91     unsigned char *ptr=b->headptr;
    91     ogg_reference *head=b->head;
    92     ogg_reference *head=b->head;
    92 
    93 
    93     if(end<0)return -1;
    94     if(end<0)return -1;
    94 
    95     
    95     if(bits){
    96     if(bits){
    96       _lookspan();
    97       _lookspan();
    97       ret=*ptr++>>b->headbit;
    98       ret=*ptr++>>b->headbit;
    98       if(bits>8){
    99       if(bits>8){
    99         --end;
   100         --end;
   100         _lookspan();
   101         _lookspan();
   101         ret|=*ptr++<<(8-b->headbit);
   102         ret|=*ptr++<<(8-b->headbit);  
   102         if(bits>16){
   103         if(bits>16){
   103           --end;
   104           --end;
   104           _lookspan();
   105           _lookspan();
   105           ret|=*ptr++<<(16-b->headbit);
   106           ret|=*ptr++<<(16-b->headbit);  
   106           if(bits>24){
   107           if(bits>24){
   107             --end;
   108             --end;
   108             _lookspan();
   109             _lookspan();
   109             ret|=*ptr++<<(24-b->headbit);
   110             ret|=*ptr++<<(24-b->headbit);  
   110             if(bits>32 && b->headbit){
   111             if(bits>32 && b->headbit){
   111               --end;
   112               --end;
   112               _lookspan();
   113               _lookspan();
   113               ret|=*ptr<<(32-b->headbit);
   114               ret|=*ptr<<(32-b->headbit);
   114             }
   115             }
   144   b->headbit=bits&7;
   145   b->headbit=bits&7;
   145   b->headptr+=bits/8;
   146   b->headptr+=bits/8;
   146   if((b->headend-=bits/8)<1)_span(b);
   147   if((b->headend-=bits/8)<1)_span(b);
   147 }
   148 }
   148 
   149 
   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){
   150 int oggpack_eop(oggpack_buffer *b){
   171   if(b->headend<0)return -1;
   151   if(b->headend<0)return -1;
   172   return 0;
   152   return 0;
   173 }
   153 }
   174 
   154 
   175 /* bits <= 32 */
   155 /* bits <= 32 */
   176 long oggpack_read(oggpack_buffer *b,int bits){
   156 long oggpack_read(oggpack_buffer *b,int bits){
   177   unsigned long m=mask[bits];
   157   long ret=oggpack_look(b,bits);
   178   ogg_uint32_t ret=-1;
   158   oggpack_adv(b,bits);
   179 
   159   return(ret);
   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 }
   160 }
   255 
   161 
   256 long oggpack_bytes(oggpack_buffer *b){
   162 long oggpack_bytes(oggpack_buffer *b){
   257   return(b->count+b->headptr-b->head->buffer->data-b->head->begin+
   163   return(b->count+b->headptr-b->head->buffer->data-b->head->begin+
   258          (b->headbit+7)/8);
   164          (b->headbit+7)/8);