UNPKG

32.9 kBJavaScriptView Raw
1function JSDeflater(/*inbuff*/inbuf) {
2
3 var WSIZE = 0x8000, // Sliding Window size
4 WINDOW_SIZE = 0x10000,
5
6 /* for deflate */
7 MIN_MATCH = 0x03,
8 MAX_MATCH = 0x102,
9 LIT_BUFSIZE = 0x2000,
10 MAX_DIST = 0x7EFA,
11 MAX_BITS = 0x0F,
12 MAX_BL_BITS = 0x07,
13 L_CODES = 0x11E,
14 D_CODES = 0x1E,
15 BL_CODES = 0x13,
16 REP_3_6 = 0x10,
17 REPZ_3_10 = 0x11,
18 REPZ_11_138 = 0x12,
19 HEAP_SIZE = 2 * L_CODES + 1,
20 H_SHIFT = parseInt((0x10 + MIN_MATCH - 1) / MIN_MATCH),
21
22 /* variables */
23 freeQueue,
24 qHead, qTail,
25 initFlag,
26 outbuf = null,
27 outcnt, outoff,
28 complete,
29 window,
30 dBuf,
31 lBuf,
32 prev,
33 biBuf,
34 biValid,
35 blockStart,
36 zip_ins_h,
37 hashHead,
38 prevMatch,
39 matchAvailable,
40 matchLength,
41 matchStart,
42 prevLength,
43 dataStart,
44 eofile,
45 lookahead,
46 maxChainLength,
47 maxLazyMatch,
48 compression_level,
49 goodMatch,
50 dynLTree = [],
51 dynDTree = [],
52 staticLTree = [],
53 staticDTree = [],
54 blTree = [],
55 lDesc,
56 dDesc,
57 blDesc,
58 blCount,
59 zip_heap,
60 heapLen,
61 heapMax,
62 depth,
63 lengthCode,
64 distCode,
65 baseLength,
66 baseDist,
67 flagBuf,
68 lastLit,
69 lastDist,
70 lastFlags,
71 flags,
72 flagBit,
73 optLen,
74 staticLen,
75 deflateData,
76 deflatePos,
77
78 elbits = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0],
79 edbits = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13],
80 eblbits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7],
81 blorder = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
82
83 function deflateTreeDesc() {
84 return {
85 dyn_tree : null, // the dynamic tree
86 static_tree : null, // corresponding static tree or NULL
87 extra_bits : null, // extra bits for each code or NULL
88 extra_base : 0, // base index for extra_bits
89 elems : 0, // max number of elements in the tree
90 max_length : 0, // max bit length for the codes
91 max_code : 0
92 }
93 }
94
95 function deflateStart(level) {
96 var i;
97 compression_level = !level && 9 || level > 9 && 9 || level;
98 initFlag = false;
99 eofile = false;
100
101 if(outbuf != null)
102 return;
103
104 freeQueue = qHead = qTail = null;
105 outbuf = new Buffer(LIT_BUFSIZE);
106 window = new Buffer(WINDOW_SIZE);
107
108 dBuf = new Array(LIT_BUFSIZE);
109 lBuf = new Array(inbuf.length + 0x64); // 0x64 extra buffer length
110 prev = new Array(0x10000);
111
112 for(i = 0; i < HEAP_SIZE; i++) dynLTree[i] = {fc:0, dl:0};
113 for(i = 0; i < 2 * D_CODES + 1; i++) dynDTree[i] = {fc:0, dl:0};
114 for(i = 0; i < L_CODES + 2; i++) staticLTree[i] = {fc:0, dl:0};
115 for(i = 0; i < D_CODES; i++) staticDTree[i] = {fc:0, dl:0};
116 for(i = 0; i < 2 * BL_CODES + 1; i++) blTree[i] = {fc:0, dl:0};
117
118 lDesc = deflateTreeDesc();
119 dDesc = deflateTreeDesc();
120 blDesc = deflateTreeDesc();
121
122 blCount = new Buffer(MAX_BITS + 1);
123 zip_heap = new Array(2 * L_CODES + 1);
124 depth = new Buffer(2 * L_CODES + 1);
125 lengthCode = new Buffer(MAX_MATCH - MIN_MATCH + 1);
126 distCode = new Buffer(0x200);
127 baseLength = new Buffer(0x1D);
128 baseDist = new Buffer(D_CODES);
129 flagBuf = new Buffer(parseInt(LIT_BUFSIZE / 8));
130 }
131
132 function cleanup() {
133 freeQueue = qHead = qTail = null;
134 outbuf = null;
135 window = null;
136 dBuf = null;
137 lBuf = null;
138 prev = null;
139 dynLTree = null;
140 dynDTree = null;
141 staticLTree = null;
142 staticDTree = null;
143 blTree = null;
144 lDesc = null;
145 dDesc = null;
146 blDesc = null;
147 blCount = null;
148 zip_heap = null;
149 depth = null;
150 lengthCode = null;
151 distCode = null;
152 baseLength = null;
153 baseDist = null;
154 flagBuf = null;
155 }
156
157 function writeByte(c) {
158 outbuf[outoff + outcnt++] = c;
159 if(outoff + outcnt == LIT_BUFSIZE) {
160 if(outcnt != 0) {
161 var q, i;
162 if (freeQueue != null) {
163 q = freeQueue;
164 freeQueue = freeQueue.next;
165 } else {
166 q = {
167 "next" : null,
168 "len" : 0,
169 "ptr" : new Buffer(LIT_BUFSIZE),
170 "off" : 0
171 }
172 }
173 q.next = null;
174 q.len = q.off = 0;
175
176 if(qHead == null)
177 qHead = qTail = q;
178 else
179 qTail = qTail.next = q;
180
181 q.len = outcnt - outoff;
182 for(i = 0; i < q.len; i++)
183 q.ptr[i] = outbuf[outoff + i];
184 outcnt = outoff = 0;
185 }
186 }
187 }
188
189 function writeShort(w) {
190 w &= 0xffff;
191 if(outoff + outcnt < LIT_BUFSIZE - 2) {
192 outbuf[outoff + outcnt++] = (w & 0xff);
193 outbuf[outoff + outcnt++] = (w >>> 8);
194 } else {
195 writeByte(w & 0xff);
196 writeByte(w >>> 8);
197 }
198 return true;
199 }
200
201 function insertString() {
202 zip_ins_h = ((zip_ins_h << H_SHIFT) ^ (window[dataStart + MIN_MATCH - 1] & 0xff)) & 0x1FFF;
203 hashHead = prev[WSIZE + zip_ins_h];
204 prev[dataStart & 0x7FFF] = hashHead;
205 prev[WSIZE + zip_ins_h] = dataStart;
206 }
207
208 function sendCode(c, tree) {
209 sendBits(tree[c].fc, tree[c].dl);
210 }
211
212 function zip_D_CODE(dist) {
213 return (dist < 256 ? distCode[dist]
214 : distCode[256 + (dist>>7)]) & 0xff;
215 }
216
217 function smaller(tree, n, m) {
218 return tree[n].fc < tree[m].fc ||
219 (tree[n].fc == tree[m].fc && depth[n] <= depth[m]);
220 }
221
222 function readBuff(buff, offset, n) {
223 var i, len = deflateData.length;
224 for(i = 0; i < n && deflatePos < len; i++) {
225 buff[offset + i] = deflateData[deflatePos++];
226 }
227 return i;
228 }
229
230 function lmInit() {
231 var j;
232
233 for(j = 0; j < 0x2000; j++) prev[WSIZE + j] = 0;
234
235 goodMatch = [0x0, 0x4, 0x4, 0x4, 0x4, 0x8, 0x8, 0x8, 0x20, 0x20][compression_level];
236 maxLazyMatch = [0x0, 0x4, 0x5, 0x6, 0x4, 0x10, 0x10, 0x20, 0x80, 0x102][compression_level];
237 maxChainLength = [0x0, 0x4, 0x8, 0x20, 0x10, 0x20, 0x80, 0x100, 0x400, 0x1000][compression_level];
238
239 dataStart = 0;
240 blockStart = 0;
241
242 lookahead = readBuff(window, 0, 2 * WSIZE);
243 if(lookahead <= 0) {
244 eofile = true;
245 lookahead = 0;
246 return;
247 }
248 eofile = false;
249
250 while(lookahead < 0x106 && !eofile)
251 fillWindow();
252
253 zip_ins_h = 0;
254 for(j = 0; j < MIN_MATCH - 1; j++) {
255 zip_ins_h = ((zip_ins_h << H_SHIFT) ^ (window[j] & 0xFF)) & 0x1FFF;
256 }
257 }
258
259 function longestMatch(cur_match) {
260 var chain_length = maxChainLength, // max hash chain length
261 scanp = dataStart, // current string
262 matchp, // matched string
263 len, // length of current match
264 best_len = prevLength, // best match length so far
265 limit = (dataStart > MAX_DIST ? dataStart - MAX_DIST : 0),
266 strendp = dataStart + MAX_MATCH,
267 scan_end1 = window[scanp + best_len - 1],
268 scan_end = window[scanp + best_len];
269
270 prevLength >= goodMatch && (chain_length >>= 2);
271 do {
272 matchp = cur_match;
273 if(window[matchp + best_len] != scan_end ||
274 window[matchp + best_len - 1] != scan_end1 ||
275 window[matchp] != window[scanp] ||
276 window[++matchp] != window[scanp + 1]) {
277 continue;
278 }
279
280 scanp += 2;
281 matchp++;
282
283 do {} while(window[++scanp] == window[++matchp] &&
284 window[++scanp] == window[++matchp] &&
285 window[++scanp] == window[++matchp] &&
286 window[++scanp] == window[++matchp] &&
287 window[++scanp] == window[++matchp] &&
288 window[++scanp] == window[++matchp] &&
289 window[++scanp] == window[++matchp] &&
290 window[++scanp] == window[++matchp] &&
291 scanp < strendp);
292
293 len = MAX_MATCH - (strendp - scanp);
294 scanp = strendp - MAX_MATCH;
295
296 if(len > best_len) {
297 matchStart = cur_match;
298 best_len = len;
299 if(len >= MAX_MATCH) break;
300
301 scan_end1 = window[scanp + best_len-1];
302 scan_end = window[scanp + best_len];
303 }
304 } while((cur_match = prev[cur_match & 0x7FFF]) > limit && --chain_length != 0);
305
306 return best_len;
307 }
308
309 function fillWindow() {
310 var n, m,
311 more = WINDOW_SIZE - lookahead - dataStart;
312
313 if(more == -1) {
314 more--;
315 } else if(dataStart >= WSIZE + MAX_DIST) {
316
317 for(n = 0; n < WSIZE; n++)
318 window[n] = window[n + WSIZE];
319
320 matchStart -= WSIZE;
321 dataStart -= WSIZE;
322 blockStart -= WSIZE;
323
324 for(n = 0; n < 0x2000; n++) {
325 m = prev[WSIZE + n];
326 prev[WSIZE + n] = m >= WSIZE ? m - WSIZE : 0;
327 }
328 for(n = 0; n < WSIZE; n++) {
329 m = prev[n];
330 prev[n] = (m >= WSIZE ? m - WSIZE : 0);
331 }
332 more += WSIZE;
333 }
334 if(!eofile) {
335 n = readBuff(window, dataStart + lookahead, more);
336 n <= 0 && (eofile = true) || (lookahead += n);
337 }
338 }
339
340 function deflateFast() {
341 while(lookahead != 0 && qHead == null) {
342 var flush; // set if current block must be flushed
343
344 insertString();
345
346 if(hashHead != 0 && dataStart - hashHead <= MAX_DIST) {
347 matchLength = longestMatch(hashHead);
348 matchLength > lookahead && (matchLength = lookahead);
349 }
350 if(matchLength >= MIN_MATCH) {
351 flush = ctTally(dataStart - matchStart, matchLength - MIN_MATCH);
352 lookahead -= matchLength;
353
354 if(matchLength <= maxLazyMatch) {
355 matchLength--;
356 do {
357 dataStart++;
358 insertString();
359 } while(--matchLength != 0);
360 dataStart++;
361 } else {
362 dataStart += matchLength;
363 matchLength = 0;
364 zip_ins_h = (((window[dataStart] & 0xFF) << H_SHIFT) ^ (window[dataStart + 1] & 0xFF)) & 0x1FFF;
365 }
366 } else {
367 flush = ctTally(0, window[dataStart] & 0xFF);
368 lookahead--;
369 dataStart++;
370 }
371 if(flush) {
372 flushBlock(0);
373 blockStart = dataStart;
374 }
375
376 while(lookahead < 0x106 && !eofile)
377 fillWindow();
378 }
379 }
380
381 function deflateBetter() {
382 while(lookahead != 0 && qHead == null) {
383 insertString();
384 prevLength = matchLength;
385 prevMatch = matchStart;
386 matchLength = MIN_MATCH - 1;
387
388 if(hashHead != 0 && prevLength < maxLazyMatch && dataStart - hashHead <= MAX_DIST) {
389 matchLength = longestMatch(hashHead);
390 matchLength > lookahead && (matchLength = lookahead);
391 (matchLength == MIN_MATCH && dataStart - matchStart > 0x1000) && matchLength--;
392 }
393 if(prevLength >= MIN_MATCH && matchLength <= prevLength) {
394 var flush; // set if current block must be flushed
395 flush = ctTally(dataStart - 1 - prevMatch, prevLength - MIN_MATCH);
396 lookahead -= prevLength - 1;
397 prevLength -= 2;
398 do {
399 dataStart++;
400 insertString();
401 } while(--prevLength != 0);
402 matchAvailable = 0;
403 matchLength = MIN_MATCH - 1;
404 dataStart++;
405 if(flush) {
406 flushBlock(0);
407 blockStart = dataStart;
408 }
409 } else if( matchAvailable != 0) {
410 if(ctTally(0, window[dataStart - 1] & 0xff)) {
411 flushBlock(0);
412 blockStart = dataStart;
413 }
414 dataStart++;
415 lookahead--;
416 } else {
417 matchAvailable = 1;
418 dataStart++;
419 lookahead--;
420 }
421
422 while(lookahead < 0x106 && !eofile)
423 fillWindow();
424 }
425 }
426
427 function initDeflate() {
428 if(eofile) return;
429
430 biBuf = 0;
431 biValid = 0;
432 ctInit();
433 lmInit();
434
435 qHead = null;
436 outcnt = 0;
437 outoff = 0;
438
439 if(compression_level <= 3) {
440 prevLength = MIN_MATCH - 1;
441 matchLength = 0;
442 } else {
443 matchLength = MIN_MATCH - 1;
444 matchAvailable = 0;
445 }
446
447 complete = false;
448 }
449
450 function internalDeflate(buff, off, buff_size) {
451 var n;
452 if(!initFlag) {
453 initDeflate();
454 initFlag = true;
455 if(lookahead == 0) { // empty
456 complete = true;
457 return 0;
458 }
459 }
460 if((n = qCopy(buff, off, buff_size)) == buff_size) return buff_size;
461 if(complete) return n;
462 if(compression_level <= 3) // optimized for speed
463 deflateFast();
464 else
465 deflateBetter();
466 if(lookahead == 0) {
467 matchAvailable != 0 && ctTally(0, window[dataStart - 1] & 0xff);
468 flushBlock(1);
469 complete = true;
470 }
471 return n + qCopy(buff, n + off, buff_size - n);
472 }
473
474 function qCopy(buff, off, buff_size) {
475 var n = 0, i, j;
476
477 while(qHead != null && n < buff_size) {
478 i = buff_size - n;
479 i > qHead.len && (i = qHead.len);
480 for(j = 0; j < i; j++) buff[off + n + j] = qHead.ptr[qHead.off + j];
481 qHead.off += i;
482 qHead.len -= i;
483 n += i;
484 if(qHead.len == 0) {
485 var p;
486 p = qHead;
487 qHead = qHead.next;
488 p.next = freeQueue;
489 freeQueue = p;
490 }
491 }
492
493 if(n == buff_size) return n;
494
495 if(outoff < outcnt) {
496 i = buff_size - n;
497 if(i > outcnt - outoff)
498 i = outcnt - outoff;
499 for(j = 0; j < i; j++)
500 buff[off + n + j] = outbuf[outoff + j];
501 outoff += i;
502 n += i;
503 if(outcnt == outoff)
504 outcnt = outoff = 0;
505 }
506 return n;
507 }
508
509 function ctInit() {
510 var n, // iterates over tree elements
511 bits, // bit counter
512 length, // length value
513 code, // code value
514 dist; // distance index
515
516 if(staticDTree[0].dl != 0) return; // ct_init already called
517
518 lDesc.dyn_tree = dynLTree;
519 lDesc.static_tree = staticLTree;
520 lDesc.extra_bits = elbits;
521 lDesc.extra_base = 0x101;
522 lDesc.elems = L_CODES;
523 lDesc.max_length = MAX_BITS;
524 lDesc.max_code = 0;
525
526 dDesc.dyn_tree = dynDTree;
527 dDesc.static_tree = staticDTree;
528 dDesc.extra_bits = edbits;
529 dDesc.extra_base = 0;
530 dDesc.elems = D_CODES;
531 dDesc.max_length = MAX_BITS;
532 dDesc.max_code = 0;
533
534 blDesc.dyn_tree = blTree;
535 blDesc.static_tree = null;
536 blDesc.extra_bits = eblbits;
537 blDesc.extra_base = 0;
538 blDesc.elems = BL_CODES;
539 blDesc.max_length = MAX_BL_BITS;
540 blDesc.max_code = 0;
541
542 // Initialize the mapping length (0..255) -> length code (0..28)
543 length = 0;
544 for(code = 0; code < 0x1E; code++) {
545 baseLength[code] = length;
546 for(n = 0; n < (1 << elbits[code]); n++)
547 lengthCode[length++] = code;
548 }
549 lengthCode[length - 1] = code;
550 dist = 0;
551 for(code = 0 ; code < 16; code++) {
552 baseDist[code] = dist;
553 for(n = 0; n < (1 << edbits[code]); n++)
554 distCode[dist++] = code;
555 }
556 dist >>= 7; // from now on, all distances are divided by 128
557 for( ; code < D_CODES; code++) {
558 baseDist[code] = dist << 7;
559 for(n = 0; n < (1<<(edbits[code]-7)); n++)
560 distCode[256 + dist++] = code;
561 }
562 for(bits = 0; bits <= MAX_BITS; bits++) blCount[bits] = 0;
563
564 n = 0;
565 while(n <= 143) { staticLTree[n++].dl = 8; blCount[8]++; }
566 while(n <= 255) { staticLTree[n++].dl = 9; blCount[9]++; }
567 while(n <= 279) { staticLTree[n++].dl = 7; blCount[7]++; }
568 while(n <= 287) { staticLTree[n++].dl = 8; blCount[8]++; }
569
570 genCodes(staticLTree, L_CODES + 1);
571
572 for(n = 0; n < D_CODES; n++) {
573 staticDTree[n].dl = 5;
574 staticDTree[n].fc = reverse(n, 5);
575 }
576 initBlock();
577 }
578
579 function initBlock() {
580 var n;
581
582 for(n = 0; n < L_CODES; n++) dynLTree[n].fc = 0;
583 for(n = 0; n < D_CODES; n++) dynDTree[n].fc = 0;
584 for(n = 0; n < BL_CODES; n++) blTree[n].fc = 0;
585
586 dynLTree[0x100].fc = flagBit = 1; // end block
587 flags = optLen = staticLen = lastLit = lastDist = lastFlags = 0;
588 }
589
590 function pqDownHeap(tree, k) {
591 var v = zip_heap[k],
592 j = k << 1;
593
594 while(j <= heapLen) {
595 (j < heapLen && smaller(tree, zip_heap[j + 1], zip_heap[j])) && j++;
596 if(smaller(tree, v, zip_heap[j])) break;
597 zip_heap[k] = zip_heap[j];
598 k = j;
599 j <<= 1;
600 }
601 zip_heap[k] = v;
602 }
603
604
605 function genBitLen(desc) {
606 var tree = desc.dyn_tree,
607 extra = desc.extra_bits,
608 base = desc.extra_base,
609 max_code = desc.max_code,
610 max_length = desc.max_length,
611 stree = desc.static_tree,
612 h, // heap index
613 n, m, // iterate over the tree elements
614 bits, // bit length
615 xbits, // extra bits
616 f, // frequency
617 overflow = 0; // number of elements with bit length too large
618
619 for(bits = 0; bits <= MAX_BITS; bits++)
620 blCount[bits] = 0;
621
622 tree[zip_heap[heapMax]].dl = 0; // root of the heap
623
624 for(h = heapMax + 1; h < HEAP_SIZE; h++) {
625 n = zip_heap[h];
626 bits = tree[tree[n].dl].dl + 1;
627 if(bits > max_length) {
628 bits = max_length;
629 overflow++;
630 }
631 tree[n].dl = bits;
632
633 if(n > max_code) continue; // not a leaf node
634
635 blCount[bits]++;
636 xbits = 0;
637 n >= base && (xbits = extra[n - base]);
638 f = tree[n].fc;
639 optLen += f * (bits + xbits);
640 stree != null && (staticLen += f * (stree[n].dl + xbits));
641 }
642 if (!overflow) return;
643 do {
644 bits = max_length - 1;
645 while(blCount[bits] == 0) bits--;
646 blCount[bits]--; // move one leaf down the tree
647 blCount[bits + 1] += 2; // move one overflow item as its brother
648 blCount[max_length]--;
649 overflow -= 2;
650 } while(overflow > 0);
651
652 for(bits = max_length; bits != 0; bits--) {
653 n = blCount[bits];
654 while(n != 0) {
655 m = zip_heap[--h];
656 if(m > max_code) continue;
657 if(tree[m].dl != bits) {
658 optLen += (bits - tree[m].dl) * tree[m].fc;
659 tree[m].fc = bits;
660 }
661 n--;
662 }
663 }
664 }
665
666 function genCodes(tree, max_code) {
667 var next_code = new Array(MAX_BITS + 1), // next code value for each bit length
668 code = 0, // running code value
669 bits, // bit index
670 n; // code index
671
672 for(bits = 1; bits <= MAX_BITS; bits++) {
673 code = ((code + blCount[bits-1]) << 1);
674 next_code[bits] = code;
675 }
676
677 for(n = 0; n <= max_code; n++) {
678 var len = tree[n].dl;
679 if (len == 0)
680 continue;
681 tree[n].fc = reverse(next_code[len]++, len);
682 }
683 }
684
685 function buildTree(desc) { // the tree descriptor
686 var tree = desc.dyn_tree,
687 stree = desc.static_tree,
688 elems = desc.elems,
689 n, m, // iterate over heap elements
690 max_code = -1, // largest code with non zero frequency
691 node = elems; // next internal node of the tree
692 heapLen = 0;
693 heapMax = HEAP_SIZE;
694
695 for(n = 0; n < elems; n++) {
696 if(tree[n].fc != 0) {
697 zip_heap[++heapLen] = max_code = n;
698 depth[n] = 0;
699 } else
700 tree[n].dl = 0;
701 }
702
703 while(heapLen < 2) {
704 var xnew = zip_heap[++heapLen] = (max_code < 2 ? ++max_code : 0);
705 tree[xnew].fc = 1;
706 depth[xnew] = 0;
707 optLen--;
708 stree != null && (staticLen -= stree[xnew].dl);
709 }
710 desc.max_code = max_code;
711
712 for(n = heapLen >> 1; n >= 1; n--) pqDownHeap(tree, n);
713
714 do {
715 n = zip_heap[1];
716 zip_heap[1] = zip_heap[heapLen--];
717 pqDownHeap(tree, 1);
718
719 m = zip_heap[1]; // m = node of next least frequency
720
721 // keep the nodes sorted by frequency
722 zip_heap[--heapMax] = n;
723 zip_heap[--heapMax] = m;
724
725 // Create a new node father of n and m
726 tree[node].fc = tree[n].fc + tree[m].fc;
727
728 if(depth[n] > depth[m] + 1)
729 depth[node] = depth[n];
730 else
731 depth[node] = depth[m] + 1;
732
733 tree[n].dl = tree[m].dl = node;
734
735 // and insert the new node in the heap
736 zip_heap[1] = node++;
737 pqDownHeap(tree, 1);
738
739 } while(heapLen >= 2);
740
741 zip_heap[--heapMax] = zip_heap[1];
742
743 genBitLen(desc);
744 genCodes(tree, max_code);
745 }
746
747 function scanTree(tree, max_code) {
748 var n, // iterates over all tree elements
749 prevlen = -1, // last emitted length
750 curlen, // length of current code
751 nextlen = tree[0].dl, // length of next code
752 count = 0, // repeat count of the current code
753 max_count = 7, // max repeat count
754 min_count = 4; // min repeat count
755
756 if(nextlen == 0) {
757 max_count = 138;
758 min_count = 3;
759 }
760 tree[max_code + 1].dl = 0xffff; // guard
761
762 for(n = 0; n <= max_code; n++) {
763 curlen = nextlen;
764 nextlen = tree[n + 1].dl;
765 if(++count < max_count && curlen == nextlen)
766 continue;
767 else if(count < min_count)
768 blTree[curlen].fc += count;
769 else if(curlen != 0) {
770 if(curlen != prevlen)
771 blTree[curlen].fc++;
772 blTree[REP_3_6].fc++;
773 } else if(count <= 10)
774 blTree[REPZ_3_10].fc++;
775 else
776 blTree[REPZ_11_138].fc++;
777 count = 0; prevlen = curlen;
778 if(nextlen == 0) {
779 max_count = 138;
780 min_count = 3;
781 } else if(curlen == nextlen) {
782 max_count = 6;
783 min_count = 3;
784 } else {
785 max_count = 7;
786 min_count = 4;
787 }
788 }
789 }
790
791 function sendTree(tree, max_code) {
792 var n, // iterates over all tree elements
793 prevlen = -1, // last emitted length
794 curlen, // length of current code
795 nextlen = tree[0].dl, // length of next code
796 count = 0, // repeat count of the current code
797 max_count = 7, // max repeat count
798 min_count = 4; // min repeat count
799
800 if(nextlen == 0) {
801 max_count = 138;
802 min_count = 3;
803 }
804
805 for(n = 0; n <= max_code; n++) {
806 curlen = nextlen;
807 nextlen = tree[n+1].dl;
808 if(++count < max_count && curlen == nextlen) {
809 continue;
810 } else if(count < min_count) {
811 do { sendCode(curlen, blTree); } while(--count != 0);
812 } else if(curlen != 0) {
813 if(curlen != prevlen) {
814 sendCode(curlen, blTree);
815 count--;
816 }
817 sendCode(REP_3_6, blTree);
818 sendBits(count - 3, 2);
819 } else if(count <= 10) {
820 sendCode(REPZ_3_10, blTree);
821 sendBits(count-3, 3);
822 } else {
823 sendCode(REPZ_11_138, blTree);
824 sendBits(count-11, 7);
825 }
826 count = 0;
827 prevlen = curlen;
828 if(nextlen == 0) {
829 max_count = 138;
830 min_count = 3;
831 } else if(curlen == nextlen) {
832 max_count = 6;
833 min_count = 3;
834 } else {
835 max_count = 7;
836 min_count = 4;
837 }
838 }
839 }
840
841 function buildBLTree() {
842 var max_blindex; // index of last bit length code of non zero freq
843 scanTree(dynLTree, lDesc.max_code);
844 scanTree(dynDTree, dDesc.max_code);
845 buildTree(blDesc);
846 for(max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
847 if(blTree[blorder[max_blindex]].dl != 0) break;
848 }
849 /* Update opt_len to include the bit length tree and counts */
850 optLen += 3 * (max_blindex + 1) + 0xE;
851
852 return max_blindex;
853 }
854
855 function sendTrees(lcodes, dcodes, blcodes) {
856 var rank; // index in bl_order
857 sendBits(lcodes - 0x101, 5);
858 sendBits(dcodes - 1, 5);
859 sendBits(blcodes - 4, 4);
860 for(rank = 0; rank < blcodes; rank++)
861 sendBits(blTree[blorder[rank]].dl, 3);
862
863 sendTree(dynLTree, lcodes - 1);
864 sendTree(dynDTree, dcodes - 1);
865 }
866
867 function flushBlock(eof) { // true if this is the last block for a file
868 var opt_lenb, static_lenb, // opt_len and static_len in bytes
869 max_blindex, // index of last bit length code of non zero freq
870 stored_len = dataStart - blockStart; // length of input block
871
872 flagBuf[lastFlags] = flags; // Save the flags for the last 8 items
873
874 buildTree(lDesc);
875 buildTree(dDesc);
876
877 max_blindex = buildBLTree();
878
879 // Determine the best encoding. Compute first the block length in bytes
880 opt_lenb = (optLen + 3 + 7) >> 3;
881 static_lenb = (staticLen + 3 + 7) >> 3;
882
883 static_lenb <= opt_lenb && (opt_lenb = static_lenb);
884
885 if(stored_len + 4 <= opt_lenb && blockStart >= 0) {
886 var i;
887 sendBits(eof, 3); /* send block type */
888 biValid && writeShort(biBuf) && (biBuf = biValid = 0); /* align on byte boundary */
889 writeShort(stored_len);
890 writeShort(~stored_len);
891 for(i = 0; i < stored_len; i++) writeByte(window[blockStart + i]);
892
893 } else if(static_lenb == opt_lenb) {
894 sendBits(eof + 2, 3);
895 compress(staticLTree, staticDTree);
896 } else {
897 sendBits(eof + 4, 3);
898 sendTrees(lDesc.max_code + 1, dDesc.max_code + 1, max_blindex + 1);
899 compress(dynLTree, dynDTree);
900 }
901
902 initBlock();
903
904 (eof != 0) && (biValid && writeShort(biBuf) && (biBuf = biValid = 0));
905 }
906
907 function ctTally(dist, lc) {
908 lBuf[lastLit++] = lc;
909 if(dist == 0) {
910 dynLTree[lc].fc++;
911 } else {
912 dist--;
913 dynLTree[lengthCode[lc] + 0x101].fc++;
914 dynDTree[zip_D_CODE(dist)].fc++;
915 dBuf[lastDist++] = dist;
916 flags |= flagBit;
917 }
918 flagBit <<= 1;
919 if((lastLit & 7) == 0) {
920 flagBuf[lastFlags++] = flags;
921 flags = 0;
922 flagBit = 1;
923 }
924 if(compression_level > 2 && (lastLit & 0xfff) == 0) {
925 var out_length = lastLit * 8,
926 in_length = dataStart - blockStart,
927 dcode;
928
929 for(dcode = 0; dcode < D_CODES; dcode++) {
930 out_length += dynDTree[dcode].fc * (5 + edbits[dcode]);
931 }
932 out_length >>= 3;
933 if(lastDist < parseInt(lastLit / 2) && out_length < parseInt(in_length / 2))
934 return true;
935 }
936 return (lastLit == LIT_BUFSIZE - 1 || lastDist == LIT_BUFSIZE);
937 }
938
939 function compress(ltree, dtree) {
940 var dist, // distance of matched string
941 lc, // match length or unmatched char (if dist == 0)
942 lx = 0, // running index in l_buf
943 dx = 0, // running index in d_buf
944 fx = 0, // running index in flag_buf
945 flag = 0, // current flags
946 code, // the code to send
947 extra; // number of extra bits to send
948
949 if (lastLit != 0) do {
950 (lx & 7) == 0 && (flag = flagBuf[fx++]);
951 lc = lBuf[lx++] & 0xff;
952 if ((flag & 1) == 0) {
953 sendCode(lc, ltree); /* send a literal byte */
954 } else {
955 code = lengthCode[lc];
956 sendCode(code + 0x101, ltree); // send the length code
957 extra = elbits[code];
958 if(extra != 0) {
959 lc -= baseLength[code];
960 sendBits(lc, extra); // send the extra length bits
961 }
962 dist = dBuf[dx++];
963 code = zip_D_CODE(dist);
964 sendCode(code, dtree); // send the distance code
965 extra = edbits[code];
966 if(extra != 0) {
967 dist -= baseDist[code];
968 sendBits(dist, extra); // send the extra distance bits
969 }
970 } // literal or match pair ?
971 flag >>= 1;
972 } while(lx < lastLit);
973
974 sendCode(0x100, ltree); // end block
975 }
976
977 function sendBits(value, length) {
978 if(biValid > 0x10 - length) {
979 biBuf |= (value << biValid);
980 writeShort(biBuf);
981 biBuf = (value >> (0x10 - biValid));
982 biValid += length - 0x10;
983 } else {
984 biBuf |= value << biValid;
985 biValid += length;
986 }
987 }
988
989 function reverse(code, len) {
990 var res = 0;
991 do {
992 res |= code & 1;
993 code >>= 1;
994 res <<= 1;
995 } while(--len > 0);
996 return res >> 1;
997 }
998
999 function deflate(buffData, level) {
1000 deflateData = buffData;
1001 deflatePos = 0;
1002 deflateStart(level);
1003
1004 var buff = new Array(1),
1005 pages = [],
1006 totalSize = 0,
1007 i;
1008
1009 while((i = internalDeflate(buff, 0, buff.length)) > 0) {
1010 var buf = new Buffer(buff);
1011 pages.push(buf);
1012 totalSize += buff.length;
1013 }
1014 var result = new Buffer(totalSize),
1015 index = 0;
1016 for (i = 0; i < pages.length; i++) {
1017 pages[i].copy(result, index);
1018 index = index + pages[i].length
1019 }
1020
1021 cleanup();
1022
1023 return result;
1024 }
1025
1026 return {
1027 deflate : function() {
1028 return deflate(inbuf, 9);
1029 }
1030 }
1031}
1032
1033module.exports = function(/*Buffer*/inbuf) {
1034
1035 var zlib = require("zlib");
1036
1037 return {
1038 deflate : function() {
1039 return new JSDeflater(inbuf).deflate();
1040 },
1041
1042 deflateAsync : function(/*Function*/callback) {
1043 var tmp = zlib.createDeflateRaw();
1044 tmp.on('data', function(data) {
1045 callback(data);
1046 });
1047 tmp.end(inbuf)
1048 }
1049 }
1050};
\No newline at end of file