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