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