made bitio visible from outside.
[swftools.git] / lib / bitio.c
1 /* bitio.c
2    implementation of bitio.h.
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 */#include <stdio.h>
9
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <fcntl.h>
13 #include <zlib.h>
14 #include "./bitio.h"
15
16 #define ZLIB_BUFFER_SIZE 16384
17
18 struct memread_t
19 {
20     unsigned char*data;
21     int pos;
22     int length;
23 };
24
25 struct memwrite_t
26 {
27     unsigned char*data;
28     int pos;
29     int length;
30 };
31
32 struct zlibinflate_t
33 {
34     z_stream zs;
35     struct reader_t*input;
36     unsigned char readbuffer[ZLIB_BUFFER_SIZE];
37 };
38
39 struct zlibdeflate_t
40 {
41     z_stream zs;
42     struct writer_t*output;
43     unsigned char writebuffer[ZLIB_BUFFER_SIZE];
44 };
45
46 void reader_resetbits(struct reader_t*r)
47 {
48     r->mybyte = 0;
49     r->bitpos = 8;
50
51 }
52
53 static int reader_zlibinflate(struct reader_t*reader, void* data, int len);
54 static int reader_fileread(struct reader_t*reader, void* data, int len);
55 static int reader_memread(struct reader_t*reader, void* data, int len);
56 static void zlib_error(int ret, char* msg, z_stream*zs);
57
58 void reader_init_filereader(struct reader_t*r, int handle)
59 {
60     r->read = reader_fileread;
61     r->internal = (void*)handle;
62     r->type = READER_TYPE_FILE;
63     r->mybyte = 0;
64     r->bitpos = 8;
65 }
66
67 void reader_init_memreader(struct reader_t*r, void*newdata, int newlength)
68 {
69     struct memread_t*mr = malloc(sizeof(struct memread_t));
70     mr->data = newdata;
71     mr->length = newlength;
72     r->read = reader_memread;
73     r->internal = (void*)mr;
74     r->type = READER_TYPE_MEM;
75     r->mybyte = 0;
76     r->bitpos = 8;
77 }
78
79 void reader_init_zlibinflate(struct reader_t*r, struct reader_t*input)
80 {
81     struct zlibinflate_t*z;
82     int ret;
83     memset(r, 0, sizeof(struct reader_t));
84     z = (struct zlibinflate_t*)malloc(sizeof(struct zlibinflate_t));
85     memset(z, 0, sizeof(struct zlibinflate_t));
86     r->internal = z;
87     r->read = reader_zlibinflate;
88     r->type = READER_TYPE_ZLIB;
89     z->input = input;
90     memset(&z->zs,0,sizeof(z_stream));
91     z->zs.zalloc = Z_NULL;
92     z->zs.zfree  = Z_NULL;
93     z->zs.opaque = Z_NULL;
94     ret = inflateInit(&z->zs);
95     if (ret != Z_OK) zlib_error(ret, "bitio:inflate_init", &z->zs);
96     reader_resetbits(r);
97 }
98
99 static void zlib_error(int ret, char* msg, z_stream*zs)
100 {
101     fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n",
102           msg,
103           ret,
104           zs->msg?zs->msg:"unknown");
105     perror("errno:");
106     exit(1);
107 }
108
109 static int reader_fileread(struct reader_t*reader, void* data, int len) 
110 {
111     return read((int)reader->internal, data, len);
112 }
113
114 static int reader_memread(struct reader_t*reader, void* data, int len) 
115 {
116     struct memread_t*mr = (struct memread_t*)reader->internal;
117
118     if(mr->length - mr->pos > len) {
119         memcpy(data, &mr->data[mr->pos], len);
120         mr->pos += len;
121         return len;
122     } else {
123         memcpy(data, &mr->data[mr->pos], mr->length - mr->pos);
124         mr->pos = mr->length;
125         return mr->length - mr->pos;
126     }
127 }
128
129 static int reader_zlibinflate(struct reader_t*reader, void* data, int len) 
130 {
131     struct zlibinflate_t*z = (struct zlibinflate_t*)reader->internal;
132     int ret;
133     if(!z)
134         return 0;
135     
136     z->zs.next_out = data;
137     z->zs.avail_out = len;
138
139     while(1) {
140         if(!z->zs.avail_in) {
141             z->zs.avail_in = z->input->read(z->input, z->readbuffer, ZLIB_BUFFER_SIZE);
142             z->zs.next_in = z->readbuffer;
143         }
144         if(z->zs.avail_in)
145             ret = inflate(&z->zs, Z_NO_FLUSH);
146         else
147             ret = inflate(&z->zs, Z_FINISH);
148     
149         if (ret != Z_OK &&
150             ret != Z_STREAM_END) zlib_error(ret, "bitio:inflate_inflate", &z->zs);
151
152         if (ret == Z_STREAM_END) {
153                 int pos = z->zs.next_out - (Bytef*)data;
154                 ret = inflateEnd(&z->zs);
155                 if (ret != Z_OK) zlib_error(ret, "bitio:inflate_end", &z->zs);
156                 free(reader->internal);
157                 reader->internal = 0;
158                 return pos;
159         }
160         if(!z->zs.avail_out) {
161             break;
162         }
163     }
164     return len;
165 }
166 unsigned int reader_readbit(struct reader_t*r)
167 {
168     if(r->bitpos==8) 
169     {
170         r->bitpos=0;
171         r->read(r, &r->mybyte, 1);
172     }
173     return (r->mybyte>>(7-r->bitpos++))&1;
174 }
175 unsigned int reader_readbits(struct reader_t*r, int num)
176 {
177     int t;
178     int val = 0;
179     for(t=0;t<num;t++)
180     {
181         val<<=1;
182         val|=reader_readbit(r);
183     }
184     return val;
185 }
186
187 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len);
188 static void writer_zlibdeflate_finish(struct writer_t*writer);
189 static int writer_filewrite_write(struct writer_t*w, void* data, int len);
190 static void writer_filewrite_finish(struct writer_t*w);
191
192 static int writer_filewrite_write(struct writer_t*w, void* data, int len) 
193 {
194     return write((int)w->internal, data, len);
195 }
196 static void writer_filewrite_finish(struct writer_t*w)
197 {
198 }
199
200 static int writer_memwrite_write(struct writer_t*w, void* data, int len) 
201 {
202     struct memread_t*mw = (struct memread_t*)w->internal;
203     if(mw->length - mw->pos > len) {
204         memcpy(&mw->data[mw->pos], data, len);
205         mw->pos += len;
206         return len;
207     } else {
208         memcpy(&mw->data[mw->pos], data, mw->length - mw->pos);
209         mw->pos = mw->length;
210         return mw->length - mw->pos;
211     }
212 }
213 static void writer_memwrite_finish(struct writer_t*w)
214 {
215     free(w->internal);
216 }
217
218 void writer_resetbits(struct writer_t*w)
219 {
220     if(w->bitpos)
221         w->write(w, &w->mybyte, 1);
222     w->bitpos = 0;
223     w->mybyte = 0;
224 }
225 void writer_init_filewriter(struct writer_t*w, int handle)
226 {
227     memset(w, 0, sizeof(struct writer_t));
228     w->write = writer_filewrite_write;
229     w->finish = writer_filewrite_finish;
230     w->internal = (void*)handle;
231     w->type = WRITER_TYPE_FILE;
232     w->bitpos = 0;
233     w->mybyte = 0;
234 }
235 void writer_init_memwriter(struct writer_t*w, void*data, int len)
236 {
237     struct memwrite_t *mr;
238     mr = malloc(sizeof(struct memwrite_t));
239     mr->data = data;
240     mr->length = len;
241     memset(w, 0, sizeof(struct writer_t));
242     w->write = writer_memwrite_write;
243     w->finish = writer_memwrite_finish;
244     w->internal = (void*)mr;
245     w->type = WRITER_TYPE_FILE;
246     w->bitpos = 0;
247     w->mybyte = 0;
248 }
249
250 void writer_init_zlibdeflate(struct writer_t*w, struct writer_t*output)
251 {
252     struct zlibdeflate_t*z;
253     int ret;
254     memset(w, 0, sizeof(struct writer_t));
255     z = (struct zlibdeflate_t*)malloc(sizeof(struct zlibdeflate_t));
256     memset(z, 0, sizeof(struct zlibdeflate_t));
257     w->internal = z;
258     w->write = writer_zlibdeflate_write;
259     w->finish = writer_zlibdeflate_finish;
260     w->type = WRITER_TYPE_ZLIB;
261     z->output = output;
262     memset(&z->zs,0,sizeof(z_stream));
263     z->zs.zalloc = Z_NULL;
264     z->zs.zfree  = Z_NULL;
265     z->zs.opaque = Z_NULL;
266     ret = deflateInit(&z->zs, 9);
267     if (ret != Z_OK) zlib_error(ret, "bitio:deflate_init", &z->zs);
268     w->bitpos = 0;
269     w->mybyte = 0;
270     z->zs.next_out = z->writebuffer;
271     z->zs.avail_out = ZLIB_BUFFER_SIZE;
272 }
273 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len) 
274 {
275     struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
276     int ret;
277     if(!z)
278         return 0;
279     
280     z->zs.next_in = data;
281     z->zs.avail_in = len;
282
283     while(1) {
284         ret = deflate(&z->zs, Z_NO_FLUSH);
285         
286         if (ret != Z_OK) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
287
288         if(z->zs.next_out != z->writebuffer) {
289             z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
290             z->zs.next_out = z->writebuffer;
291             z->zs.avail_out = ZLIB_BUFFER_SIZE;
292         }
293
294         if(!z->zs.avail_in) {
295             break;
296         }
297     }
298     return len;
299 }
300 static void writer_zlibdeflate_finish(struct writer_t*writer)
301 {
302     struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
303     struct writer_t*output;
304     int ret;
305     if(!z)
306         return;
307     output= z->output;
308     while(1) {
309         ret = deflate(&z->zs, Z_FINISH);
310         if (ret != Z_OK &&
311             ret != Z_STREAM_END) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
312
313         if(z->zs.next_out != z->writebuffer) {
314             z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
315             z->zs.next_out = z->writebuffer;
316             z->zs.avail_out = ZLIB_BUFFER_SIZE;
317         }
318
319         if (ret == Z_STREAM_END) {
320             break;
321
322         }
323     }
324     ret = deflateEnd(&z->zs);
325     if (ret != Z_OK) zlib_error(ret, "bitio:deflate_end", &z->zs);
326     free(writer->internal);
327     writer->internal = 0;
328     output->finish(output);
329 }
330
331 void writer_writebit(struct writer_t*w, int bit)
332 {    
333     if(w->bitpos==8) 
334     {
335         w->write(w, &w->mybyte, 1);
336         w->bitpos = 0;
337         w->mybyte = 0;
338     }
339     if(bit&1)
340         w->mybyte |= 1 << (7 - w->bitpos);
341     w->bitpos ++;
342 }
343 void writer_writebits(struct writer_t*w, unsigned int data, int bits)
344 {
345     int t;
346     for(t=0;t<bits;t++)
347     {
348         writer_writebit(w, (data >> (bits-t-1))&1);
349     }
350 }
351