Skip to content

Commit 2dd4a62

Browse files
committed
Refactored INFLATE.LUA so that all helper functions are nested where they're relevant.
1 parent 0183f9b commit 2dd4a62

File tree

1 file changed

+116
-115
lines changed

1 file changed

+116
-115
lines changed

arch/INFLATE.LUA

Lines changed: 116 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,72 @@
1-
---New bit stream
2-
local function nbs(r)
3-
4-
-- b = buffer
5-
-- p = position
6-
-- bb = bit buffer
7-
-- bc = bit count
8-
local b, p, bb, bc = "", 1, 0, 0
9-
10-
---Fill
11-
local function F()
12-
if p > #b then
13-
b = r()
14-
if b or #b ~= 0 then p = 1 else return 0 end
15-
end
16-
return 1
17-
end
18-
19-
---Need bits
20-
local function nb(n)
21-
while bc < n do
22-
if p > #b then
23-
if F()==0 then error("!EOF",0) end
24-
end
25-
bb = bb + (b:byte(p) << bc)
26-
p = p + 1
27-
bc = bc + 8
28-
end
29-
end
30-
31-
---Read bits
32-
local function rb(n)
33-
nb(n)
34-
local v = bb & ((1 << n) - 1)
35-
bb, bc = (bb >> n), bc - n
36-
return v
37-
end
38-
39-
---Align byte
40-
local function ab() bb, bc = 0, 0 end
41-
42-
return { r = rb, a = ab }
43-
end
44-
45-
---Reverse bits
46-
local function rv(x, bits)
47-
local y = 0
48-
49-
for _ = 1, bits do
50-
y = (y << 1) | (x & 1)
51-
x = x >> 1
52-
end
53-
54-
return y
55-
end
1+
---Inflate (a.k.a decompress) a deflated file inside a zip
2+
---@param r function The reader function
3+
---@param w function The writer function
4+
function inflate(r, w)
565

57-
---Make huffman
58-
local function mh(lengths)
6+
---New bit stream
7+
function nbs(rf)
8+
9+
-- b = buffer
10+
-- p = position
11+
-- bb = bit buffer
12+
-- bc = bit count
13+
local b, p, bb, bc = "", 1, 0, 0
14+
15+
---Need bits
16+
function nb(n)
17+
while bc < n do
18+
if p > #b then
19+
20+
---Fill
21+
function I()
22+
if p > #b then
23+
b = rf()
24+
if b or #b ~= 0 then p = 1 else return 0 end
25+
end
26+
return 1
27+
end
5928

60-
-- m = maximum length
61-
-- c = counts
62-
-- o = code
63-
-- n = next code
64-
-- t = tab
65-
local m, c, o, n, t = 0, {}, 0, {}, {}
29+
if I()==0 then error("!EOF",0) end
30+
end
6631

67-
for _, len in ipairs(lengths) do
68-
if len > 0 then
69-
c[len] = (c[len] or 0) + 1
70-
if len > m then m = len end
32+
bb = bb + (b:byte(p) << bc)
33+
p = p + 1
34+
bc = bc + 8
35+
end
7136
end
72-
end
73-
74-
-- b = bits
75-
for b = 1, m do
76-
o = (o + (c[b - 1] or 0)) << 1
77-
n[b] = o
78-
end
7937

80-
-- s = sym
81-
-- l = len
82-
for s, l in ipairs(lengths) do
83-
if l > 0 then
84-
local r = rv(n[l], l)
85-
t[r] = { sym = s - 1, len = l }
86-
n[l] = n[l] + 1
38+
---Read bits
39+
function rb(n)
40+
nb(n)
41+
local v = bb & ((1 << n) - 1)
42+
bb, bc = (bb >> n), bc - n
43+
return v
8744
end
88-
end
89-
90-
return { tab = t, max = m }
91-
end
92-
93-
---Read huffman
94-
local function rh(bs, h)
9545

96-
-- c = code
97-
local c = 0
46+
---Align byte
47+
function ab() bb, bc = 0, 0 end
9848

99-
-- l = len
100-
for l = 1, h.max do
101-
c = c | (bs.r(1) << (l - 1))
102-
local e = h.tab[c & ((1 << l) - 1)]
103-
if e and e.len == l then return e.sym end
49+
return { r = rb, a = ab }
10450
end
10551

