misc/libtremor/tremor/bitwise.c
changeset 7849 a12155461b34
parent 7697 767d3c4153a1
--- a/misc/libtremor/tremor/bitwise.c	Sun Oct 28 03:48:37 2012 +0100
+++ b/misc/libtremor/tremor/bitwise.c	Sun Oct 28 04:00:07 2012 +0100
@@ -20,7 +20,6 @@
 
 #include <string.h>
 #include <stdlib.h>
-#include "misc.h"
 #include "ogg.h"
 
 static unsigned long mask[]=
@@ -48,8 +47,8 @@
     if(b->head->next){
       b->count+=b->head->length;
       b->head=b->head->next;
-      b->headptr=b->head->buffer->data+b->head->begin-b->headend; 
-      b->headend+=b->head->length;      
+      b->headptr=b->head->buffer->data+b->head->begin-b->headend;
+      b->headend+=b->head->length;
     }else{
       /* we've either met the end of decode, or gone past it. halt
          only if we're past */
@@ -82,7 +81,7 @@
 /* Read in bits without advancing the bitptr; bits <= 32 */
 long oggpack_look(oggpack_buffer *b,int bits){
   unsigned long m=mask[bits];
-  unsigned long ret;
+  unsigned long ret=-1;
 
   bits+=b->headbit;
 
@@ -92,22 +91,22 @@
     ogg_reference *head=b->head;
 
     if(end<0)return -1;
-    
+
     if(bits){
       _lookspan();
       ret=*ptr++>>b->headbit;
       if(bits>8){
         --end;
         _lookspan();
-        ret|=*ptr++<<(8-b->headbit);  
+        ret|=*ptr++<<(8-b->headbit);
         if(bits>16){
           --end;
           _lookspan();
-          ret|=*ptr++<<(16-b->headbit);  
+          ret|=*ptr++<<(16-b->headbit);
           if(bits>24){
             --end;
             _lookspan();
-            ret|=*ptr++<<(24-b->headbit);  
+            ret|=*ptr++<<(24-b->headbit);
             if(bits>32 && b->headbit){
               --end;
               _lookspan();
@@ -147,6 +146,27 @@
   if((b->headend-=bits/8)<1)_span(b);
 }
 
+/* spans forward and finds next byte.  Never halts */
+static void _span_one(oggpack_buffer *b){
+  while(b->headend<1){
+    if(b->head->next){
+      b->count+=b->head->length;
+      b->head=b->head->next;
+      b->headptr=b->head->buffer->data+b->head->begin;
+      b->headend=b->head->length;
+    }else
+      break;
+  }
+}
+
+static int _halt_one(oggpack_buffer *b){
+  if(b->headend<1){
+    _adv_halt(b);
+    return -1;
+  }
+  return 0;
+}
+
 int oggpack_eop(oggpack_buffer *b){
   if(b->headend<0)return -1;
   return 0;
@@ -154,9 +174,83 @@
 
 /* bits <= 32 */
 long oggpack_read(oggpack_buffer *b,int bits){
-  long ret=oggpack_look(b,bits);
-  oggpack_adv(b,bits);
-  return(ret);
+  unsigned long m=mask[bits];
+  ogg_uint32_t ret=-1;
+
+  bits+=b->headbit;
+
+  if(bits >= b->headend<<3){
+
+    if(b->headend<0)return -1;
+
+    if(bits){
+      if (_halt_one(b)) return -1;
+      ret=*b->headptr>>b->headbit;
+
+      if(bits>=8){
+        ++b->headptr;
+        --b->headend;
+        _span_one(b);
+        if(bits>8){
+          if (_halt_one(b)) return -1;
+          ret|=*b->headptr<<(8-b->headbit);
+
+          if(bits>=16){
+            ++b->headptr;
+            --b->headend;
+            _span_one(b);
+            if(bits>16){
+              if (_halt_one(b)) return -1;
+              ret|=*b->headptr<<(16-b->headbit);
+
+              if(bits>=24){
+                ++b->headptr;
+                --b->headend;
+                _span_one(b);
+                if(bits>24){
+                  if (_halt_one(b)) return -1;
+                  ret|=*b->headptr<<(24-b->headbit);
+
+                  if(bits>=32){
+                    ++b->headptr;
+                    --b->headend;
+                    _span_one(b);
+                    if(bits>32){
+                      if (_halt_one(b)) return -1;
+                      if(b->headbit)ret|=*b->headptr<<(32-b->headbit);
+
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }else{
+
+    ret=b->headptr[0]>>b->headbit;
+    if(bits>8){
+      ret|=b->headptr[1]<<(8-b->headbit);
+      if(bits>16){
+        ret|=b->headptr[2]<<(16-b->headbit);
+        if(bits>24){
+          ret|=b->headptr[3]<<(24-b->headbit);
+          if(bits>32 && b->headbit){
+            ret|=b->headptr[4]<<(32-b->headbit);
+          }
+        }
+      }
+    }
+
+    b->headptr+=bits/8;
+    b->headend-=bits/8;
+  }
+
+  ret&=m;
+  b->headbit=bits&7;
+  return ret;
 }
 
 long oggpack_bytes(oggpack_buffer *b){