2 implementation of bitio.h.
4 Part of the swftools package.
6 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
8 This file is distributed under the GPL, see file COPYING for details */#include <stdio.h>
16 #define ZLIB_BUFFER_SIZE 16384
33 struct reader_t*input;
34 unsigned char readbuffer[ZLIB_BUFFER_SIZE];
40 struct writer_t*output;
41 unsigned char writebuffer[ZLIB_BUFFER_SIZE];
44 void reader_resetbits(struct reader_t*r)
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);
56 void reader_init_filereader(struct reader_t*r, int handle)
58 r->read = reader_fileread;
59 r->internal = (void*)handle;
60 r->type = READER_TYPE_FILE;
66 void reader_init_memreader(struct reader_t*r, void*newdata, int newlength)
68 struct memread_t*mr = malloc(sizeof(struct memread_t));
70 mr->length = newlength;
71 r->read = reader_memread;
72 r->internal = (void*)mr;
73 r->type = READER_TYPE_MEM;
79 void reader_init_zlibinflate(struct reader_t*r, struct reader_t*input)
81 struct zlibinflate_t*z;
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));
87 r->read = reader_zlibinflate;
88 r->type = READER_TYPE_ZLIB;
91 memset(&z->zs,0,sizeof(z_stream));
92 z->zs.zalloc = 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);
100 static void zlib_error(int ret, char* msg, z_stream*zs)
102 fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n",
105 zs->msg?zs->msg:"unknown");
110 static int reader_fileread(struct reader_t*reader, void* data, int len)
112 int ret = read((int)reader->internal, data, len);
118 static int reader_memread(struct reader_t*reader, void* data, int len)
120 struct memread_t*mr = (struct memread_t*)reader->internal;
122 if(mr->length - reader->pos > len) {
123 memcpy(data, &mr->data[reader->pos], len);
127 memcpy(data, &mr->data[reader->pos], mr->length - reader->pos);
128 reader->pos = mr->length;
129 return mr->length - reader->pos;
133 static int reader_zlibinflate(struct reader_t*reader, void* data, int len)
135 struct zlibinflate_t*z = (struct zlibinflate_t*)reader->internal;
140 z->zs.next_out = data;
141 z->zs.avail_out = len;
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;
149 ret = inflate(&z->zs, Z_NO_FLUSH);
151 ret = inflate(&z->zs, Z_FINISH);
154 ret != Z_STREAM_END) zlib_error(ret, "bitio:inflate_inflate", &z->zs);
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;
165 if(!z->zs.avail_out) {
172 unsigned int reader_readbit(struct reader_t*r)
177 r->read(r, &r->mybyte, 1);
179 return (r->mybyte>>(7-r->bitpos++))&1;
181 unsigned int reader_readbits(struct reader_t*r, int num)
188 val|=reader_readbit(r);
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);
198 static int writer_filewrite_write(struct writer_t*w, void* data, int len)
200 return write((int)w->internal, data, len);
202 static void writer_filewrite_finish(struct writer_t*w)
206 static int writer_memwrite_write(struct writer_t*w, void* data, int len)
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);
214 memcpy(&mw->data[w->pos], data, mw->length - w->pos);
216 return mw->length - w->pos;
219 static void writer_memwrite_finish(struct writer_t*w)
224 void writer_resetbits(struct writer_t*w)
227 w->write(w, &w->mybyte, 1);
231 void writer_init_filewriter(struct writer_t*w, int handle)
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;
242 void writer_init_memwriter(struct writer_t*w, void*data, int len)
244 struct memwrite_t *mr;
245 mr = malloc(sizeof(struct memwrite_t));
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;
258 void writer_init_zlibdeflate(struct writer_t*w, struct writer_t*output)
260 struct zlibdeflate_t*z;
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));
266 w->write = writer_zlibdeflate_write;
267 w->finish = writer_zlibdeflate_finish;
268 w->type = WRITER_TYPE_ZLIB;
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);
279 z->zs.next_out = z->writebuffer;
280 z->zs.avail_out = ZLIB_BUFFER_SIZE;
282 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len)
284 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
289 z->zs.next_in = data;
290 z->zs.avail_in = len;
293 ret = deflate(&z->zs, Z_NO_FLUSH);
295 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
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;
303 if(!z->zs.avail_in) {
310 static void writer_zlibdeflate_finish(struct writer_t*writer)
312 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
313 struct writer_t*output;
319 ret = deflate(&z->zs, Z_FINISH);
321 ret != Z_STREAM_END) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
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;
329 if (ret == Z_STREAM_END) {
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);
341 void writer_writebit(struct writer_t*w, int bit)
345 w->write(w, &w->mybyte, 1);
350 w->mybyte |= 1 << (7 - w->bitpos);
353 void writer_writebits(struct writer_t*w, unsigned int data, int bits)
358 writer_writebit(w, (data >> (bits-t-1))&1);