grf-file-extractor 1.0.35
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/README.md +33 -0
- package/dist/index.js +32 -0
- package/dist/index.mjs +7 -0
- package/index.js +192 -0
- package/lib/Loaders/GameFile.js +368 -0
- package/lib/Loaders/GameFileDecrypt.js +346 -0
- package/lib/Utils/BinaryReader.js +334 -0
- package/lib/Utils/BinaryWriter.js +326 -0
- package/lib/Utils/Inflate.js +382 -0
- package/lib/Utils/Struct.js +76 -0
- package/lib/Vendors/text-encoding.js +2494 -0
- package/lib/cps.js +72 -0
- package/lib/extractor.js +258 -0
- package/lib/grf.js +41 -0
- package/package.json +24 -0
- package/profile.js +17 -0
- package/src/index.ts +3 -0
- package/tsconfig.json +18 -0
- package/tsup.config.ts +10 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils/BinaryWriter.js
|
|
3
|
+
*
|
|
4
|
+
* BinaryWriter Helper
|
|
5
|
+
*
|
|
6
|
+
* Helper to build binary data (write sockets, files, ...)
|
|
7
|
+
*
|
|
8
|
+
* This file is part of ROBrowser, Ragnarok Online in the Web Browser (http://www.robrowser.com/).
|
|
9
|
+
*
|
|
10
|
+
* @author Vincent Thibault
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
var TextEnconding = require('../Vendors/text-encoding')
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Extend DataView to add position
|
|
19
|
+
*
|
|
20
|
+
* @param {number} offset
|
|
21
|
+
* @param {Array} value (x, y)
|
|
22
|
+
* @param {boolean} littleEndian (if true use LE encode order)
|
|
23
|
+
*/
|
|
24
|
+
DataView.prototype.setPos = function SetPos( offset, value, littleEndian ) {
|
|
25
|
+
var x = value[0];
|
|
26
|
+
var y = value[1];
|
|
27
|
+
|
|
28
|
+
if (littleEndian) {
|
|
29
|
+
this.setInt8( offset + 0, x >> 2, true);
|
|
30
|
+
this.setInt8( offset + 1, ((x % 4) << 6) | (y >> 4), true);
|
|
31
|
+
this.setInt8( offset + 2, (y % 16) << 4, true);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.setInt8( offset + 2, x >> 2, true);
|
|
35
|
+
this.setInt8( offset + 1, ((x % 4) << 6) | (y >> 4), true);
|
|
36
|
+
this.setInt8( offset + 0, (y % 16) << 4, true);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Extend DataView to get setString method
|
|
43
|
+
*
|
|
44
|
+
* @param {number} offset
|
|
45
|
+
* @param {string} str
|
|
46
|
+
* @param {number} len
|
|
47
|
+
*/
|
|
48
|
+
DataView.prototype.setString = function SetString( offset, str, len) {
|
|
49
|
+
if (len) {
|
|
50
|
+
str = String(str).substr(0,len);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var i, count;
|
|
54
|
+
var data = TextEncoding.encode(str);
|
|
55
|
+
|
|
56
|
+
// fuck it, need to rebuild the buffer
|
|
57
|
+
if (!len && data.length > str.length) {
|
|
58
|
+
// make sure to not use it in this case, else it will bug :(
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (i = 0, count = len || data.length; i < count; ++i) {
|
|
62
|
+
this.setUint8( offset+i, data[i]);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Extend DataView to get setBinaryString method
|
|
69
|
+
*
|
|
70
|
+
* @param {number} offset
|
|
71
|
+
* @param {string} str
|
|
72
|
+
* @param {number} len
|
|
73
|
+
*/
|
|
74
|
+
DataView.prototype.setBinaryString = function SetBinaryString( offset, str, len) {
|
|
75
|
+
if (len) {
|
|
76
|
+
str = String(str).substr(0,len);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var i, count;
|
|
80
|
+
|
|
81
|
+
for (i = 0, count = str.length; i < count; ++i) {
|
|
82
|
+
this.setUint8( offset+i, str.charCodeAt(i) & 0xff);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* BinaryWriter
|
|
89
|
+
* Helper to write binary data
|
|
90
|
+
*
|
|
91
|
+
* @param {number} length
|
|
92
|
+
*/
|
|
93
|
+
function BinaryWriter( length )
|
|
94
|
+
{
|
|
95
|
+
this.buffer = new ArrayBuffer( length );
|
|
96
|
+
this.view = new DataView( this.buffer );
|
|
97
|
+
this.offset = 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Write Int8 to buffer
|
|
103
|
+
*
|
|
104
|
+
* @param {number} value
|
|
105
|
+
* @return {BinaryWriter}
|
|
106
|
+
*/
|
|
107
|
+
BinaryWriter.prototype.setInt8 =
|
|
108
|
+
BinaryWriter.prototype.writeChar =
|
|
109
|
+
BinaryWriter.prototype.writeByte = function setInt8( value )
|
|
110
|
+
{
|
|
111
|
+
this.view.setInt8( this.offset++, value, true );
|
|
112
|
+
return this;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Write Uint8 to buffer
|
|
118
|
+
*
|
|
119
|
+
* @param {number} value
|
|
120
|
+
* @return {BinaryWriter}
|
|
121
|
+
*/
|
|
122
|
+
BinaryWriter.prototype.setUint8 =
|
|
123
|
+
BinaryWriter.prototype.writeUChar =
|
|
124
|
+
BinaryWriter.prototype.writeUByte = function setUint8( value )
|
|
125
|
+
{
|
|
126
|
+
this.view.setUint8( this.offset++, value, true );
|
|
127
|
+
return this;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Write Int16 to buffer
|
|
133
|
+
*
|
|
134
|
+
* @param {number} value
|
|
135
|
+
* @return {BinaryWriter}
|
|
136
|
+
*/
|
|
137
|
+
BinaryWriter.prototype.setInt16 =
|
|
138
|
+
BinaryWriter.prototype.writeShort = function setInt16( value )
|
|
139
|
+
{
|
|
140
|
+
this.view.setInt16( this.offset, value, true );
|
|
141
|
+
this.offset += 2;
|
|
142
|
+
return this;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Write Uint16 to buffer
|
|
148
|
+
*
|
|
149
|
+
* @param {number} value
|
|
150
|
+
* @return {BinaryWriter}
|
|
151
|
+
*/
|
|
152
|
+
BinaryWriter.prototype.setUint16 =
|
|
153
|
+
BinaryWriter.prototype.writeUShort = function setUint16( value )
|
|
154
|
+
{
|
|
155
|
+
this.view.setUint16( this.offset, value, true );
|
|
156
|
+
this.offset += 2;
|
|
157
|
+
return this;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Write Int32 to buffer
|
|
163
|
+
*
|
|
164
|
+
* @param {number} value
|
|
165
|
+
* @return {BinaryWriter}
|
|
166
|
+
*/
|
|
167
|
+
BinaryWriter.prototype.setInt32 =
|
|
168
|
+
BinaryWriter.prototype.writeInt =
|
|
169
|
+
BinaryWriter.prototype.writeLong = function setInt32( value )
|
|
170
|
+
{
|
|
171
|
+
this.view.setInt32( this.offset, value, true );
|
|
172
|
+
this.offset += 4;
|
|
173
|
+
return this;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Write Uint32 to buffer
|
|
179
|
+
*
|
|
180
|
+
* @param {number} value
|
|
181
|
+
* @return {BinaryWriter}
|
|
182
|
+
*/
|
|
183
|
+
BinaryWriter.prototype.setUint32 =
|
|
184
|
+
BinaryWriter.prototype.writeUInt =
|
|
185
|
+
BinaryWriter.prototype.writeULong = function setUint32( value )
|
|
186
|
+
{
|
|
187
|
+
this.view.setUint32( this.offset, value, true );
|
|
188
|
+
this.offset += 4;
|
|
189
|
+
return this;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Write Float32 to buffer
|
|
195
|
+
*
|
|
196
|
+
* @param {number} value
|
|
197
|
+
* @return {BinaryWriter}
|
|
198
|
+
*/
|
|
199
|
+
BinaryWriter.prototype.setFloat32 =
|
|
200
|
+
BinaryWriter.prototype.writeFloat = function setFloat32( value )
|
|
201
|
+
{
|
|
202
|
+
this.view.setFloat32( this.offset, value, true );
|
|
203
|
+
this.offset += 4;
|
|
204
|
+
return this;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Write Float64 to buffer
|
|
210
|
+
*
|
|
211
|
+
* @param {number} value
|
|
212
|
+
* @return {BinaryWriter}
|
|
213
|
+
*/
|
|
214
|
+
BinaryWriter.prototype.setFloat64 =
|
|
215
|
+
BinaryWriter.prototype.writeDouble = function setFloat64( value )
|
|
216
|
+
{
|
|
217
|
+
this.view.setFloat64( this.offset, value, true );
|
|
218
|
+
this.offset += 8;
|
|
219
|
+
return this;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Write String to buffer
|
|
225
|
+
*
|
|
226
|
+
* @param {string} str
|
|
227
|
+
* @param {number} length
|
|
228
|
+
* @return {BinaryWriter}
|
|
229
|
+
*/
|
|
230
|
+
BinaryWriter.prototype.setString =
|
|
231
|
+
BinaryWriter.prototype.writeString = function setString( str, length )
|
|
232
|
+
{
|
|
233
|
+
if (length) {
|
|
234
|
+
str = String(str).substr(0, length);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
var data = TextEncoding.encode(str);
|
|
238
|
+
var i, count = length || data.length;
|
|
239
|
+
|
|
240
|
+
// TODO: make it better.
|
|
241
|
+
// Fuck it ! Because of the charset the string is longer
|
|
242
|
+
// So we need to create another buffer with the new size for it
|
|
243
|
+
if (!length && data.length > str.length) {
|
|
244
|
+
// create new buffer
|
|
245
|
+
var uint8 = new Uint8Array( this.buffer.byteLength + (data.length-str.length) );
|
|
246
|
+
|
|
247
|
+
// copy the old one and use the new one
|
|
248
|
+
uint8.set(new Uint8Array(this.buffer), 0);
|
|
249
|
+
this.buffer = uint8.buffer;
|
|
250
|
+
this.view = new DataView(this.buffer);
|
|
251
|
+
|
|
252
|
+
// Modify packet size
|
|
253
|
+
this.view.setInt16( 2, uint8.length, true );
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
for (i = 0; i < count; ++i) {
|
|
257
|
+
this.view.setUint8( this.offset + i, data[i] );
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
this.offset += (length || count);
|
|
261
|
+
return this;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Write Binary String to buffer
|
|
267
|
+
*
|
|
268
|
+
* @param {string} str
|
|
269
|
+
* @param {number} length
|
|
270
|
+
* @return {BinaryWriter}
|
|
271
|
+
*/
|
|
272
|
+
BinaryWriter.prototype.setBinaryString =
|
|
273
|
+
BinaryWriter.prototype.writeBinaryString = function setBinaryString( str, length )
|
|
274
|
+
{
|
|
275
|
+
if (length) {
|
|
276
|
+
str = String(str).substr(0, length);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
var i, count = str.length;
|
|
280
|
+
|
|
281
|
+
for (i = 0; i < count; ++i) {
|
|
282
|
+
this.view.setUint8( this.offset + i, str.charCodeAt(i) & 0xff );
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
this.offset += (length || count);
|
|
286
|
+
return this;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Skip X bytes from buffer
|
|
292
|
+
*
|
|
293
|
+
* @param {number}
|
|
294
|
+
* @return {BinaryWriter}
|
|
295
|
+
*/
|
|
296
|
+
BinaryWriter.prototype.skip = function skip( count )
|
|
297
|
+
{
|
|
298
|
+
this.offset += count;
|
|
299
|
+
return this;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Write x, y pos to buffer
|
|
305
|
+
*
|
|
306
|
+
* @param {Array} (x, y)
|
|
307
|
+
* @return {BinaryWriter}
|
|
308
|
+
*/
|
|
309
|
+
BinaryWriter.prototype.setPos =
|
|
310
|
+
BinaryWriter.prototype.writePos = function setPos( xy )
|
|
311
|
+
{
|
|
312
|
+
var x = xy[0],
|
|
313
|
+
y = xy[1];
|
|
314
|
+
|
|
315
|
+
this.view.setInt8( this.offset++, x >> 2, true);
|
|
316
|
+
this.view.setInt8( this.offset++, ((x % 4) << 6) | (y >> 4), true);
|
|
317
|
+
this.view.setInt8( this.offset++, (y % 16) << 4, true);
|
|
318
|
+
|
|
319
|
+
return this;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Export
|
|
325
|
+
*/
|
|
326
|
+
module.exports = BinaryWriter;
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils/Inflate.js
|
|
3
|
+
*
|
|
4
|
+
* GZIP uncompress code, adapted from pdf.js
|
|
5
|
+
*
|
|
6
|
+
* This file is part of ROBrowser, Ragnarok Online in the Web Browser (http://www.robrowser.com/).
|
|
7
|
+
*
|
|
8
|
+
* @author Vincent Thibault
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
var codeLenCodeMap = new Uint32Array([
|
|
14
|
+
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
var _codeLenCodeLengths = new Uint32Array(19);
|
|
18
|
+
var _clean_codeLenCodeLengths = new Uint32Array(19);
|
|
19
|
+
var _codeLengths = new Uint8Array(640);
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
var lengthDecode = new Uint32Array([
|
|
23
|
+
0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a,
|
|
24
|
+
0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f,
|
|
25
|
+
0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073,
|
|
26
|
+
0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
var distDecode = new Uint32Array([
|
|
30
|
+
0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d,
|
|
31
|
+
0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1,
|
|
32
|
+
0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01,
|
|
33
|
+
0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
var fixedLitCodeTab = [new Uint32Array([
|
|
37
|
+
0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0,
|
|
38
|
+
0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0,
|
|
39
|
+
0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0,
|
|
40
|
+
0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0,
|
|
41
|
+
0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8,
|
|
42
|
+
0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8,
|
|
43
|
+
0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8,
|
|
44
|
+
0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8,
|
|
45
|
+
0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4,
|
|
46
|
+
0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4,
|
|
47
|
+
0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4,
|
|
48
|
+
0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4,
|
|
49
|
+
0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc,
|
|
50
|
+
0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec,
|
|
51
|
+
0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc,
|
|
52
|
+
0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc,
|
|
53
|
+
0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2,
|
|
54
|
+
0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2,
|
|
55
|
+
0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2,
|
|
56
|
+
0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2,
|
|
57
|
+
0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca,
|
|
58
|
+
0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea,
|
|
59
|
+
0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da,
|
|
60
|
+
0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa,
|
|
61
|
+
0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6,
|
|
62
|
+
0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6,
|
|
63
|
+
0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6,
|
|
64
|
+
0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6,
|
|
65
|
+
0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce,
|
|
66
|
+
0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee,
|
|
67
|
+
0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de,
|
|
68
|
+
0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe,
|
|
69
|
+
0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1,
|
|
70
|
+
0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1,
|
|
71
|
+
0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1,
|
|
72
|
+
0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1,
|
|
73
|
+
0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9,
|
|
74
|
+
0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9,
|
|
75
|
+
0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9,
|
|
76
|
+
0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9,
|
|
77
|
+
0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5,
|
|
78
|
+
0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5,
|
|
79
|
+
0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5,
|
|
80
|
+
0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5,
|
|
81
|
+
0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd,
|
|
82
|
+
0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed,
|
|
83
|
+
0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd,
|
|
84
|
+
0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd,
|
|
85
|
+
0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3,
|
|
86
|
+
0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3,
|
|
87
|
+
0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3,
|
|
88
|
+
0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3,
|
|
89
|
+
0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb,
|
|
90
|
+
0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb,
|
|
91
|
+
0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db,
|
|
92
|
+
0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb,
|
|
93
|
+
0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7,
|
|
94
|
+
0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7,
|
|
95
|
+
0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7,
|
|
96
|
+
0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7,
|
|
97
|
+
0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf,
|
|
98
|
+
0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef,
|
|
99
|
+
0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df,
|
|
100
|
+
0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff
|
|
101
|
+
]), 9];
|
|
102
|
+
|
|
103
|
+
var fixedDistCodeTab = [new Uint32Array([
|
|
104
|
+
0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c,
|
|
105
|
+
0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000,
|
|
106
|
+
0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d,
|
|
107
|
+
0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000
|
|
108
|
+
]), 5];
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
*
|
|
112
|
+
* @param {Uint8Array} bytes
|
|
113
|
+
* @constructor
|
|
114
|
+
*/
|
|
115
|
+
function Inflate(bytes) {
|
|
116
|
+
var bytesPos = 0;
|
|
117
|
+
|
|
118
|
+
var cmf = bytes[bytesPos++];
|
|
119
|
+
var flg = bytes[bytesPos++];
|
|
120
|
+
if (cmf === -1 || flg === -1)
|
|
121
|
+
throw new Error('Invalid header in flate stream: ' + cmf + ', ' + flg);
|
|
122
|
+
if ((cmf & 0x0f) != 0x08)
|
|
123
|
+
throw new Error('Unknown compression method in flate stream: ' + cmf + ', ' + flg);
|
|
124
|
+
if (((cmf << 8) + flg) % 31 !== 0)
|
|
125
|
+
throw new Error('Bad FCHECK in flate stream: ' + cmf + ', ' + flg);
|
|
126
|
+
if (flg & 0x20)
|
|
127
|
+
throw new Error('FDICT bit set in flate stream: ' + cmf + ', ' + flg);
|
|
128
|
+
|
|
129
|
+
this.bytes = bytes;
|
|
130
|
+
this.bytesPos = bytesPos;
|
|
131
|
+
this.bytesLength = bytes.length;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Extract data from ZIP
|
|
136
|
+
* @param {Uint8Array} output
|
|
137
|
+
*/
|
|
138
|
+
Inflate.prototype.getBytes = function(output) {
|
|
139
|
+
this.buffer = output;
|
|
140
|
+
this.bufferPos = 0;
|
|
141
|
+
|
|
142
|
+
this.codeSize = 0;
|
|
143
|
+
this.codeBuf = 0;
|
|
144
|
+
|
|
145
|
+
while (!this.readBlock());
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get bits
|
|
150
|
+
* @param {number} bits
|
|
151
|
+
* @returns {number}
|
|
152
|
+
*/
|
|
153
|
+
Inflate.prototype.getBits = function Inflate_getBits(bits) {
|
|
154
|
+
var codeSize = this.codeSize;
|
|
155
|
+
var codeBuf = this.codeBuf;
|
|
156
|
+
var bytes = this.bytes;
|
|
157
|
+
var bytesPos = this.bytesPos;
|
|
158
|
+
var b;
|
|
159
|
+
|
|
160
|
+
if (this.bytesLength <= bytesPos + (bits-codeSize) * 0.2) {
|
|
161
|
+
throw new Error('Bad encoding in flate stream ');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
while (codeSize < bits) {
|
|
165
|
+
codeBuf |= bytes[bytesPos++] << codeSize;
|
|
166
|
+
codeSize += 8;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
b = codeBuf & ((1 << bits) - 1);
|
|
170
|
+
this.codeBuf = codeBuf >> bits;
|
|
171
|
+
this.codeSize = codeSize - bits;
|
|
172
|
+
this.bytesPos = bytesPos;
|
|
173
|
+
return b;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Get Code
|
|
178
|
+
* @param {Array} table
|
|
179
|
+
* @returns {number}
|
|
180
|
+
*/
|
|
181
|
+
Inflate.prototype.getCode = function Inflate_getCode(table) {
|
|
182
|
+
var codes = table[0];
|
|
183
|
+
var maxLen = table[1];
|
|
184
|
+
var codeSize = this.codeSize;
|
|
185
|
+
var codeBuf = this.codeBuf;
|
|
186
|
+
var bytes = this.bytes;
|
|
187
|
+
var bytesPos = this.bytesPos;
|
|
188
|
+
|
|
189
|
+
if (this.bytesLength <= bytesPos + (maxLen-codeSize) * 0.2)
|
|
190
|
+
throw new Error('Bad encoding in flate stream');
|
|
191
|
+
|
|
192
|
+
while (codeSize < maxLen) {
|
|
193
|
+
codeBuf |= (bytes[bytesPos++] << codeSize);
|
|
194
|
+
codeSize += 8;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
var code = codes[codeBuf & ((1 << maxLen) - 1)];
|
|
198
|
+
var codeLen = code >> 16;
|
|
199
|
+
var codeVal = code & 0xffff;
|
|
200
|
+
|
|
201
|
+
if (codeSize === 0 || codeSize < codeLen || codeLen === 0)
|
|
202
|
+
throw new Error('Bad encoding in flate stream ' + codeSize + ' ' + codeLen);
|
|
203
|
+
|
|
204
|
+
this.codeBuf = (codeBuf >> codeLen);
|
|
205
|
+
this.codeSize = (codeSize - codeLen);
|
|
206
|
+
this.bytesPos = bytesPos;
|
|
207
|
+
return codeVal;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get bits
|
|
212
|
+
* @param {Uint32Array} lengths
|
|
213
|
+
* @param {number} start
|
|
214
|
+
* @param {number} end
|
|
215
|
+
* @returns {Array}
|
|
216
|
+
*/
|
|
217
|
+
Inflate.prototype.generateHuffmanTable = function Inflate_GenerateHuffmanTable( lengths, start, end ) {
|
|
218
|
+
// find max code length
|
|
219
|
+
var maxLen = 0;
|
|
220
|
+
var i;
|
|
221
|
+
|
|
222
|
+
for (i = start; i < end; ++i) {
|
|
223
|
+
if (lengths[i] > maxLen)
|
|
224
|
+
maxLen = lengths[i];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// build the table
|
|
228
|
+
var size = 1 << maxLen;
|
|
229
|
+
var codes = new Uint32Array(size);
|
|
230
|
+
for (var len = 1, code = 0, skip = 2;
|
|
231
|
+
len <= maxLen;
|
|
232
|
+
++len, code <<= 1, skip <<= 1) {
|
|
233
|
+
for (var val = start; val < end; ++val) {
|
|
234
|
+
if (lengths[val] === len) {
|
|
235
|
+
// bit-reverse the code
|
|
236
|
+
var code2 = 0;
|
|
237
|
+
var t = code;
|
|
238
|
+
var v = val - start;
|
|
239
|
+
for (i = 0; i < len; ++i) {
|
|
240
|
+
code2 = (code2 << 1) | (t & 1);
|
|
241
|
+
t >>= 1;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// fill the table entries
|
|
245
|
+
for (i = code2; i < size; i += skip)
|
|
246
|
+
codes[i] = (len << 16) | v;
|
|
247
|
+
|
|
248
|
+
++code;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return [codes, maxLen];
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @returns {boolean}
|
|
258
|
+
*/
|
|
259
|
+
Inflate.prototype.readBlock = function Inflate_readBlock() {
|
|
260
|
+
// read block header
|
|
261
|
+
var hdr = this.getBits(3);
|
|
262
|
+
var stop = !!(hdr & 1);
|
|
263
|
+
var len;
|
|
264
|
+
hdr >>= 1;
|
|
265
|
+
|
|
266
|
+
if (hdr === 0) { // uncompressed block
|
|
267
|
+
var bytes = this.bytes;
|
|
268
|
+
var bytesPos = this.bytesPos;
|
|
269
|
+
var bytesLength = this.bytesLength;
|
|
270
|
+
|
|
271
|
+
if (bytesPos + 4 >= bytesLength )
|
|
272
|
+
throw new Error('Bad block header in flate stream');
|
|
273
|
+
|
|
274
|
+
var blockLen = bytes[bytesPos++] | bytes[bytesPos++] << 8;
|
|
275
|
+
var check = bytes[bytesPos++] | bytes[bytesPos++] << 8;
|
|
276
|
+
|
|
277
|
+
if (check !== (~blockLen & 0xffff))
|
|
278
|
+
throw new Error('Bad uncompressed block length in flate stream');
|
|
279
|
+
|
|
280
|
+
this.codeBuf = 0;
|
|
281
|
+
this.codeSize = 0;
|
|
282
|
+
|
|
283
|
+
var bufferPos = this.bufferPos;
|
|
284
|
+
var end = bufferPos + blockLen;
|
|
285
|
+
this.bufferPos = end;
|
|
286
|
+
|
|
287
|
+
for (var n = bufferPos; n < end && bytesPos < bytesLength; ++n)
|
|
288
|
+
this.buffer[n] = bytes[bytesPos++];
|
|
289
|
+
|
|
290
|
+
this.bytesPos = bytesPos;
|
|
291
|
+
return stop || (n < end);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
var litCodeTable;
|
|
295
|
+
var distCodeTable;
|
|
296
|
+
|
|
297
|
+
if (hdr == 1) { // compressed block, fixed codes
|
|
298
|
+
litCodeTable = fixedLitCodeTab;
|
|
299
|
+
distCodeTable = fixedDistCodeTab;
|
|
300
|
+
} else if (hdr == 2) { // compressed block, dynamic codes
|
|
301
|
+
var i;
|
|
302
|
+
var numLitCodes = this.getBits(5) + 257;
|
|
303
|
+
var numDistCodes = this.getBits(5) + 1;
|
|
304
|
+
var numCodeLenCodes = this.getBits(4) + 4;
|
|
305
|
+
|
|
306
|
+
// build the code lengths code table
|
|
307
|
+
_codeLenCodeLengths.set(_clean_codeLenCodeLengths);
|
|
308
|
+
|
|
309
|
+
for (i = 0; i < numCodeLenCodes; ++i)
|
|
310
|
+
_codeLenCodeLengths[codeLenCodeMap[i]] = this.getBits(3);
|
|
311
|
+
var codeLenCodeTab = this.generateHuffmanTable(_codeLenCodeLengths, 0, 19);
|
|
312
|
+
|
|
313
|
+
// build the literal and distance code tables
|
|
314
|
+
len = 0;
|
|
315
|
+
var bitsLength, bitsOffset, what;
|
|
316
|
+
i = 0;
|
|
317
|
+
var codes = numLitCodes + numDistCodes;
|
|
318
|
+
//var codeLengths = new Uint8Array(codes);
|
|
319
|
+
while (i < codes) {
|
|
320
|
+
var code = this.getCode(codeLenCodeTab);
|
|
321
|
+
if (code === 16) {
|
|
322
|
+
bitsLength = 2;
|
|
323
|
+
bitsOffset = 3;
|
|
324
|
+
what = len;
|
|
325
|
+
} else if (code === 17) {
|
|
326
|
+
bitsLength = 3;
|
|
327
|
+
bitsOffset = 3;
|
|
328
|
+
what = (len = 0);
|
|
329
|
+
} else if (code === 18) {
|
|
330
|
+
bitsLength = 7;
|
|
331
|
+
bitsOffset = 11;
|
|
332
|
+
what = (len = 0);
|
|
333
|
+
} else {
|
|
334
|
+
_codeLengths[i++] = len = code;
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
var repeatLength = this.getBits(bitsLength) + bitsOffset;
|
|
339
|
+
while (repeatLength-- > 0) {
|
|
340
|
+
_codeLengths[i++] = what;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
litCodeTable = this.generateHuffmanTable(_codeLengths, 0, numLitCodes);
|
|
345
|
+
distCodeTable = this.generateHuffmanTable(_codeLengths, numLitCodes, codes);
|
|
346
|
+
} else {
|
|
347
|
+
throw new Error('Unknown block type in flate stream');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
var buffer = this.buffer;
|
|
351
|
+
var pos = this.bufferPos;
|
|
352
|
+
while (true) {
|
|
353
|
+
var code1 = this.getCode(litCodeTable);
|
|
354
|
+
if (code1 < 256) {
|
|
355
|
+
buffer[pos++] = code1;
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (code1 == 256) {
|
|
359
|
+
this.bufferPos = pos;
|
|
360
|
+
return stop;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
code1 = lengthDecode[code1-257];
|
|
364
|
+
var code2 = code1 >> 16;
|
|
365
|
+
if (code2 > 0)
|
|
366
|
+
code2 = this.getBits(code2);
|
|
367
|
+
len = (code1 & 0xffff) + code2;
|
|
368
|
+
code1 = this.getCode(distCodeTable);
|
|
369
|
+
code1 = distDecode[code1];
|
|
370
|
+
code2 = code1 >> 16;
|
|
371
|
+
if (code2 > 0)
|
|
372
|
+
code2 = this.getBits(code2);
|
|
373
|
+
var dist = (code1 & 0xffff) + code2;
|
|
374
|
+
for (var k = 0; k < len; ++k, ++pos)
|
|
375
|
+
buffer[pos] = buffer[pos - dist];
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Export
|
|
381
|
+
*/
|
|
382
|
+
module.exports = Inflate;
|