PageRenderTime 152ms CodeModel.GetById 18ms app.highlight 46ms RepoModel.GetById 54ms app.codeStats 0ms

/zlib.js

http://github.com/sbober/pocjs
JavaScript | 464 lines | 383 code | 42 blank | 39 comment | 89 complexity | 6b0250df873f8ac882719af6e52d62e5 MD5 | raw file
  1/*
  2 * Extracted from pdf.js
  3 * https://github.com/andreasgal/pdf.js
  4 *
  5 * Copyright (c) 2011 Mozilla Foundation
  6 *
  7 * Contributors: Andreas Gal <gal@mozilla.com>
  8 *               Chris G Jones <cjones@mozilla.com>
  9 *               Shaon Barman <shaon.barman@gmail.com>
 10 *               Vivien Nicolas <21@vingtetun.org>
 11 *               Justin D'Arcangelo <justindarc@gmail.com>
 12 *               Yury Delendik
 13 *
 14 * Permission is hereby granted, free of charge, to any person obtaining a
 15 * copy of this software and associated documentation files (the "Software"),
 16 * to deal in the Software without restriction, including without limitation
 17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 18 * and/or sell copies of the Software, and to permit persons to whom the
 19 * Software is furnished to do so, subject to the following conditions:
 20 *
 21 * The above copyright notice and this permission notice shall be included in
 22 * all copies or substantial portions of the Software.
 23 *
 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 27 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 30 * DEALINGS IN THE SOFTWARE.
 31 */
 32
 33var DecodeStream = (function() {
 34  function constructor() {
 35    this.pos = 0;
 36    this.bufferLength = 0;
 37    this.eof = false;
 38    this.buffer = null;
 39  }
 40
 41  constructor.prototype = {
 42    ensureBuffer: function decodestream_ensureBuffer(requested) {
 43      var buffer = this.buffer;
 44      var current = buffer ? buffer.byteLength : 0;
 45      if (requested < current)
 46        return buffer;
 47      var size = 512;
 48      while (size < requested)
 49        size <<= 1;
 50      var buffer2 = new Uint8Array(size);
 51      for (var i = 0; i < current; ++i)
 52        buffer2[i] = buffer[i];
 53      return this.buffer = buffer2;
 54    },
 55    getByte: function decodestream_getByte() {
 56      var pos = this.pos;
 57      while (this.bufferLength <= pos) {
 58        if (this.eof)
 59          return null;
 60        this.readBlock();
 61      }
 62      return this.buffer[this.pos++];
 63    },
 64    getBytes: function decodestream_getBytes(length) {
 65      var pos = this.pos;
 66
 67      if (length) {
 68        this.ensureBuffer(pos + length);
 69        var end = pos + length;
 70
 71        while (!this.eof && this.bufferLength < end)
 72          this.readBlock();
 73
 74        var bufEnd = this.bufferLength;
 75        if (end > bufEnd)
 76          end = bufEnd;
 77      } else {
 78        while (!this.eof)
 79          this.readBlock();
 80
 81        var end = this.bufferLength;
 82      }
 83
 84      this.pos = end;
 85      return this.buffer.subarray(pos, end);
 86    },
 87    lookChar: function decodestream_lookChar() {
 88      var pos = this.pos;
 89      while (this.bufferLength <= pos) {
 90        if (this.eof)
 91          return null;
 92        this.readBlock();
 93      }
 94      return String.fromCharCode(this.buffer[this.pos]);
 95    },
 96    getChar: function decodestream_getChar() {
 97      var pos = this.pos;
 98      while (this.bufferLength <= pos) {
 99        if (this.eof)
100          return null;
101        this.readBlock();
102      }
103      return String.fromCharCode(this.buffer[this.pos++]);
104    },
105    makeSubStream: function decodestream_makeSubstream(start, length, dict) {
106      var end = start + length;
107      while (this.bufferLength <= end && !this.eof)
108        this.readBlock();
109      return new Stream(this.buffer, start, length, dict);
110    },
111    skip: function decodestream_skip(n) {
112      if (!n)
113        n = 1;
114      this.pos += n;
115    },
116    reset: function decodestream_reset() {
117      this.pos = 0;
118    }
119  };
120
121  return constructor;
122})();
123
124var FlateStream = (function() {
125  var codeLenCodeMap = new Uint32Array([
126    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
127  ]);
128
129  var lengthDecode = new Uint32Array([
130    0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a,
131    0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f,
132    0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073,
133    0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102
134  ]);
135
136  var distDecode = new Uint32Array([
137    0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d,
138    0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1,
139    0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01,
140    0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001
141  ]);
142
143  var fixedLitCodeTab = [new Uint32Array([
144    0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0,
145    0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0,
146    0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0,
147    0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0,
148    0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8,
149    0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8,
150    0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8,
151    0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8,
152    0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4,
153    0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4,
154    0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4,
155    0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4,
156    0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc,
157    0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec,
158    0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc,
159    0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc,
160    0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2,
161    0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2,
162    0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2,
163    0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2,
164    0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca,
165    0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea,
166    0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da,
167    0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa,
168    0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6,
169    0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6,
170    0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6,
171    0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6,
172    0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce,
173    0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee,
174    0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de,
175    0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe,
176    0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1,
177    0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1,
178    0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1,
179    0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1,
180    0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9,
181    0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9,
182    0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9,
183    0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9,
184    0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5,
185    0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5,
186    0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5,
187    0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5,
188    0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd,
189    0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed,
190    0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd,
191    0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd,
192    0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3,
193    0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3,
194    0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3,
195    0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3,
196    0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb,
197    0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb,
198    0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db,
199    0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb,
200    0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7,
201    0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7,
202    0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7,
203    0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7,
204    0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf,
205    0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef,
206    0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df,
207    0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff
208  ]), 9];
209
210  var fixedDistCodeTab = [new Uint32Array([
211    0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c,
212    0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000,
213    0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d,
214    0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000
215  ]), 5];
216  
217  function error(e) {
218      throw new Error(e)
219  }
220
221  function constructor(bytes) {
222    //var bytes = stream.getBytes();
223    var bytesPos = 0;
224
225    var cmf = bytes[bytesPos++];
226    var flg = bytes[bytesPos++];
227    if (cmf == -1 || flg == -1)
228      error('Invalid header in flate stream');
229    if ((cmf & 0x0f) != 0x08)
230      error('Unknown compression method in flate stream');
231    if ((((cmf << 8) + flg) % 31) != 0)
232      error('Bad FCHECK in flate stream');
233    if (flg & 0x20)
234      error('FDICT bit set in flate stream');
235
236    this.bytes = bytes;
237    this.bytesPos = bytesPos;
238
239    this.codeSize = 0;
240    this.codeBuf = 0;
241
242    DecodeStream.call(this);
243  }
244
245  constructor.prototype = Object.create(DecodeStream.prototype);
246
247  constructor.prototype.getBits = function(bits) {
248    var codeSize = this.codeSize;
249    var codeBuf = this.codeBuf;
250    var bytes = this.bytes;
251    var bytesPos = this.bytesPos;
252
253    var b;
254    while (codeSize < bits) {
255      if (typeof (b = bytes[bytesPos++]) == 'undefined')
256        error('Bad encoding in flate stream');
257      codeBuf |= b << codeSize;
258      codeSize += 8;
259    }
260    b = codeBuf & ((1 << bits) - 1);
261    this.codeBuf = codeBuf >> bits;
262    this.codeSize = codeSize -= bits;
263    this.bytesPos = bytesPos;
264    return b;
265  };
266
267  constructor.prototype.getCode = function(table) {
268    var codes = table[0];
269    var maxLen = table[1];
270    var codeSize = this.codeSize;
271    var codeBuf = this.codeBuf;
272    var bytes = this.bytes;
273    var bytesPos = this.bytesPos;
274
275    while (codeSize < maxLen) {
276      var b;
277      if (typeof (b = bytes[bytesPos++]) == 'undefined')
278        error('Bad encoding in flate stream');
279      codeBuf |= (b << codeSize);
280      codeSize += 8;
281    }
282    var code = codes[codeBuf & ((1 << maxLen) - 1)];
283    var codeLen = code >> 16;
284    var codeVal = code & 0xffff;
285    if (codeSize == 0 || codeSize < codeLen || codeLen == 0)
286      error('Bad encoding in flate stream');
287    this.codeBuf = (codeBuf >> codeLen);
288    this.codeSize = (codeSize - codeLen);
289    this.bytesPos = bytesPos;
290    return codeVal;
291  };
292
293  constructor.prototype.generateHuffmanTable = function(lengths) {
294    var n = lengths.length;
295
296    // find max code length
297    var maxLen = 0;
298    for (var i = 0; i < n; ++i) {
299      if (lengths[i] > maxLen)
300        maxLen = lengths[i];
301    }
302
303    // build the table
304    var size = 1 << maxLen;
305    var codes = new Uint32Array(size);
306    for (var len = 1, code = 0, skip = 2;
307         len <= maxLen;
308         ++len, code <<= 1, skip <<= 1) {
309      for (var val = 0; val < n; ++val) {
310        if (lengths[val] == len) {
311          // bit-reverse the code
312          var code2 = 0;
313          var t = code;
314          for (var i = 0; i < len; ++i) {
315            code2 = (code2 << 1) | (t & 1);
316            t >>= 1;
317          }
318
319          // fill the table entries
320          for (var i = code2; i < size; i += skip)
321            codes[i] = (len << 16) | val;
322
323          ++code;
324        }
325      }
326    }
327
328    return [codes, maxLen];
329  };
330
331  constructor.prototype.readBlock = function() {
332    function repeat(stream, array, len, offset, what) {
333      var repeat = stream.getBits(len) + offset;
334      while (repeat-- > 0)
335        array[i++] = what;
336    }
337
338    // read block header
339    var hdr = this.getBits(3);
340    if (hdr & 1)
341      this.eof = true;
342    hdr >>= 1;
343
344    if (hdr == 0) { // uncompressed block
345      var bytes = this.bytes;
346      var bytesPos = this.bytesPos;
347      var b;
348
349      if (typeof (b = bytes[bytesPos++]) == 'undefined')
350        error('Bad block header in flate stream');
351      var blockLen = b;
352      if (typeof (b = bytes[bytesPos++]) == 'undefined')
353        error('Bad block header in flate stream');
354      blockLen |= (b << 8);
355      if (typeof (b = bytes[bytesPos++]) == 'undefined')
356        error('Bad block header in flate stream');
357      var check = b;
358      if (typeof (b = bytes[bytesPos++]) == 'undefined')
359        error('Bad block header in flate stream');
360      check |= (b << 8);
361      if (check != (~blockLen & 0xffff))
362        error('Bad uncompressed block length in flate stream');
363
364      this.codeBuf = 0;
365      this.codeSize = 0;
366
367      var bufferLength = this.bufferLength;
368      var buffer = this.ensureBuffer(bufferLength + blockLen);
369      var end = bufferLength + blockLen;
370      this.bufferLength = end;
371      for (var n = bufferLength; n < end; ++n) {
372        if (typeof (b = bytes[bytesPos++]) == 'undefined') {
373          this.eof = true;
374          break;
375        }
376        buffer[n] = b;
377      }
378      this.bytesPos = bytesPos;
379      return;
380    }
381
382    var litCodeTable;
383    var distCodeTable;
384    if (hdr == 1) { // compressed block, fixed codes
385      litCodeTable = fixedLitCodeTab;
386      distCodeTable = fixedDistCodeTab;
387    } else if (hdr == 2) { // compressed block, dynamic codes
388      var numLitCodes = this.getBits(5) + 257;
389      var numDistCodes = this.getBits(5) + 1;
390      var numCodeLenCodes = this.getBits(4) + 4;
391
392      // build the code lengths code table
393      var codeLenCodeLengths = Array(codeLenCodeMap.length);
394      var i = 0;
395      while (i < numCodeLenCodes)
396        codeLenCodeLengths[codeLenCodeMap[i++]] = this.getBits(3);
397      var codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths);
398
399      // build the literal and distance code tables
400      var len = 0;
401      var i = 0;
402      var codes = numLitCodes + numDistCodes;
403      var codeLengths = new Array(codes);
404      while (i < codes) {
405        var code = this.getCode(codeLenCodeTab);
406        if (code == 16) {
407          repeat(this, codeLengths, 2, 3, len);
408        } else if (code == 17) {
409          repeat(this, codeLengths, 3, 3, len = 0);
410        } else if (code == 18) {
411          repeat(this, codeLengths, 7, 11, len = 0);
412        } else {
413          codeLengths[i++] = len = code;
414        }
415      }
416
417      litCodeTable =
418        this.generateHuffmanTable(codeLengths.slice(0, numLitCodes));
419      distCodeTable =
420        this.generateHuffmanTable(codeLengths.slice(numLitCodes, codes));
421    } else {
422      error('Unknown block type in flate stream');
423    }
424
425    var buffer = this.buffer;
426    var limit = buffer ? buffer.length : 0;
427    var pos = this.bufferLength;
428    while (true) {
429      var code1 = this.getCode(litCodeTable);
430      if (code1 < 256) {
431        if (pos + 1 >= limit) {
432          buffer = this.ensureBuffer(pos + 1);
433          limit = buffer.length;
434        }
435        buffer[pos++] = code1;
436        continue;
437      }
438      if (code1 == 256) {
439        this.bufferLength = pos;
440        return;
441      }
442      code1 -= 257;
443      code1 = lengthDecode[code1];
444      var code2 = code1 >> 16;
445      if (code2 > 0)
446        code2 = this.getBits(code2);
447      var len = (code1 & 0xffff) + code2;
448      code1 = this.getCode(distCodeTable);
449      code1 = distDecode[code1];
450      code2 = code1 >> 16;
451      if (code2 > 0)
452        code2 = this.getBits(code2);
453      var dist = (code1 & 0xffff) + code2;
454      if (pos + len >= limit) {
455        buffer = this.ensureBuffer(pos + len);
456        limit = buffer.length;
457      }
458      for (var k = 0; k < len; ++k, ++pos)
459        buffer[pos] = buffer[pos - dist];
460    }
461  };
462
463  return constructor;
464})();