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);
+}