Mercurial > hg > toybox
annotate toys/pending/gzip.c @ 1189:95ae2805622f draft
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Confirmed with him on IRC it's ok to use under toybox license, glued the files
together and hammered square peg into round hole, no other changes yet.
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 31 Jan 2014 06:01:30 -0600 |
parents | |
children | 1568ba420f32 |
rev | line source |
---|---|
1189
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1 /* gzip.c - deflate and inflate code rolled into a ball. |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
2 * |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
3 * Copyright 2009 Szabolcs Nagy <nszabolcs@gmail.com> |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
4 * |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
5 * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/gzip.html |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
6 * And RFCs 1950, 1951, and 1952 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
7 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
8 USE_GZIP(NEWTOY(gzip, "qvcdrgzp", TOYFLAG_USR|TOYFLAG_BIN)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
9 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
10 config GZIP |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
11 bool "gzip" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
12 default n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
13 help |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
14 usage: gzip [-qvcdrgzp] FILE |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
15 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
16 Transitional gzip, needs work. Combines gzip, zlib, and pkzip. |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
17 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
18 -q quiet (default)\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
19 -v verbose\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
20 -c compress (default)\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
21 -d decompress\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
22 -r raw (default)\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
23 -g gzip\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
24 -z zlib\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
25 -p pkzip\n |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
26 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
27 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
28 #define FOR_gzip |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
29 #include "toys.h" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
30 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
31 typedef unsigned char uchar; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
32 typedef unsigned short ushort; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
33 typedef unsigned int uint; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
34 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
35 /* deflate and inflate return values */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
36 enum { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
37 FlateOk = 0, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
38 FlateErr = -1, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
39 FlateIn = -2, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
40 FlateOut = -3 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
41 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
42 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
43 typedef struct { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
44 int nin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
45 int nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
46 uchar *in; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
47 uchar *out; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
48 char *err; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
49 void *state; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
50 } FlateStream; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
51 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
52 int deflate(FlateStream *s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
53 int inflate(FlateStream *s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
54 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
55 uint adler32(uchar *p, int n, uint adler); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
56 void crc32init(void); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
57 uint crc32(uchar *p, int n, uint crc); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
58 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
59 uint crctab[256]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
60 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
61 void crc32init(void) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
62 static const uint poly = 0xedb88320; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
63 int i,j; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
64 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
65 for (i = 0; i < 256; ++i) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
66 uint crc = i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
67 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
68 for (j = 0; j < 8; j++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
69 if (crc & 1) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
70 crc = (crc >> 1) ^ poly; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
71 else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
72 crc >>= 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
73 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
74 crctab[i] = crc; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
75 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
76 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
77 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
78 uint crc32(uchar *p, int n, uint crc) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
79 uchar *ep = p + n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
80 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
81 crc ^= 0xffffffff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
82 while (p < ep) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
83 crc = crctab[(crc & 0xff) ^ *p++] ^ (crc >> 8); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
84 return crc ^ 0xffffffff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
85 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
86 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
87 enum { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
88 AdlerBase = 65521, /* largest 16bit prime */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
89 AdlerN = 5552 /* max iters before 32bit overflow */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
90 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
91 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
92 uint adler32(uchar *p, int n, uint adler) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
93 uint s1 = adler & 0xffff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
94 uint s2 = (adler >> 16) & 0xffff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
95 uchar *ep; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
96 int k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
97 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
98 for (; n >= 16; n -= k) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
99 k = n < AdlerN ? n : AdlerN; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
100 k &= ~0xf; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
101 for (ep = p + k; p < ep; p += 16) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
102 s1 += p[0]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
103 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
104 s1 += p[1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
105 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
106 s1 += p[2]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
107 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
108 s1 += p[3]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
109 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
110 s1 += p[4]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
111 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
112 s1 += p[5]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
113 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
114 s1 += p[6]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
115 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
116 s1 += p[7]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
117 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
118 s1 += p[8]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
119 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
120 s1 += p[9]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
121 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
122 s1 += p[10]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
123 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
124 s1 += p[11]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
125 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
126 s1 += p[12]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
127 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
128 s1 += p[13]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
129 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
130 s1 += p[14]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
131 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
132 s1 += p[15]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
133 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
134 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
135 s1 %= AdlerBase; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
136 s2 %= AdlerBase; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
137 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
138 if (n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
139 for (ep = p + n; p < ep; p++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
140 s1 += p[0]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
141 s2 += s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
142 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
143 s1 %= AdlerBase; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
144 s2 %= AdlerBase; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
145 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
146 return (s2 << 16) + s1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
147 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
148 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
149 enum { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
150 CodeBits = 16, /* max number of bits in a code + 1 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
151 LitlenTableBits = 9, /* litlen code bits used in lookup table */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
152 DistTableBits = 6, /* dist code bits used in lookup table */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
153 ClenTableBits = 6, /* clen code bits used in lookup table */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
154 TableBits = LitlenTableBits, /* log2(lookup table size) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
155 Nlit = 256, /* number of lit codes */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
156 Nlen = 29, /* number of len codes */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
157 Nlitlen = Nlit+Nlen+3, /* litlen codes + block end + 2 unused */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
158 Ndist = 30, /* number of distance codes */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
159 Nclen = 19, /* number of code length codes */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
160 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
161 EOB = 256, /* end of block symbol */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
162 MinMatch = 3, /* min match length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
163 MaxMatch = 258, /* max match length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
164 WinSize = 1 << 15, /* sliding window size */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
165 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
166 MaxChainLen = 256, /* max length of hash chain */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
167 HashBits = 13, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
168 HashSize = 1 << HashBits, /* hash table size */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
169 BigDist = 1 << 12, /* max match distance for short match length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
170 MaxDist = WinSize, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
171 BlockSize = 1 << 15, /* TODO */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
172 SrcSize = 2*WinSize + MaxMatch, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
173 DstSize = BlockSize + MaxMatch + 6, /* worst case compressed block size */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
174 LzSize = 1 << 13, /* lz buffer size */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
175 LzGuard = LzSize - 2, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
176 LzLitFlag = 1 << 15 /* marks literal run length in lz buffer */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
177 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
178 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
179 /* states */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
180 enum { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
181 BlockHead, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
182 UncompressedBlock, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
183 CopyUncompressed, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
184 FixedHuff, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
185 DynamicHuff, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
186 DynamicHuffClen, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
187 DynamicHuffLitlenDist, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
188 DynamicHuffContinue, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
189 DecodeBlock, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
190 DecodeBlockLenBits, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
191 DecodeBlockDist, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
192 DecodeBlockDistBits, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
193 DecodeBlockCopy |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
194 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
195 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
196 typedef struct { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
197 short len; /* code length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
198 ushort sym; /* symbol */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
199 } Entry; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
200 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
201 /* huffman code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
202 typedef struct { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
203 Entry table[1 << TableBits]; /* prefix lookup table */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
204 uint nbits; /* prefix length (table size is 1 << nbits) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
205 uint sum; /* full codes in table: sum(count[0..nbits]) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
206 ushort count[CodeBits]; /* number of codes with given length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
207 ushort symbol[Nlitlen]; /* symbols ordered by code length (lexic.) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
208 } Huff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
209 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
210 typedef struct { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
211 uchar *src; /* input buffer pointer */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
212 uchar *srcend; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
213 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
214 uint bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
215 uint nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
216 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
217 uchar win[WinSize]; /* output window */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
218 uint pos; /* window pos */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
219 uint posout; /* used for flushing win */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
220 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
221 int state; /* decode state */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
222 int final; /* last block flag */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
223 char *err; /* TODO: error message */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
224 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
225 /* for decoding dynamic code trees in inflate() */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
226 int nlit; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
227 int ndist; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
228 int nclen; /* also used in decode_block() */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
229 int lenpos; /* also used in decode_block() */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
230 uchar lens[Nlitlen + Ndist]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
231 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
232 int fixed; /* fixed code tree flag */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
233 Huff lhuff; /* dynamic lit/len huffman code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
234 Huff dhuff; /* dynamic distance huffman code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
235 } DecodeState; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
236 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
237 /* TODO: globals.. initialization is not thread safe */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
238 static Huff lhuff; /* fixed lit/len huffman code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
239 static Huff dhuff; /* fixed distance huffman code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
240 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
241 /* base offset and extra bits tables */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
242 static uchar lenbits[Nlen] = { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
243 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
244 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
245 static ushort lenbase[Nlen] = { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
246 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
247 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
248 static uchar distbits[Ndist] = { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
249 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
250 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
251 static ushort distbase[Ndist] = { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
252 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
253 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
254 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
255 /* ordering of code lengths */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
256 static uchar clenorder[Nclen] = { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
257 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
258 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
259 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
260 /* TODO: this or normal inc + reverse() */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
261 /* increment bitwise reversed n (msb is bit 0, lsb is bit len-1) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
262 static uint revinc(uint n, uint len) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
263 uint i = 1 << (len - 1); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
264 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
265 while (n & i) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
266 i >>= 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
267 if (i) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
268 n &= i - 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
269 n |= i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
270 } else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
271 n = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
272 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
273 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
274 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
275 /* build huffman code tree from code lengths (each should be < CodeBits) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
276 static int build_huff(Huff *huff, uchar *lens, uint n, uint nbits) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
277 int offs[CodeBits]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
278 int left; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
279 uint i, c, sum, code, len, min, max; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
280 ushort *count = huff->count; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
281 ushort *symbol = huff->symbol; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
282 Entry *table = huff->table; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
283 Entry entry; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
284 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
285 /* count code lengths */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
286 for (i = 0; i < CodeBits; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
287 count[i] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
288 for (i = 0; i < n; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
289 count[lens[i]]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
290 if (count[0] == n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
291 huff->nbits = table[0].len = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
292 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
293 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
294 count[0] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
295 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
296 /* bound code lengths, force nbits to be within the bounds */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
297 for (max = CodeBits - 1; max > 0; max--) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
298 if (count[max] != 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
299 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
300 if (nbits > max) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
301 nbits = max; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
302 for (min = 1; min < CodeBits; min++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
303 if (count[min] != 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
304 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
305 if (nbits < min) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
306 nbits = min; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
307 if (nbits > TableBits) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
308 return -1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
309 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
310 huff->nbits = nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
311 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
312 /* check if length is over-subscribed or incomplete */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
313 for (left = 1 << min, i = min; i <= max; left <<= 1, i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
314 left -= count[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
315 /* left < 0: over-subscribed, left > 0: incomplete */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
316 if (left < 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
317 return -1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
318 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
319 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
320 for (sum = 0, i = 0; i <= max; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
321 offs[i] = sum; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
322 sum += count[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
323 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
324 /* needed for decoding codes longer than nbits */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
325 if (nbits < max) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
326 huff->sum = offs[nbits + 1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
327 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
328 /* sort symbols by code length (lexicographic order) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
329 for (i = 0; i < n; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
330 if (lens[i]) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
331 symbol[offs[lens[i]]++] = i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
332 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
333 /* lookup table for decoding nbits from input.. */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
334 for (i = 0; i < 1 << nbits; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
335 table[i].len = table[i].sym = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
336 code = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
337 /* ..if code is at most nbits (bits are in reverse order, sigh..) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
338 for (len = min; len <= nbits; len++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
339 for (c = count[len]; c > 0; c--) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
340 entry.len = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
341 entry.sym = *symbol; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
342 for (i = code; i < 1 << nbits; i += 1 << len) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
343 table[i] = entry; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
344 /* next code */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
345 symbol++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
346 code = revinc(code, len); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
347 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
348 /* ..if code is longer than nbits: values for simple bitwise decode */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
349 for (i = 0; code; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
350 table[code].len = -1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
351 table[code].sym = i << 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
352 code = revinc(code, nbits); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
353 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
354 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
355 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
356 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
357 /* fixed huffman code trees (should be done at compile time..) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
358 static void init_fixed_huffs(void) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
359 int i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
360 uchar lens[Nlitlen]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
361 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
362 for (i = 0; i < 144; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
363 lens[i] = 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
364 for (; i < 256; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
365 lens[i] = 9; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
366 for (; i < 280; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
367 lens[i] = 7; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
368 for (; i < Nlitlen; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
369 lens[i] = 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
370 build_huff(&lhuff, lens, Nlitlen, 8); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
371 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
372 for (i = 0; i < Ndist; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
373 lens[i] = 5; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
374 build_huff(&dhuff, lens, Ndist, 5); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
375 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
376 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
377 /* fill *bits with n bits from *src */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
378 static int fillbits_fast(uchar **src, uchar *srcend, uint *bits, uint *nbits, uint n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
379 while (*nbits < n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
380 if (*src == srcend) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
381 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
382 *bits |= *(*src)++ << *nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
383 *nbits += 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
384 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
385 return 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
386 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
387 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
388 /* get n bits from *bits */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
389 static uint getbits_fast(uint *bits, uint *nbits, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
390 uint k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
391 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
392 k = *bits & ((1 << n) - 1); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
393 *bits >>= n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
394 *nbits -= n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
395 return k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
396 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
397 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
398 static int fillbits(DecodeState *s, uint n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
399 return fillbits_fast(&s->src, s->srcend, &s->bits, &s->nbits, n); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
400 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
401 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
402 static uint getbits(DecodeState *s, uint n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
403 return getbits_fast(&s->bits, &s->nbits, n); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
404 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
405 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
406 /* decode symbol bitwise if code is longer than huffbits */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
407 static uint decode_symbol_long(DecodeState *s, Huff *huff, uint bits, uint nbits, int cur) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
408 int sum = huff->sum; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
409 uint huffbits = huff->nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
410 ushort *count = huff->count + huffbits + 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
411 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
412 /* get bits if we are near the end */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
413 if (s->src + 2 >= s->srcend) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
414 while (nbits < CodeBits - 1 && s->src < s->srcend) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
415 bits |= *s->src++ << nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
416 nbits += 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
417 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
418 s->bits = bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
419 s->nbits = nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
420 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
421 bits >>= huffbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
422 nbits -= huffbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
423 for (;;) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
424 if (!nbits--) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
425 if (s->src == s->srcend) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
426 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
427 bits = *s->src++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
428 nbits = 7; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
429 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
430 cur |= bits & 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
431 bits >>= 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
432 sum += *count; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
433 cur -= *count; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
434 if (cur < 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
435 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
436 cur <<= 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
437 count++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
438 if (count == huff->count + CodeBits) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
439 return s->err = "symbol decoding failed.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
440 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
441 s->bits = bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
442 s->nbits = nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
443 return huff->symbol[sum + cur]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
444 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
445 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
446 /* decode a symbol from stream with huff code */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
447 static uint decode_symbol(DecodeState *s, Huff *huff) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
448 uint huffbits = huff->nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
449 uint nbits = s->nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
450 uint bits = s->bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
451 uint mask = (1 << huffbits) - 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
452 Entry entry; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
453 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
454 /* get enough bits efficiently */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
455 if (nbits < huffbits) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
456 uchar *src = s->src; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
457 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
458 if (src + 2 < s->srcend) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
459 /* we assume huffbits <= 9 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
460 bits |= *src++ << nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
461 nbits += 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
462 bits |= *src++ << nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
463 nbits += 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
464 bits |= *src++ << nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
465 nbits += 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
466 s->src = src; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
467 } else /* rare */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
468 do { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
469 if (s->src == s->srcend) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
470 entry = huff->table[bits & mask]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
471 if (entry.len > 0 && entry.len <= nbits) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
472 s->bits = bits >> entry.len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
473 s->nbits = nbits - entry.len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
474 return entry.sym; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
475 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
476 s->bits = bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
477 s->nbits = nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
478 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
479 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
480 bits |= *s->src++ << nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
481 nbits += 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
482 } while (nbits < huffbits); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
483 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
484 /* decode bits */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
485 entry = huff->table[bits & mask]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
486 if (entry.len > 0) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
487 s->bits = bits >> entry.len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
488 s->nbits = nbits - entry.len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
489 return entry.sym; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
490 } else if (entry.len == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
491 return s->err = "symbol decoding failed.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
492 return decode_symbol_long(s, huff, bits, nbits, entry.sym); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
493 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
494 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
495 /* decode a block of data from stream with trees */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
496 static int decode_block(DecodeState *s, Huff *lhuff, Huff *dhuff) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
497 uchar *win = s->win; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
498 uint pos = s->pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
499 uint sym = s->nclen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
500 uint len = s->lenpos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
501 uint dist = s->nclen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
502 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
503 switch (s->state) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
504 case DecodeBlock: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
505 for (;;) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
506 sym = decode_symbol(s, lhuff); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
507 if (sym < 256) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
508 win[pos++] = sym; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
509 if (pos == WinSize) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
510 s->pos = WinSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
511 s->state = DecodeBlock; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
512 return FlateOut; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
513 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
514 } else if (sym > 256) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
515 sym -= 257; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
516 if (sym >= Nlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
517 s->pos = pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
518 s->state = DecodeBlock; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
519 if (sym + 257 == (uint)FlateIn) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
520 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
521 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
522 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
523 case DecodeBlockLenBits: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
524 if (!fillbits_fast(&s->src, s->srcend, &s->bits, &s->nbits, lenbits[sym])) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
525 s->nclen = sym; /* using nclen to store sym */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
526 s->pos = pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
527 s->state = DecodeBlockLenBits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
528 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
529 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
530 len = lenbase[sym] + getbits_fast(&s->bits, &s->nbits, lenbits[sym]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
531 case DecodeBlockDist: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
532 sym = decode_symbol(s, dhuff); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
533 if (sym == (uint)FlateIn) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
534 s->pos = pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
535 s->lenpos = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
536 s->state = DecodeBlockDist; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
537 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
538 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
539 if (sym >= Ndist) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
540 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
541 case DecodeBlockDistBits: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
542 if (!fillbits_fast(&s->src, s->srcend, &s->bits, &s->nbits, distbits[sym])) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
543 s->nclen = sym; /* using nclen to store sym */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
544 s->pos = pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
545 s->lenpos = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
546 s->state = DecodeBlockDistBits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
547 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
548 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
549 dist = distbase[sym] + getbits_fast(&s->bits, &s->nbits, distbits[sym]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
550 /* copy match, loop unroll in common case */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
551 if (pos + len < WinSize) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
552 /* lenbase[sym] >= 3 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
553 do { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
554 win[pos] = win[(pos - dist) % WinSize]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
555 pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
556 win[pos] = win[(pos - dist) % WinSize]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
557 pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
558 win[pos] = win[(pos - dist) % WinSize]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
559 pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
560 len -= 3; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
561 } while (len >= 3); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
562 if (len--) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
563 win[pos] = win[(pos - dist) % WinSize]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
564 pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
565 if (len) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
566 win[pos] = win[(pos - dist) % WinSize]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
567 pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
568 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
569 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
570 } else { /* rare */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
571 case DecodeBlockCopy: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
572 while (len--) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
573 win[pos] = win[(pos - dist) % WinSize]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
574 pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
575 if (pos == WinSize) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
576 s->pos = WinSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
577 s->lenpos = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
578 s->nclen = dist; /* using nclen to store dist */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
579 s->state = DecodeBlockCopy; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
580 return FlateOut; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
581 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
582 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
583 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
584 } else { /* EOB: sym == 256 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
585 s->pos = pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
586 return FlateOk; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
587 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
588 } /* for (;;) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
589 } /* switch () */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
590 return s->err = "corrupted state.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
591 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
592 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
593 /* inflate state machine (decodes s->src into s->win) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
594 static int inflate_state(DecodeState *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
595 int n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
596 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
597 if (s->posout) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
598 return FlateOut; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
599 for (;;) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
600 switch (s->state) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
601 case BlockHead: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
602 if (s->final) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
603 if (s->pos) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
604 return FlateOut; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
605 else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
606 return FlateOk; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
607 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
608 if (!fillbits(s, 3)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
609 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
610 s->final = getbits(s, 1); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
611 n = getbits(s, 2); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
612 if (n == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
613 s->state = UncompressedBlock; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
614 else if (n == 1) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
615 s->state = FixedHuff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
616 else if (n == 2) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
617 s->state = DynamicHuff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
618 else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
619 return s->err = "corrupt block header.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
620 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
621 case UncompressedBlock: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
622 /* start block on a byte boundary */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
623 s->bits >>= s->nbits & 7; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
624 s->nbits &= ~7; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
625 if (!fillbits(s, 32)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
626 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
627 s->lenpos = getbits(s, 16); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
628 n = getbits(s, 16); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
629 if (s->lenpos != (~n & 0xffff)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
630 return s->err = "corrupt uncompressed length.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
631 s->state = CopyUncompressed; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
632 case CopyUncompressed: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
633 /* TODO: untested, slow, memcpy etc */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
634 /* s->nbits should be 0 here */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
635 while (s->lenpos) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
636 if (s->src == s->srcend) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
637 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
638 s->lenpos--; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
639 s->win[s->pos++] = *s->src++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
640 if (s->pos == WinSize) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
641 return FlateOut; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
642 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
643 s->state = BlockHead; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
644 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
645 case FixedHuff: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
646 s->fixed = 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
647 s->state = DecodeBlock; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
648 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
649 case DynamicHuff: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
650 /* decode dynamic huffman code trees */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
651 if (!fillbits(s, 14)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
652 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
653 s->nlit = 257 + getbits(s, 5); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
654 s->ndist = 1 + getbits(s, 5); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
655 s->nclen = 4 + getbits(s, 4); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
656 if (s->nlit > Nlitlen || s->ndist > Ndist) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
657 return s->err = "corrupt code tree.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
658 /* build code length tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
659 for (n = 0; n < Nclen; n++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
660 s->lens[n] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
661 s->fixed = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
662 s->state = DynamicHuffClen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
663 s->lenpos = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
664 case DynamicHuffClen: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
665 for (n = s->lenpos; n < s->nclen; n++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
666 if (fillbits(s, 3)) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
667 s->lens[clenorder[n]] = getbits(s, 3); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
668 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
669 s->lenpos = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
670 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
671 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
672 /* using lhuff for code length huff code */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
673 if (build_huff(&s->lhuff, s->lens, Nclen, ClenTableBits) < 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
674 return s->err = "building clen tree failed.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
675 s->state = DynamicHuffLitlenDist; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
676 s->lenpos = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
677 case DynamicHuffLitlenDist: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
678 /* decode code lengths for the dynamic trees */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
679 for (n = s->lenpos; n < s->nlit + s->ndist; ) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
680 uint sym = decode_symbol(s, &s->lhuff); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
681 uint len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
682 uchar c; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
683 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
684 if (sym < 16) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
685 s->lens[n++] = sym; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
686 continue; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
687 } else if (sym == (uint)FlateIn) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
688 s->lenpos = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
689 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
690 case DynamicHuffContinue: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
691 n = s->lenpos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
692 sym = s->nclen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
693 s->state = DynamicHuffLitlenDist; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
694 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
695 if (!fillbits(s, 7)) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
696 /* TODO: 7 is too much when an almost empty block is at the end */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
697 if (sym == (uint)FlateErr) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
698 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
699 s->nclen = sym; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
700 s->lenpos = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
701 s->state = DynamicHuffContinue; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
702 return FlateIn; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
703 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
704 /* TODO: bound check s->lens */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
705 if (sym == 16) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
706 /* copy previous code length 3-6 times */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
707 c = s->lens[n - 1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
708 for (len = 3 + getbits(s, 2); len; len--) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
709 s->lens[n++] = c; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
710 } else if (sym == 17) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
711 /* repeat 0 for 3-10 times */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
712 for (len = 3 + getbits(s, 3); len; len--) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
713 s->lens[n++] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
714 } else if (sym == 18) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
715 /* repeat 0 for 11-138 times */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
716 for (len = 11 + getbits(s, 7); len; len--) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
717 s->lens[n++] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
718 } else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
719 return s->err = "corrupt code tree.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
720 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
721 /* build dynamic huffman code trees */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
722 if (build_huff(&s->lhuff, s->lens, s->nlit, LitlenTableBits) < 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
723 return s->err = "building litlen tree failed.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
724 if (build_huff(&s->dhuff, s->lens + s->nlit, s->ndist, DistTableBits) < 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
725 return s->err = "building dist tree failed.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
726 s->state = DecodeBlock; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
727 case DecodeBlock: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
728 case DecodeBlockLenBits: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
729 case DecodeBlockDist: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
730 case DecodeBlockDistBits: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
731 case DecodeBlockCopy: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
732 n = decode_block(s, s->fixed ? &lhuff : &s->lhuff, s->fixed ? &dhuff : &s->dhuff); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
733 if (n != FlateOk) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
734 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
735 s->state = BlockHead; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
736 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
737 default: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
738 return s->err = "corrupt internal state.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
739 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
740 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
741 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
742 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
743 static DecodeState *alloc_decode_state(void) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
744 DecodeState *s = malloc(sizeof(DecodeState)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
745 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
746 if (s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
747 s->final = s->pos = s->posout = s->bits = s->nbits = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
748 s->state = BlockHead; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
749 s->src = s->srcend = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
750 s->err = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
751 /* TODO: globals.. */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
752 if (lhuff.nbits == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
753 init_fixed_huffs(); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
754 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
755 return s; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
756 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
757 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
758 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
759 /* extern */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
760 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
761 int inflate(FlateStream *stream) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
762 DecodeState *s = stream->state; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
763 int n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
764 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
765 if (stream->err) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
766 if (s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
767 free(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
768 stream->state = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
769 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
770 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
771 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
772 if (!s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
773 s = stream->state = alloc_decode_state(); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
774 if (!s) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
775 return stream->err = "no mem.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
776 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
777 if (stream->nin) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
778 s->src = stream->in; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
779 s->srcend = s->src + stream->nin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
780 stream->nin = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
781 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
782 n = inflate_state(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
783 if (n == FlateOut) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
784 if (s->pos < stream->nout) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
785 stream->nout = s->pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
786 memcpy(stream->out, s->win + s->posout, stream->nout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
787 s->pos -= stream->nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
788 if (s->pos) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
789 s->posout += stream->nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
790 else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
791 s->posout = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
792 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
793 if (n == FlateOk || n == FlateErr) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
794 if (s->nbits || s->src < s->srcend) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
795 s->nbits /= 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
796 stream->in = s->src - s->nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
797 stream->nin = s->srcend - s->src + s->nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
798 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
799 stream->err = s->err; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
800 free(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
801 stream->state = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
802 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
803 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
804 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
805 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
806 typedef struct { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
807 ushort dist; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
808 ushort len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
809 } Match; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
810 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
811 typedef struct { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
812 ushort n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
813 ushort bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
814 } LzCode; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
815 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
816 typedef struct { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
817 int pos; /* position in input src */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
818 int startpos; /* block start pos in input src */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
819 int endpos; /* end of available bytes in src */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
820 int skip; /* skipped hash chain updates (until next iter) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
821 Match prevm; /* previous (deferred) match */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
822 int state; /* prev return value */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
823 int eof; /* end of input */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
824 uchar *in; /* input data (not yet in src) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
825 uchar *inend; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
826 uint bits; /* for output */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
827 int nbits; /* for output */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
828 uchar *dst; /* compressed output (position in dstbuf) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
829 uchar *dstbegin; /* start position of unflushed data in dstbuf */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
830 LzCode *lz; /* current pos in lzbuf */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
831 int nlit; /* literal run length in lzbuf */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
832 ushort head[HashSize]; /* position of hash chain heads */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
833 ushort chain[WinSize]; /* hash chain */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
834 ushort lfreq[Nlitlen]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
835 ushort dfreq[Ndist]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
836 uchar src[SrcSize]; /* input buf */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
837 uchar dstbuf[DstSize]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
838 LzCode lzbuf[LzSize]; /* literal run length, match len, match dist */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
839 } State; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
840 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
841 static uchar fixllen[Nlitlen]; /* fixed lit/len huffman code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
842 static ushort fixlcode[Nlitlen]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
843 static uchar fixdlen[Ndist]; /* fixed distance huffman code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
844 static ushort fixdcode[Ndist]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
845 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
846 static uint revcode(uint c, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
847 int i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
848 uint r = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
849 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
850 for (i = 0; i < n; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
851 r = (r << 1) | (c & 1); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
852 c >>= 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
853 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
854 return r; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
855 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
856 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
857 /* build huffman code tree from code lengths */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
858 static void huffcodes(ushort *codes, const uchar *lens, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
859 int c[CodeBits]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
860 int i, code, count; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
861 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
862 /* count code lengths and calc first code for each length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
863 for (i = 0; i < CodeBits; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
864 c[i] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
865 for (i = 0; i < n; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
866 c[lens[i]]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
867 for (code = 0, i = 1; i < CodeBits; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
868 count = c[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
869 c[i] = code; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
870 code += count; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
871 if (code > (1 << i)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
872 abort(); /* over-subscribed */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
873 code <<= 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
874 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
875 if (code < (1 << i)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
876 /* incomplete */; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
877 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
878 for (i = 0; i < n; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
879 if (lens[i]) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
880 codes[i] = revcode(c[lens[i]]++, lens[i]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
881 else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
882 codes[i] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
883 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
884 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
885 static int heapparent(int n) {return (n - 2)/4 * 2;} |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
886 static int heapchild(int n) {return 2 * n + 2;} |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
887 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
888 static int heappush(int *heap, int len, int w, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
889 int p, c, tmp; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
890 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
891 c = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
892 heap[len++] = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
893 heap[len++] = w; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
894 while (c > 0) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
895 p = heapparent(c); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
896 if (heap[c+1] < heap[p+1]) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
897 tmp = heap[c]; heap[c] = heap[p]; heap[p] = tmp; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
898 tmp = heap[c+1]; heap[c+1] = heap[p+1]; heap[p+1] = tmp; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
899 c = p; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
900 } else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
901 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
902 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
903 return len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
904 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
905 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
906 static int heappop(int *heap, int len, int *w, int *n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
907 int p, c, tmp; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
908 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
909 *n = heap[0]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
910 *w = heap[1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
911 heap[1] = heap[--len]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
912 heap[0] = heap[--len]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
913 p = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
914 for (;;) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
915 c = heapchild(p); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
916 if (c >= len) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
917 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
918 if (c+2 < len && heap[c+3] < heap[c+1]) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
919 c += 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
920 if (heap[p+1] > heap[c+1]) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
921 tmp = heap[p]; heap[p] = heap[c]; heap[c] = tmp; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
922 tmp = heap[p+1]; heap[p+1] = heap[c+1]; heap[c+1] = tmp; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
923 } else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
924 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
925 p = c; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
926 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
927 return len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
928 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
929 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
930 /* symbol frequencies -> code lengths (limited to 255) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
931 static void hufflens(uchar *lens, ushort *freqs, int nsym, int limit) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
932 /* 2 <= nsym <= Nlitlen, log(nsym) <= limit <= CodeBits-1 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
933 int parent[2*Nlitlen-1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
934 int count[CodeBits]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
935 int heap[2*Nlitlen]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
936 int n, len, top, overflow; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
937 int i, j; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
938 int wi, wj; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
939 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
940 for (n = 0; n < limit+1; n++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
941 count[n] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
942 for (len = n = 0; n < nsym; n++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
943 if (freqs[n] > 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
944 len = heappush(heap, len, freqs[n], n); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
945 else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
946 lens[n] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
947 /* deflate: fewer than two symbols: add new */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
948 for (n = 0; len < 4; n++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
949 if (freqs[n] == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
950 len = heappush(heap, len, ++freqs[n], n); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
951 /* build code tree */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
952 top = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
953 for (n = nsym; len > 2; n++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
954 len = heappop(heap, len, &wi, &i); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
955 len = heappop(heap, len, &wj, &j); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
956 parent[i] = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
957 parent[j] = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
958 len = heappush(heap, len, wi + wj, n); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
959 /* keep an ordered list of nodes at the end */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
960 heap[len+1] = i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
961 heap[len] = j; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
962 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
963 /* calc code lengths (deflate: with limit) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
964 overflow = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
965 parent[--n] = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
966 for (i = 2; i < top; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
967 n = heap[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
968 if (n >= nsym) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
969 /* overwrite parent index with length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
970 parent[n] = parent[parent[n]] + 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
971 if (parent[n] > limit) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
972 overflow++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
973 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
974 lens[n] = parent[parent[n]] + 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
975 if (lens[n] > limit) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
976 lens[n] = limit; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
977 overflow++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
978 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
979 count[lens[n]]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
980 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
981 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
982 if (overflow == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
983 return; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
984 /* modify code tree to fix overflow (from zlib) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
985 while (overflow > 0) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
986 for (n = limit-1; count[n] == 0; n--); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
987 count[n]--; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
988 count[n+1] += 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
989 count[limit]--; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
990 overflow -= 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
991 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
992 for (len = limit; len > 0; len--) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
993 for (i = count[len]; i > 0;) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
994 n = heap[--top]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
995 if (n < nsym) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
996 lens[n] = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
997 i--; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
998 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
999 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1000 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1001 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1002 /* output n (<= 16) bits */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1003 static void putbits(State *s, uint bits, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1004 s->bits |= bits << s->nbits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1005 s->nbits += n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1006 while (s->nbits >= 8) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1007 *s->dst++ = s->bits & 0xff; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1008 s->bits >>= 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1009 s->nbits -= 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1010 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1011 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1012 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1013 /* run length encode literal and dist code lengths into codes and extra */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1014 static int clencodes(uchar *codes, uchar *extra, uchar *llen, int nlit, uchar *dlen, int ndist) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1015 int i, c, r, rr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1016 int n = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1017 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1018 for (i = 0; i < nlit; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1019 codes[i] = llen[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1020 for (i = 0; i < ndist; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1021 codes[nlit + i] = dlen[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1022 for (i = 0; i < nlit + ndist;) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1023 c = codes[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1024 for (r = 1; i + r < nlit + ndist && codes[i + r] == c; r++); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1025 i += r; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1026 if (c == 0) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1027 while (r >= 11) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1028 rr = r > 138 ? 138 : r; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1029 codes[n] = 18; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1030 extra[n++] = rr - 11; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1031 r -= rr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1032 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1033 if (r >= 3) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1034 codes[n] = 17; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1035 extra[n++] = r - 3; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1036 r = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1037 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1038 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1039 while (r--) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1040 codes[n++] = c; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1041 while (r >= 3) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1042 rr = r > 6 ? 6 : r; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1043 codes[n] = 16; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1044 extra[n++] = rr - 3; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1045 r -= rr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1046 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1047 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1048 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1049 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1050 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1051 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1052 /* compress block data into s->dstbuf using given codes */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1053 static void putblock(State *s, ushort *lcode, uchar *llen, ushort *dcode, uchar *dlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1054 int n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1055 LzCode *lz; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1056 uchar *p; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1057 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1058 for (lz = s->lzbuf, p = s->src + s->startpos; lz != s->lz; lz++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1059 if (lz->bits & LzLitFlag) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1060 for (n = lz->n; n > 0; n--, p++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1061 putbits(s, lcode[*p], llen[*p]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1062 else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1063 p += lenbase[lz->n] + lz->bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1064 putbits(s, lcode[Nlit + lz->n + 1], llen[Nlit + lz->n + 1]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1065 putbits(s, lz->bits, lenbits[lz->n]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1066 lz++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1067 putbits(s, dcode[lz->n], dlen[lz->n]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1068 putbits(s, lz->bits, distbits[lz->n]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1069 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1070 putbits(s, lcode[EOB], llen[EOB]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1071 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1072 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1073 /* build code trees and select dynamic/fixed/uncompressed block compression */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1074 static void deflate_block(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1075 uchar codes[Nlitlen + Ndist], extra[Nlitlen + Ndist]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1076 uchar llen[Nlitlen], dlen[Ndist], clen[Nclen]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1077 ushort cfreq[Nclen]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1078 /* freq can be overwritten by code */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1079 ushort *lcode = s->lfreq, *dcode = s->dfreq, *ccode = cfreq; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1080 int i, c, n, ncodes; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1081 int nlit, ndist, nclen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1082 LzCode *lz; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1083 uchar *p; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1084 int dynsize, fixsize, uncsize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1085 int blocklen = s->pos - s->startpos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1086 /* int dyntree; */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1087 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1088 /* calc dynamic codes */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1089 hufflens(llen, s->lfreq, Nlitlen, CodeBits-1); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1090 hufflens(dlen, s->dfreq, Ndist, CodeBits-1); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1091 huffcodes(lcode, llen, Nlitlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1092 huffcodes(dcode, dlen, Ndist); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1093 for (nlit = Nlitlen; nlit > Nlit && llen[nlit-1] == 0; nlit--); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1094 for (ndist = Ndist; ndist > 1 && dlen[ndist-1] == 0; ndist--); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1095 ncodes = clencodes(codes, extra, llen, nlit, dlen, ndist); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1096 memset(cfreq, 0, sizeof(cfreq)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1097 for (i = 0; i < ncodes; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1098 cfreq[codes[i]]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1099 hufflens(clen, cfreq, Nclen, 7); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1100 huffcodes(ccode, clen, Nclen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1101 for (nclen = Nclen; nclen > 4 && clen[clenorder[nclen-1]] == 0; nclen--); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1102 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1103 /* calc compressed size */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1104 uncsize = 3 + 16 + 8 * blocklen + (16 - 3 - s->nbits) % 8; /* byte aligned */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1105 fixsize = 3; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1106 dynsize = 3 + 5 + 5 + 4 + 3 * nclen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1107 for (i = 0; i < ncodes; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1108 c = codes[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1109 dynsize += clen[c]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1110 if (c == 16) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1111 dynsize += 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1112 if (c == 17) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1113 dynsize += 3; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1114 if (c == 18) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1115 dynsize += 7; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1116 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1117 /* dyntree = dynsize - 3; */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1118 for (lz = s->lzbuf, p = s->src + s->startpos; lz != s->lz; lz++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1119 if (lz->bits & LzLitFlag) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1120 for (n = lz->n; n > 0; n--, p++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1121 fixsize += fixllen[*p]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1122 dynsize += llen[*p]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1123 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1124 else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1125 p += lenbase[lz->n] + lz->bits; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1126 fixsize += fixllen[Nlit + lz->n + 1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1127 dynsize += llen[Nlit + lz->n + 1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1128 fixsize += lenbits[lz->n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1129 dynsize += lenbits[lz->n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1130 lz++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1131 fixsize += fixdlen[lz->n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1132 dynsize += dlen[lz->n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1133 fixsize += distbits[lz->n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1134 dynsize += distbits[lz->n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1135 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1136 fixsize += fixllen[EOB]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1137 dynsize += llen[EOB]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1138 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1139 /* emit block */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1140 putbits(s, s->eof && s->pos == s->endpos, 1); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1141 if (dynsize < fixsize && dynsize < uncsize) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1142 /* dynamic code */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1143 putbits(s, 2, 2); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1144 putbits(s, nlit - 257, 5); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1145 putbits(s, ndist - 1, 5); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1146 putbits(s, nclen - 4, 4); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1147 for (i = 0; i < nclen; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1148 putbits(s, clen[clenorder[i]], 3); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1149 for (i = 0; i < ncodes; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1150 c = codes[i]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1151 putbits(s, ccode[c], clen[c]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1152 if (c == 16) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1153 putbits(s, extra[i], 2); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1154 if (c == 17) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1155 putbits(s, extra[i], 3); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1156 if (c == 18) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1157 putbits(s, extra[i], 7); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1158 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1159 putblock(s, lcode, llen, dcode, dlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1160 } else if (fixsize < uncsize) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1161 /* fixed code */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1162 putbits(s, 1, 2); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1163 putblock(s, fixlcode, fixllen, fixdcode, fixdlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1164 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1165 /* uncompressed */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1166 putbits(s, 0, 2); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1167 putbits(s, 0, 7); /* align to byte boundary */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1168 s->nbits = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1169 putbits(s, blocklen, 16); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1170 putbits(s, ~blocklen & 0xffff, 16); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1171 memcpy(s->dst, s->src + s->startpos, blocklen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1172 s->dst += blocklen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1173 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1174 /* |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1175 fprintf(stderr, "blen:%d [%d,%d] lzlen:%d dynlen:%d (tree:%d rate:%.3f) fixlen:%d (rate:%.3f) unclen:%d (rate:%.3f)\n", |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1176 blocklen, s->startpos, s->pos, s->lz - s->lzbuf, dynsize, dyntree, dynsize/(float)blocklen, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1177 fixsize, fixsize/(float)blocklen, uncsize, uncsize/(float)blocklen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1178 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1179 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1180 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1181 /* find n in base */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1182 static int bisect(ushort *base, int len, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1183 int lo = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1184 int hi = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1185 int k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1186 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1187 while (lo < hi) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1188 k = (lo + hi) / 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1189 if (n < base[k]) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1190 hi = k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1191 else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1192 lo = k + 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1193 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1194 return lo - 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1195 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1196 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1197 /* add literal run length to lzbuf */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1198 static void flushlit(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1199 if (s->nlit) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1200 s->lz->bits = LzLitFlag; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1201 s->lz->n = s->nlit; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1202 s->lz++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1203 s->nlit = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1204 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1205 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1206 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1207 /* add match to lzbuf and update freq counts */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1208 static void recordmatch(State *s, Match m) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1209 int n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1210 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1211 /*fprintf(stderr, "m %d %d\n", m.len, m.dist);*/ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1212 flushlit(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1213 n = bisect(lenbase, Nlen, m.len); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1214 s->lz->n = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1215 s->lz->bits = m.len - lenbase[n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1216 s->lz++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1217 s->lfreq[Nlit + n + 1]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1218 n = bisect(distbase, Ndist, m.dist); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1219 s->lz->n = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1220 s->lz->bits = m.dist - distbase[n]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1221 s->lz++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1222 s->dfreq[n]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1223 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1224 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1225 /* update literal run length */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1226 static void recordlit(State *s, int c) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1227 /*fprintf(stderr, "l %c\n", c);*/ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1228 s->nlit++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1229 s->lfreq[c]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1230 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1231 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1232 /* multiplicative hash (using a prime close to golden ratio * 2^32) */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1233 static int gethash(uchar *p) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1234 return (0x9e3779b1 * ((p[0]<<16) + (p[1]<<8) + p[2]) >> (32 - HashBits)) % HashSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1235 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1236 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1237 /* update hash chain at the current position */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1238 static int updatechain(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1239 int hash, next = 0, p = s->pos, i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1240 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1241 if (s->endpos - p < MinMatch) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1242 p = s->endpos - MinMatch; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1243 for (i = s->pos - s->skip; i <= p; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1244 hash = gethash(s->src + i); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1245 next = s->head[hash]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1246 s->head[hash] = i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1247 if (next >= i || i - next >= MaxDist) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1248 next = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1249 s->chain[i % WinSize] = next; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1250 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1251 s->skip = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1252 return next; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1253 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1254 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1255 /* find longest match, next position in the hash chain is given */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1256 static Match getmatch(State *s, int next) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1257 Match m = {0, MinMatch-1}; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1258 int len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1259 int limit = s->pos - MaxDist; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1260 int chainlen = MaxChainLen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1261 uchar *q; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1262 uchar *p = s->src + s->pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1263 uchar *end = p + MaxMatch; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1264 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1265 do { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1266 q = s->src + next; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1267 /*fprintf(stderr,"match: next:%d pos:%d limit:%d\n", next, s->pos, limit);*/ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1268 /* next match should be at least m.len+1 long */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1269 if (q[m.len] != p[m.len] || q[m.len-1] != p[m.len-1] || q[0] != p[0]) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1270 continue; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1271 while (++p != end && *++q == *p); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1272 len = MaxMatch - (end - p); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1273 p -= len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1274 /*fprintf(stderr,"match: len:%d dist:%d\n", len, s->pos - next);*/ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1275 if (len > m.len) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1276 m.dist = s->pos - next; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1277 m.len = len; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1278 if (s->pos + len >= s->endpos) { /* TODO: overflow */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1279 m.len = s->endpos - s->pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1280 return m; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1281 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1282 if (len == MaxMatch) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1283 return m; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1284 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1285 } while ((next = s->chain[next % WinSize]) > limit && --chainlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1286 if (m.len < MinMatch || (m.len == MinMatch && m.dist > BigDist)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1287 m.len = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1288 return m; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1289 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1290 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1291 static void startblock(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1292 s->startpos = s->pos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1293 s->dst = s->dstbegin = s->dstbuf; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1294 s->lz = s->lzbuf; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1295 s->nlit = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1296 memset(s->lfreq, 0, sizeof(s->lfreq)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1297 memset(s->dfreq, 0, sizeof(s->dfreq)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1298 s->lfreq[EOB]++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1299 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1300 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1301 static int shiftwin(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1302 int n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1303 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1304 if (s->startpos < WinSize) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1305 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1306 memmove(s->src, s->src + WinSize, SrcSize - WinSize); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1307 for (n = 0; n < HashSize; n++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1308 s->head[n] = s->head[n] > WinSize ? s->head[n] - WinSize : 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1309 for (n = 0; n < WinSize; n++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1310 s->chain[n] = s->chain[n] > WinSize ? s->chain[n] - WinSize : 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1311 s->pos -= WinSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1312 s->startpos -= WinSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1313 s->endpos -= WinSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1314 return 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1315 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1316 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1317 static int endblock(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1318 if ((s->pos >= 2*WinSize && !shiftwin(s)) || s->pos - s->startpos >= BlockSize || |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1319 s->lz - s->lzbuf >= LzGuard || (s->eof && s->pos == s->endpos)) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1320 /* deflate block */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1321 flushlit(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1322 if (s->prevm.len) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1323 s->pos--; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1324 deflate_block(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1325 if (s->eof && s->pos == s->endpos) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1326 putbits(s, 0, 7); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1327 return 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1328 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1329 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1330 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1331 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1332 static int fillsrc(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1333 int n, k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1334 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1335 if (s->endpos < SrcSize && !s->eof) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1336 n = SrcSize - s->endpos; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1337 k = s->inend - s->in; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1338 if (n > k) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1339 n = k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1340 memcpy(s->src + s->endpos, s->in, n); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1341 s->in += n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1342 s->endpos += n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1343 if (s->endpos < SrcSize) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1344 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1345 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1346 return 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1347 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1348 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1349 static int calcguard(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1350 int p = s->endpos - MaxMatch; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1351 int q = s->startpos + BlockSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1352 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1353 return p < q ? p : q; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1354 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1355 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1356 /* deflate compress from s->src into s->dstbuf */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1357 static int deflate_state(State *s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1358 Match m; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1359 int next; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1360 int guard; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1361 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1362 if (s->state == FlateIn) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1363 s->eof = s->in == s->inend; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1364 else if (s->state == FlateOut) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1365 if (s->dstbegin < s->dst) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1366 return (s->state = FlateOut); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1367 if (s->eof && s->pos == s->endpos) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1368 return (s->state = FlateOk); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1369 startblock(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1370 if (s->prevm.len) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1371 s->pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1372 } else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1373 return s->state; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1374 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1375 guard = calcguard(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1376 for (;;) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1377 if (s->pos >= guard || s->lz - s->lzbuf >= LzGuard) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1378 /*fprintf(stderr,"guard:%d pos:%d len:%d lzlen:%d end:%d start:%d nin:%d eof:%d\n", guard, s->pos, s->pos - s->startpos, s->lz - s->lzbuf, s->endpos, s->startpos, s->inend - s->in, s->eof);*/ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1379 if (endblock(s)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1380 return (s->state = FlateOut); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1381 if (!fillsrc(s)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1382 return (s->state = FlateIn); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1383 guard = calcguard(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1384 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1385 next = updatechain(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1386 if (next) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1387 m = getmatch(s, next); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1388 if (next && m.len > s->prevm.len) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1389 if (s->prevm.len) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1390 recordlit(s, s->src[s->pos-1]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1391 s->prevm = m; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1392 } else if (s->prevm.len) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1393 recordmatch(s, s->prevm); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1394 s->skip = s->prevm.len - 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1395 s->prevm.len = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1396 s->pos += s->skip; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1397 } else |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1398 recordlit(s, s->src[s->pos]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1399 s->pos++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1400 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1401 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1402 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1403 /* alloc and init state */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1404 static State *alloc_state(void) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1405 State *s = malloc(sizeof(State)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1406 int i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1407 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1408 if (!s) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1409 return s; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1410 memset(s->chain, 0, sizeof(s->chain)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1411 memset(s->head, 0, sizeof(s->head)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1412 s->bits = s->nbits = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1413 /* TODO: globals */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1414 if (fixllen[0] == 0) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1415 for (i = 0; i < 144; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1416 fixllen[i] = 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1417 for (; i < 256; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1418 fixllen[i] = 9; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1419 for (; i < 280; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1420 fixllen[i] = 7; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1421 for (; i < Nlitlen; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1422 fixllen[i] = 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1423 for (i = 0; i < Ndist; i++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1424 fixdlen[i] = 5; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1425 huffcodes(fixlcode, fixllen, Nlitlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1426 huffcodes(fixdcode, fixdlen, Ndist); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1427 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1428 s->state = FlateOut; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1429 s->in = s->inend = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1430 s->dst = s->dstbegin = s->dstbuf; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1431 s->pos = s->startpos = s->endpos = WinSize; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1432 s->eof = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1433 s->skip = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1434 s->prevm.len = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1435 return s; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1436 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1437 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1438 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1439 /* extern */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1440 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1441 int deflate(FlateStream *stream) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1442 State *s = stream->state; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1443 int n, k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1444 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1445 if (stream->err) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1446 free(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1447 stream->state = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1448 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1449 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1450 if (!s) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1451 s = stream->state = alloc_state(); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1452 if (!s) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1453 return stream->err = "no mem.", FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1454 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1455 if (stream->nin) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1456 s->in = stream->in; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1457 s->inend = s->in + stream->nin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1458 stream->nin = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1459 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1460 n = deflate_state(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1461 if (n == FlateOut) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1462 k = s->dst - s->dstbegin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1463 if (k < stream->nout) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1464 stream->nout = k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1465 memcpy(stream->out, s->dstbegin, stream->nout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1466 s->dstbegin += stream->nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1467 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1468 if (n == FlateOk || n == FlateErr) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1469 free(s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1470 stream->state = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1471 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1472 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1473 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1474 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1475 static void set32(uchar *p, uint n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1476 p[0] = n >> 24; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1477 p[1] = n >> 16; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1478 p[2] = n >> 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1479 p[3] = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1480 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1481 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1482 static void set32le(uchar *p, uint n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1483 p[0] = n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1484 p[1] = n >> 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1485 p[2] = n >> 16; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1486 p[3] = n >> 24; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1487 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1488 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1489 static int check32(uchar *p, uint n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1490 return n == ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1491 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1492 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1493 static int check32le(uchar *p, uint n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1494 return n == (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1495 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1496 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1497 enum { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1498 ZlibCM = 7 << 4, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1499 ZlibCINFO = 8, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1500 ZlibFLEV = 3 << 6, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1501 ZlibFDICT = 1 << 5, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1502 ZlibFCHK = 31 - (((ZlibCM | ZlibCINFO) << 8) | ZlibFLEV) % 31 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1503 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1504 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1505 int deflate_zlib_header(uchar *p, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1506 if (n < 2) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1507 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1508 p[0] = ZlibCM | ZlibCINFO; /* deflate method, 32K window size */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1509 p[1] = ZlibFLEV | ZlibFCHK; /* highest compression */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1510 return 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1511 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1512 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1513 int deflate_zlib_footer(uchar *p, int n, uint sum, uint len, uint zlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1514 if (n < 4) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1515 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1516 set32(p, sum); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1517 return 4; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1518 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1519 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1520 int inflate_zlib_header(uchar *p, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1521 if (n < 2) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1522 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1523 if (((p[0] << 8) | p[1]) % 31) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1524 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1525 if ((p[0] & 0xf0) != ZlibCM || (p[0] & 0x0f) > ZlibCINFO) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1526 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1527 if (p[1] & ZlibFDICT) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1528 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1529 return 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1530 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1531 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1532 int inflate_zlib_footer(uchar *p, int n, uint sum, uint len, uint zlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1533 if (n < 4 || !check32(p, sum)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1534 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1535 return 4; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1536 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1537 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1538 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1539 enum { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1540 GZipID1 = 0x1f, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1541 GZipID2 = 0x8b, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1542 GZipCM = 8, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1543 GZipFHCRC = 1 << 1, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1544 GZipFEXTRA = 1 << 2, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1545 GZipFNAME = 1 << 3, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1546 GZipFCOMM = 1 << 4, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1547 GZipXFL = 2, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1548 GZipOS = 255 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1549 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1550 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1551 int deflate_gzip_header(uchar *p, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1552 if (n < 10) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1553 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1554 memset(p, 0, 10); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1555 p[0] = GZipID1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1556 p[1] = GZipID2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1557 p[2] = GZipCM; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1558 p[8] = GZipXFL; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1559 p[9] = GZipOS; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1560 return 10; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1561 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1562 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1563 int deflate_gzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1564 if (n < 8) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1565 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1566 set32le(p, sum); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1567 set32le(p+4, len); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1568 return 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1569 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1570 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1571 int inflate_gzip_header(uchar *p, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1572 int k = 10; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1573 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1574 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1575 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1576 if (p[0] != GZipID1 || p[1] != GZipID2 || p[2] != GZipCM) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1577 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1578 if (p[3] & GZipFEXTRA) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1579 k += 2 + ((p[k] << 8) | p[k+1]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1580 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1581 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1582 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1583 if (p[3] & GZipFNAME) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1584 for (; k < n; k++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1585 if (p[k] == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1586 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1587 k++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1588 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1589 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1590 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1591 if (p[3] & GZipFCOMM) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1592 for (; k < n; k++) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1593 if (p[k] == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1594 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1595 k++; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1596 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1597 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1598 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1599 if (p[3] & GZipFHCRC) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1600 k += 2; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1601 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1602 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1603 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1604 return k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1605 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1606 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1607 int inflate_gzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1608 if (n < 8 || !check32le(p, sum) || !check32le(p+4, len)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1609 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1610 return 8; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1611 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1612 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1613 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1614 static char pkname[] = "sflate_stream"; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1615 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1616 enum { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1617 PKHeadID = 0x04034b50, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1618 PKDataID = 0x08074b50, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1619 PKDirID = 0x02014b50, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1620 PKFootID = 0x06054b50, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1621 PKVersion = 20, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1622 PKFlag = 1 << 3, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1623 PKMethod = 8, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1624 PKDate = ((2009 - 1980) << 25) | (1 << 21) | (1 << 16), |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1625 PKHeadSize = 30, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1626 PKDirSize = 46, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1627 PKNameLen = sizeof(pkname) - 1 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1628 }; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1629 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1630 int deflate_pkzip_header(uchar *p, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1631 if (n < PKHeadSize + PKNameLen) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1632 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1633 memset(p, 0, PKHeadSize); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1634 set32le(p, PKHeadID); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1635 set32le(p+4, PKVersion); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1636 set32le(p+6, PKFlag); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1637 set32le(p+8, PKMethod); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1638 set32le(p+10, PKDate); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1639 set32le(p+26, PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1640 memcpy(p + PKHeadSize, pkname, PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1641 return PKHeadSize + PKNameLen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1642 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1643 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1644 int deflate_pkzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1645 if (n < PKDirSize + PKNameLen + 22) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1646 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1647 /* unzip bug */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1648 /* |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1649 if (n < 16 + PKDirSize + PKNameLen + 22) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1650 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1651 set32le(p, PKDataID); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1652 set32le(p+4, sum); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1653 set32le(p+8, zlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1654 set32le(p+12, len); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1655 p += 16; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1656 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1657 memset(p, 0, PKDirSize); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1658 set32le(p, PKDirID); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1659 set32le(p+4, PKVersion | (PKVersion << 16)); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1660 set32le(p+8, PKFlag); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1661 set32le(p+10, PKMethod); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1662 set32le(p+12, PKDate); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1663 set32le(p+16, sum); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1664 set32le(p+20, zlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1665 set32le(p+24, len); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1666 set32le(p+28, PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1667 memcpy(p + PKDirSize, pkname, PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1668 p += PKDirSize + PKNameLen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1669 memset(p, 0, 22); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1670 set32le(p, PKFootID); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1671 p[8] = p[10] = 1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1672 set32le(p+12, PKDirSize + PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1673 set32le(p+16, zlen + PKHeadSize + PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1674 return PKDirSize + PKNameLen + 22; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1675 /* |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1676 set32le(p+12, 16 + PKDirSize + PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1677 set32le(p+16, zlen + PKHeadSize + PKNameLen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1678 return 16 + PKDirSize + PKNameLen + 22; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1679 */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1680 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1681 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1682 int inflate_pkzip_header(uchar *p, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1683 int k = 30; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1684 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1685 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1686 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1687 if (!check32le(p, PKHeadID)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1688 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1689 if ((p[4] | (p[5] << 8)) > PKVersion) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1690 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1691 if ((p[8] | (p[9] << 8)) != PKMethod) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1692 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1693 k += p[26] | (p[27] << 8); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1694 k += p[28] | (p[29] << 8); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1695 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1696 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1697 return k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1698 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1699 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1700 int inflate_pkzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1701 int k = PKDirSize + 22; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1702 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1703 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1704 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1705 if (check32le(p, PKDataID)) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1706 p += 16; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1707 k += 16; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1708 if (k > n) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1709 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1710 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1711 if (!check32le(p, PKDirID)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1712 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1713 if (!check32le(p+16, sum)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1714 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1715 if (!check32le(p+20, zlen)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1716 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1717 if (!check32le(p+24, len)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1718 return FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1719 return k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1720 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1721 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1722 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1723 /* example usage */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1724 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1725 static int (*header)(uchar *, int); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1726 static int (*footer)(uchar *, int, uint, uint, uint); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1727 static uint (*checksum)(uchar *, int, uint); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1728 static char *err; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1729 static uint sum; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1730 static uint nin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1731 static uint nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1732 static uint headerlen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1733 static uint footerlen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1734 static uint extralen; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1735 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1736 static int dummyheader(uchar *p, int n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1737 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1738 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1739 static int dummyfooter(uchar *p, int n, uint sum, uint len, uint zlen) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1740 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1741 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1742 static uint dummysum(uchar *p, int n, uint sum) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1743 return 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1744 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1745 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1746 /* compress, using FlateStream interface */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1747 int compress_stream(FILE *in, FILE *out) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1748 FlateStream s; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1749 int k, n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1750 enum {Nin = 1<<15, Nout = 1<<15}; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1751 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1752 s.in = malloc(Nin); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1753 s.out = malloc(Nout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1754 s.nin = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1755 s.nout = Nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1756 s.err = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1757 s.state = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1758 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1759 k = header(s.out, s.nout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1760 if (k == FlateErr) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1761 s.err = "header error."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1762 n = FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1763 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1764 headerlen = s.nout = k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1765 n = FlateOut; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1766 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1767 for (;; n = deflate(&s)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1768 switch (n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1769 case FlateOk: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1770 k = footer(s.out, s.nout, sum, nin, nout - headerlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1771 if (k == FlateErr) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1772 s.err = "footer error."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1773 n = FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1774 } else if (k != fwrite(s.out, 1, k, out)) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1775 s.err = "write error."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1776 n = FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1777 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1778 footerlen = k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1779 nout += k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1780 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1781 case FlateErr: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1782 free(s.in); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1783 free(s.out); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1784 err = s.err; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1785 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1786 case FlateIn: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1787 s.nin = fread(s.in, 1, Nin, in); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1788 nin += s.nin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1789 sum = checksum(s.in, s.nin, sum); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1790 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1791 case FlateOut: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1792 k = fwrite(s.out, 1, s.nout, out); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1793 if (k != s.nout) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1794 s.err = "write error."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1795 nout += k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1796 s.nout = Nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1797 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1798 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1799 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1800 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1801 /* decompress, using FlateStream interface */ |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1802 int decompress_stream(FILE *in, FILE *out) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1803 FlateStream s; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1804 uchar *begin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1805 int k, n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1806 enum {Nin = 1<<15, Nout = 1<<15}; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1807 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1808 s.in = begin = malloc(Nin); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1809 s.out = malloc(Nout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1810 s.nout = Nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1811 s.err = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1812 s.state = 0; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1813 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1814 s.nin = fread(s.in, 1, Nin, in); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1815 nin += s.nin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1816 k = header(s.in, s.nin); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1817 if (k == FlateErr) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1818 s.err = "header error."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1819 n = FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1820 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1821 headerlen = k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1822 s.nin -= k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1823 s.in += k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1824 n = inflate(&s); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1825 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1826 for (;; n = inflate(&s)) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1827 switch (n) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1828 case FlateOk: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1829 memmove(begin, s.in, s.nin); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1830 k = fread(begin, 1, Nin-s.nin, in); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1831 nin += k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1832 s.nin += k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1833 k = footer(begin, s.nin, sum, nout, nin - s.nin - headerlen); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1834 if (k == FlateErr) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1835 s.err = "footer error."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1836 n = FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1837 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1838 footerlen = k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1839 extralen = s.nin - k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1840 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1841 case FlateErr: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1842 free(begin); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1843 free(s.out); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1844 err = s.err; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1845 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1846 case FlateIn: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1847 s.in = begin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1848 s.nin = fread(s.in, 1, Nin, in); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1849 nin += s.nin; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1850 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1851 case FlateOut: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1852 k = fwrite(s.out, 1, s.nout, out); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1853 if (k != s.nout) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1854 s.err = "write error."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1855 sum = checksum(s.out, k, sum); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1856 nout += k; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1857 s.nout = Nout; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1858 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1859 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1860 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1861 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1862 static int old_main(int argc, char *argv[]) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1863 char comp = 'c'; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1864 char fmt = 'r'; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1865 char verbose = 'q'; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1866 int (*call)(FILE *, FILE*); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1867 int n, i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1868 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1869 for (i = 1; i < argc; i++) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1870 if (argv[i][0] == '-' && argv[i][1] && argv[i][2] == 0) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1871 switch (argv[i][1]) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1872 case 'q': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1873 case 'v': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1874 verbose = argv[i][1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1875 continue; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1876 case 'c': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1877 case 'd': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1878 comp = argv[i][1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1879 continue; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1880 case 'r': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1881 case 'g': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1882 case 'z': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1883 case 'p': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1884 fmt = argv[i][1]; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1885 continue; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1886 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1887 fprintf(stderr, "usage: %s [-q|-v] [-c|-d] [-r|-g|-z|-p]\n\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1888 "deflate stream compression\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1889 " -q quiet (default)\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1890 " -v verbose\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1891 " -c compress (default)\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1892 " -d decompress\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1893 " -r raw (default)\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1894 " -g gzip\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1895 " -z zlib\n" |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1896 " -p pkzip\n", argv[0]); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1897 return -1; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1898 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1899 call = comp == 'c' ? compress_stream : decompress_stream; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1900 switch (fmt) { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1901 case 'r': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1902 header = dummyheader; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1903 footer = dummyfooter; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1904 checksum = dummysum; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1905 n = call(stdin, stdout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1906 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1907 case 'g': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1908 if (comp == 'c') { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1909 header = deflate_gzip_header; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1910 footer = deflate_gzip_footer; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1911 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1912 header = inflate_gzip_header; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1913 footer = inflate_gzip_footer; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1914 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1915 checksum = crc32; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1916 crc32init(); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1917 n = call(stdin, stdout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1918 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1919 case 'z': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1920 if (comp == 'c') { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1921 header = deflate_zlib_header; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1922 footer = deflate_zlib_footer; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1923 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1924 header = inflate_zlib_header; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1925 footer = inflate_zlib_footer; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1926 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1927 checksum = adler32; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1928 n = call(stdin, stdout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1929 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1930 case 'p': |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1931 if (comp == 'c') { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1932 header = deflate_pkzip_header; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1933 footer = deflate_pkzip_footer; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1934 } else { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1935 header = inflate_pkzip_header; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1936 footer = inflate_pkzip_footer; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1937 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1938 checksum = crc32; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1939 crc32init(); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1940 n = call(stdin, stdout); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1941 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1942 default: |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1943 err = "uninplemented."; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1944 n = FlateErr; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1945 break; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1946 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1947 if (verbose == 'v') |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1948 fprintf(stderr, "in:%d out:%d checksum: 0x%08x (header:%d data:%d footer:%d extra input:%s)\n", |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1949 nin, nout, sum, headerlen, (comp == 'c' ? nout : nin) - headerlen - footerlen - extralen, |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1950 footerlen, extralen ? "yes" : "no"); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1951 if (n != FlateOk) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1952 fprintf(stderr, "error: %s\n", err); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1953 return n; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1954 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1955 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1956 // Total hack |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1957 void gzip_main(void) |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1958 { |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1959 int i; |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1960 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1961 for (i=0; toys.argv[i]; i++); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1962 old_main(i, toys.argv); |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1963 } |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1964 |
95ae2805622f
Add Szabolcs Nagy's deflate/inflate code from git://git.suckless.org/flate
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1965 |