Skip to content

Commit 65772af

Browse files
committed
Reduce amount of memory copying between tables by allowing a offset to be applied to the mh() function.
1 parent 53f6cc1 commit 65772af

1 file changed

Lines changed: 33 additions & 56 deletions

File tree

arch/INFLATE.LUA

Lines changed: 33 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function inflate(r, w, f)
1515
-- lex = Length base & extra bits (pairs of bytes)
1616
-- dix = Distance extra bits (1 byte per entry)
1717
-- dib = Distance base (packed 32-bit LE)
18-
local b, p, bb, bc, op, kg, lex, dix, dib = "", 1, 0, 0, 0, 1,
18+
local b, p, bb, bc, op, kg, le, ll, dl, lex, dix, dib = "", 1, 0, 0, 0, 1, {}, {}, {},
1919

2020
-- lex, dix & dib are packed string constants
2121
"\3\0\4\0\5\0\6\0\7\0\8\0\9\0\10\0\11\1\13\1\15\1\17\1\19\2\23\2\27\2\31\2\35\3\43\3\51\3\59\3\67\4\83\4\99\4\115\4\131\5\163\5\195\5\227\5\2\0",
@@ -76,35 +76,26 @@ function inflate(r, w, f)
7676

7777
---Constructs a canonical Huffman decoding table from a list of code lengths.
7878
---@param ls table An array where the index is the symbol and the value is its bit length.
79+
---@param nc number The number of codes to process from the table.
80+
---@param off number The offset in the table to start from.
7981
---@return table A Huffman object containing the lookup table (`tab`) and the maximum code length (`max`).
80-
function mh(ls)
81-
82-
-- m = Maximum length
83-
-- c = Counts
84-
-- d = Code
85-
-- n = Next code
86-
-- t = Tab
82+
function mh(ls, nc, off)
83+
off = off or 0
8784
local m, c, d, n, t = 0, {}, 0, {}, {}
8885

89-
-- l = Length
90-
for _, l in ipairs(ls) do
91-
if l > 0 then
86+
for i = 1, nc do
87+
local l = ls[i + off]
88+
if l and l > 0 then
9289
c[l] = (c[l] or 0) + 1
93-
if l > m then m = l
94-
end
90+
if l > m then m = l end
9591
end
9692
end
9793

98-
-- i = Bits
99-
for i = 1, m do
100-
d = (d + (c[i - 1] or 0)) << 1
101-
n[i] = d
102-
end
94+
for i = 1, m do d = (d + (c[i - 1] or 0)) << 1 n[i] = d end
10395

104-
-- s = Sym
105-
-- l = Len
106-
for s, l in ipairs(ls) do
107-
if l > 0 then
96+
for s = 1, nc do
97+
local l = ls[s + off]
98+
if l and l > 0 then
10899
t[rv(n[l], l)] = { sym = s - 1, len = l }
109100
n[l] = n[l] + 1
110101
end
@@ -174,56 +165,42 @@ function inflate(r, w, f)
174165
-- dl = Distance bit-lengths
175166
-- h = Literal/length Huffman decoding table
176167
-- d = Distance Huffman decoding table
177-
local ll, dl, h, d = {}, {}
168+
local h, d = {}, {}
178169

179170
if t == 1 then
180-
-- Fixed Huffman
181-
for _ = 0, 143 do ll[#ll + 1] = 8 end
182-
for _ = 144, 255 do ll[#ll + 1] = 9 end
183-
for _ = 256, 279 do ll[#ll + 1] = 7 end
184-
for _ = 280, 287 do ll[#ll + 1] = 8 end
185-
h = mh(ll)
186-
for _ = 0, 31 do dl[#dl + 1] = 5 end
187-
d = mh(dl)
171+
-- Fixed Huffman: Use le as a scratchpad
172+
for i = 1, 144 do le[i] = 8 end
173+
for i = 145, 256 do le[i] = 9 end
174+
for i = 257, 280 do le[i] = 7 end
175+
for i = 281, 288 do le[i] = 8 end
176+
h = mh(le, 288)
177+
for i = 289, 289 + 31 do le[i] = 5 end
178+
d = mh(le, 32, 288)
188179
else
189180
-- Dynamic Huffman
190-
191-
-- hl = Literal/length code count (HLIT)
192-
-- hd = Distance code count (HDIST)
193-
-- hc = Meta-code length count (HCLEN)
194-
-- od = Permutation order for code lengths
195-
-- cl = Code lengths for the meta-table
196-
-- le = Decoded bit-lengths for literal/distance tables
197-
-- ch = Huffman table for decoding bit-lengths
198-
local hl, hd, hc, od, cl, le, ch = rb(5) + 257, rb(5) + 1, rb(4) + 4, "\16\17\18\0\8\7\9\6\10\5\11\4\12\3\13\2\14\1\15", {}, {}
181+
local hl, hd, hc, od, cl = rb(5) + 257, rb(5) + 1, rb(4) + 4, "\16\17\18\0\8\7\9\6\10\5\11\4\12\3\13\2\14\1\15", {}
199182

200183
for i = 1, 19 do cl[i] = 0 end
201184
for i = 1, hc do cl[od:byte(i) + 1] = rb(3) end
202-
ch = mh(cl)
203-
204-
while #le < hl + hd do
185+
local ch = mh(cl, 19)
205186

206-
-- s = Symbol
207-
-- x = Repeat count
208-
-- l = Code length
187+
local lei = 1
188+
while lei <= hl + hd do
209189
local s, x, l = rh(ch)
210-
211190
if s <= 15 then
212-
le[#le + 1] = s
191+
le[lei] = s; lei = lei + 1
213192
elseif s == 16 then
214-
x, l = rb(2) + 3, le[#le]
215-
for _ = 1, x do le[#le + 1] = l end
193+
x, l = rb(2) + 3, le[lei - 1]
194+
for _ = 1, x do le[lei] = l; lei = lei + 1 end
216195
elseif s == 17 then
217196
x = rb(3) + 3
218-
for _ = 1, x do le[#le + 1] = 0 end
197+
for _ = 1, x do le[lei] = 0; lei = lei + 1 end
219198
elseif s == 18 then
220199
x = rb(7) + 11
221-
for _ = 1, x do le[#le + 1] = 0 end
200+
for _ = 1, x do le[lei] = 0; lei = lei + 1 end
222201
end
223202
end
224-
for i = 1, hl do ll[i] = le[i] end
225-
for i = hl + 1, hl + hd do dl[i - hl] = le[i] end
226-
h = mh(ll) d = mh(dl)
203+
h = mh(le, hl) d = mh(le, hd, hl)
227204
end
228205

229206
while true do
@@ -268,7 +245,7 @@ function inflate(r, w, f)
268245
end
269246

270247
-- Read from output history using the file-backed sliding window
271-
f:seek("end", -dv)
248+
f:seek("set", op - dv)
272249

273250
-- n = Pattern
274251
local n = f:read(math.min(dv, l))

0 commit comments

Comments
 (0)