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 */
16 #include "../config.h"
20 #define ZLIB_BUFFER_SIZE 16384
40 struct reader_t*input;
41 unsigned char readbuffer[ZLIB_BUFFER_SIZE];
49 struct writer_t*output;
50 unsigned char writebuffer[ZLIB_BUFFER_SIZE];
54 void reader_resetbits(struct reader_t*r)
61 static int reader_zlibinflate(struct reader_t*reader, void* data, int len);
62 static int reader_fileread(struct reader_t*reader, void* data, int len);
63 static int reader_memread(struct reader_t*reader, void* data, int len);
65 static void zlib_error(int ret, char* msg, z_stream*zs);
68 void reader_init_filereader(struct reader_t*r, int handle)
70 r->read = reader_fileread;
71 r->internal = (void*)handle;
72 r->type = READER_TYPE_FILE;
78 void reader_init_memreader(struct reader_t*r, void*newdata, int newlength)
80 struct memread_t*mr = malloc(sizeof(struct memread_t));
82 mr->length = newlength;
83 r->read = reader_memread;
84 r->internal = (void*)mr;
85 r->type = READER_TYPE_MEM;
91 void reader_init_zlibinflate(struct reader_t*r, struct reader_t*input)
94 struct zlibinflate_t*z;
96 memset(r, 0, sizeof(struct reader_t));
97 z = (struct zlibinflate_t*)malloc(sizeof(struct zlibinflate_t));
98 memset(z, 0, sizeof(struct zlibinflate_t));
100 r->read = reader_zlibinflate;
101 r->type = READER_TYPE_ZLIB;
104 memset(&z->zs,0,sizeof(z_stream));
105 z->zs.zalloc = Z_NULL;
106 z->zs.zfree = Z_NULL;
107 z->zs.opaque = Z_NULL;
108 ret = inflateInit(&z->zs);
109 if (ret != Z_OK) zlib_error(ret, "bitio:inflate_init", &z->zs);
112 fprintf(stderr, "Error: swftools was compiled without zlib support");
117 static void zlib_error(int ret, char* msg, z_stream*zs)
119 fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n",
122 zs->msg?zs->msg:"unknown");
128 static int reader_fileread(struct reader_t*reader, void* data, int len)
130 int ret = read((int)reader->internal, data, len);
136 static int reader_memread(struct reader_t*reader, void* data, int len)
138 struct memread_t*mr = (struct memread_t*)reader->internal;
140 if(mr->length - reader->pos > len) {
141 memcpy(data, &mr->data[reader->pos], len);
145 memcpy(data, &mr->data[reader->pos], mr->length - reader->pos);
146 reader->pos = mr->length;
147 return mr->length - reader->pos;
151 static int reader_zlibinflate(struct reader_t*reader, void* data, int len)
154 struct zlibinflate_t*z = (struct zlibinflate_t*)reader->internal;
159 z->zs.next_out = data;
160 z->zs.avail_out = len;
163 if(!z->zs.avail_in) {
164 z->zs.avail_in = z->input->read(z->input, z->readbuffer, ZLIB_BUFFER_SIZE);
165 z->zs.next_in = z->readbuffer;
168 ret = inflate(&z->zs, Z_NO_FLUSH);
170 ret = inflate(&z->zs, Z_FINISH);
173 ret != Z_STREAM_END) zlib_error(ret, "bitio:inflate_inflate", &z->zs);
175 if (ret == Z_STREAM_END) {
176 int pos = z->zs.next_out - (Bytef*)data;
177 ret = inflateEnd(&z->zs);
178 if (ret != Z_OK) zlib_error(ret, "bitio:inflate_end", &z->zs);
179 free(reader->internal);
180 reader->internal = 0;
184 if(!z->zs.avail_out) {
191 fprintf(stderr, "Error: swftools was compiled without zlib support");
195 unsigned int reader_readbit(struct reader_t*r)
200 r->read(r, &r->mybyte, 1);
202 return (r->mybyte>>(7-r->bitpos++))&1;
204 unsigned int reader_readbits(struct reader_t*r, int num)
211 val|=reader_readbit(r);
216 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len);
217 static void writer_zlibdeflate_finish(struct writer_t*writer);
218 static int writer_filewrite_write(struct writer_t*w, void* data, int len);
219 static void writer_filewrite_finish(struct writer_t*w);
221 static int writer_filewrite_write(struct writer_t*w, void* data, int len)
223 return write((int)w->internal, data, len);
225 static void writer_filewrite_finish(struct writer_t*w)
229 static int writer_memwrite_write(struct writer_t*w, void* data, int len)
231 struct memread_t*mw = (struct memread_t*)w->internal;
232 if(mw->length - w->pos > len) {
233 memcpy(&mw->data[w->pos], data, len);
237 memcpy(&mw->data[w->pos], data, mw->length - w->pos);
239 return mw->length - w->pos;
242 static void writer_memwrite_finish(struct writer_t*w)
247 void writer_resetbits(struct writer_t*w)
250 w->write(w, &w->mybyte, 1);
254 void writer_init_filewriter(struct writer_t*w, int handle)
256 memset(w, 0, sizeof(struct writer_t));
257 w->write = writer_filewrite_write;
258 w->finish = writer_filewrite_finish;
259 w->internal = (void*)handle;
260 w->type = WRITER_TYPE_FILE;
265 void writer_init_memwriter(struct writer_t*w, void*data, int len)
267 struct memwrite_t *mr;
268 mr = malloc(sizeof(struct memwrite_t));
271 memset(w, 0, sizeof(struct writer_t));
272 w->write = writer_memwrite_write;
273 w->finish = writer_memwrite_finish;
274 w->internal = (void*)mr;
275 w->type = WRITER_TYPE_FILE;
281 void writer_init_zlibdeflate(struct writer_t*w, struct writer_t*output)
284 struct zlibdeflate_t*z;
286 memset(w, 0, sizeof(struct writer_t));
287 z = (struct zlibdeflate_t*)malloc(sizeof(struct zlibdeflate_t));
288 memset(z, 0, sizeof(struct zlibdeflate_t));
290 w->write = writer_zlibdeflate_write;
291 w->finish = writer_zlibdeflate_finish;
292 w->type = WRITER_TYPE_ZLIB;
295 memset(&z->zs,0,sizeof(z_stream));
296 z->zs.zalloc = Z_NULL;
297 z->zs.zfree = Z_NULL;
298 z->zs.opaque = Z_NULL;
299 ret = deflateInit(&z->zs, 9);
300 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_init", &z->zs);
303 z->zs.next_out = z->writebuffer;
304 z->zs.avail_out = ZLIB_BUFFER_SIZE;
306 fprintf(stderr, "Error: swftools was compiled without zlib support");
310 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len)
313 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
318 z->zs.next_in = data;
319 z->zs.avail_in = len;
322 ret = deflate(&z->zs, Z_NO_FLUSH);
324 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
326 if(z->zs.next_out != z->writebuffer) {
327 z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
328 z->zs.next_out = z->writebuffer;
329 z->zs.avail_out = ZLIB_BUFFER_SIZE;
332 if(!z->zs.avail_in) {
339 fprintf(stderr, "Error: swftools was compiled without zlib support");
343 static void writer_zlibdeflate_finish(struct writer_t*writer)
346 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
347 struct writer_t*output;
353 ret = deflate(&z->zs, Z_FINISH);
355 ret != Z_STREAM_END) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
357 if(z->zs.next_out != z->writebuffer) {
358 z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
359 z->zs.next_out = z->writebuffer;
360 z->zs.avail_out = ZLIB_BUFFER_SIZE;
363 if (ret == Z_STREAM_END) {
368 ret = deflateEnd(&z->zs);
369 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_end", &z->zs);
370 free(writer->internal);
371 writer->internal = 0;
372 output->finish(output);
374 fprintf(stderr, "Error: swftools was compiled without zlib support");
379 void writer_writebit(struct writer_t*w, int bit)
383 w->write(w, &w->mybyte, 1);
388 w->mybyte |= 1 << (7 - w->bitpos);
391 void writer_writebits(struct writer_t*w, unsigned int data, int bits)
396 writer_writebit(w, (data >> (bits-t-1))&1);