8a494b26b6a9ee9e41bfec4d863b0ce808564090
[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
13 void reader_init(struct reader_t*r, uchar*newdata, int newlength)
14 {
15     r->data = newdata;
16     r->datalength = newlength;
17     r->datapos = 0;
18     reader_resetbits(r);
19 }
20 void reader_skip(struct reader_t*r, int length)
21 {
22     r->datapos += length;
23 }
24 void reader_resetbits(struct reader_t*r)
25 {
26     r->bitpos = 8;
27 }
28
29 void reader_input1(struct reader_t*r, void*target)
30 {
31     *(uchar*)target = *(uchar*)&r->data[r->datapos];
32     r->datapos ++;
33 }
34 void reader_input2(struct reader_t*r, void*target)
35 {
36     *(unsigned short int*)target = *(unsigned short int*)&r->data[r->datapos];
37     r->datapos += 2;
38 }
39 void reader_input4(struct reader_t*r, void*target)
40 {
41     *(unsigned int*)target = *(unsigned int*)&r->data[r->datapos];
42     r->datapos += 4;
43 }
44 uchar*reader_getinputpos(struct reader_t*r)
45 {
46     return &r->data[r->datapos];
47 }
48 int reader_getinputlength(struct reader_t*r)
49 {
50     return r->datalength;
51 }
52 void reader_setinputpos(struct reader_t*r, uchar*pos)
53 {
54     r->datapos = pos-r->data;
55 }
56 u32 reader_readbit(struct reader_t*r)
57 {
58     if(r->bitpos==8) 
59     {
60         r->bitpos=0;
61         reader_input1(r, &r->mybyte);
62     }
63     return (r->mybyte>>(7-r->bitpos++))&1;
64 }
65 void reader_readbits(struct reader_t*r, u32*val,int num)
66 {
67     int t;
68     *val=0;
69     for(t=0;t<num;t++)
70     {
71         *val<<=1;
72         *val|=reader_readbit(r);
73     }
74 }
75
76 void reader_readsbits(struct reader_t*r, s32*val,int num)
77 {
78     u32 x;
79     reader_readbits(r, &x, num);
80     if((x>>(num-1))&1)
81     {
82         x|=(0xffffffff<<num);
83     }
84     *(s32*)val=x;
85 }
86
87 u32 reader_getbits(struct reader_t*r, int num)
88 {
89     u32 x;
90     reader_readbits(r,&x,num);
91     return x;
92 }
93
94 s32 reader_getsbits(struct reader_t*r, int num)
95 {
96     s32 x;
97     reader_readsbits(r, &x,num);
98     return x;
99 }
100
101 u8 reader_readu8(struct reader_t*r)
102 {
103     u8 a;
104     reader_input1(r, &a);
105     return a;
106 }
107
108 u16 reader_readu16(struct reader_t*r)
109 {
110     u8 a,b;
111     reader_input1(r, &a);
112     reader_input1(r, &b);
113     return ((u16)b)*256+a;
114 }
115
116 u32 reader_readu32(struct reader_t*r)
117 {
118     u8 a,b,c,d;
119     reader_input1(r, &a);
120     reader_input1(r, &b);
121     reader_input1(r, &c);
122     reader_input1(r, &d);
123     return (((((u32)d)*256+(u32)c)*256+(u32)b)*256+(u32)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_writeu32(struct writer_t*w, u32 value)
154 {
155     writer_resetbits(w);
156     writer_write(w, &value, 4);
157 }
158
159 void* writer_getpos(struct writer_t*w)
160 {
161     return &w->data[w->pos];
162 }
163
164 void writer_resetbits(struct writer_t*w)
165 {
166     if(w->bitpos)
167         writer_write(w, &w->mybyte, 1);
168     w->bitpos = 0;
169     w->mybyte = 0;
170 }
171
172 void writer_writebit(struct writer_t*w, int bit)
173 {    
174     if(w->bitpos==8) 
175     {
176         writer_write(w, &w->mybyte, 1);
177         w->bitpos = 0;
178         w->mybyte = 0;
179     }
180     if(bit&1)
181         w->mybyte |= 1 << (7 - w->bitpos);
182     w->bitpos ++;
183 }
184
185 void writer_writebits(struct writer_t*w, u32 data, int bits)
186 {
187     int t;
188     for(t=0;t<bits;t++)
189     {
190         writer_writebit(w, (data >> (bits-t-1))&1);
191     }
192 }
193