14280
|
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
|