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