rsc | b6afd33 | 2003-11-23 18:19:18 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | #include <flate.h> |
| 4 | #include "zlib.h" |
| 5 | |
| 6 | typedef struct ZRead ZRead; |
| 7 | |
| 8 | struct ZRead |
| 9 | { |
| 10 | ulong adler; |
| 11 | void *rr; |
| 12 | int (*r)(void*, void*, int); |
| 13 | }; |
| 14 | |
| 15 | static int |
| 16 | zlread(void *vzr, void *buf, int n) |
| 17 | { |
| 18 | ZRead *zr; |
| 19 | |
| 20 | zr = vzr; |
| 21 | n = (*zr->r)(zr->rr, buf, n); |
| 22 | if(n <= 0) |
| 23 | return n; |
| 24 | zr->adler = adler32(zr->adler, buf, n); |
| 25 | return n; |
| 26 | } |
| 27 | |
| 28 | int |
| 29 | deflatezlib(void *wr, int (*w)(void*, void*, int), void *rr, int (*r)(void*, void*, int), int level, int debug) |
| 30 | { |
| 31 | ZRead zr; |
| 32 | uchar buf[4]; |
| 33 | int ok; |
| 34 | |
| 35 | buf[0] = ZlibDeflate | ZlibWin32k; |
| 36 | |
| 37 | /* bogus zlib encoding of compression level */ |
| 38 | buf[1] = ((level > 2) + (level > 5) + (level > 8)) << 6; |
| 39 | |
| 40 | /* header check field */ |
| 41 | buf[1] |= 31 - ((buf[0] << 8) | buf[1]) % 31; |
| 42 | if((*w)(wr, buf, 2) != 2) |
| 43 | return FlateOutputFail; |
| 44 | |
| 45 | zr.rr = rr; |
| 46 | zr.r = r; |
| 47 | zr.adler = 1; |
| 48 | ok = deflate(wr, w, &zr, zlread, level, debug); |
| 49 | if(ok != FlateOk) |
| 50 | return ok; |
| 51 | |
| 52 | buf[0] = zr.adler >> 24; |
| 53 | buf[1] = zr.adler >> 16; |
| 54 | buf[2] = zr.adler >> 8; |
| 55 | buf[3] = zr.adler; |
| 56 | if((*w)(wr, buf, 4) != 4) |
| 57 | return FlateOutputFail; |
| 58 | |
| 59 | return FlateOk; |
| 60 | } |