diff tremor/bitwise.c @ 14280:8631a3803289

internal Tremor decoder for Ogg/Vorbis
author henry
date Thu, 30 Dec 2004 12:11:32 +0000 (2004-12-30)
parents
children e891ff7a7b6c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tremor/bitwise.c	Thu Dec 30 12:11:32 2004 +0000
@@ -0,0 +1,144 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
+ *                                                                  *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
+ * ALL REDISTRIBUTION RIGHTS RESERVED.                              *
+ *                                                                  *
+ ********************************************************************
+
+  function: packing variable sized words into an octet stream
+
+ ********************************************************************/
+
+/* We're 'LSb' endian; if we write a word but read individual bits,
+   then we'll read the lsb first */
+
+#include <string.h>
+#include <stdlib.h>
+#include "ogg.h"
+
+#define BUFFER_INCREMENT 256
+
+static unsigned long mask[]=
+{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
+ 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
+ 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
+ 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
+ 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
+ 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
+ 0x3fffffff,0x7fffffff,0xffffffff };
+
+void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
+  memset(b,0,sizeof(*b));
+  b->buffer=b->ptr=buf;
+  b->storage=bytes;
+}
+
+/* Read in bits without advancing the bitptr; bits <= 32 */
+long oggpack_look(oggpack_buffer *b,int bits){
+  unsigned long ret;
+  unsigned long m=mask[bits];
+
+  bits+=b->endbit;
+
+  if(b->endbyte+4>=b->storage){
+    /* not the main path */
+    if(b->endbyte*8+bits>b->storage*8)return(-1);
+  }
+  
+  ret=b->ptr[0]>>b->endbit;
+  if(bits>8){
+    ret|=b->ptr[1]<<(8-b->endbit);  
+    if(bits>16){
+      ret|=b->ptr[2]<<(16-b->endbit);  
+      if(bits>24){
+	ret|=b->ptr[3]<<(24-b->endbit);  
+	if(bits>32 && b->endbit)
+	  ret|=b->ptr[4]<<(32-b->endbit);
+      }
+    }
+  }
+  return(m&ret);
+}
+
+long oggpack_look1(oggpack_buffer *b){
+  if(b->endbyte>=b->storage)return(-1);
+  return((b->ptr[0]>>b->endbit)&1);
+}
+
+void oggpack_adv(oggpack_buffer *b,int bits){
+  bits+=b->endbit;
+  b->ptr+=bits/8;
+  b->endbyte+=bits/8;
+  b->endbit=bits&7;
+}
+
+void oggpack_adv1(oggpack_buffer *b){
+  if(++(b->endbit)>7){
+    b->endbit=0;
+    b->ptr++;
+    b->endbyte++;
+  }
+}
+
+/* bits <= 32 */
+long oggpack_read(oggpack_buffer *b,int bits){
+  unsigned long ret;
+  unsigned long m=mask[bits];
+
+  bits+=b->endbit;
+
+  if(b->endbyte+4>=b->storage){
+    /* not the main path */
+    ret=-1UL;
+    if(b->endbyte*8+bits>b->storage*8)goto overflow;
+  }
+  
+  ret=b->ptr[0]>>b->endbit;
+  if(bits>8){
+    ret|=b->ptr[1]<<(8-b->endbit);  
+    if(bits>16){
+      ret|=b->ptr[2]<<(16-b->endbit);  
+      if(bits>24){
+	ret|=b->ptr[3]<<(24-b->endbit);  
+	if(bits>32 && b->endbit){
+	  ret|=b->ptr[4]<<(32-b->endbit);
+	}
+      }
+    }
+  }
+  ret&=m;
+  
+ overflow:
+
+  b->ptr+=bits/8;
+  b->endbyte+=bits/8;
+  b->endbit=bits&7;
+  return(ret);
+}
+
+long oggpack_read1(oggpack_buffer *b){
+  unsigned long ret;
+  
+  if(b->endbyte>=b->storage){
+    /* not the main path */
+    ret=-1UL;
+    goto overflow;
+  }
+
+  ret=(b->ptr[0]>>b->endbit)&1;
+  
+ overflow:
+
+  b->endbit++;
+  if(b->endbit>7){
+    b->endbit=0;
+    b->ptr++;
+    b->endbyte++;
+  }
+  return(ret);
+}
+
+#undef BUFFER_INCREMENT