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.
@@ -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;