106-
error("!Huffman", 0)
107-
end
108-
109-
---Inflate a deflated file inside a zip
110-
---@param r function The reader function
111-
---@param w function The writer function
112-
function inflate(r, w)
113-
11452
-- bs = bit stream
11553
-- op = output position
11654
-- kg = keep going (in a loop)
11755
-- sw = sliding window (32KB circular buffer)
11856
-- wp = window pointer
11957
-- o = output chunk buffer
120-
local bs, op, kg, sw, wp, o = nbs(r), 0, true, {}, 0, {}
58+
local bs, op, kg, sw, wp, o = nbs(r), 0, 1, {}, 0, {}
12159

12260
---Flush all unwritten data to the output file
123-
local function F()
61+
function F()
12462
if #o > 0 then
12563
w(table.concat(o))
12664
o = {}
12765
end
12866
end
12967

13068
---Append byte
131-
local function ab(byte)
69+
function ab(byte)
13270
op = op + 1
13371

13472
-- Add to output chunk
@@ -140,20 +78,83 @@ function inflate(r, w)
14078
wp = (wp + 1) % 32768
14179
end
14280

81+
---Make huffman
82+
function mh(lengths)
83+
84+
-- m = maximum length
85+
-- c = counts
86+
-- o = code
87+
-- n = next code
88+
-- t = tab
89+
local m, c, o, n, t = 0, {}, 0, {}, {}
90+
91+
for _, len in ipairs(lengths) do
92+
if len > 0 then
93+
c[len] = (c[len] or 0) + 1
94+
if len > m then m = len end
95+
end
96+
end
97+
98+
-- b = bits
99+
for b = 1, m do
100+
o = (o + (c[b - 1] or 0)) << 1
101+
n[b] = o
102+
end
103+
104+
---Reverse bits
105+
function rv(x, bits)
106+
local y = 0
107+
108+
for _ = 1, bits do
109+
y = (y << 1) | (x & 1)
110+
x = x >> 1
111+
end
112+
113+
return y
114+
end
115+
116+
-- s = sym
117+
-- l = len
118+
for s, l in ipairs(lengths) do
119+
if l > 0 then
120+
t[rv(n[l], l)] = { sym = s - 1, len = l }
121+
n[l] = n[l] + 1
122+
end
123+
end
124+
125+
return { tab = t, max = m }
126+
end
127+
128+
---Read huffman
129+
function rh(h)
130+
131+
-- c = code
132+
local c = 0
133+
134+
-- l = len
135+
for l = 1, h.max do
136+
c = c | (bs.r(1) << (l - 1))
137+
local e = h.tab[c & ((1 << l) - 1)]
138+
if e and e.len == l then return e.sym end
139+
end
140+
141+
error("!Huffman", 0)
142+
end
143+
143144
---Append string
144-
local function as(s) for i = 1, #s do ab(s:byte(i)) end end
145+
function as(s) for i = 1, #s do ab(s:byte(i)) end end
145146

146-
while kg do
147+
while kg > 0 do
147148

148149
-- f = final
149150
-- t = block type
150151
local f, t = bs.r(1), bs.r(2)
151152

152153
if t == 0 then
153154
-- uncompressed block: align, then read LEN, NLEN from byte stream
154-
local h, len, s = bs.ra(4)
155-
len = h:byte(1) + h:byte(2)*256
156-
s = bs.ra(len)
155+
local h, l, s = bs.ra(4)
156+
l = h:byte(1) + h:byte(2)*256
157+
s = bs.ra(l)
157158
as(s)
158159

159160
elseif t == 1 or t == 2 then
@@ -186,7 +187,7 @@ function inflate(r, w)
186187
while #le < hl + hd do
187188

188189
-- s = sym
189-
local s = rh(bs, ch)
190+
local s = rh(ch)
190191

191192
if s <= 15 then
192193
le[#le + 1] = s
@@ -225,7 +226,7 @@ function inflate(r, w)
225226

226227
while true do
227228
-- s = sym
228-
local s = rh(bs, h)
229+
local s = rh(h)
229230
if s < 256 then
230231
ab(s)
231232
elseif s == 256 then
@@ -246,7 +247,7 @@ function inflate(r, w)
246247

247248
b, x = e[1], e[2]
248249
a = x > 0 and bs.r(x) or 0
249-
l, ds = b + a, rh(bs, d)
250+
l, ds = b + a, rh(d)
250251
de = dix[ds + 1]
251252
db, dx = de[1], de[2]
252253
da = dx > 0 and bs.r(dx) or 0
@@ -267,7 +268,7 @@ function inflate(r, w)
267268
error("!Unsupported", 0)
268269
end
269270

270-
if f == 1 then kg = false end
271+
if f == 1 then kg = 0 end
271272
end
272273

273274
F()

0 commit comments

Comments
 (0)