annotate tremor/bitwise.c @ 14280:8631a3803289

internal Tremor decoder for Ogg/Vorbis
author henry
date Thu, 30 Dec 2004 12:11:32 +0000
parents
children e891ff7a7b6c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
1 /********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
2 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
4 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
5 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
6 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
7 * ALL REDISTRIBUTION RIGHTS RESERVED. *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
8 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
9 ********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
10
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
11 function: packing variable sized words into an octet stream
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
12
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
13 ********************************************************************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
14
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
15 /* We're 'LSb' endian; if we write a word but read individual bits,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
16 then we'll read the lsb first */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
17
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
18 #include <string.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
19 #include <stdlib.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
20 #include "ogg.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
21
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
22 #define BUFFER_INCREMENT 256
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
23
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
24 static unsigned long mask[]=
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
25 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
26 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
27 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
28 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
29 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
30 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
31 0x3fffffff,0x7fffffff,0xffffffff };
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
32
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
33 void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
34 memset(b,0,sizeof(*b));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
35 b->buffer=b->ptr=buf;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
36 b->storage=bytes;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
37 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
38
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
39 /* Read in bits without advancing the bitptr; bits <= 32 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
40 long oggpack_look(oggpack_buffer *b,int bits){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
41 unsigned long ret;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
42 unsigned long m=mask[bits];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
43
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
44 bits+=b->endbit;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
45
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
46 if(b->endbyte+4>=b->storage){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
47 /* not the main path */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
48 if(b->endbyte*8+bits>b->storage*8)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
49 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
50
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
51 ret=b->ptr[0]>>b->endbit;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
52 if(bits>8){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
53 ret|=b->ptr[1]<<(8-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
54 if(bits>16){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
55 ret|=b->ptr[2]<<(16-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
56 if(bits>24){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
57 ret|=b->ptr[3]<<(24-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
58 if(bits>32 && b->endbit)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
59 ret|=b->ptr[4]<<(32-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
60 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
61 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
62 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
63 return(m&ret);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
64 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
65
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
66 long oggpack_look1(oggpack_buffer *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
67 if(b->endbyte>=b->storage)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
68 return((b->ptr[0]>>b->endbit)&1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
69 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
70
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
71 void oggpack_adv(oggpack_buffer *b,int bits){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
72 bits+=b->endbit;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
73 b->ptr+=bits/8;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
74 b->endbyte+=bits/8;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
75 b->endbit=bits&7;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
76 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
77
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
78 void oggpack_adv1(oggpack_buffer *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
79 if(++(b->endbit)>7){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
80 b->endbit=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
81 b->ptr++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
82 b->endbyte++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
83 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
84 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
85
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
86 /* bits <= 32 */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
87 long oggpack_read(oggpack_buffer *b,int bits){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
88 unsigned long ret;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
89 unsigned long m=mask[bits];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
90
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
91 bits+=b->endbit;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
92
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
93 if(b->endbyte+4>=b->storage){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
94 /* not the main path */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
95 ret=-1UL;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
96 if(b->endbyte*8+bits>b->storage*8)goto overflow;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
97 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
98
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
99 ret=b->ptr[0]>>b->endbit;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
100 if(bits>8){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
101 ret|=b->ptr[1]<<(8-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
102 if(bits>16){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
103 ret|=b->ptr[2]<<(16-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
104 if(bits>24){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
105 ret|=b->ptr[3]<<(24-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
106 if(bits>32 && b->endbit){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
107 ret|=b->ptr[4]<<(32-b->endbit);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
108 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
109 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
110 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
111 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
112 ret&=m;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
113
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
114 overflow:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
115
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
116 b->ptr+=bits/8;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
117 b->endbyte+=bits/8;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
118 b->endbit=bits&7;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
119 return(ret);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
120 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
121
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
122 long oggpack_read1(oggpack_buffer *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
123 unsigned long ret;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
124
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
125 if(b->endbyte>=b->storage){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
126 /* not the main path */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
127 ret=-1UL;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
128 goto overflow;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
129 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
130
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
131 ret=(b->ptr[0]>>b->endbit)&1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
132
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
133 overflow:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
134
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
135 b->endbit++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
136 if(b->endbit>7){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
137 b->endbit=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
138 b->ptr++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
139 b->endbyte++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
140 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
141 return(ret);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
142 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
143
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
144 #undef BUFFER_INCREMENT