brought up to date
[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 u16 readu8()
110 {
111     u8 a;
112     input1(&a);
113     return a;
114 }
115
116 u16 readu16()
117 {
118     u8 a,b;
119     // I'm not using input2(&a) here because our input is
120     // little endian.
121     input1(&a);
122     input1(&b);
123     return ((u16)b)*256+a;
124 }
125
126 void writer_init(struct writer_t*w, u8*data, int maxlength)
127 {
128     w->data = data;
129     w->maxlength = maxlength;
130     w->pos = 0;
131     w->bitpos = 0;
132     w->mybyte = 0;
133 }
134
135 void writer_write(struct writer_t*w, void*data, int length)
136 {
137     memcpy(&w->data[w->pos], data, length);
138     w->pos += length;
139 }
140
141 void writer_writeu8(struct writer_t*w, u8 value)
142 {
143     writer_resetbits(w);
144     writer_write(w, &value, 1);
145 }
146
147 void writer_writeu16(struct writer_t*w, u16 value)
148 {
149     writer_resetbits(w);
150     writer_write(w, &value, 2);
151 }
152
153 void* writer_getpos(struct writer_t*w)
154 {
155     return &w->data[w->pos];
156 }
157
158 void writer_resetbits(struct writer_t*w)
159 {
160     if(w->bitpos)
161         writer_write(w, &w->mybyte, 1);
162     w->bitpos = 0;
163     w->mybyte = 0;
164 }
165
166 void writer_writebit(struct writer_t*w, int bit)
167 {    
168     if(w->bitpos==8) 
169     {
170         writer_write(w, &w->mybyte, 1);
171         w->bitpos = 0;
172         w->mybyte = 0;
173     }
174     if(bit&1)
175         w->mybyte |= 1 << (7 - w->bitpos);
176     w->bitpos ++;
177 }
178
179 void writer_writebits(struct writer_t*w, u32 data, int bits)
180 {
181     int t;
182     for(t=0;t<bits;t++)
183     {
184         writer_writebit(w, (data >> (bits-t-1))&1);
185     }
186 }
187