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
35 struct reader_t*input;
36 unsigned char readbuffer[ZLIB_BUFFER_SIZE];
42 struct writer_t*output;
43 unsigned char writebuffer[ZLIB_BUFFER_SIZE];
46 void reader_resetbits(struct reader_t*r)
53 static int reader_zlibinflate(struct reader_t*reader, void* data, int len);
54 static int reader_fileread(struct reader_t*reader, void* data, int len);
55 static int reader_memread(struct reader_t*reader, void* data, int len);
56 static void zlib_error(int ret, char* msg, z_stream*zs);
58 void reader_init_filereader(struct reader_t*r, int handle)
60 r->read = reader_fileread;
61 r->internal = (void*)handle;
62 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;
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;
90 memset(&z->zs,0,sizeof(z_stream));
91 z->zs.zalloc = Z_NULL;
93 z->zs.opaque = Z_NULL;
94 ret = inflateInit(&z->zs);
95 if (ret != Z_OK) zlib_error(ret, "bitio:inflate_init", &z->zs);
99 static void zlib_error(int ret, char* msg, z_stream*zs)
101 fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n",
104 zs->msg?zs->msg:"unknown");
109 static int reader_fileread(struct reader_t*reader, void* data, int len)
111 return read((int)reader->internal, data, len);
114 static int reader_memread(struct reader_t*reader, void* data, int len)
116 struct memread_t*mr = (struct memread_t*)reader->internal;
118 if(mr->length - mr->pos > len) {
119 memcpy(data, &mr->data[mr->pos], len);
123 memcpy(data, &mr->data[mr->pos], mr->length - mr->pos);
124 mr->pos = mr->length;
125 return mr->length - mr->pos;
129 static int reader_zlibinflate(struct reader_t*reader, void* data, int len)
131 struct zlibinflate_t*z = (struct zlibinflate_t*)reader->internal;
136 z->zs.next_out = data;
137 z->zs.avail_out = len;
140 if(!z->zs.avail_in) {
141 z->zs.avail_in = z->input->read(z->input, z->readbuffer, ZLIB_BUFFER_SIZE);
142 z->zs.next_in = z->readbuffer;
145 ret = inflate(&z->zs, Z_NO_FLUSH);
147 ret = inflate(&z->zs, Z_FINISH);
150 ret != Z_STREAM_END) zlib_error(ret, "bitio:inflate_inflate", &z->zs);
152 if (ret == Z_STREAM_END) {
153 int pos = z->zs.next_out - (Bytef*)data;
154 ret = inflateEnd(&z->zs);
155 if (ret != Z_OK) zlib_error(ret, "bitio:inflate_end", &z->zs);
156 free(reader->internal);
157 reader->internal = 0;
160 if(!z->zs.avail_out) {
166 unsigned int reader_readbit(struct reader_t*r)
171 r->read(r, &r->mybyte, 1);
173 return (r->mybyte>>(7-r->bitpos++))&1;
175 unsigned int reader_readbits(struct reader_t*r, int num)
182 val|=reader_readbit(r);
187 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len);
188 static void writer_zlibdeflate_finish(struct writer_t*writer);
189 static int writer_filewrite_write(struct writer_t*w, void* data, int len);
190 static void writer_filewrite_finish(struct writer_t*w);
192 static int writer_filewrite_write(struct writer_t*w, void* data, int len)
194 return write((int)w->internal, data, len);
196 static void writer_filewrite_finish(struct writer_t*w)
200 static int writer_memwrite_write(struct writer_t*w, void* data, int len)
202 struct memread_t*mw = (struct memread_t*)w->internal;
203 if(mw->length - mw->pos > len) {
204 memcpy(&mw->data[mw->pos], data, len);
208 memcpy(&mw->data[mw->pos], data, mw->length - mw->pos);
209 mw->pos = mw->length;
210 return mw->length - mw->pos;
213 static void writer_memwrite_finish(struct writer_t*w)
218 void writer_resetbits(struct writer_t*w)
221 w->write(w, &w->mybyte, 1);
225 void writer_init_filewriter(struct writer_t*w, int handle)
227 memset(w, 0, sizeof(struct writer_t));
228 w->write = writer_filewrite_write;
229 w->finish = writer_filewrite_finish;
230 w->internal = (void*)handle;
231 w->type = WRITER_TYPE_FILE;
235 void writer_init_memwriter(struct writer_t*w, void*data, int len)
237 struct memwrite_t *mr;
238 mr = malloc(sizeof(struct memwrite_t));
241 memset(w, 0, sizeof(struct writer_t));
242 w->write = writer_memwrite_write;
243 w->finish = writer_memwrite_finish;
244 w->internal = (void*)mr;
245 w->type = WRITER_TYPE_FILE;
250 void writer_init_zlibdeflate(struct writer_t*w, struct writer_t*output)
252 struct zlibdeflate_t*z;
254 memset(w, 0, sizeof(struct writer_t));
255 z = (struct zlibdeflate_t*)malloc(sizeof(struct zlibdeflate_t));
256 memset(z, 0, sizeof(struct zlibdeflate_t));
258 w->write = writer_zlibdeflate_write;
259 w->finish = writer_zlibdeflate_finish;
260 w->type = WRITER_TYPE_ZLIB;
262 memset(&z->zs,0,sizeof(z_stream));
263 z->zs.zalloc = Z_NULL;
264 z->zs.zfree = Z_NULL;
265 z->zs.opaque = Z_NULL;
266 ret = deflateInit(&z->zs, 9);
267 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_init", &z->zs);
270 z->zs.next_out = z->writebuffer;
271 z->zs.avail_out = ZLIB_BUFFER_SIZE;
273 static int writer_zlibdeflate_write(struct writer_t*writer, void* data, int len)
275 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
280 z->zs.next_in = data;
281 z->zs.avail_in = len;
284 ret = deflate(&z->zs, Z_NO_FLUSH);
286 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
288 if(z->zs.next_out != z->writebuffer) {
289 z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
290 z->zs.next_out = z->writebuffer;
291 z->zs.avail_out = ZLIB_BUFFER_SIZE;
294 if(!z->zs.avail_in) {
300 static void writer_zlibdeflate_finish(struct writer_t*writer)
302 struct zlibdeflate_t*z = (struct zlibdeflate_t*)writer->internal;
303 struct writer_t*output;
309 ret = deflate(&z->zs, Z_FINISH);
311 ret != Z_STREAM_END) zlib_error(ret, "bitio:deflate_deflate", &z->zs);
313 if(z->zs.next_out != z->writebuffer) {
314 z->output->write(z->output, z->writebuffer, z->zs.next_out - (Bytef*)z->writebuffer);
315 z->zs.next_out = z->writebuffer;
316 z->zs.avail_out = ZLIB_BUFFER_SIZE;
319 if (ret == Z_STREAM_END) {
324 ret = deflateEnd(&z->zs);
325 if (ret != Z_OK) zlib_error(ret, "bitio:deflate_end", &z->zs);
326 free(writer->internal);
327 writer->internal = 0;
328 output->finish(output);
331 void writer_writebit(struct writer_t*w, int bit)
335 w->write(w, &w->mybyte, 1);
340 w->mybyte |= 1 << (7 - w->bitpos);
343 void writer_writebits(struct writer_t*w, unsigned int data, int bits)
348 writer_writebit(w, (data >> (bits-t-1))&1);