From 1d053636d67cc0457784a20f1f7a3befce493e24 Mon Sep 17 00:00:00 2001 From: kramm Date: Sun, 21 Apr 2002 15:01:34 +0000 Subject: [PATCH] * from ../src/bitio.c - r/w routines are now replaceable ("virtual") * implemented zlib reader. --- lib/bitio.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 lib/bitio.c diff --git a/lib/bitio.c b/lib/bitio.c new file mode 100644 index 0000000..00ac647 --- /dev/null +++ b/lib/bitio.c @@ -0,0 +1,170 @@ +#define READER_TYPE_FILE 0 +#define READER_TYPE_MEM 1 +#define READER_TYPE_ZLIB 2 +#define WRITER_TYPE_FILE 0 +#define WRITER_TYPE_MEM 1 +#define WRITER_TYPE_ZLIB 2 + +struct reader_t +{ + int (*read)(struct reader_t*, void*data, int len); + void *internal; + int type; + unsigned char mybyte; + unsigned char bitpos; +}; +struct writer_t +{ + int (*write)(struct writer_t*, void*data, int len); + void *internal; + int type; + unsigned char mybyte; + unsigned char bitpos; +}; +static int reader_fileread(struct reader_t*reader, void* data, int len) +{ + return read((int)reader->internal, data, len); +} +static void reader_resetbits(struct reader_t*r) +{ + r->mybyte = 0; + r->bitpos = 8; +} +static void reader_init_filereader(struct reader_t*r, int handle) +{ + r->read = reader_fileread; + r->internal = (void*)handle; + r->type = READER_TYPE_FILE; + reader_resetbits(r); +} +#define ZLIB_BUFFER_SIZE 16384 +struct zlibinflate_t +{ + z_stream zs; + struct reader_t*input; + U8 readbuffer[ZLIB_BUFFER_SIZE]; +}; +static void zlib_error(int ret, char* msg, z_stream*zs) +{ + fprintf(stderr, "%s: zlib error (%d): last zlib error: %s\n", + msg, + ret, + zs->msg?zs->msg:"unknown"); + perror("errno:"); + exit(1); +} +static int reader_zlibinflate(struct reader_t*reader, void* data, int len); +static void reader_init_zlibinflate(struct reader_t*r, struct reader_t*input) +{ + struct zlibinflate_t*z; + int ret; + z = (struct zlibinflate_t*)malloc(sizeof(struct zlibinflate_t)); + r->internal = z; + r->read = reader_zlibinflate; + r->type = READER_TYPE_ZLIB; + z->input = input; + memset(&z->zs,0,sizeof(z_stream)); + z->zs.zalloc = Z_NULL; + z->zs.zfree = Z_NULL; + z->zs.opaque = Z_NULL; + ret = inflateInit(&z->zs); + if (ret != Z_OK) zlib_error(ret, "bitio:inflate_init", &z->zs); + reader_resetbits(r); +} +static int reader_zlibinflate(struct reader_t*reader, void* data, int len) +{ + struct zlibinflate_t*z = (struct zlibinflate_t*)reader->internal; + int ret; + if(!z) + return 0; + + z->zs.next_out = data; + z->zs.avail_out = len; + + while(1) { + if(!z->zs.avail_in) { + z->zs.avail_in = z->input->read(z->input, z->readbuffer, ZLIB_BUFFER_SIZE); + z->zs.next_in = z->readbuffer; + } + if(z->zs.avail_in) + ret = inflate(&z->zs, Z_NO_FLUSH); + else + ret = inflate(&z->zs, Z_FINISH); + + if (ret != Z_OK && + ret != Z_STREAM_END) zlib_error(ret, "bitio:inflate_inflate", &z->zs); + + if (ret == Z_STREAM_END) { + int pos = z->zs.next_out - (Bytef*)data; + ret = inflateEnd(&z->zs); + if (ret != Z_OK) zlib_error(ret, "bitio:inflate_end", &z->zs); + free(reader->internal); + reader->internal = 0; + return pos; + } + if(!z->zs.avail_out) { + break; + } + } + return len; +} +static unsigned int reader_readbit(struct reader_t*r) +{ + if(r->bitpos==8) + { + r->bitpos=0; + r->read(r, &r->mybyte, 1); + } + return (r->mybyte>>(7-r->bitpos++))&1; +} +static unsigned int reader_readbits(struct reader_t*r, int num) +{ + int t; + int val = 0; + for(t=0;tinternal, data, len); +} +static void writer_resetbits(struct writer_t*w) +{ + if(w->bitpos) + w->write(w, &w->mybyte, 1); + w->bitpos = 0; + w->mybyte = 0; +} +static void writer_init_filewriter(struct writer_t*w, int handle) +{ + w->write = writer_filewrite; + w->internal = (void*)handle; + w->type = WRITER_TYPE_FILE; + w->bitpos = 0; + w->mybyte = 0; +} +static void writer_writebit(struct writer_t*w, int bit) +{ + if(w->bitpos==8) + { + w->write(w, &w->mybyte, 1); + w->bitpos = 0; + w->mybyte = 0; + } + if(bit&1) + w->mybyte |= 1 << (7 - w->bitpos); + w->bitpos ++; +} +static void writer_writebits(struct writer_t*w, U32 data, int bits) +{ + int t; + for(t=0;t> (bits-t-1))&1); + } +} + -- 1.7.10.4