flate

deflate implementation
git clone git://git.suckless.org/flate
Log | Files | Refs | README

commit c74af3ca586060b2172459ddcac6055d0358f57a
parent b4ac11e701ddfb012b25d6f77f75ab8aa4db405e
Author: nsz <nszabolcs@gmail.com>
Date:   Sat,  1 Aug 2009 19:16:25 +0200

inflate.h, example
Diffstat:
inflate.h | 29+++++++++++++++++++++++++++++
inflate_example.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/inflate.h b/inflate.h @@ -0,0 +1,29 @@ +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; + +/* TODO: flatein flateout flateerr */ + +/* return values */ +enum { + FlateOk = 0, + FlateError = -1, + FlateNeedInput = -2, + FlateHasOutput = -3 +}; + +typedef struct { + uchar *in; + int nin; + uchar *out; + int nout; + char *err; + void *state; +} FlateStream; + +/* state and err should be initialized to 0, to free internal state call s->err = ""; inflate(s) */ +/* decode from in to out, return if input is needed or output is available */ +int inflate(FlateStream *s); + +/* callback interface: r(buf, n, rdata) reads at most n bytes into buf */ +int inflate_callback(int (*r)(void *, int, void *), void *rdata, int (*w)(void *, int, void *), void *wdata); diff --git a/inflate_example.c b/inflate_example.c @@ -0,0 +1,70 @@ +#include <stdlib.h> +#include <stdio.h> +#include "inflate.h" + +int decompress_stream(FILE *in, FILE *out) { + FlateStream s; + int n, nin, nout; + enum {Nin = 1<<12, Nout = 1<<15}; + + s.in = malloc(Nin); + s.out = malloc(Nout); + s.nout = Nout; + s.err = 0; + s.state = 0; + nin = nout = 0; + + for (n = FlateNeedInput; ; n = inflate(&s)) + switch (n) { + case FlateOk: + case FlateError: + fprintf(stderr, "in: %d out: %d err: %s\n", nin, nout, s.err); + return n; + case FlateNeedInput: + s.nin = fread(s.in, 1, Nin, in); + if (s.nin == 0) + s.err = "read error."; + nin += s.nin; + break; + case FlateHasOutput: + if (s.nout != fwrite(s.out, 1, s.nout, out)) + s.err = "write error."; + nout += s.nout; + s.nout = Nout; + break; + } +} + +int decompress_mem(void *src, int srclen, void *dst, int dstlen) { + FlateStream s; + int n; + + s.in = src; + s.nin = srclen; + s.out = dst; + s.nout = dstlen; + s.err = 0; + s.state = 0; + + while ((n = inflate(&s)) == FlateHasOutput) { + dstlen -= s.nout; + s.out += s.nout; + s.nout = dstlen; + if (dstlen < 0) + s.err = "not enough output space."; + } + if (n == FlateNeedInput) { + s.err = "input is not terminated."; + n = inflate(&s); + } + if (n == FlateOk) { + fprintf(stderr, "in: %d out: %d\n", srclen, (char *)s.out - (char *)dst); + return (char *)s.out - (char *)dst; + } + fprintf(stderr, "in: %d out: %d err: %s\n", srclen, (char *)s.out - (char *)dst, s.err); + return -1; +} + +int main(void) { + return decompress_stream(stdin, stdout); +}