1 | function JSDeflater(/*inbuff*/inbuf) {
|
2 |
|
3 | var WSIZE = 0x8000,
|
4 | WINDOW_SIZE = 0x10000,
|
5 |
|
6 |
|
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 |
|
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,
|
86 | static_tree : null,
|
87 | extra_bits : null,
|
88 | extra_base : 0,
|
89 | elems : 0,
|
90 | max_length : 0,
|
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);
|
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,
|
261 | scanp = dataStart,
|
262 | matchp,
|
263 | len,
|
264 | best_len = prevLength,
|
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;
|
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;
|
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) {
|
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)
|
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,
|
511 | bits,
|
512 | length,
|
513 | code,
|
514 | dist;
|
515 |
|
516 | if(staticDTree[0].dl != 0) return;
|
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 |
|
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;
|
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;
|
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,
|
613 | n, m,
|
614 | bits,
|
615 | xbits,
|
616 | f,
|
617 | overflow = 0;
|
618 |
|
619 | for(bits = 0; bits <= MAX_BITS; bits++)
|
620 | blCount[bits] = 0;
|
621 |
|
622 | tree[zip_heap[heapMax]].dl = 0;
|
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;
|
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]--;
|
647 | blCount[bits + 1] += 2;
|
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),
|
668 | code = 0,
|
669 | bits,
|
670 | n;
|
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) {
|
686 | var tree = desc.dyn_tree,
|
687 | stree = desc.static_tree,
|
688 | elems = desc.elems,
|
689 | n, m,
|
690 | max_code = -1,
|
691 | node = elems;
|
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];
|
720 |
|
721 |
|
722 | zip_heap[--heapMax] = n;
|
723 | zip_heap[--heapMax] = m;
|
724 |
|
725 |
|
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 |
|
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,
|
749 | prevlen = -1,
|
750 | curlen,
|
751 | nextlen = tree[0].dl,
|
752 | count = 0,
|
753 | max_count = 7,
|
754 | min_count = 4;
|
755 |
|
756 | if(nextlen == 0) {
|
757 | max_count = 138;
|
758 | min_count = 3;
|
759 | }
|
760 | tree[max_code + 1].dl = 0xffff;
|
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,
|
793 | prevlen = -1,
|
794 | curlen,
|
795 | nextlen = tree[0].dl,
|
796 | count = 0,
|
797 | max_count = 7,
|
798 | min_count = 4;
|
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;
|
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 |
|
850 | optLen += 3 * (max_blindex + 1) + 0xE;
|
851 |
|
852 | return max_blindex;
|
853 | }
|
854 |
|
855 | function sendTrees(lcodes, dcodes, blcodes) {
|
856 | var rank;
|
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) {
|
868 | var opt_lenb, static_lenb,
|
869 | max_blindex,
|
870 | stored_len = dataStart - blockStart;
|
871 |
|
872 | flagBuf[lastFlags] = flags;
|
873 |
|
874 | buildTree(lDesc);
|
875 | buildTree(dDesc);
|
876 |
|
877 | max_blindex = buildBLTree();
|
878 |
|
879 |
|
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);
|
888 | biValid && writeShort(biBuf) && (biBuf = biValid = 0);
|
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,
|
941 | lc,
|
942 | lx = 0,
|
943 | dx = 0,
|
944 | fx = 0,
|
945 | flag = 0,
|
946 | code,
|
947 | extra;
|
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);
|
954 | } else {
|
955 | code = lengthCode[lc];
|
956 | sendCode(code + 0x101, ltree);
|
957 | extra = elbits[code];
|
958 | if(extra != 0) {
|
959 | lc -= baseLength[code];
|
960 | sendBits(lc, extra);
|
961 | }
|
962 | dist = dBuf[dx++];
|
963 | code = zip_D_CODE(dist);
|
964 | sendCode(code, dtree);
|
965 | extra = edbits[code];
|
966 | if(extra != 0) {
|
967 | dist -= baseDist[code];
|
968 | sendBits(dist, extra);
|
969 | }
|
970 | }
|
971 | flag >>= 1;
|
972 | } while(lx < lastLit);
|
973 |
|
974 | sendCode(0x100, ltree);
|
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 |
|
1033 | module.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 |