xref: /inferno-os/os/boot/libflate/deflatezlib.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
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