added zlib writer.
[swftools.git] / lib / bitio.c
1 #define READER_TYPE_FILE 0
2 #define READER_TYPE_MEM  1
3 #define READER_TYPE_ZLIB 2
4 #define WRITER_TYPE_FILE 0
5 #define WRITER_TYPE_MEM  1
6 #define WRITER_TYPE_ZLIB 2
7
8 struct reader_t
9 {
10     int (*read)(struct reader_t*, void*data, int len);
11     void *internal;
12     int type;
13     unsigned char mybyte;
14     unsigned char bitpos;
15 };
16 struct writer_t
17 {
18     int (*write)(struct writer_t*, void*data, int len);
19     void (*finish)();
20     void *internal;
21     int type;
22     unsigned char mybyte;
23     unsigned char bitpos;
24 };
25 static int reader_fileread(struct reader_t*reader, void* data, int len) 
26 {
27     return read((int)reader->internal, data, len);
28 }
29 static void reader_resetbits(struct reader_t*r)
30 {
31     r->mybyte = 0;
32     r->bitpos = 8;
33 }
34 static void reader_init_filereader(struct reader_t*r, int handle)
35 {
36     r->read = reader_fileread;
37     r->internal = (void*)handle;
38     r->type = READER_TYPE_FILE;
39     r->mybyte = 0;
40     r->bitpos = 8;
41 }
42 #define ZLIB_BUFFER_SIZE 16384
43 struct zlibinflate_t
44 {
45     z_stream zs;
46     struct reader_t*input;
47     U8 readbuffer[ZLIB_BUFFER_SIZE];
48 };
49 static void zlib_error(int ret, char* msg, z_stream*zs)
50 {
51     fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n",
52           msg,
53           ret,
54           zs->msg?zs->msg:"unknown");
55     perror("errno:");
56     exit(1);
57 }
58 static int reader_zlibinflate(struct reader_t*reader, void* data, int len);
59 static void reader_init_zlibinflate(struct reader_t*r, struct reader_t*input)
60 {
61     struct zlibinflate_t*z;
62     int ret;
63     z = (struct zlibinflate_t*)malloc(sizeof(struct zlibinflate_t));
64     r->internal = z;
65     r->read = reader_zlibinflate;
66     r->type = READER_TYPE_ZLIB;
67     z->input = input;
68     memset(&z->zs,0,sizeof(z_stream));
69     z->zs.zalloc = Z_NULL;
70     z->zs.zfree  = Z_NULL;
71     z->zs.opaque = Z_NULL;
72     ret = inflateInit(&z->zs);
73     if (ret != Z_OK) zlib_error(ret, "bitio:inflate_init", &z->zs);
74     reader_resetbits(r);
75 }
76 static int reader_zlibinflate(struct reader_t*reader, void* data, int len) 
77 {
78     struct zlibinflate_t*z = (struct zlibinflate_t*)reader->internal;
79     int ret;
80     if(!z)
81         return 0;
82     
83     z->zs.next_out = data;
84     z->zs.avail_out = len;
85
86     while(1) {
87         if(!z->zs.avail_in) {
88             z->zs.avail_in = z->input->read(z->input, z->readbuffer, ZLIB_BUFFER_SIZE);
89             z->zs.next_in = z->readbuffer;
90         }
91         if(z->zs.avail_in)
92             ret = inflate(&z->zs, Z_NO_FLUSH);
93         else
94             ret = inflate(&z->zs, Z_FINISH);
95     
96         if (ret != Z_OK &&
97             ret != Z_STREAM_END) zlib_error(ret, "bitio:inflate_inflate", &z->zs);
98
99         if (ret == Z_STREAM_END) {
100                 int pos = z->zs.next_out - (Bytef*)data;
101                 ret = inflateEnd(&z->zs);
102                 if (ret != Z_OK) zlib_error(ret, "bitio:inflate_end", &z->zs);
103                 free(reader->internal);
104                 reader->internal = 0;
105                 return pos;
106         }
107         if(!z->zs.avail_out) {
108             break;
109         }
110     }
111     return len;
112 }
113 static unsigned int reader_readbit(struct reader_t*r)
114 {
115     if(r->bitpos==8) 
116     {
117         r->bitpos=0;
118         r->read(r, &r->mybyte, 1);
119     }
120     return (r->mybyte>>(7-r->bitpos++))&1;
121 }
122 static unsigned int reader_readbits(struct reader_t*r, int num)
123 {
124     int t;
125     int val = 0;
126     for(t=0;t<num;t++)
127     {
128         val<<=1;
129         val|=reader_readbit(r);
130     }
131     return val;
132 }
133 static int writer_filewrite_write(struct writer_t*w, void* data, int len) 
134 {
135     return write((int)w->internal, data, len);
136 }
137 static void writer_filewrite_finish()
138 {
139 }
140 static void writer_resetbits(struct writer_t*w)
141 {
142     if(w->bitpos)
143         w->write(w, &w->mybyte, 1);
144     w->bitpos = 0;
145     w->mybyte = 0;
146 }
147 static void writer_init_filewriter(struct writer_t*w, int handle)
148 {
149     w->write = writer_filewrite_write;
150     w->finish = writer_filewrite_finish;
151     w->internal = (void*)handle;
152     w->type = WRITER_TYPE_FILE;
153     w->bitpos = 0;
154     w->mybyte = 0;
155 }
156 struct zlibdeflate_t
157 {
158     z_stream zs;
159     struct writer_t*output;
160     U8 writebuffer[ZLIB_BUFFER_SIZE];
161 };
162 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len);
163 static void writer_zlibdeflate_finish();
164 static void writer_init_zlibdeflate(struct writer_t*w, struct writer_t*output)
165 {
166     struct zlibdeflate_t*z;
167     int ret;
168     z = (struct zlibdeflate_t*)malloc(sizeof(struct zlibdeflate_t));
169     w->internal = z;
170     w->write = writer_zlibdeflate_write;
171     w->finish = writer_zlibdeflate_finish;
172     w->type = WRITER_TYPE_ZLIB;
173     z->output = output;
174     memset(&z->zs,0,sizeof(z_stream));
175     z->zs.zalloc = Z_NULL;
176     z->zs.zfree  = Z_NULL;
177     z->zs.opaque = Z_NULL;
178     ret = deflateInit(&z->zs, 9);
179     if (ret != Z_OK) zlib_error(ret, "bitio:deflate_init", &z->zs);
180     w->bitpos = 0;
181     w->mybyte = 0;
182     z->zs.next_out = z->writebuffer;
183     z->zs.avail_out = ZLIB_BUFFER_SIZE;
184 }
185 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len) 
186 {
187     struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
188     int ret;
189     if(!z)
190         return 0;
191     
192     z->zs.next_in = data;
193     z->zs.avail_in = len;
194
195     while(1) {
196         ret = deflate(&z->zs, Z_NO_FLUSH);
197         
198         if (ret != Z_OK) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
199
200         if(z->zs.next_out != z->writebuffer) {
201             z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
202             z->zs.next_out = z->writebuffer;
203             z->zs.avail_out = ZLIB_BUFFER_SIZE;
204         }
205
206         if(!z->zs.avail_in) {
207             break;
208         }
209     }
210     return len;
211 }
212 static void writer_zlibdeflate_finish(struct writer_t*writer)
213 {
214     struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
215     int ret;
216     if(!z)
217         return;
218     while(1) {
219         ret = deflate(&z->zs, Z_FINISH);
220         if (ret != Z_OK &&
221             ret != Z_STREAM_END) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
222
223         if(z->zs.next_out != z->writebuffer) {
224             z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
225             z->zs.next_out = z->writebuffer;
226             z->zs.avail_out = ZLIB_BUFFER_SIZE;
227         }
228
229         if (ret == Z_STREAM_END) {
230             break;
231
232         }
233     }
234     ret = deflateEnd(&z->zs);
235     if (ret != Z_OK) zlib_error(ret, "bitio:deflate_end", &z->zs);
236     free(writer->internal);
237     writer->internal = 0;
238 }
239
240 static void writer_writebit(struct writer_t*w, int bit)
241 {    
242     if(w->bitpos==8) 
243     {
244         w->write(w, &w->mybyte, 1);
245         w->bitpos = 0;
246         w->mybyte = 0;
247     }
248     if(bit&1)
249         w->mybyte |= 1 << (7 - w->bitpos);
250     w->bitpos ++;
251 }
252 static void writer_writebits(struct writer_t*w, U32 data, int bits)
253 {
254     int t;
255     for(t=0;t<bits;t++)
256     {
257         writer_writebit(w, (data >> (bits-t-1))&1);
258     }
259 }
260