ranger-compiler 3.4.0 → 3.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +102 -24
- package/README.md +3 -2
- package/dist/README.md +1 -1
- package/dist/api.d.ts +393 -0
- package/dist/api.js +4140 -413
- package/dist/git-http.mjs +126 -0
- package/dist/lib/zip/Inflate.rgr +675 -0
- package/dist/lib/zip/ZipBuffer.rgr +358 -0
- package/dist/package.json +1 -1
- package/dist/rgrc.js +3540 -56
- package/package.json +10 -10
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; Inflate.rgr - DEFLATE decompression (RFC 1951)
|
|
4
|
+
; Used to decompress ZIP files with compression method 8
|
|
5
|
+
|
|
6
|
+
Import "ZipBuffer.rgr"
|
|
7
|
+
|
|
8
|
+
class InflateHuffmanTable {
|
|
9
|
+
def counts:[int] ; Count of codes at each bit length (index 0-15)
|
|
10
|
+
def symbols:[int] ; Symbol for each code
|
|
11
|
+
def maxBits:int 0
|
|
12
|
+
|
|
13
|
+
Constructor () {
|
|
14
|
+
; Initialize counts array (16 entries for bit lengths 0-15)
|
|
15
|
+
def i 0
|
|
16
|
+
while (i < 16) {
|
|
17
|
+
push counts 0
|
|
18
|
+
i = i + 1
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
fn build:void (lengths:[int] numSymbols:int) {
|
|
23
|
+
; Build Huffman table from code lengths
|
|
24
|
+
; lengths[i] = bit length for symbol i
|
|
25
|
+
|
|
26
|
+
; Count codes of each length
|
|
27
|
+
def i 0
|
|
28
|
+
while (i < 16) {
|
|
29
|
+
set counts i 0
|
|
30
|
+
i = i + 1
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
i = 0
|
|
34
|
+
while (i < numSymbols) {
|
|
35
|
+
def len:int (itemAt lengths i)
|
|
36
|
+
if (len > 0) {
|
|
37
|
+
def cnt:int (itemAt counts len)
|
|
38
|
+
set counts len (cnt + 1)
|
|
39
|
+
if (len > maxBits) {
|
|
40
|
+
maxBits = len
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
i = i + 1
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
; Generate offsets for sorting symbols by code length
|
|
47
|
+
def offsets:[int]
|
|
48
|
+
def offset:int 0
|
|
49
|
+
i = 0
|
|
50
|
+
while (i < 16) {
|
|
51
|
+
push offsets offset
|
|
52
|
+
def cnt:int (itemAt counts i)
|
|
53
|
+
offset = offset + cnt
|
|
54
|
+
i = i + 1
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
; Sort symbols by code length, preserving order within same length
|
|
58
|
+
; Allocate symbols array
|
|
59
|
+
i = 0
|
|
60
|
+
while (i < numSymbols) {
|
|
61
|
+
push symbols 0
|
|
62
|
+
i = i + 1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
i = 0
|
|
66
|
+
while (i < numSymbols) {
|
|
67
|
+
def len:int (itemAt lengths i)
|
|
68
|
+
if (len > 0) {
|
|
69
|
+
def off:int (itemAt offsets len)
|
|
70
|
+
set symbols off i
|
|
71
|
+
set offsets len (off + 1)
|
|
72
|
+
}
|
|
73
|
+
i = i + 1
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fn decode:int (reader:InflateBitReader) {
|
|
78
|
+
; Decode next symbol using this Huffman table
|
|
79
|
+
def code:int 0
|
|
80
|
+
def first:int 0
|
|
81
|
+
def index:int 0
|
|
82
|
+
|
|
83
|
+
def len:int 1
|
|
84
|
+
while (len <= maxBits) {
|
|
85
|
+
def bit:int (reader.readBit())
|
|
86
|
+
code = (code * 2) + bit
|
|
87
|
+
def count:int (itemAt counts len)
|
|
88
|
+
if ((code - first) < count) {
|
|
89
|
+
return (itemAt symbols (index + code - first))
|
|
90
|
+
}
|
|
91
|
+
index = index + count
|
|
92
|
+
first = (first + count) * 2
|
|
93
|
+
len = len + 1
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
; Invalid code
|
|
97
|
+
return -1
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
class InflateBitReader {
|
|
102
|
+
def data:buffer (buffer_alloc 0)
|
|
103
|
+
def bytePos:int 0
|
|
104
|
+
def bitPos:int 0 ; Bits remaining in current byte (0 = need new byte)
|
|
105
|
+
def currentByte:int 0
|
|
106
|
+
def dataLength:int 0
|
|
107
|
+
|
|
108
|
+
Constructor () {
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fn init:void (buf:buffer offset:int length:int) {
|
|
112
|
+
data = buf
|
|
113
|
+
bytePos = offset
|
|
114
|
+
dataLength = offset + length
|
|
115
|
+
bitPos = 0
|
|
116
|
+
currentByte = 0
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fn readBit:int () {
|
|
120
|
+
; DEFLATE reads bits LSB first (unlike JPEG which is MSB first)
|
|
121
|
+
if (bitPos == 0) {
|
|
122
|
+
if (bytePos >= dataLength) {
|
|
123
|
+
return 0
|
|
124
|
+
}
|
|
125
|
+
currentByte = (buffer_get data bytePos)
|
|
126
|
+
bytePos = bytePos + 1
|
|
127
|
+
bitPos = 8
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
def bit:int (bit_and currentByte 1)
|
|
131
|
+
currentByte = (bit_shr currentByte 1)
|
|
132
|
+
bitPos = bitPos - 1
|
|
133
|
+
return bit
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fn readBits:int (count:int) {
|
|
137
|
+
; Read multiple bits, LSB first
|
|
138
|
+
def result:int 0
|
|
139
|
+
def multiplier:int 1
|
|
140
|
+
def i 0
|
|
141
|
+
while (i < count) {
|
|
142
|
+
def bit:int (this.readBit())
|
|
143
|
+
result = result + (bit * multiplier)
|
|
144
|
+
multiplier = multiplier * 2
|
|
145
|
+
i = i + 1
|
|
146
|
+
}
|
|
147
|
+
return result
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
fn alignToByte:void () {
|
|
151
|
+
; Skip remaining bits in current byte
|
|
152
|
+
bitPos = 0
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
fn readByte:int () {
|
|
156
|
+
this.alignToByte()
|
|
157
|
+
if (bytePos >= dataLength) {
|
|
158
|
+
return 0
|
|
159
|
+
}
|
|
160
|
+
def b:int (buffer_get data bytePos)
|
|
161
|
+
bytePos = bytePos + 1
|
|
162
|
+
return b
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
fn readUint16LE:int () {
|
|
166
|
+
def b0:int (this.readByte())
|
|
167
|
+
def b1:int (this.readByte())
|
|
168
|
+
return (b0 + (b1 * 256))
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
fn getBytePosition:int () {
|
|
172
|
+
return bytePos
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
fn isEOF:boolean () {
|
|
176
|
+
return ((bytePos >= dataLength) && (bitPos == 0))
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
class Inflate {
|
|
181
|
+
def input:buffer (buffer_alloc 0)
|
|
182
|
+
def reader:InflateBitReader (new InflateBitReader())
|
|
183
|
+
|
|
184
|
+
; Flat random-access output buffer (doubles on growth). LZ77 back-references
|
|
185
|
+
; read directly from already-decoded bytes — no per-byte reconstruction.
|
|
186
|
+
def outBuf:buffer (buffer_alloc 0)
|
|
187
|
+
def outLen:int 0
|
|
188
|
+
def outCap:int 0
|
|
189
|
+
|
|
190
|
+
; Fixed Huffman tables (built once)
|
|
191
|
+
def fixedLitLen:InflateHuffmanTable (new InflateHuffmanTable())
|
|
192
|
+
def fixedDist:InflateHuffmanTable (new InflateHuffmanTable())
|
|
193
|
+
def fixedTablesBuilt:boolean false
|
|
194
|
+
|
|
195
|
+
; Length and distance extra bits tables
|
|
196
|
+
def lengthBase:[int]
|
|
197
|
+
def lengthExtra:[int]
|
|
198
|
+
def distBase:[int]
|
|
199
|
+
def distExtra:[int]
|
|
200
|
+
|
|
201
|
+
Constructor () {
|
|
202
|
+
this.buildLengthDistTables()
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
fn resetOutput:void (hint:int) {
|
|
206
|
+
def cap:int hint
|
|
207
|
+
if (cap < 4096) {
|
|
208
|
+
cap = 4096
|
|
209
|
+
}
|
|
210
|
+
outBuf = (buffer_alloc cap)
|
|
211
|
+
outCap = cap
|
|
212
|
+
outLen = 0
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
fn ensureCapacity:void (extra:int) {
|
|
216
|
+
def need:int (outLen + extra)
|
|
217
|
+
if (need <= outCap) {
|
|
218
|
+
return
|
|
219
|
+
}
|
|
220
|
+
def newCap:int (outCap * 2)
|
|
221
|
+
if (newCap < need) {
|
|
222
|
+
newCap = need
|
|
223
|
+
}
|
|
224
|
+
def grown:buffer (buffer_alloc newCap)
|
|
225
|
+
buffer_copy grown 0 outBuf 0 outLen
|
|
226
|
+
outBuf = grown
|
|
227
|
+
outCap = newCap
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
fn pushByte:void (b:int) {
|
|
231
|
+
this.ensureCapacity(1)
|
|
232
|
+
buffer_set outBuf outLen b
|
|
233
|
+
outLen = (outLen + 1)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
fn finalOutput:buffer () {
|
|
237
|
+
def size:int outLen
|
|
238
|
+
def result:buffer (buffer_alloc size)
|
|
239
|
+
buffer_copy result 0 outBuf 0 size
|
|
240
|
+
return result
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
fn buildLengthDistTables:void () {
|
|
244
|
+
; Length codes 257-285 -> lengths 3-258
|
|
245
|
+
; Base lengths for codes 257-285
|
|
246
|
+
def bases:[int]
|
|
247
|
+
push bases 3 ; 257
|
|
248
|
+
push bases 4 ; 258
|
|
249
|
+
push bases 5 ; 259
|
|
250
|
+
push bases 6 ; 260
|
|
251
|
+
push bases 7 ; 261
|
|
252
|
+
push bases 8 ; 262
|
|
253
|
+
push bases 9 ; 263
|
|
254
|
+
push bases 10 ; 264
|
|
255
|
+
push bases 11 ; 265
|
|
256
|
+
push bases 13 ; 266
|
|
257
|
+
push bases 15 ; 267
|
|
258
|
+
push bases 17 ; 268
|
|
259
|
+
push bases 19 ; 269
|
|
260
|
+
push bases 23 ; 270
|
|
261
|
+
push bases 27 ; 271
|
|
262
|
+
push bases 31 ; 272
|
|
263
|
+
push bases 35 ; 273
|
|
264
|
+
push bases 43 ; 274
|
|
265
|
+
push bases 51 ; 275
|
|
266
|
+
push bases 59 ; 276
|
|
267
|
+
push bases 67 ; 277
|
|
268
|
+
push bases 83 ; 278
|
|
269
|
+
push bases 99 ; 279
|
|
270
|
+
push bases 115 ; 280
|
|
271
|
+
push bases 131 ; 281
|
|
272
|
+
push bases 163 ; 282
|
|
273
|
+
push bases 195 ; 283
|
|
274
|
+
push bases 227 ; 284
|
|
275
|
+
push bases 258 ; 285
|
|
276
|
+
lengthBase = bases
|
|
277
|
+
|
|
278
|
+
; Extra bits for length codes 257-285
|
|
279
|
+
def extras:[int]
|
|
280
|
+
push extras 0 ; 257
|
|
281
|
+
push extras 0 ; 258
|
|
282
|
+
push extras 0 ; 259
|
|
283
|
+
push extras 0 ; 260
|
|
284
|
+
push extras 0 ; 261
|
|
285
|
+
push extras 0 ; 262
|
|
286
|
+
push extras 0 ; 263
|
|
287
|
+
push extras 0 ; 264
|
|
288
|
+
push extras 1 ; 265
|
|
289
|
+
push extras 1 ; 266
|
|
290
|
+
push extras 1 ; 267
|
|
291
|
+
push extras 1 ; 268
|
|
292
|
+
push extras 2 ; 269
|
|
293
|
+
push extras 2 ; 270
|
|
294
|
+
push extras 2 ; 271
|
|
295
|
+
push extras 2 ; 272
|
|
296
|
+
push extras 3 ; 273
|
|
297
|
+
push extras 3 ; 274
|
|
298
|
+
push extras 3 ; 275
|
|
299
|
+
push extras 3 ; 276
|
|
300
|
+
push extras 4 ; 277
|
|
301
|
+
push extras 4 ; 278
|
|
302
|
+
push extras 4 ; 279
|
|
303
|
+
push extras 4 ; 280
|
|
304
|
+
push extras 5 ; 281
|
|
305
|
+
push extras 5 ; 282
|
|
306
|
+
push extras 5 ; 283
|
|
307
|
+
push extras 5 ; 284
|
|
308
|
+
push extras 0 ; 285
|
|
309
|
+
lengthExtra = extras
|
|
310
|
+
|
|
311
|
+
; Distance codes 0-29 -> distances 1-32768
|
|
312
|
+
def dBases:[int]
|
|
313
|
+
push dBases 1
|
|
314
|
+
push dBases 2
|
|
315
|
+
push dBases 3
|
|
316
|
+
push dBases 4
|
|
317
|
+
push dBases 5
|
|
318
|
+
push dBases 7
|
|
319
|
+
push dBases 9
|
|
320
|
+
push dBases 13
|
|
321
|
+
push dBases 17
|
|
322
|
+
push dBases 25
|
|
323
|
+
push dBases 33
|
|
324
|
+
push dBases 49
|
|
325
|
+
push dBases 65
|
|
326
|
+
push dBases 97
|
|
327
|
+
push dBases 129
|
|
328
|
+
push dBases 193
|
|
329
|
+
push dBases 257
|
|
330
|
+
push dBases 385
|
|
331
|
+
push dBases 513
|
|
332
|
+
push dBases 769
|
|
333
|
+
push dBases 1025
|
|
334
|
+
push dBases 1537
|
|
335
|
+
push dBases 2049
|
|
336
|
+
push dBases 3073
|
|
337
|
+
push dBases 4097
|
|
338
|
+
push dBases 6145
|
|
339
|
+
push dBases 8193
|
|
340
|
+
push dBases 12289
|
|
341
|
+
push dBases 16385
|
|
342
|
+
push dBases 24577
|
|
343
|
+
distBase = dBases
|
|
344
|
+
|
|
345
|
+
def dExtras:[int]
|
|
346
|
+
push dExtras 0
|
|
347
|
+
push dExtras 0
|
|
348
|
+
push dExtras 0
|
|
349
|
+
push dExtras 0
|
|
350
|
+
push dExtras 1
|
|
351
|
+
push dExtras 1
|
|
352
|
+
push dExtras 2
|
|
353
|
+
push dExtras 2
|
|
354
|
+
push dExtras 3
|
|
355
|
+
push dExtras 3
|
|
356
|
+
push dExtras 4
|
|
357
|
+
push dExtras 4
|
|
358
|
+
push dExtras 5
|
|
359
|
+
push dExtras 5
|
|
360
|
+
push dExtras 6
|
|
361
|
+
push dExtras 6
|
|
362
|
+
push dExtras 7
|
|
363
|
+
push dExtras 7
|
|
364
|
+
push dExtras 8
|
|
365
|
+
push dExtras 8
|
|
366
|
+
push dExtras 9
|
|
367
|
+
push dExtras 9
|
|
368
|
+
push dExtras 10
|
|
369
|
+
push dExtras 10
|
|
370
|
+
push dExtras 11
|
|
371
|
+
push dExtras 11
|
|
372
|
+
push dExtras 12
|
|
373
|
+
push dExtras 12
|
|
374
|
+
push dExtras 13
|
|
375
|
+
push dExtras 13
|
|
376
|
+
distExtra = dExtras
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
fn buildFixedTables:void () {
|
|
380
|
+
if fixedTablesBuilt {
|
|
381
|
+
return
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
; Build fixed literal/length Huffman table
|
|
385
|
+
; Literals 0-143: 8-bit codes
|
|
386
|
+
; Literals 144-255: 9-bit codes
|
|
387
|
+
; End-of-block 256: 7-bit code
|
|
388
|
+
; Lengths 257-279: 7-bit codes
|
|
389
|
+
; Lengths 280-287: 8-bit codes
|
|
390
|
+
def lengths:[int]
|
|
391
|
+
def i 0
|
|
392
|
+
while (i < 144) {
|
|
393
|
+
push lengths 8
|
|
394
|
+
i = i + 1
|
|
395
|
+
}
|
|
396
|
+
while (i < 256) {
|
|
397
|
+
push lengths 9
|
|
398
|
+
i = i + 1
|
|
399
|
+
}
|
|
400
|
+
while (i < 280) {
|
|
401
|
+
push lengths 7
|
|
402
|
+
i = i + 1
|
|
403
|
+
}
|
|
404
|
+
while (i < 288) {
|
|
405
|
+
push lengths 8
|
|
406
|
+
i = i + 1
|
|
407
|
+
}
|
|
408
|
+
fixedLitLen.build(lengths 288)
|
|
409
|
+
|
|
410
|
+
; Build fixed distance Huffman table (all 5-bit codes)
|
|
411
|
+
def distLengths:[int]
|
|
412
|
+
i = 0
|
|
413
|
+
while (i < 32) {
|
|
414
|
+
push distLengths 5
|
|
415
|
+
i = i + 1
|
|
416
|
+
}
|
|
417
|
+
fixedDist.build(distLengths 32)
|
|
418
|
+
|
|
419
|
+
fixedTablesBuilt = true
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
fn decompress:buffer (data:buffer) {
|
|
423
|
+
return this.decompressFrom(data 0)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
; Inflate a DEFLATE stream that begins at `offset` inside `data` and
|
|
427
|
+
; runs until BFINAL. Used by ZIP (offset 0, known length) and by Git
|
|
428
|
+
; zlib wrappers (offset after the 2-byte CMF/FLG, unknown length —
|
|
429
|
+
; the next object in a pack starts at inputPos after this returns).
|
|
430
|
+
fn decompressFrom:buffer (data:buffer offset:int) {
|
|
431
|
+
input = data
|
|
432
|
+
def dataLen:int (buffer_length data)
|
|
433
|
+
def from:int offset
|
|
434
|
+
if (from < 0) {
|
|
435
|
+
from = 0
|
|
436
|
+
}
|
|
437
|
+
if (from > dataLen) {
|
|
438
|
+
from = dataLen
|
|
439
|
+
}
|
|
440
|
+
def rest:int (dataLen - from)
|
|
441
|
+
; Deflate typically expands 2-4x; start generous to avoid re-growth.
|
|
442
|
+
this.resetOutput(rest * 4)
|
|
443
|
+
reader.init(data from rest)
|
|
444
|
+
|
|
445
|
+
this.buildFixedTables()
|
|
446
|
+
|
|
447
|
+
def finalBlock:boolean false
|
|
448
|
+
while ((false == finalBlock)) {
|
|
449
|
+
; Read block header
|
|
450
|
+
def bfinal:int (reader.readBit())
|
|
451
|
+
def btype:int (reader.readBits(2))
|
|
452
|
+
|
|
453
|
+
finalBlock = (bfinal == 1)
|
|
454
|
+
|
|
455
|
+
if (btype == 0) {
|
|
456
|
+
; Stored block (no compression)
|
|
457
|
+
this.decompressStored()
|
|
458
|
+
}
|
|
459
|
+
if (btype == 1) {
|
|
460
|
+
; Fixed Huffman codes
|
|
461
|
+
this.decompressHuffman(fixedLitLen fixedDist)
|
|
462
|
+
}
|
|
463
|
+
if (btype == 2) {
|
|
464
|
+
; Dynamic Huffman codes
|
|
465
|
+
this.decompressDynamic()
|
|
466
|
+
}
|
|
467
|
+
; btype == 3 is reserved/error
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
return (this.finalOutput())
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
; Absolute byte index in the input after the last DEFLATE bit.
|
|
474
|
+
; Unused bits in that last byte have already been skipped: the next
|
|
475
|
+
; zlib Adler-32 (or the next Git pack object) starts here.
|
|
476
|
+
fn inputPos:int () {
|
|
477
|
+
return reader.getBytePosition()
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
fn decompressStored:void () {
|
|
481
|
+
; Stored block: skip to byte boundary, read length, copy literal bytes
|
|
482
|
+
reader.alignToByte()
|
|
483
|
+
def len:int (reader.readUint16LE())
|
|
484
|
+
def nlen:int (reader.readUint16LE())
|
|
485
|
+
if ((len + nlen) != 65535) {
|
|
486
|
+
; NLEN read advances the bitstream even when LEN/NLEN do not match.
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
this.ensureCapacity(len)
|
|
490
|
+
def i 0
|
|
491
|
+
while (i < len) {
|
|
492
|
+
def b:int (reader.readByte())
|
|
493
|
+
this.pushByte(b)
|
|
494
|
+
i = i + 1
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
fn decompressHuffman:void (litLenTable:InflateHuffmanTable distTable:InflateHuffmanTable) {
|
|
499
|
+
; Decode Huffman-compressed data
|
|
500
|
+
def done:boolean false
|
|
501
|
+
while ((false == done)) {
|
|
502
|
+
def sym:int (litLenTable.decode(reader))
|
|
503
|
+
|
|
504
|
+
if (sym < 256) {
|
|
505
|
+
; Literal byte
|
|
506
|
+
this.pushByte(sym)
|
|
507
|
+
}
|
|
508
|
+
if (sym == 256) {
|
|
509
|
+
; End of block
|
|
510
|
+
done = true
|
|
511
|
+
}
|
|
512
|
+
if (sym > 256) {
|
|
513
|
+
; Length/distance pair
|
|
514
|
+
def lengthCode:int (sym - 257)
|
|
515
|
+
def length:int (itemAt lengthBase lengthCode)
|
|
516
|
+
def extraBits:int (itemAt lengthExtra lengthCode)
|
|
517
|
+
if (extraBits > 0) {
|
|
518
|
+
length = length + (reader.readBits(extraBits))
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
def distCode:int (distTable.decode(reader))
|
|
522
|
+
def dist:int (itemAt distBase distCode)
|
|
523
|
+
def distExtraBits:int (itemAt distExtra distCode)
|
|
524
|
+
if (distExtraBits > 0) {
|
|
525
|
+
dist = dist + (reader.readBits(distExtraBits))
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
; Copy from output buffer (LZ77)
|
|
529
|
+
this.copyFromOutput(dist length)
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
fn decompressDynamic:void () {
|
|
535
|
+
; Read dynamic Huffman table definitions
|
|
536
|
+
def hlit:int ((reader.readBits(5)) + 257) ; # of literal/length codes
|
|
537
|
+
def hdist:int ((reader.readBits(5)) + 1) ; # of distance codes
|
|
538
|
+
def hclen:int ((reader.readBits(4)) + 4) ; # of code length codes
|
|
539
|
+
|
|
540
|
+
; Code length code order
|
|
541
|
+
def clOrder:[int]
|
|
542
|
+
push clOrder 16
|
|
543
|
+
push clOrder 17
|
|
544
|
+
push clOrder 18
|
|
545
|
+
push clOrder 0
|
|
546
|
+
push clOrder 8
|
|
547
|
+
push clOrder 7
|
|
548
|
+
push clOrder 9
|
|
549
|
+
push clOrder 6
|
|
550
|
+
push clOrder 10
|
|
551
|
+
push clOrder 5
|
|
552
|
+
push clOrder 11
|
|
553
|
+
push clOrder 4
|
|
554
|
+
push clOrder 12
|
|
555
|
+
push clOrder 3
|
|
556
|
+
push clOrder 13
|
|
557
|
+
push clOrder 2
|
|
558
|
+
push clOrder 14
|
|
559
|
+
push clOrder 1
|
|
560
|
+
push clOrder 15
|
|
561
|
+
|
|
562
|
+
; Read code length code lengths
|
|
563
|
+
def clLengths:[int]
|
|
564
|
+
def i 0
|
|
565
|
+
while (i < 19) {
|
|
566
|
+
push clLengths 0
|
|
567
|
+
i = i + 1
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
i = 0
|
|
571
|
+
while (i < hclen) {
|
|
572
|
+
def idx:int (itemAt clOrder i)
|
|
573
|
+
def len:int (reader.readBits(3))
|
|
574
|
+
set clLengths idx len
|
|
575
|
+
i = i + 1
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
; Build code length Huffman table
|
|
579
|
+
def clTable (new InflateHuffmanTable())
|
|
580
|
+
clTable.build(clLengths 19)
|
|
581
|
+
|
|
582
|
+
; Decode literal/length and distance code lengths
|
|
583
|
+
def allLengths:[int]
|
|
584
|
+
def totalCodes:int (hlit + hdist)
|
|
585
|
+
i = 0
|
|
586
|
+
while (i < totalCodes) {
|
|
587
|
+
def sym:int (clTable.decode(reader))
|
|
588
|
+
|
|
589
|
+
if (sym < 16) {
|
|
590
|
+
; Literal code length
|
|
591
|
+
push allLengths sym
|
|
592
|
+
i = i + 1
|
|
593
|
+
}
|
|
594
|
+
if (sym == 16) {
|
|
595
|
+
; Repeat previous length 3-6 times
|
|
596
|
+
def repeat:int ((reader.readBits(2)) + 3)
|
|
597
|
+
def prevLen:int 0
|
|
598
|
+
def arrLen:int (array_length allLengths)
|
|
599
|
+
if (arrLen > 0) {
|
|
600
|
+
prevLen = (itemAt allLengths (arrLen - 1))
|
|
601
|
+
}
|
|
602
|
+
def j 0
|
|
603
|
+
while (j < repeat) {
|
|
604
|
+
push allLengths prevLen
|
|
605
|
+
j = j + 1
|
|
606
|
+
}
|
|
607
|
+
i = i + repeat
|
|
608
|
+
}
|
|
609
|
+
if (sym == 17) {
|
|
610
|
+
; Repeat zero 3-10 times
|
|
611
|
+
def repeat:int ((reader.readBits(3)) + 3)
|
|
612
|
+
def j 0
|
|
613
|
+
while (j < repeat) {
|
|
614
|
+
push allLengths 0
|
|
615
|
+
j = j + 1
|
|
616
|
+
}
|
|
617
|
+
i = i + repeat
|
|
618
|
+
}
|
|
619
|
+
if (sym == 18) {
|
|
620
|
+
; Repeat zero 11-138 times
|
|
621
|
+
def repeat:int ((reader.readBits(7)) + 11)
|
|
622
|
+
def j 0
|
|
623
|
+
while (j < repeat) {
|
|
624
|
+
push allLengths 0
|
|
625
|
+
j = j + 1
|
|
626
|
+
}
|
|
627
|
+
i = i + repeat
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
; Split into literal/length and distance lengths
|
|
632
|
+
def litLenLengths:[int]
|
|
633
|
+
def distLengths:[int]
|
|
634
|
+
i = 0
|
|
635
|
+
while (i < hlit) {
|
|
636
|
+
push litLenLengths (itemAt allLengths i)
|
|
637
|
+
i = i + 1
|
|
638
|
+
}
|
|
639
|
+
while (i < totalCodes) {
|
|
640
|
+
push distLengths (itemAt allLengths i)
|
|
641
|
+
i = i + 1
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
; Build dynamic Huffman tables
|
|
645
|
+
def dynLitLen (new InflateHuffmanTable())
|
|
646
|
+
dynLitLen.build(litLenLengths hlit)
|
|
647
|
+
|
|
648
|
+
def dynDist (new InflateHuffmanTable())
|
|
649
|
+
dynDist.build(distLengths hdist)
|
|
650
|
+
|
|
651
|
+
; Decode data using dynamic tables
|
|
652
|
+
this.decompressHuffman(dynLitLen dynDist)
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
fn copyFromOutput:void (distance:int length:int) {
|
|
656
|
+
; Copy 'length' bytes from 'distance' bytes back in output.
|
|
657
|
+
; Byte-by-byte read-then-write handles overlapping copies (distance < length)
|
|
658
|
+
; correctly, since each read position trails the write head.
|
|
659
|
+
def srcPos:int (outLen - distance)
|
|
660
|
+
this.ensureCapacity(length)
|
|
661
|
+
def i 0
|
|
662
|
+
while (i < length) {
|
|
663
|
+
def b:int 0
|
|
664
|
+
def readPos:int (srcPos + i)
|
|
665
|
+
if (readPos >= 0) {
|
|
666
|
+
if (readPos < outLen) {
|
|
667
|
+
b = (buffer_get outBuf readPos)
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
buffer_set outBuf outLen b
|
|
671
|
+
outLen = (outLen + 1)
|
|
672
|
+
i = i + 1
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|