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