11#! /usr/bin/env lua
22
3- local function newbitstream (data )
4- local pos , bitbuf , bitcnt = 1 , 0 , 0
5- local function needbits (n )
6- while bitcnt < n do
7- bitbuf = bitbuf + ((data :byte (pos ) or 0 ) << bitcnt )
8- pos = pos + 1
9- bitcnt = bitcnt + 8
3+ -- nbs = new bit stream
4+ local function nbs (data )
5+
6+ -- p = position
7+ -- bb = bit buffer
8+ -- bc = bit count
9+ local p , bb , bc = 1 , 0 , 0
10+
11+ -- nb = need bits
12+ local function nb (n )
13+ while bc < n do
14+ bb = bb + ((data :byte (p ) or 0 ) << bc )
15+ p = p + 1
16+ bc = bc + 8
1017 end
1118 end
12- local function readbits (n )
13- needbits (n )
14- local v = bitbuf & ((1 << n ) - 1 )
15- bitbuf , bitcnt = (bitbuf >> n ), bitcnt - n
19+
20+ -- rb = read bits
21+ local function rb (n )
22+ nb (n )
23+ local v = bb & ((1 << n ) - 1 )
24+ bb , bc = (bb >> n ), bc - n
1625 return v
1726 end
18- local function alignbyte () bitbuf , bitcnt = 0 , 0 end
19- local function skip (n ) pos = pos + n end
20- return { readbits = readbits , align = alignbyte , pos = pos , skip = skip }
27+
28+ -- ab = align byte
29+ local function ab () bb , bc = 0 , 0 end
30+
31+ -- s = skip
32+ local function s (n ) p = p + n end
33+
34+ return { r = rb , a = ab , p = p , s = s }
2135end
2236
2337local function revbits (x , bits )
2438 local y = 0
39+
2540 for _ = 1 , bits do
2641 y = (y << 1 ) | (x & 1 )
2742 x = x >> 1
2843 end
44+
2945 return y
3046end
3147
@@ -71,7 +87,7 @@ local function read_huff(bs, h)
7187
7288 -- l = len
7389 for l = 1 , h .max do
74- c = c | (bs .readbits (1 ) << (l - 1 ))
90+ c = c | (bs .r (1 ) << (l - 1 ))
7591 local e = h .tab [c & ((1 << l ) - 1 )]
7692 if e and e .len == l then return e .sym end
7793 end
@@ -80,40 +96,50 @@ local function read_huff(bs, h)
8096end
8197
8298local function inflate (data )
83- local bs , out , outpos = newbitstream (data ), {}, 0
84- local function append_byte (byte )
85- outpos = outpos + 1
86- out [outpos ] = string.char (byte )
99+
100+ -- bs = bit stream
101+ -- o = output byte stream
102+ -- op = output position
103+ -- d = done
104+ local bs , o , op , d = nbs (data ), {}, 0 , false
105+
106+ -- ab = append byte
107+ local function ab (byte )
108+ op = op + 1
109+ o [op ] = string.char (byte )
87110 end
88- local function append_str (s )
111+
112+ -- as = append string
113+ local function as (s )
89114 -- push each byte as single-character entry
90115 for i = 1 , # s do
91- outpos = outpos + 1
92- out [ outpos ] = s :sub (i ,i )
116+ op = op + 1
117+ o [ op ] = s :sub (i ,i )
93118 end
94119 end
95120
96- local done = false
97- while not done do
98- local final = bs .readbits (1 )
99- local btype = bs .readbits (2 )
121+ while not d do
100122
101- if btype == 0 then
123+ -- f = final
124+ -- t = block type
125+ local f , t = bs .r (1 ), bs .r (2 )
126+
127+ if t == 0 then
102128 -- uncompressed block: align, then read LEN, NLEN from byte stream
103- bs .align ()
104- local p = bs .pos ()
129+ bs .a ()
130+ local p = bs .p ()
105131 local function le16 (s , i )
106132 local a ,b = s :byte (i ,i + 1 ) return a + b * 256
107133 end
108134 local len , _ = le16 (data , p ), le16 (data , p + 2 )
109- bs .skip (4 ) -- consume LEN and NLEN
110- local s = data :sub (bs .pos (), bs .pos () + len - 1 )
111- append_str (s )
112- bs .skip (len )
135+ bs .s (4 ) -- consume LEN and NLEN
136+ local s = data :sub (bs .p (), bs .p () + len - 1 )
137+ as (s )
138+ bs .s (len )
113139
114- elseif btype == 1 or btype == 2 then
140+ elseif t == 1 or t == 2 then
115141 local litlen , dist
116- if btype == 1 then
142+ if t == 1 then
117143 -- fixed Huffman
118144 local ll = {}
119145 for _ = 0 , 143 do ll [# ll + 1 ] = 8 end
@@ -126,28 +152,28 @@ local function inflate(data)
126152 dist = make_huff (dl )
127153 else
128154 -- dynamic Huffman
129- local hlit = bs .readbits (5 ) + 257
130- local hdist = bs .readbits (5 ) + 1
131- local hclen = bs .readbits (4 ) + 4
155+ local hlit = bs .r (5 ) + 257
156+ local hdist = bs .r (5 ) + 1
157+ local hclen = bs .r (4 ) + 4
132158 local order = {16 ,17 ,18 ,0 ,8 ,7 ,9 ,6 ,10 ,5 ,11 ,4 ,12 ,3 ,13 ,2 ,14 ,1 ,15 }
133159 local clen = {}
134160 for i = 1 , 19 do clen [i ] = 0 end
135- for i = 1 , hclen do clen [order [i ] + 1 ] = bs .readbits (3 ) end
161+ for i = 1 , hclen do clen [order [i ] + 1 ] = bs .r (3 ) end
136162 local chuff = make_huff (clen )
137163 local lens = {}
138164 while # lens < hlit + hdist do
139165 local sym = read_huff (bs , chuff )
140166 if sym <= 15 then
141167 lens [# lens + 1 ] = sym
142168 elseif sym == 16 then
143- local r = bs .readbits (2 ) + 3
169+ local r = bs .r (2 ) + 3
144170 local last = lens [# lens ]
145171 for _ = 1 , r do lens [# lens + 1 ] = last end
146172 elseif sym == 17 then
147- local r = bs .readbits (3 ) + 3
173+ local r = bs .r (3 ) + 3
148174 for _ = 1 , r do lens [# lens + 1 ] = 0 end
149175 elseif sym == 18 then
150- local r = bs .readbits (7 ) + 11
176+ local r = bs .r (7 ) + 11
151177 for _ = 1 , r do lens [# lens + 1 ] = 0 end
152178 end
153179 end
@@ -175,38 +201,38 @@ local function inflate(data)
175201 while true do
176202 local sym = read_huff (bs , litlen )
177203 if sym < 256 then
178- append_byte (sym )
204+ ab (sym )
179205 elseif sym == 256 then
180206 break
181207 else
182208 local entry = len_extra [sym ]
183209 local base , extra = entry [1 ], entry [2 ]
184- local add = extra > 0 and bs .readbits (extra ) or 0
210+ local add = extra > 0 and bs .r (extra ) or 0
185211 local length , dsym = base + add , read_huff (bs , dist )
186212 local dentry = dist_extra [dsym + 1 ]
187213 local dbase , dextra = dentry [1 ], dentry [2 ]
188- local dadd = dextra > 0 and bs .readbits (dextra ) or 0
214+ local dadd = dextra > 0 and bs .r (dextra ) or 0
189215 local distval = dbase + dadd
190216
191- if distval <= 0 or distval > outpos then
192- error (" invalid distance " .. tostring (distval ).. " (outpos=" .. tostring (outpos ).. " )" )
217+ if distval <= 0 or distval > op then
218+ error (" invalid distance " .. tostring (distval ).. " (outpos=" .. tostring (op ).. " )" )
193219 end
194220
195- local base_index = outpos - distval
221+ local base_index = op - distval
196222 for i = 1 , length do
197223 -- copy byte-by-byte (handles overlaps correctly)
198- append_byte ( out [base_index + i ]:byte ())
224+ ab ( o [base_index + i ]:byte ())
199225 end
200226 end
201227 end
202228 else
203- error (" unsupported block type: " .. tostring (btype ))
229+ error (" unsupported block type: " .. tostring (t ))
204230 end
205231
206- if final == 1 then done = true end
232+ if f == 1 then d = true end
207233 end
208234
209- return table.concat (out )
235+ return table.concat (o )
210236end
211237
212238local function crc32 (s )
@@ -262,18 +288,22 @@ local function unzip(path)
262288 if # os ~= us then
263289 io.stderr :write (string.format (" Warning: uncompressed size mismatch for %s: expected %d, got %d\n " , fn , us , # os ))
264290 end
265- local gotcrc = crc32 (os )
266- if cr ~= gotcrc then
267- io.stderr :write (string.format (" CRC mismatch for %s: expected %08x, got %08x\n " , fn , cr , gotcrc ))
291+
292+ -- c = actual crc32
293+ local c = crc32 (os )
294+
295+ if cr ~= c then
296+ io.stderr :write (string.format (" CRC mismatch for %s: expected %08x, got %08x\n " , fn , cr , c ))
268297 else
269- print (string.format (" CRC OK: %08x" , gotcrc ))
298+ print (string.format (" CRC OK: %08x" , c ))
270299 end
271300
272- local dir = fn :match (" (.+)/" )
273- if dir then
301+ -- d = directory
302+ local d = fn :match (" (.+)/" )
303+ if d then
274304 if os.execute then
275305 -- portable make dir (POSIX/Windows-friendly-ish)
276- os.execute (' mkdir -p "' .. dir .. ' "' )
306+ os.execute (' mkdir -p "' .. d .. ' "' )
277307 end
278308 end
279309 local of = assert (io.open (fn , " wb" ))
0 commit comments