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