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 */
17 #define ZLIB_BUFFER_SIZE 16384
34 struct reader_t*input;
35 unsigned char readbuffer[ZLIB_BUFFER_SIZE];
41 struct writer_t*output;
42 unsigned char writebuffer[ZLIB_BUFFER_SIZE];
45 void reader_resetbits(struct reader_t*r)
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);
57 void reader_init_filereader(struct reader_t*r, int handle)
59 r->read = reader_fileread;
60 r->internal = (void*)handle;
61 r->type = READER_TYPE_FILE;
67 void reader_init_memreader(struct reader_t*r, void*newdata, int newlength)
69 struct memread_t*mr = malloc(sizeof(struct memread_t));
71 mr->length = newlength;
72 r->read = reader_memread;
73 r->internal = (void*)mr;
74 r->type = READER_TYPE_MEM;
80 void reader_init_zlibinflate(struct reader_t*r, struct reader_t*input)
82 struct zlibinflate_t*z;
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));
88 r->read = reader_zlibinflate;
89 r->type = READER_TYPE_ZLIB;
92 memset(&z->zs,0,sizeof(z_stream));
93 z->zs.zalloc = 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);
101 static void zlib_error(int ret, char* msg, z_stream*zs)
103 fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n",
106 zs->msg?zs->msg:"unknown");
111 static int reader_fileread(struct reader_t*reader, void* data, int len)
113 int ret = read((int)reader->internal, data, len);
119 static int reader_memread(struct reader_t*reader, void* data, int len)
121 struct memread_t*mr = (struct memread_t*)reader->internal;
123 if(mr->length - reader->pos > len) {
124 memcpy(data, &mr->data[reader->pos], len);
128 memcpy(data, &mr->data[reader->pos], mr->length - reader->pos);
129 reader->pos = mr->length;
130 return mr->length - reader->pos;
134 static int reader_zlibinflate(struct reader_t*reader, void* data, int len)
136 struct zlibinflate_t*z = (struct zlibinflate_t*)reader->internal;
141 z->zs.next_out = data;
142 z->zs.avail_out = len;
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;
150 ret = inflate(&z->zs, Z_NO_FLUSH);
152 ret = inflate(&z->zs, Z_FINISH);
155 ret != Z_STREAM_END) zlib_error(ret, "bitio:inflate_inflate", &z->zs);
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;
166 if(!z->zs.avail_out) {
173 unsigned int reader_readbit(struct reader_t*r)
178 r->read(r, &r->mybyte, 1);
180 return (r->mybyte>>(7-r->bitpos++))&1;
182 unsigned int reader_readbits(struct reader_t*r, int num)
189 val|=reader_readbit(r);
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);
199 static int writer_filewrite_write(struct writer_t*w, void* data, int len)
201 return write((int)w->internal, data, len);
203 static void writer_filewrite_finish(struct writer_t*w)
207 static int writer_memwrite_write(struct writer_t*w, void* data, int len)
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);
215 memcpy(&mw->data[w->pos], data, mw->length - w->pos);
217 return mw->length - w->pos;
220 static void writer_memwrite_finish(struct writer_t*w)
225 void writer_resetbits(struct writer_t*w)
228 w->write(w, &w->mybyte, 1);
232 void writer_init_filewriter(struct writer_t*w, int handle)
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;
243 void writer_init_memwriter(struct writer_t*w, void*data, int len)
245 struct memwrite_t *mr;
246 mr = malloc(sizeof(struct memwrite_t));
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;
259 void writer_init_zlibdeflate(struct writer_t*w, struct writer_t*output)
261 struct zlibdeflate_t*z;
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));
267 w->write = writer_zlibdeflate_write;
268 w->finish = writer_zlibdeflate_finish;
269 w->type = WRITER_TYPE_ZLIB;
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);
280 z->zs.next_out = z->writebuffer;
281 z->zs.avail_out = ZLIB_BUFFER_SIZE;
283 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len)
285 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
290 z->zs.next_in = data;
291 z->zs.avail_in = len;
294 ret = deflate(&z->zs, Z_NO_FLUSH);
296 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
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;
304 if(!z->zs.avail_in) {
311 static void writer_zlibdeflate_finish(struct writer_t*writer)
313 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
314 struct writer_t*output;
320 ret = deflate(&z->zs, Z_FINISH);
322 ret != Z_STREAM_END) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
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;
330 if (ret == Z_STREAM_END) {
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);
342 void writer_writebit(struct writer_t*w, int bit)
346 w->write(w, &w->mybyte, 1);
351 w->mybyte |= 1 << (7 - w->bitpos);
354 void writer_writebits(struct writer_t*w, unsigned int data, int bits)
359 writer_writebit(w, (data >> (bits-t-1))&1);