added readu32().
[swftools.git] / src / bitio.c
1 /* bitio.c 
2    Various routines for reading and writing bit- and bytewise, from and to memory.
3
4    Part of the swftools package.
5    
6    Copyright (c) 2001 Matthias Kramm <kramm@quiss.org> 
7
8    This file is distributed under the GPL, see file COPYING for details */
9
10 #include "bitio.h"
11
12 static uchar*data;
13 static int datalength;
14 static int datapos;
15
16 void resetbits();
17
18 void reader_init(uchar*newdata, int newlength)
19 {
20     data = newdata;
21     datalength = newlength;
22     datapos = 0;
23     resetbits();
24 }
25 void skip(int length)
26 {
27     datapos += length;
28 }
29 static u8 bitpos=8,mybyte;
30 static u8 bitmem=0;
31 void resetbits()
32 {
33     bitpos=8;
34 }
35
36 void input1(void*target)
37 {
38     *(uchar*)target = *(uchar*)&data[datapos];
39     datapos ++;
40 }
41 void input2(void*target)
42 {
43     *(unsigned short int*)target = *(unsigned short int*)&data[datapos];
44     datapos += 2;
45 }
46 void input4(void*target)
47 {
48     *(unsigned int*)target = *(unsigned int*)&data[datapos];
49     datapos += 4;
50 }
51 uchar*getinputpos()
52 {
53     return &data[datapos];
54 }
55 int getinputlength()
56 {
57     return datalength;
58 }
59 void setinputpos(uchar*pos)
60 {
61     datapos = pos-data;
62 }
63
64 u32 readbit()
65 {
66     if(bitpos==8) 
67     {
68         bitpos=0;
69         input1(&mybyte);
70     }
71     return (mybyte>>(7-bitpos++))&1;
72 }
73 void readbits(u32*val,int num)
74 {
75     int t;
76     *val=0;
77     for(t=0;t<num;t++)
78     {
79         *val<<=1;
80         *val|=readbit();
81     }
82 }
83
84 void readsbits(s32*val,int num)
85 {
86     u32 x;
87     readbits(&x, num);
88     if((x>>(num-1))&1)
89     {
90         x|=(0xffffffff<<num);
91     }
92     *(s32*)val=x;
93 }
94
95 u32 getbits(int num)
96 {
97     u32 x;
98     readbits(&x,num);
99     return x;
100 }
101
102 s32 getsbits(int num)
103 {
104     s32 x;
105     readsbits(&x,num);
106     return x;
107 }
108
109 u8 readu8()
110 {
111     u8 a;
112     input1(&a);
113     return a;
114 }
115
116 u16 readu16()
117 {
118     u8 a,b;
119     input1(&a);
120     input1(&b);
121     return ((u16)b)*256+a;
122 }
123
124 u32 readu32()
125 {
126     u8 a,b,c,d;
127     input1(&a);
128     input1(&b);
129     input1(&c);
130     input1(&d);
131     return (((((u32)d)*256+(u32)c)*256+(u32)b)*256+(u32)a);
132 }
133
134 void writer_init(struct writer_t*w, u8*data, int maxlength)
135 {
136     w->data = data;
137     w->maxlength = maxlength;
138     w->pos = 0;
139     w->bitpos = 0;
140     w->mybyte = 0;
141 }
142
143 void writer_write(struct writer_t*w, void*data, int length)
144 {
145     memcpy(&w->data[w->pos], data, length);
146     w->pos += length;
147 }
148
149 void writer_writeu8(struct writer_t*w, u8 value)
150 {
151     writer_resetbits(w);
152     writer_write(w, &value, 1);
153 }
154
155 void writer_writeu16(struct writer_t*w, u16 value)
156 {
157     writer_resetbits(w);
158     writer_write(w, &value, 2);
159 }
160
161 void* writer_getpos(struct writer_t*w)
162 {
163     return &w->data[w->pos];
164 }
165
166 void writer_resetbits(struct writer_t*w)
167 {
168     if(w->bitpos)
169         writer_write(w, &w->mybyte, 1);
170     w->bitpos = 0;
171     w->mybyte = 0;
172 }
173
174 void writer_writebit(struct writer_t*w, int bit)
175 {    
176     if(w->bitpos==8) 
177     {
178         writer_write(w, &w->mybyte, 1);
179         w->bitpos = 0;
180         w->mybyte = 0;
181     }
182     if(bit&1)
183         w->mybyte |= 1 << (7 - w->bitpos);
184     w->bitpos ++;
185 }
186
187 void writer_writebits(struct writer_t*w, u32 data, int bits)
188 {
189     int t;
190     for(t=0;t<bits;t++)
191     {
192         writer_writebit(w, (data >> (bits-t-1))&1);
193     }
194 }
195