├── README.md
├── test
├── demo.html
└── base64.js
├── rawinflate.js
└── rawdeflate.js
/README.md:
--------------------------------------------------------------------------------
1 | Raw (De|In)flate in Javascript
2 | ==============================
3 |
4 | See [demo] for usage.
5 |
6 | [demo]: test/demo.html
7 |
8 |
9 | License
10 | -------
11 | GPL-2
12 |
--------------------------------------------------------------------------------
/test/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Demo
6 |
7 |
8 | Demo
9 | $Id: demo.html,v 0.4 2013/04/09 14:25:38 dankogai Exp dankogai $
10 |
11 | - Inflated + Base64-Decoded (Original):
12 |
17 | - Deflated + Base64-Encoded (Compressed):
18 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/test/base64.js:
--------------------------------------------------------------------------------
1 | /*
2 | * $Id: base64.js,v 2.11 2013/04/08 12:27:14 dankogai Exp dankogai $
3 | *
4 | * Licensed under the MIT license.
5 | * http://opensource.org/licenses/mit-license
6 | *
7 | * References:
8 | * http://en.wikipedia.org/wiki/Base64
9 | */
10 |
11 | (function(global) {
12 | 'use strict';
13 | if (global.Base64) return;
14 | var version = "2.1.1";
15 | // if node.js, we use Buffer
16 | var buffer;
17 | if (typeof module !== 'undefined' && module.exports) {
18 | buffer = require('buffer').Buffer;
19 | }
20 | // constants
21 | var b64chars
22 | = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
23 | var b64tab = function(bin) {
24 | var t = {};
25 | for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
26 | return t;
27 | }(b64chars);
28 | var fromCharCode = String.fromCharCode;
29 | // encoder stuff
30 | var cb_utob = function(c) {
31 | if (c.length < 2) {
32 | var cc = c.charCodeAt(0);
33 | return cc < 0x80 ? c
34 | : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
35 | + fromCharCode(0x80 | (cc & 0x3f)))
36 | : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
37 | + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
38 | + fromCharCode(0x80 | ( cc & 0x3f)));
39 | } else {
40 | var cc = 0x10000
41 | + (c.charCodeAt(0) - 0xD800) * 0x400
42 | + (c.charCodeAt(1) - 0xDC00);
43 | return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))
44 | + fromCharCode(0x80 | ((cc >>> 12) & 0x3f))
45 | + fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
46 | + fromCharCode(0x80 | ( cc & 0x3f)));
47 | }
48 | };
49 | var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
50 | var utob = function(u) {
51 | return u.replace(re_utob, cb_utob);
52 | };
53 | var cb_encode = function(ccc) {
54 | var padlen = [0, 2, 1][ccc.length % 3],
55 | ord = ccc.charCodeAt(0) << 16
56 | | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
57 | | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
58 | chars = [
59 | b64chars.charAt( ord >>> 18),
60 | b64chars.charAt((ord >>> 12) & 63),
61 | padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
62 | padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
63 | ];
64 | return chars.join('');
65 | };
66 | var btoa = global.btoa || function(b) {
67 | return b.replace(/[\s\S]{1,3}/g, cb_encode);
68 | };
69 | var _encode = buffer
70 | ? function (u) { return (new buffer(u)).toString('base64') }
71 | : function (u) { return btoa(utob(u)) }
72 | ;
73 | var encode = function(u, urisafe) {
74 | return !urisafe
75 | ? _encode(u)
76 | : _encode(u).replace(/[+\/]/g, function(m0) {
77 | return m0 == '+' ? '-' : '_';
78 | }).replace(/=/g, '');
79 | };
80 | var encodeURI = function(u) { return encode(u, true) };
81 | // decoder stuff
82 | var re_btou = new RegExp([
83 | '[\xC0-\xDF][\x80-\xBF]',
84 | '[\xE0-\xEF][\x80-\xBF]{2}',
85 | '[\xF0-\xF7][\x80-\xBF]{3}'
86 | ].join('|'), 'g');
87 | var cb_btou = function(cccc) {
88 | switch(cccc.length) {
89 | case 4:
90 | var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
91 | | ((0x3f & cccc.charCodeAt(1)) << 12)
92 | | ((0x3f & cccc.charCodeAt(2)) << 6)
93 | | (0x3f & cccc.charCodeAt(3)),
94 | offset = cp - 0x10000;
95 | return (fromCharCode((offset >>> 10) + 0xD800)
96 | + fromCharCode((offset & 0x3FF) + 0xDC00));
97 | case 3:
98 | return fromCharCode(
99 | ((0x0f & cccc.charCodeAt(0)) << 12)
100 | | ((0x3f & cccc.charCodeAt(1)) << 6)
101 | | (0x3f & cccc.charCodeAt(2))
102 | );
103 | default:
104 | return fromCharCode(
105 | ((0x1f & cccc.charCodeAt(0)) << 6)
106 | | (0x3f & cccc.charCodeAt(1))
107 | );
108 | }
109 | };
110 | var btou = function(b) {
111 | return b.replace(re_btou, cb_btou);
112 | };
113 | var cb_decode = function(cccc) {
114 | var len = cccc.length,
115 | padlen = len % 4,
116 | n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
117 | | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
118 | | (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
119 | | (len > 3 ? b64tab[cccc.charAt(3)] : 0),
120 | chars = [
121 | fromCharCode( n >>> 16),
122 | fromCharCode((n >>> 8) & 0xff),
123 | fromCharCode( n & 0xff)
124 | ];
125 | chars.length -= [0, 0, 2, 1][padlen];
126 | return chars.join('');
127 | };
128 | var atob = global.atob || function(a){
129 | return a.replace(/[\s\S]{1,4}/g, cb_decode);
130 | };
131 | var _decode = buffer
132 | ? function(a) { return (new buffer(a, 'base64')).toString() }
133 | : function(a) { return btou(atob(a)) };
134 | var decode = function(a){
135 | return _decode(
136 | a.replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })
137 | .replace(/[^A-Za-z0-9\+\/]/g, '')
138 | );
139 | };
140 | // export Base64
141 | global.Base64 = {
142 | VERSION: version,
143 | atob: atob,
144 | btoa: btoa,
145 | fromBase64: decode,
146 | toBase64: encode,
147 | utob: utob,
148 | encode: encode,
149 | encodeURI: encodeURI,
150 | btou: btou,
151 | decode: decode
152 | };
153 | // if ES5 is available, make Base64.extendString() available
154 | if (typeof Object.defineProperty === 'function') {
155 | var noEnum = function(v){
156 | return {value:v,enumerable:false,writable:true,configurable:true};
157 | };
158 | global.Base64.extendString = function () {
159 | Object.defineProperty(
160 | String.prototype, 'fromBase64', noEnum(function () {
161 | return decode(this)
162 | }));
163 | Object.defineProperty(
164 | String.prototype, 'toBase64', noEnum(function (urisafe) {
165 | return encode(this, urisafe)
166 | }));
167 | Object.defineProperty(
168 | String.prototype, 'toBase64URI', noEnum(function () {
169 | return encode(this, true)
170 | }));
171 | };
172 | }
173 | // that's it!
174 | })(this);
175 |
--------------------------------------------------------------------------------
/rawinflate.js:
--------------------------------------------------------------------------------
1 | /*
2 | * $Id: rawinflate.js,v 0.4 2014/03/01 21:59:08 dankogai Exp dankogai $
3 | *
4 | * GNU General Public License, version 2 (GPL-2.0)
5 | * http://opensource.org/licenses/GPL-2.0
6 | * original:
7 | * http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
8 | */
9 |
10 | (function(ctx){
11 |
12 | /* Copyright (C) 1999 Masanao Izumo
13 | * Version: 1.0.0.1
14 | * LastModified: Dec 25 1999
15 | */
16 |
17 | /* Interface:
18 | * data = zip_inflate(src);
19 | */
20 |
21 | /* constant parameters */
22 | var zip_WSIZE = 32768; // Sliding Window size
23 | var zip_STORED_BLOCK = 0;
24 | var zip_STATIC_TREES = 1;
25 | var zip_DYN_TREES = 2;
26 |
27 | /* for inflate */
28 | var zip_lbits = 9; // bits in base literal/length lookup table
29 | var zip_dbits = 6; // bits in base distance lookup table
30 | var zip_INBUFSIZ = 32768; // Input buffer size
31 | var zip_INBUF_EXTRA = 64; // Extra buffer
32 |
33 | /* variables (inflate) */
34 | var zip_slide;
35 | var zip_wp; // current position in slide
36 | var zip_fixed_tl = null; // inflate static
37 | var zip_fixed_td; // inflate static
38 | var zip_fixed_bl, zip_fixed_bd; // inflate static
39 | var zip_bit_buf; // bit buffer
40 | var zip_bit_len; // bits in bit buffer
41 | var zip_method;
42 | var zip_eof;
43 | var zip_copy_leng;
44 | var zip_copy_dist;
45 | var zip_tl, zip_td; // literal/length and distance decoder tables
46 | var zip_bl, zip_bd; // number of bits decoded by tl and td
47 |
48 | var zip_inflate_data;
49 | var zip_inflate_pos;
50 |
51 |
52 | /* constant tables (inflate) */
53 | var zip_MASK_BITS = new Array(
54 | 0x0000,
55 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
56 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff);
57 | // Tables for deflate from PKZIP's appnote.txt.
58 | var zip_cplens = new Array( // Copy lengths for literal codes 257..285
59 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
60 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);
61 | /* note: see note #13 above about the 258 in this list. */
62 | var zip_cplext = new Array( // Extra bits for literal codes 257..285
63 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
64 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid
65 | var zip_cpdist = new Array( // Copy offsets for distance codes 0..29
66 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
67 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
68 | 8193, 12289, 16385, 24577);
69 | var zip_cpdext = new Array( // Extra bits for distance codes
70 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
71 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
72 | 12, 12, 13, 13);
73 | var zip_border = new Array( // Order of the bit length code lengths
74 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
75 | /* objects (inflate) */
76 |
77 | var zip_HuftList = function() {
78 | this.next = null;
79 | this.list = null;
80 | }
81 |
82 | var zip_HuftNode = function() {
83 | this.e = 0; // number of extra bits or operation
84 | this.b = 0; // number of bits in this code or subcode
85 |
86 | // union
87 | this.n = 0; // literal, length base, or distance base
88 | this.t = null; // (zip_HuftNode) pointer to next level of table
89 | }
90 |
91 | var zip_HuftBuild = function(b, // code lengths in bits (all assumed <= BMAX)
92 | n, // number of codes (assumed <= N_MAX)
93 | s, // number of simple-valued codes (0..s-1)
94 | d, // list of base values for non-simple codes
95 | e, // list of extra bits for non-simple codes
96 | mm // maximum lookup bits
97 | ) {
98 | this.BMAX = 16; // maximum bit length of any code
99 | this.N_MAX = 288; // maximum number of codes in any set
100 | this.status = 0; // 0: success, 1: incomplete table, 2: bad input
101 | this.root = null; // (zip_HuftList) starting table
102 | this.m = 0; // maximum lookup bits, returns actual
103 |
104 | /* Given a list of code lengths and a maximum table size, make a set of
105 | tables to decode that set of codes. Return zero on success, one if
106 | the given code set is incomplete (the tables are still built in this
107 | case), two if the input is invalid (all zero length codes or an
108 | oversubscribed set of lengths), and three if not enough memory.
109 | The code with value 256 is special, and the tables are constructed
110 | so that no bits beyond that code are fetched when that code is
111 | decoded. */
112 | {
113 | var a; // counter for codes of length k
114 | var c = new Array(this.BMAX+1); // bit length count table
115 | var el; // length of EOB code (value 256)
116 | var f; // i repeats in table every f entries
117 | var g; // maximum code length
118 | var h; // table level
119 | var i; // counter, current code
120 | var j; // counter
121 | var k; // number of bits in current code
122 | var lx = new Array(this.BMAX+1); // stack of bits per table
123 | var p; // pointer into c[], b[], or v[]
124 | var pidx; // index of p
125 | var q; // (zip_HuftNode) points to current table
126 | var r = new zip_HuftNode(); // table entry for structure assignment
127 | var u = new Array(this.BMAX); // zip_HuftNode[BMAX][] table stack
128 | var v = new Array(this.N_MAX); // values in order of bit length
129 | var w;
130 | var x = new Array(this.BMAX+1);// bit offsets, then code stack
131 | var xp; // pointer into x or c
132 | var y; // number of dummy codes added
133 | var z; // number of entries in current table
134 | var o;
135 | var tail; // (zip_HuftList)
136 |
137 | tail = this.root = null;
138 | for(i = 0; i < c.length; i++)
139 | c[i] = 0;
140 | for(i = 0; i < lx.length; i++)
141 | lx[i] = 0;
142 | for(i = 0; i < u.length; i++)
143 | u[i] = null;
144 | for(i = 0; i < v.length; i++)
145 | v[i] = 0;
146 | for(i = 0; i < x.length; i++)
147 | x[i] = 0;
148 |
149 | // Generate counts for each bit length
150 | el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any
151 | p = b; pidx = 0;
152 | i = n;
153 | do {
154 | c[p[pidx]]++; // assume all entries <= BMAX
155 | pidx++;
156 | } while(--i > 0);
157 | if(c[0] == n) { // null input--all zero length codes
158 | this.root = null;
159 | this.m = 0;
160 | this.status = 0;
161 | return;
162 | }
163 |
164 | // Find minimum and maximum length, bound *m by those
165 | for(j = 1; j <= this.BMAX; j++)
166 | if(c[j] != 0)
167 | break;
168 | k = j; // minimum code length
169 | if(mm < j)
170 | mm = j;
171 | for(i = this.BMAX; i != 0; i--)
172 | if(c[i] != 0)
173 | break;
174 | g = i; // maximum code length
175 | if(mm > i)
176 | mm = i;
177 |
178 | // Adjust last length count to fill out codes, if needed
179 | for(y = 1 << j; j < i; j++, y <<= 1)
180 | if((y -= c[j]) < 0) {
181 | this.status = 2; // bad input: more codes than bits
182 | this.m = mm;
183 | return;
184 | }
185 | if((y -= c[i]) < 0) {
186 | this.status = 2;
187 | this.m = mm;
188 | return;
189 | }
190 | c[i] += y;
191 |
192 | // Generate starting offsets into the value table for each length
193 | x[1] = j = 0;
194 | p = c;
195 | pidx = 1;
196 | xp = 2;
197 | while(--i > 0) // note that i == g from above
198 | x[xp++] = (j += p[pidx++]);
199 |
200 | // Make a table of values in order of bit lengths
201 | p = b; pidx = 0;
202 | i = 0;
203 | do {
204 | if((j = p[pidx++]) != 0)
205 | v[x[j]++] = i;
206 | } while(++i < n);
207 | n = x[g]; // set n to length of v
208 |
209 | // Generate the Huffman codes and for each, make the table entries
210 | x[0] = i = 0; // first Huffman code is zero
211 | p = v; pidx = 0; // grab values in bit order
212 | h = -1; // no tables yet--level -1
213 | w = lx[0] = 0; // no bits decoded yet
214 | q = null; // ditto
215 | z = 0; // ditto
216 |
217 | // go through the bit lengths (k already is bits in shortest code)
218 | for(; k <= g; k++) {
219 | a = c[k];
220 | while(a-- > 0) {
221 | // here i is the Huffman code of length k bits for value p[pidx]
222 | // make tables up to required level
223 | while(k > w + lx[1 + h]) {
224 | w += lx[1 + h]; // add bits already decoded
225 | h++;
226 |
227 | // compute minimum size table less than or equal to *m bits
228 | z = (z = g - w) > mm ? mm : z; // upper limit
229 | if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
230 | // too few codes for k-w bit table
231 | f -= a + 1; // deduct codes from patterns left
232 | xp = k;
233 | while(++j < z) { // try smaller tables up to z bits
234 | if((f <<= 1) <= c[++xp])
235 | break; // enough codes to use up j bits
236 | f -= c[xp]; // else deduct codes from patterns
237 | }
238 | }
239 | if(w + j > el && w < el)
240 | j = el - w; // make EOB code end at table
241 | z = 1 << j; // table entries for j-bit table
242 | lx[1 + h] = j; // set table size in stack
243 |
244 | // allocate and link in new table
245 | q = new Array(z);
246 | for(o = 0; o < z; o++) {
247 | q[o] = new zip_HuftNode();
248 | }
249 |
250 | if(tail == null)
251 | tail = this.root = new zip_HuftList();
252 | else
253 | tail = tail.next = new zip_HuftList();
254 | tail.next = null;
255 | tail.list = q;
256 | u[h] = q; // table starts after link
257 |
258 | /* connect to last table, if there is one */
259 | if(h > 0) {
260 | x[h] = i; // save pattern for backing up
261 | r.b = lx[h]; // bits to dump before this table
262 | r.e = 16 + j; // bits in this table
263 | r.t = q; // pointer to this table
264 | j = (i & ((1 << w) - 1)) >> (w - lx[h]);
265 | u[h-1][j].e = r.e;
266 | u[h-1][j].b = r.b;
267 | u[h-1][j].n = r.n;
268 | u[h-1][j].t = r.t;
269 | }
270 | }
271 |
272 | // set up table entry in r
273 | r.b = k - w;
274 | if(pidx >= n)
275 | r.e = 99; // out of values--invalid code
276 | else if(p[pidx] < s) {
277 | r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code
278 | r.n = p[pidx++]; // simple code is just the value
279 | } else {
280 | r.e = e[p[pidx] - s]; // non-simple--look up in lists
281 | r.n = d[p[pidx++] - s];
282 | }
283 |
284 | // fill code-like entries with r //
285 | f = 1 << (k - w);
286 | for(j = i >> w; j < z; j += f) {
287 | q[j].e = r.e;
288 | q[j].b = r.b;
289 | q[j].n = r.n;
290 | q[j].t = r.t;
291 | }
292 |
293 | // backwards increment the k-bit code i
294 | for(j = 1 << (k - 1); (i & j) != 0; j >>= 1)
295 | i ^= j;
296 | i ^= j;
297 |
298 | // backup over finished tables
299 | while((i & ((1 << w) - 1)) != x[h]) {
300 | w -= lx[h]; // don't need to update q
301 | h--;
302 | }
303 | }
304 | }
305 |
306 | /* return actual size of base table */
307 | this.m = lx[1];
308 |
309 | /* Return true (1) if we were given an incomplete table */
310 | this.status = ((y != 0 && g != 1) ? 1 : 0);
311 | } /* end of constructor */
312 | }
313 |
314 |
315 | /* routines (inflate) */
316 |
317 | var zip_GET_BYTE = function() {
318 | if(zip_inflate_data.length == zip_inflate_pos)
319 | return -1;
320 | return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
321 | }
322 |
323 | var zip_NEEDBITS = function(n) {
324 | while(zip_bit_len < n) {
325 | zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
326 | zip_bit_len += 8;
327 | }
328 | }
329 |
330 | var zip_GETBITS = function(n) {
331 | return zip_bit_buf & zip_MASK_BITS[n];
332 | }
333 |
334 | var zip_DUMPBITS = function(n) {
335 | zip_bit_buf >>= n;
336 | zip_bit_len -= n;
337 | }
338 |
339 | var zip_inflate_codes = function(buff, off, size) {
340 | /* inflate (decompress) the codes in a deflated (compressed) block.
341 | Return an error code or zero if it all goes ok. */
342 | var e; // table entry flag/number of extra bits
343 | var t; // (zip_HuftNode) pointer to table entry
344 | var n;
345 |
346 | if(size == 0)
347 | return 0;
348 |
349 | // inflate the coded data
350 | n = 0;
351 | for(;;) { // do until end of block
352 | zip_NEEDBITS(zip_bl);
353 | t = zip_tl.list[zip_GETBITS(zip_bl)];
354 | e = t.e;
355 | while(e > 16) {
356 | if(e == 99)
357 | return -1;
358 | zip_DUMPBITS(t.b);
359 | e -= 16;
360 | zip_NEEDBITS(e);
361 | t = t.t[zip_GETBITS(e)];
362 | e = t.e;
363 | }
364 | zip_DUMPBITS(t.b);
365 |
366 | if(e == 16) { // then it's a literal
367 | zip_wp &= zip_WSIZE - 1;
368 | buff[off + n++] = zip_slide[zip_wp++] = t.n;
369 | if(n == size)
370 | return size;
371 | continue;
372 | }
373 |
374 | // exit if end of block
375 | if(e == 15)
376 | break;
377 |
378 | // it's an EOB or a length
379 |
380 | // get length of block to copy
381 | zip_NEEDBITS(e);
382 | zip_copy_leng = t.n + zip_GETBITS(e);
383 | zip_DUMPBITS(e);
384 |
385 | // decode distance of block to copy
386 | zip_NEEDBITS(zip_bd);
387 | t = zip_td.list[zip_GETBITS(zip_bd)];
388 | e = t.e;
389 |
390 | while(e > 16) {
391 | if(e == 99)
392 | return -1;
393 | zip_DUMPBITS(t.b);
394 | e -= 16;
395 | zip_NEEDBITS(e);
396 | t = t.t[zip_GETBITS(e)];
397 | e = t.e;
398 | }
399 | zip_DUMPBITS(t.b);
400 | zip_NEEDBITS(e);
401 | zip_copy_dist = zip_wp - t.n - zip_GETBITS(e);
402 | zip_DUMPBITS(e);
403 |
404 | // do the copy
405 | while(zip_copy_leng > 0 && n < size) {
406 | zip_copy_leng--;
407 | zip_copy_dist &= zip_WSIZE - 1;
408 | zip_wp &= zip_WSIZE - 1;
409 | buff[off + n++] = zip_slide[zip_wp++]
410 | = zip_slide[zip_copy_dist++];
411 | }
412 |
413 | if(n == size)
414 | return size;
415 | }
416 |
417 | zip_method = -1; // done
418 | return n;
419 | }
420 |
421 | var zip_inflate_stored = function(buff, off, size) {
422 | /* "decompress" an inflated type 0 (stored) block. */
423 | var n;
424 |
425 | // go to byte boundary
426 | n = zip_bit_len & 7;
427 | zip_DUMPBITS(n);
428 |
429 | // get the length and its complement
430 | zip_NEEDBITS(16);
431 | n = zip_GETBITS(16);
432 | zip_DUMPBITS(16);
433 | zip_NEEDBITS(16);
434 | if(n != ((~zip_bit_buf) & 0xffff))
435 | return -1; // error in compressed data
436 | zip_DUMPBITS(16);
437 |
438 | // read and output the compressed data
439 | zip_copy_leng = n;
440 |
441 | n = 0;
442 | while(zip_copy_leng > 0 && n < size) {
443 | zip_copy_leng--;
444 | zip_wp &= zip_WSIZE - 1;
445 | zip_NEEDBITS(8);
446 | buff[off + n++] = zip_slide[zip_wp++] =
447 | zip_GETBITS(8);
448 | zip_DUMPBITS(8);
449 | }
450 |
451 | if(zip_copy_leng == 0)
452 | zip_method = -1; // done
453 | return n;
454 | }
455 |
456 | var zip_inflate_fixed = function(buff, off, size) {
457 | /* decompress an inflated type 1 (fixed Huffman codes) block. We should
458 | either replace this with a custom decoder, or at least precompute the
459 | Huffman tables. */
460 |
461 | // if first time, set up tables for fixed blocks
462 | if(zip_fixed_tl == null) {
463 | var i; // temporary variable
464 | var l = new Array(288); // length list for huft_build
465 | var h; // zip_HuftBuild
466 |
467 | // literal table
468 | for(i = 0; i < 144; i++)
469 | l[i] = 8;
470 | for(; i < 256; i++)
471 | l[i] = 9;
472 | for(; i < 280; i++)
473 | l[i] = 7;
474 | for(; i < 288; i++) // make a complete, but wrong code set
475 | l[i] = 8;
476 | zip_fixed_bl = 7;
477 |
478 | h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext,
479 | zip_fixed_bl);
480 | if(h.status != 0) {
481 | alert("HufBuild error: "+h.status);
482 | return -1;
483 | }
484 | zip_fixed_tl = h.root;
485 | zip_fixed_bl = h.m;
486 |
487 | // distance table
488 | for(i = 0; i < 30; i++) // make an incomplete code set
489 | l[i] = 5;
490 | zip_fixed_bd = 5;
491 |
492 | h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd);
493 | if(h.status > 1) {
494 | zip_fixed_tl = null;
495 | alert("HufBuild error: "+h.status);
496 | return -1;
497 | }
498 | zip_fixed_td = h.root;
499 | zip_fixed_bd = h.m;
500 | }
501 |
502 | zip_tl = zip_fixed_tl;
503 | zip_td = zip_fixed_td;
504 | zip_bl = zip_fixed_bl;
505 | zip_bd = zip_fixed_bd;
506 | return zip_inflate_codes(buff, off, size);
507 | }
508 |
509 | var zip_inflate_dynamic = function(buff, off, size) {
510 | // decompress an inflated type 2 (dynamic Huffman codes) block.
511 | var i; // temporary variables
512 | var j;
513 | var l; // last length
514 | var n; // number of lengths to get
515 | var t; // (zip_HuftNode) literal/length code table
516 | var nb; // number of bit length codes
517 | var nl; // number of literal/length codes
518 | var nd; // number of distance codes
519 | var ll = new Array(286+30); // literal/length and distance code lengths
520 | var h; // (zip_HuftBuild)
521 |
522 | for(i = 0; i < ll.length; i++)
523 | ll[i] = 0;
524 |
525 | // read in table lengths
526 | zip_NEEDBITS(5);
527 | nl = 257 + zip_GETBITS(5); // number of literal/length codes
528 | zip_DUMPBITS(5);
529 | zip_NEEDBITS(5);
530 | nd = 1 + zip_GETBITS(5); // number of distance codes
531 | zip_DUMPBITS(5);
532 | zip_NEEDBITS(4);
533 | nb = 4 + zip_GETBITS(4); // number of bit length codes
534 | zip_DUMPBITS(4);
535 | if(nl > 286 || nd > 30)
536 | return -1; // bad lengths
537 |
538 | // read in bit-length-code lengths
539 | for(j = 0; j < nb; j++)
540 | {
541 | zip_NEEDBITS(3);
542 | ll[zip_border[j]] = zip_GETBITS(3);
543 | zip_DUMPBITS(3);
544 | }
545 | for(; j < 19; j++)
546 | ll[zip_border[j]] = 0;
547 |
548 | // build decoding table for trees--single level, 7 bit lookup
549 | zip_bl = 7;
550 | h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl);
551 | if(h.status != 0)
552 | return -1; // incomplete code set
553 |
554 | zip_tl = h.root;
555 | zip_bl = h.m;
556 |
557 | // read in literal and distance code lengths
558 | n = nl + nd;
559 | i = l = 0;
560 | while(i < n) {
561 | zip_NEEDBITS(zip_bl);
562 | t = zip_tl.list[zip_GETBITS(zip_bl)];
563 | j = t.b;
564 | zip_DUMPBITS(j);
565 | j = t.n;
566 | if(j < 16) // length of code in bits (0..15)
567 | ll[i++] = l = j; // save last length in l
568 | else if(j == 16) { // repeat last length 3 to 6 times
569 | zip_NEEDBITS(2);
570 | j = 3 + zip_GETBITS(2);
571 | zip_DUMPBITS(2);
572 | if(i + j > n)
573 | return -1;
574 | while(j-- > 0)
575 | ll[i++] = l;
576 | } else if(j == 17) { // 3 to 10 zero length codes
577 | zip_NEEDBITS(3);
578 | j = 3 + zip_GETBITS(3);
579 | zip_DUMPBITS(3);
580 | if(i + j > n)
581 | return -1;
582 | while(j-- > 0)
583 | ll[i++] = 0;
584 | l = 0;
585 | } else { // j == 18: 11 to 138 zero length codes
586 | zip_NEEDBITS(7);
587 | j = 11 + zip_GETBITS(7);
588 | zip_DUMPBITS(7);
589 | if(i + j > n)
590 | return -1;
591 | while(j-- > 0)
592 | ll[i++] = 0;
593 | l = 0;
594 | }
595 | }
596 |
597 | // build the decoding tables for literal/length and distance codes
598 | zip_bl = zip_lbits;
599 | h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl);
600 | if(zip_bl == 0) // no literals or lengths
601 | h.status = 1;
602 | if(h.status != 0) {
603 | if(h.status == 1)
604 | ;// **incomplete literal tree**
605 | return -1; // incomplete code set
606 | }
607 | zip_tl = h.root;
608 | zip_bl = h.m;
609 |
610 | for(i = 0; i < nd; i++)
611 | ll[i] = ll[i + nl];
612 | zip_bd = zip_dbits;
613 | h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd);
614 | zip_td = h.root;
615 | zip_bd = h.m;
616 |
617 | if(zip_bd == 0 && nl > 257) { // lengths but no distances
618 | // **incomplete distance tree**
619 | return -1;
620 | }
621 |
622 | if(h.status == 1) {
623 | ;// **incomplete distance tree**
624 | }
625 | if(h.status != 0)
626 | return -1;
627 |
628 | // decompress until an end-of-block code
629 | return zip_inflate_codes(buff, off, size);
630 | }
631 |
632 | var zip_inflate_start = function() {
633 | var i;
634 |
635 | if(zip_slide == null)
636 | zip_slide = new Array(2 * zip_WSIZE);
637 | zip_wp = 0;
638 | zip_bit_buf = 0;
639 | zip_bit_len = 0;
640 | zip_method = -1;
641 | zip_eof = false;
642 | zip_copy_leng = zip_copy_dist = 0;
643 | zip_tl = null;
644 | }
645 |
646 | var zip_inflate_internal = function(buff, off, size) {
647 | // decompress an inflated entry
648 | var n, i;
649 |
650 | n = 0;
651 | while(n < size) {
652 | if(zip_eof && zip_method == -1)
653 | return n;
654 |
655 | if(zip_copy_leng > 0) {
656 | if(zip_method != zip_STORED_BLOCK) {
657 | // STATIC_TREES or DYN_TREES
658 | while(zip_copy_leng > 0 && n < size) {
659 | zip_copy_leng--;
660 | zip_copy_dist &= zip_WSIZE - 1;
661 | zip_wp &= zip_WSIZE - 1;
662 | buff[off + n++] = zip_slide[zip_wp++] =
663 | zip_slide[zip_copy_dist++];
664 | }
665 | } else {
666 | while(zip_copy_leng > 0 && n < size) {
667 | zip_copy_leng--;
668 | zip_wp &= zip_WSIZE - 1;
669 | zip_NEEDBITS(8);
670 | buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
671 | zip_DUMPBITS(8);
672 | }
673 | if(zip_copy_leng == 0)
674 | zip_method = -1; // done
675 | }
676 | if(n == size)
677 | return n;
678 | }
679 |
680 | if(zip_method == -1) {
681 | if(zip_eof)
682 | break;
683 |
684 | // read in last block bit
685 | zip_NEEDBITS(1);
686 | if(zip_GETBITS(1) != 0)
687 | zip_eof = true;
688 | zip_DUMPBITS(1);
689 |
690 | // read in block type
691 | zip_NEEDBITS(2);
692 | zip_method = zip_GETBITS(2);
693 | zip_DUMPBITS(2);
694 | zip_tl = null;
695 | zip_copy_leng = 0;
696 | }
697 |
698 | switch(zip_method) {
699 | case 0: // zip_STORED_BLOCK
700 | i = zip_inflate_stored(buff, off + n, size - n);
701 | break;
702 |
703 | case 1: // zip_STATIC_TREES
704 | if(zip_tl != null)
705 | i = zip_inflate_codes(buff, off + n, size - n);
706 | else
707 | i = zip_inflate_fixed(buff, off + n, size - n);
708 | break;
709 |
710 | case 2: // zip_DYN_TREES
711 | if(zip_tl != null)
712 | i = zip_inflate_codes(buff, off + n, size - n);
713 | else
714 | i = zip_inflate_dynamic(buff, off + n, size - n);
715 | break;
716 |
717 | default: // error
718 | i = -1;
719 | break;
720 | }
721 |
722 | if(i == -1) {
723 | if(zip_eof)
724 | return 0;
725 | return -1;
726 | }
727 | n += i;
728 | }
729 | return n;
730 | }
731 |
732 | var zip_inflate = function(str) {
733 | var i, j;
734 |
735 | zip_inflate_start();
736 | zip_inflate_data = str;
737 | zip_inflate_pos = 0;
738 |
739 | var buff = new Array(1024);
740 | var aout = [];
741 | while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) {
742 | var cbuf = new Array(i);
743 | for(j = 0; j < i; j++){
744 | cbuf[j] = String.fromCharCode(buff[j]);
745 | }
746 | aout[aout.length] = cbuf.join("");
747 | }
748 | zip_inflate_data = null; // G.C.
749 | return aout.join("");
750 | }
751 |
752 | if (! ctx.RawDeflate) ctx.RawDeflate = {};
753 | ctx.RawDeflate.inflate = zip_inflate;
754 |
755 | })(this);
756 |
--------------------------------------------------------------------------------
/rawdeflate.js:
--------------------------------------------------------------------------------
1 | /*
2 | * $Id: rawdeflate.js,v 0.5 2013/04/09 14:25:38 dankogai Exp $
3 | *
4 | * GNU General Public License, version 2 (GPL-2.0)
5 | * http://opensource.org/licenses/GPL-2.0
6 | * Original:
7 | * http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt
8 | */
9 |
10 | (function(ctx){
11 |
12 | /* Copyright (C) 1999 Masanao Izumo
13 | * Version: 1.0.1
14 | * LastModified: Dec 25 1999
15 | */
16 |
17 | /* Interface:
18 | * data = zip_deflate(src);
19 | */
20 |
21 | /* constant parameters */
22 | var zip_WSIZE = 32768; // Sliding Window size
23 | var zip_STORED_BLOCK = 0;
24 | var zip_STATIC_TREES = 1;
25 | var zip_DYN_TREES = 2;
26 |
27 | /* for deflate */
28 | var zip_DEFAULT_LEVEL = 6;
29 | var zip_FULL_SEARCH = true;
30 | var zip_INBUFSIZ = 32768; // Input buffer size
31 | var zip_INBUF_EXTRA = 64; // Extra buffer
32 | var zip_OUTBUFSIZ = 1024 * 8;
33 | var zip_window_size = 2 * zip_WSIZE;
34 | var zip_MIN_MATCH = 3;
35 | var zip_MAX_MATCH = 258;
36 | var zip_BITS = 16;
37 | // for SMALL_MEM
38 | var zip_LIT_BUFSIZE = 0x2000;
39 | var zip_HASH_BITS = 13;
40 | // for MEDIUM_MEM
41 | // var zip_LIT_BUFSIZE = 0x4000;
42 | // var zip_HASH_BITS = 14;
43 | // for BIG_MEM
44 | // var zip_LIT_BUFSIZE = 0x8000;
45 | // var zip_HASH_BITS = 15;
46 | if(zip_LIT_BUFSIZE > zip_INBUFSIZ)
47 | alert("error: zip_INBUFSIZ is too small");
48 | if((zip_WSIZE<<1) > (1< zip_BITS-1)
51 | alert("error: zip_HASH_BITS is too large");
52 | if(zip_HASH_BITS < 8 || zip_MAX_MATCH != 258)
53 | alert("error: Code too clever");
54 | var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE;
55 | var zip_HASH_SIZE = 1 << zip_HASH_BITS;
56 | var zip_HASH_MASK = zip_HASH_SIZE - 1;
57 | var zip_WMASK = zip_WSIZE - 1;
58 | var zip_NIL = 0; // Tail of hash chains
59 | var zip_TOO_FAR = 4096;
60 | var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1;
61 | var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD;
62 | var zip_SMALLEST = 1;
63 | var zip_MAX_BITS = 15;
64 | var zip_MAX_BL_BITS = 7;
65 | var zip_LENGTH_CODES = 29;
66 | var zip_LITERALS =256;
67 | var zip_END_BLOCK = 256;
68 | var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES;
69 | var zip_D_CODES = 30;
70 | var zip_BL_CODES = 19;
71 | var zip_REP_3_6 = 16;
72 | var zip_REPZ_3_10 = 17;
73 | var zip_REPZ_11_138 = 18;
74 | var zip_HEAP_SIZE = 2 * zip_L_CODES + 1;
75 | var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) /
76 | zip_MIN_MATCH);
77 |
78 | /* variables */
79 | var zip_free_queue;
80 | var zip_qhead, zip_qtail;
81 | var zip_initflag;
82 | var zip_outbuf = null;
83 | var zip_outcnt, zip_outoff;
84 | var zip_complete;
85 | var zip_window;
86 | var zip_d_buf;
87 | var zip_l_buf;
88 | var zip_prev;
89 | var zip_bi_buf;
90 | var zip_bi_valid;
91 | var zip_block_start;
92 | var zip_ins_h;
93 | var zip_hash_head;
94 | var zip_prev_match;
95 | var zip_match_available;
96 | var zip_match_length;
97 | var zip_prev_length;
98 | var zip_strstart;
99 | var zip_match_start;
100 | var zip_eofile;
101 | var zip_lookahead;
102 | var zip_max_chain_length;
103 | var zip_max_lazy_match;
104 | var zip_compr_level;
105 | var zip_good_match;
106 | var zip_nice_match;
107 | var zip_dyn_ltree;
108 | var zip_dyn_dtree;
109 | var zip_static_ltree;
110 | var zip_static_dtree;
111 | var zip_bl_tree;
112 | var zip_l_desc;
113 | var zip_d_desc;
114 | var zip_bl_desc;
115 | var zip_bl_count;
116 | var zip_heap;
117 | var zip_heap_len;
118 | var zip_heap_max;
119 | var zip_depth;
120 | var zip_length_code;
121 | var zip_dist_code;
122 | var zip_base_length;
123 | var zip_base_dist;
124 | var zip_flag_buf;
125 | var zip_last_lit;
126 | var zip_last_dist;
127 | var zip_last_flags;
128 | var zip_flags;
129 | var zip_flag_bit;
130 | var zip_opt_len;
131 | var zip_static_len;
132 | var zip_deflate_data;
133 | var zip_deflate_pos;
134 |
135 | /* objects (deflate) */
136 |
137 | var zip_DeflateCT = function() {
138 | this.fc = 0; // frequency count or bit string
139 | this.dl = 0; // father node in Huffman tree or length of bit string
140 | }
141 |
142 | var zip_DeflateTreeDesc = function() {
143 | this.dyn_tree = null; // the dynamic tree
144 | this.static_tree = null; // corresponding static tree or NULL
145 | this.extra_bits = null; // extra bits for each code or NULL
146 | this.extra_base = 0; // base index for extra_bits
147 | this.elems = 0; // max number of elements in the tree
148 | this.max_length = 0; // max bit length for the codes
149 | this.max_code = 0; // largest code with non zero frequency
150 | }
151 |
152 | /* Values for max_lazy_match, good_match and max_chain_length, depending on
153 | * the desired pack level (0..9). The values given below have been tuned to
154 | * exclude worst case performance for pathological files. Better values may be
155 | * found for specific files.
156 | */
157 | var zip_DeflateConfiguration = function(a, b, c, d) {
158 | this.good_length = a; // reduce lazy search above this match length
159 | this.max_lazy = b; // do not perform lazy search above this match length
160 | this.nice_length = c; // quit search above this match length
161 | this.max_chain = d;
162 | }
163 |
164 | var zip_DeflateBuffer = function() {
165 | this.next = null;
166 | this.len = 0;
167 | this.ptr = new Array(zip_OUTBUFSIZ);
168 | this.off = 0;
169 | }
170 |
171 | /* constant tables */
172 | var zip_extra_lbits = new Array(
173 | 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);
174 | var zip_extra_dbits = new Array(
175 | 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);
176 | var zip_extra_blbits = new Array(
177 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7);
178 | var zip_bl_order = new Array(
179 | 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15);
180 | var zip_configuration_table = new Array(
181 | new zip_DeflateConfiguration(0, 0, 0, 0),
182 | new zip_DeflateConfiguration(4, 4, 8, 4),
183 | new zip_DeflateConfiguration(4, 5, 16, 8),
184 | new zip_DeflateConfiguration(4, 6, 32, 32),
185 | new zip_DeflateConfiguration(4, 4, 16, 16),
186 | new zip_DeflateConfiguration(8, 16, 32, 32),
187 | new zip_DeflateConfiguration(8, 16, 128, 128),
188 | new zip_DeflateConfiguration(8, 32, 128, 256),
189 | new zip_DeflateConfiguration(32, 128, 258, 1024),
190 | new zip_DeflateConfiguration(32, 258, 258, 4096));
191 |
192 |
193 | /* routines (deflate) */
194 |
195 | var zip_deflate_start = function(level) {
196 | var i;
197 |
198 | if(!level)
199 | level = zip_DEFAULT_LEVEL;
200 | else if(level < 1)
201 | level = 1;
202 | else if(level > 9)
203 | level = 9;
204 |
205 | zip_compr_level = level;
206 | zip_initflag = false;
207 | zip_eofile = false;
208 | if(zip_outbuf != null)
209 | return;
210 |
211 | zip_free_queue = zip_qhead = zip_qtail = null;
212 | zip_outbuf = new Array(zip_OUTBUFSIZ);
213 | zip_window = new Array(zip_window_size);
214 | zip_d_buf = new Array(zip_DIST_BUFSIZE);
215 | zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA);
216 | zip_prev = new Array(1 << zip_BITS);
217 | zip_dyn_ltree = new Array(zip_HEAP_SIZE);
218 | for(i = 0; i < zip_HEAP_SIZE; i++)
219 | zip_dyn_ltree[i] = new zip_DeflateCT();
220 | zip_dyn_dtree = new Array(2*zip_D_CODES+1);
221 | for(i = 0; i < 2*zip_D_CODES+1; i++)
222 | zip_dyn_dtree[i] = new zip_DeflateCT();
223 | zip_static_ltree = new Array(zip_L_CODES+2);
224 | for(i = 0; i < zip_L_CODES+2; i++)
225 | zip_static_ltree[i] = new zip_DeflateCT();
226 | zip_static_dtree = new Array(zip_D_CODES);
227 | for(i = 0; i < zip_D_CODES; i++)
228 | zip_static_dtree[i] = new zip_DeflateCT();
229 | zip_bl_tree = new Array(2*zip_BL_CODES+1);
230 | for(i = 0; i < 2*zip_BL_CODES+1; i++)
231 | zip_bl_tree[i] = new zip_DeflateCT();
232 | zip_l_desc = new zip_DeflateTreeDesc();
233 | zip_d_desc = new zip_DeflateTreeDesc();
234 | zip_bl_desc = new zip_DeflateTreeDesc();
235 | zip_bl_count = new Array(zip_MAX_BITS+1);
236 | zip_heap = new Array(2*zip_L_CODES+1);
237 | zip_depth = new Array(2*zip_L_CODES+1);
238 | zip_length_code = new Array(zip_MAX_MATCH-zip_MIN_MATCH+1);
239 | zip_dist_code = new Array(512);
240 | zip_base_length = new Array(zip_LENGTH_CODES);
241 | zip_base_dist = new Array(zip_D_CODES);
242 | zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8));
243 | }
244 |
245 | var zip_deflate_end = function() {
246 | zip_free_queue = zip_qhead = zip_qtail = null;
247 | zip_outbuf = null;
248 | zip_window = null;
249 | zip_d_buf = null;
250 | zip_l_buf = null;
251 | zip_prev = null;
252 | zip_dyn_ltree = null;
253 | zip_dyn_dtree = null;
254 | zip_static_ltree = null;
255 | zip_static_dtree = null;
256 | zip_bl_tree = null;
257 | zip_l_desc = null;
258 | zip_d_desc = null;
259 | zip_bl_desc = null;
260 | zip_bl_count = null;
261 | zip_heap = null;
262 | zip_depth = null;
263 | zip_length_code = null;
264 | zip_dist_code = null;
265 | zip_base_length = null;
266 | zip_base_dist = null;
267 | zip_flag_buf = null;
268 | }
269 |
270 | var zip_reuse_queue = function(p) {
271 | p.next = zip_free_queue;
272 | zip_free_queue = p;
273 | }
274 |
275 | var zip_new_queue = function() {
276 | var p;
277 |
278 | if(zip_free_queue != null)
279 | {
280 | p = zip_free_queue;
281 | zip_free_queue = zip_free_queue.next;
282 | }
283 | else
284 | p = new zip_DeflateBuffer();
285 | p.next = null;
286 | p.len = p.off = 0;
287 |
288 | return p;
289 | }
290 |
291 | var zip_head1 = function(i) {
292 | return zip_prev[zip_WSIZE + i];
293 | }
294 |
295 | var zip_head2 = function(i, val) {
296 | return zip_prev[zip_WSIZE + i] = val;
297 | }
298 |
299 | /* put_byte is used for the compressed output, put_ubyte for the
300 | * uncompressed output. However unlzw() uses window for its
301 | * suffix table instead of its output buffer, so it does not use put_ubyte
302 | * (to be cleaned up).
303 | */
304 | var zip_put_byte = function(c) {
305 | zip_outbuf[zip_outoff + zip_outcnt++] = c;
306 | if(zip_outoff + zip_outcnt == zip_OUTBUFSIZ)
307 | zip_qoutbuf();
308 | }
309 |
310 | /* Output a 16 bit value, lsb first */
311 | var zip_put_short = function(w) {
312 | w &= 0xffff;
313 | if(zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) {
314 | zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff);
315 | zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8);
316 | } else {
317 | zip_put_byte(w & 0xff);
318 | zip_put_byte(w >>> 8);
319 | }
320 | }
321 |
322 | /* ==========================================================================
323 | * Insert string s in the dictionary and set match_head to the previous head
324 | * of the hash chain (the most recent string with same hash key). Return
325 | * the previous length of the hash chain.
326 | * IN assertion: all calls to to INSERT_STRING are made with consecutive
327 | * input characters and the first MIN_MATCH bytes of s are valid
328 | * (except for the last MIN_MATCH-1 bytes of the input file).
329 | */
330 | var zip_INSERT_STRING = function() {
331 | zip_ins_h = ((zip_ins_h << zip_H_SHIFT)
332 | ^ (zip_window[zip_strstart + zip_MIN_MATCH - 1] & 0xff))
333 | & zip_HASH_MASK;
334 | zip_hash_head = zip_head1(zip_ins_h);
335 | zip_prev[zip_strstart & zip_WMASK] = zip_hash_head;
336 | zip_head2(zip_ins_h, zip_strstart);
337 | }
338 |
339 | /* Send a code of the given tree. c and tree must not have side effects */
340 | var zip_SEND_CODE = function(c, tree) {
341 | zip_send_bits(tree[c].fc, tree[c].dl);
342 | }
343 |
344 | /* Mapping from a distance to a distance code. dist is the distance - 1 and
345 | * must not have side effects. dist_code[256] and dist_code[257] are never
346 | * used.
347 | */
348 | var zip_D_CODE = function(dist) {
349 | return (dist < 256 ? zip_dist_code[dist]
350 | : zip_dist_code[256 + (dist>>7)]) & 0xff;
351 | }
352 |
353 | /* ==========================================================================
354 | * Compares to subtrees, using the tree depth as tie breaker when
355 | * the subtrees have equal frequency. This minimizes the worst case length.
356 | */
357 | var zip_SMALLER = function(tree, n, m) {
358 | return tree[n].fc < tree[m].fc ||
359 | (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]);
360 | }
361 |
362 | /* ==========================================================================
363 | * read string data
364 | */
365 | var zip_read_buff = function(buff, offset, n) {
366 | var i;
367 | for(i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++)
368 | buff[offset + i] =
369 | zip_deflate_data.charCodeAt(zip_deflate_pos++) & 0xff;
370 | return i;
371 | }
372 |
373 | /* ==========================================================================
374 | * Initialize the "longest match" routines for a new file
375 | */
376 | var zip_lm_init = function() {
377 | var j;
378 |
379 | /* Initialize the hash table. */
380 | for(j = 0; j < zip_HASH_SIZE; j++)
381 | // zip_head2(j, zip_NIL);
382 | zip_prev[zip_WSIZE + j] = 0;
383 | /* prev will be initialized on the fly */
384 |
385 | /* Set the default configuration parameters:
386 | */
387 | zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy;
388 | zip_good_match = zip_configuration_table[zip_compr_level].good_length;
389 | if(!zip_FULL_SEARCH)
390 | zip_nice_match = zip_configuration_table[zip_compr_level].nice_length;
391 | zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain;
392 |
393 | zip_strstart = 0;
394 | zip_block_start = 0;
395 |
396 | zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE);
397 | if(zip_lookahead <= 0) {
398 | zip_eofile = true;
399 | zip_lookahead = 0;
400 | return;
401 | }
402 | zip_eofile = false;
403 | /* Make sure that we always have enough lookahead. This is important
404 | * if input comes from a device such as a tty.
405 | */
406 | while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
407 | zip_fill_window();
408 |
409 | /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
410 | * not important since only literal bytes will be emitted.
411 | */
412 | zip_ins_h = 0;
413 | for(j = 0; j < zip_MIN_MATCH - 1; j++) {
414 | // UPDATE_HASH(ins_h, window[j]);
415 | zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK;
416 | }
417 | }
418 |
419 | /* ==========================================================================
420 | * Set match_start to the longest match starting at the given string and
421 | * return its length. Matches shorter or equal to prev_length are discarded,
422 | * in which case the result is equal to prev_length and match_start is
423 | * garbage.
424 | * IN assertions: cur_match is the head of the hash chain for the current
425 | * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
426 | */
427 | var zip_longest_match = function(cur_match) {
428 | var chain_length = zip_max_chain_length; // max hash chain length
429 | var scanp = zip_strstart; // current string
430 | var matchp; // matched string
431 | var len; // length of current match
432 | var best_len = zip_prev_length; // best match length so far
433 |
434 | /* Stop when cur_match becomes <= limit. To simplify the code,
435 | * we prevent matches with the string of window index 0.
436 | */
437 | var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL);
438 |
439 | var strendp = zip_strstart + zip_MAX_MATCH;
440 | var scan_end1 = zip_window[scanp + best_len - 1];
441 | var scan_end = zip_window[scanp + best_len];
442 |
443 | /* Do not waste too much time if we already have a good match: */
444 | if(zip_prev_length >= zip_good_match)
445 | chain_length >>= 2;
446 |
447 | // Assert(encoder->strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead");
448 |
449 | do {
450 | // Assert(cur_match < encoder->strstart, "no future");
451 | matchp = cur_match;
452 |
453 | /* Skip to next match if the match length cannot increase
454 | * or if the match length is less than 2:
455 | */
456 | if(zip_window[matchp + best_len] != scan_end ||
457 | zip_window[matchp + best_len - 1] != scan_end1 ||
458 | zip_window[matchp] != zip_window[scanp] ||
459 | zip_window[++matchp] != zip_window[scanp + 1]) {
460 | continue;
461 | }
462 |
463 | /* The check at best_len-1 can be removed because it will be made
464 | * again later. (This heuristic is not always a win.)
465 | * It is not necessary to compare scan[2] and match[2] since they
466 | * are always equal when the other bytes match, given that
467 | * the hash keys are equal and that HASH_BITS >= 8.
468 | */
469 | scanp += 2;
470 | matchp++;
471 |
472 | /* We check for insufficient lookahead only every 8th comparison;
473 | * the 256th check will be made at strstart+258.
474 | */
475 | do {
476 | } while(zip_window[++scanp] == zip_window[++matchp] &&
477 | zip_window[++scanp] == zip_window[++matchp] &&
478 | zip_window[++scanp] == zip_window[++matchp] &&
479 | zip_window[++scanp] == zip_window[++matchp] &&
480 | zip_window[++scanp] == zip_window[++matchp] &&
481 | zip_window[++scanp] == zip_window[++matchp] &&
482 | zip_window[++scanp] == zip_window[++matchp] &&
483 | zip_window[++scanp] == zip_window[++matchp] &&
484 | scanp < strendp);
485 |
486 | len = zip_MAX_MATCH - (strendp - scanp);
487 | scanp = strendp - zip_MAX_MATCH;
488 |
489 | if(len > best_len) {
490 | zip_match_start = cur_match;
491 | best_len = len;
492 | if(zip_FULL_SEARCH) {
493 | if(len >= zip_MAX_MATCH) break;
494 | } else {
495 | if(len >= zip_nice_match) break;
496 | }
497 |
498 | scan_end1 = zip_window[scanp + best_len-1];
499 | scan_end = zip_window[scanp + best_len];
500 | }
501 | } while((cur_match = zip_prev[cur_match & zip_WMASK]) > limit
502 | && --chain_length != 0);
503 |
504 | return best_len;
505 | }
506 |
507 | /* ==========================================================================
508 | * Fill the window when the lookahead becomes insufficient.
509 | * Updates strstart and lookahead, and sets eofile if end of input file.
510 | * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
511 | * OUT assertions: at least one byte has been read, or eofile is set;
512 | * file reads are performed for at least two bytes (required for the
513 | * translate_eol option).
514 | */
515 | var zip_fill_window = function() {
516 | var n, m;
517 |
518 | // Amount of free space at the end of the window.
519 | var more = zip_window_size - zip_lookahead - zip_strstart;
520 |
521 | /* If the window is almost full and there is insufficient lookahead,
522 | * move the upper half to the lower one to make room in the upper half.
523 | */
524 | if(more == -1) {
525 | /* Very unlikely, but possible on 16 bit machine if strstart == 0
526 | * and lookahead == 1 (input done one byte at time)
527 | */
528 | more--;
529 | } else if(zip_strstart >= zip_WSIZE + zip_MAX_DIST) {
530 | /* By the IN assertion, the window is not empty so we can't confuse
531 | * more == 0 with more == 64K on a 16 bit machine.
532 | */
533 | // Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM");
534 |
535 | // System.arraycopy(window, WSIZE, window, 0, WSIZE);
536 | for(n = 0; n < zip_WSIZE; n++)
537 | zip_window[n] = zip_window[n + zip_WSIZE];
538 |
539 | zip_match_start -= zip_WSIZE;
540 | zip_strstart -= zip_WSIZE; /* we now have strstart >= MAX_DIST: */
541 | zip_block_start -= zip_WSIZE;
542 |
543 | for(n = 0; n < zip_HASH_SIZE; n++) {
544 | m = zip_head1(n);
545 | zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL);
546 | }
547 | for(n = 0; n < zip_WSIZE; n++) {
548 | /* If n is not on any hash chain, prev[n] is garbage but
549 | * its value will never be used.
550 | */
551 | m = zip_prev[n];
552 | zip_prev[n] = (m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL);
553 | }
554 | more += zip_WSIZE;
555 | }
556 | // At this point, more >= 2
557 | if(!zip_eofile) {
558 | n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more);
559 | if(n <= 0)
560 | zip_eofile = true;
561 | else
562 | zip_lookahead += n;
563 | }
564 | }
565 |
566 | /* ==========================================================================
567 | * Processes a new input file and return its compressed length. This
568 | * function does not perform lazy evaluationof matches and inserts
569 | * new strings in the dictionary only for unmatched strings or for short
570 | * matches. It is used only for the fast compression options.
571 | */
572 | var zip_deflate_fast = function() {
573 | while(zip_lookahead != 0 && zip_qhead == null) {
574 | var flush; // set if current block must be flushed
575 |
576 | /* Insert the string window[strstart .. strstart+2] in the
577 | * dictionary, and set hash_head to the head of the hash chain:
578 | */
579 | zip_INSERT_STRING();
580 |
581 | /* Find the longest match, discarding those <= prev_length.
582 | * At this point we have always match_length < MIN_MATCH
583 | */
584 | if(zip_hash_head != zip_NIL &&
585 | zip_strstart - zip_hash_head <= zip_MAX_DIST) {
586 | /* To simplify the code, we prevent matches with the string
587 | * of window index 0 (in particular we have to avoid a match
588 | * of the string with itself at the start of the input file).
589 | */
590 | zip_match_length = zip_longest_match(zip_hash_head);
591 | /* longest_match() sets match_start */
592 | if(zip_match_length > zip_lookahead)
593 | zip_match_length = zip_lookahead;
594 | }
595 | if(zip_match_length >= zip_MIN_MATCH) {
596 | // check_match(strstart, match_start, match_length);
597 |
598 | flush = zip_ct_tally(zip_strstart - zip_match_start,
599 | zip_match_length - zip_MIN_MATCH);
600 | zip_lookahead -= zip_match_length;
601 |
602 | /* Insert new strings in the hash table only if the match length
603 | * is not too large. This saves time but degrades compression.
604 | */
605 | if(zip_match_length <= zip_max_lazy_match) {
606 | zip_match_length--; // string at strstart already in hash table
607 | do {
608 | zip_strstart++;
609 | zip_INSERT_STRING();
610 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are
611 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
612 | * these bytes are garbage, but it does not matter since
613 | * the next lookahead bytes will be emitted as literals.
614 | */
615 | } while(--zip_match_length != 0);
616 | zip_strstart++;
617 | } else {
618 | zip_strstart += zip_match_length;
619 | zip_match_length = 0;
620 | zip_ins_h = zip_window[zip_strstart] & 0xff;
621 | // UPDATE_HASH(ins_h, window[strstart + 1]);
622 | zip_ins_h = ((zip_ins_h< zip_lookahead)
674 | zip_match_length = zip_lookahead;
675 |
676 | /* Ignore a length 3 match if it is too distant: */
677 | if(zip_match_length == zip_MIN_MATCH &&
678 | zip_strstart - zip_match_start > zip_TOO_FAR) {
679 | /* If prev_match is also MIN_MATCH, match_start is garbage
680 | * but we will ignore the current match anyway.
681 | */
682 | zip_match_length--;
683 | }
684 | }
685 | /* If there was a match at the previous step and the current
686 | * match is not better, output the previous match:
687 | */
688 | if(zip_prev_length >= zip_MIN_MATCH &&
689 | zip_match_length <= zip_prev_length) {
690 | var flush; // set if current block must be flushed
691 |
692 | // check_match(strstart - 1, prev_match, prev_length);
693 | flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match,
694 | zip_prev_length - zip_MIN_MATCH);
695 |
696 | /* Insert in hash table all strings up to the end of the match.
697 | * strstart-1 and strstart are already inserted.
698 | */
699 | zip_lookahead -= zip_prev_length - 1;
700 | zip_prev_length -= 2;
701 | do {
702 | zip_strstart++;
703 | zip_INSERT_STRING();
704 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are
705 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
706 | * these bytes are garbage, but it does not matter since the
707 | * next lookahead bytes will always be emitted as literals.
708 | */
709 | } while(--zip_prev_length != 0);
710 | zip_match_available = 0;
711 | zip_match_length = zip_MIN_MATCH - 1;
712 | zip_strstart++;
713 | if(flush) {
714 | zip_flush_block(0);
715 | zip_block_start = zip_strstart;
716 | }
717 | } else if(zip_match_available != 0) {
718 | /* If there was no match at the previous position, output a
719 | * single literal. If there was a match but the current match
720 | * is longer, truncate the previous match to a single literal.
721 | */
722 | if(zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) {
723 | zip_flush_block(0);
724 | zip_block_start = zip_strstart;
725 | }
726 | zip_strstart++;
727 | zip_lookahead--;
728 | } else {
729 | /* There is no previous match to compare with, wait for
730 | * the next step to decide.
731 | */
732 | zip_match_available = 1;
733 | zip_strstart++;
734 | zip_lookahead--;
735 | }
736 |
737 | /* Make sure that we always have enough lookahead, except
738 | * at the end of the input file. We need MAX_MATCH bytes
739 | * for the next match, plus MIN_MATCH bytes to insert the
740 | * string following the next match.
741 | */
742 | while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
743 | zip_fill_window();
744 | }
745 | }
746 |
747 | var zip_init_deflate = function() {
748 | if(zip_eofile)
749 | return;
750 | zip_bi_buf = 0;
751 | zip_bi_valid = 0;
752 | zip_ct_init();
753 | zip_lm_init();
754 |
755 | zip_qhead = null;
756 | zip_outcnt = 0;
757 | zip_outoff = 0;
758 | zip_match_available = 0;
759 |
760 | if(zip_compr_level <= 3)
761 | {
762 | zip_prev_length = zip_MIN_MATCH - 1;
763 | zip_match_length = 0;
764 | }
765 | else
766 | {
767 | zip_match_length = zip_MIN_MATCH - 1;
768 | zip_match_available = 0;
769 | zip_match_available = 0;
770 | }
771 |
772 | zip_complete = false;
773 | }
774 |
775 | /* ==========================================================================
776 | * Same as above, but achieves better compression. We use a lazy
777 | * evaluation for matches: a match is finally adopted only if there is
778 | * no better match at the next window position.
779 | */
780 | var zip_deflate_internal = function(buff, off, buff_size) {
781 | var n;
782 |
783 | if(!zip_initflag)
784 | {
785 | zip_init_deflate();
786 | zip_initflag = true;
787 | if(zip_lookahead == 0) { // empty
788 | zip_complete = true;
789 | return 0;
790 | }
791 | }
792 |
793 | if((n = zip_qcopy(buff, off, buff_size)) == buff_size)
794 | return buff_size;
795 |
796 | if(zip_complete)
797 | return n;
798 |
799 | if(zip_compr_level <= 3) // optimized for speed
800 | zip_deflate_fast();
801 | else
802 | zip_deflate_better();
803 | if(zip_lookahead == 0) {
804 | if(zip_match_available != 0)
805 | zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff);
806 | zip_flush_block(1);
807 | zip_complete = true;
808 | }
809 | return n + zip_qcopy(buff, n + off, buff_size - n);
810 | }
811 |
812 | var zip_qcopy = function(buff, off, buff_size) {
813 | var n, i, j;
814 |
815 | n = 0;
816 | while(zip_qhead != null && n < buff_size)
817 | {
818 | i = buff_size - n;
819 | if(i > zip_qhead.len)
820 | i = zip_qhead.len;
821 | // System.arraycopy(qhead.ptr, qhead.off, buff, off + n, i);
822 | for(j = 0; j < i; j++)
823 | buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j];
824 |
825 | zip_qhead.off += i;
826 | zip_qhead.len -= i;
827 | n += i;
828 | if(zip_qhead.len == 0) {
829 | var p;
830 | p = zip_qhead;
831 | zip_qhead = zip_qhead.next;
832 | zip_reuse_queue(p);
833 | }
834 | }
835 |
836 | if(n == buff_size)
837 | return n;
838 |
839 | if(zip_outoff < zip_outcnt) {
840 | i = buff_size - n;
841 | if(i > zip_outcnt - zip_outoff)
842 | i = zip_outcnt - zip_outoff;
843 | // System.arraycopy(outbuf, outoff, buff, off + n, i);
844 | for(j = 0; j < i; j++)
845 | buff[off + n + j] = zip_outbuf[zip_outoff + j];
846 | zip_outoff += i;
847 | n += i;
848 | if(zip_outcnt == zip_outoff)
849 | zip_outcnt = zip_outoff = 0;
850 | }
851 | return n;
852 | }
853 |
854 | /* ==========================================================================
855 | * Allocate the match buffer, initialize the various tables and save the
856 | * location of the internal file attribute (ascii/binary) and method
857 | * (DEFLATE/STORE).
858 | */
859 | var zip_ct_init = function() {
860 | var n; // iterates over tree elements
861 | var bits; // bit counter
862 | var length; // length value
863 | var code; // code value
864 | var dist; // distance index
865 |
866 | if(zip_static_dtree[0].dl != 0) return; // ct_init already called
867 |
868 | zip_l_desc.dyn_tree = zip_dyn_ltree;
869 | zip_l_desc.static_tree = zip_static_ltree;
870 | zip_l_desc.extra_bits = zip_extra_lbits;
871 | zip_l_desc.extra_base = zip_LITERALS + 1;
872 | zip_l_desc.elems = zip_L_CODES;
873 | zip_l_desc.max_length = zip_MAX_BITS;
874 | zip_l_desc.max_code = 0;
875 |
876 | zip_d_desc.dyn_tree = zip_dyn_dtree;
877 | zip_d_desc.static_tree = zip_static_dtree;
878 | zip_d_desc.extra_bits = zip_extra_dbits;
879 | zip_d_desc.extra_base = 0;
880 | zip_d_desc.elems = zip_D_CODES;
881 | zip_d_desc.max_length = zip_MAX_BITS;
882 | zip_d_desc.max_code = 0;
883 |
884 | zip_bl_desc.dyn_tree = zip_bl_tree;
885 | zip_bl_desc.static_tree = null;
886 | zip_bl_desc.extra_bits = zip_extra_blbits;
887 | zip_bl_desc.extra_base = 0;
888 | zip_bl_desc.elems = zip_BL_CODES;
889 | zip_bl_desc.max_length = zip_MAX_BL_BITS;
890 | zip_bl_desc.max_code = 0;
891 |
892 | // Initialize the mapping length (0..255) -> length code (0..28)
893 | length = 0;
894 | for(code = 0; code < zip_LENGTH_CODES-1; code++) {
895 | zip_base_length[code] = length;
896 | for(n = 0; n < (1< dist code (0..29) */
908 | dist = 0;
909 | for(code = 0 ; code < 16; code++) {
910 | zip_base_dist[code] = dist;
911 | for(n = 0; n < (1<>= 7; // from now on, all distances are divided by 128
917 | for( ; code < zip_D_CODES; code++) {
918 | zip_base_dist[code] = dist << 7;
919 | for(n = 0; n < (1<<(zip_extra_dbits[code]-7)); n++)
920 | zip_dist_code[256 + dist++] = code;
921 | }
922 | // Assert (dist == 256, "ct_init: 256+dist != 512");
923 |
924 | // Construct the codes of the static literal tree
925 | for(bits = 0; bits <= zip_MAX_BITS; bits++)
926 | zip_bl_count[bits] = 0;
927 | n = 0;
928 | while(n <= 143) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; }
929 | while(n <= 255) { zip_static_ltree[n++].dl = 9; zip_bl_count[9]++; }
930 | while(n <= 279) { zip_static_ltree[n++].dl = 7; zip_bl_count[7]++; }
931 | while(n <= 287) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; }
932 | /* Codes 286 and 287 do not exist, but we must include them in the
933 | * tree construction to get a canonical Huffman tree (longest code
934 | * all ones)
935 | */
936 | zip_gen_codes(zip_static_ltree, zip_L_CODES + 1);
937 |
938 | /* The static distance tree is trivial: */
939 | for(n = 0; n < zip_D_CODES; n++) {
940 | zip_static_dtree[n].dl = 5;
941 | zip_static_dtree[n].fc = zip_bi_reverse(n, 5);
942 | }
943 |
944 | // Initialize the first block of the first file:
945 | zip_init_block();
946 | }
947 |
948 | /* ==========================================================================
949 | * Initialize a new block.
950 | */
951 | var zip_init_block = function() {
952 | var n; // iterates over tree elements
953 |
954 | // Initialize the trees.
955 | for(n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0;
956 | for(n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0;
957 | for(n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0;
958 |
959 | zip_dyn_ltree[zip_END_BLOCK].fc = 1;
960 | zip_opt_len = zip_static_len = 0;
961 | zip_last_lit = zip_last_dist = zip_last_flags = 0;
962 | zip_flags = 0;
963 | zip_flag_bit = 1;
964 | }
965 |
966 | /* ==========================================================================
967 | * Restore the heap property by moving down the tree starting at node k,
968 | * exchanging a node with the smallest of its two sons if necessary, stopping
969 | * when the heap property is re-established (each father smaller than its
970 | * two sons).
971 | */
972 | var zip_pqdownheap = function(
973 | tree, // the tree to restore
974 | k) { // node to move down
975 | var v = zip_heap[k];
976 | var j = k << 1; // left son of k
977 |
978 | while(j <= zip_heap_len) {
979 | // Set j to the smallest of the two sons:
980 | if(j < zip_heap_len &&
981 | zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j]))
982 | j++;
983 |
984 | // Exit if v is smaller than both sons
985 | if(zip_SMALLER(tree, v, zip_heap[j]))
986 | break;
987 |
988 | // Exchange v with the smallest son
989 | zip_heap[k] = zip_heap[j];
990 | k = j;
991 |
992 | // And continue down the tree, setting j to the left son of k
993 | j <<= 1;
994 | }
995 | zip_heap[k] = v;
996 | }
997 |
998 | /* ==========================================================================
999 | * Compute the optimal bit lengths for a tree and update the total bit length
1000 | * for the current block.
1001 | * IN assertion: the fields freq and dad are set, heap[heap_max] and
1002 | * above are the tree nodes sorted by increasing frequency.
1003 | * OUT assertions: the field len is set to the optimal bit length, the
1004 | * array bl_count contains the frequencies for each bit length.
1005 | * The length opt_len is updated; static_len is also updated if stree is
1006 | * not null.
1007 | */
1008 | var zip_gen_bitlen = function(desc) { // the tree descriptor
1009 | var tree = desc.dyn_tree;
1010 | var extra = desc.extra_bits;
1011 | var base = desc.extra_base;
1012 | var max_code = desc.max_code;
1013 | var max_length = desc.max_length;
1014 | var stree = desc.static_tree;
1015 | var h; // heap index
1016 | var n, m; // iterate over the tree elements
1017 | var bits; // bit length
1018 | var xbits; // extra bits
1019 | var f; // frequency
1020 | var overflow = 0; // number of elements with bit length too large
1021 |
1022 | for(bits = 0; bits <= zip_MAX_BITS; bits++)
1023 | zip_bl_count[bits] = 0;
1024 |
1025 | /* In a first pass, compute the optimal bit lengths (which may
1026 | * overflow in the case of the bit length tree).
1027 | */
1028 | tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap
1029 |
1030 | for(h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) {
1031 | n = zip_heap[h];
1032 | bits = tree[tree[n].dl].dl + 1;
1033 | if(bits > max_length) {
1034 | bits = max_length;
1035 | overflow++;
1036 | }
1037 | tree[n].dl = bits;
1038 | // We overwrite tree[n].dl which is no longer needed
1039 |
1040 | if(n > max_code)
1041 | continue; // not a leaf node
1042 |
1043 | zip_bl_count[bits]++;
1044 | xbits = 0;
1045 | if(n >= base)
1046 | xbits = extra[n - base];
1047 | f = tree[n].fc;
1048 | zip_opt_len += f * (bits + xbits);
1049 | if(stree != null)
1050 | zip_static_len += f * (stree[n].dl + xbits);
1051 | }
1052 | if(overflow == 0)
1053 | return;
1054 |
1055 | // This happens for example on obj2 and pic of the Calgary corpus
1056 |
1057 | // Find the first bit length which could increase:
1058 | do {
1059 | bits = max_length - 1;
1060 | while(zip_bl_count[bits] == 0)
1061 | bits--;
1062 | zip_bl_count[bits]--; // move one leaf down the tree
1063 | zip_bl_count[bits + 1] += 2; // move one overflow item as its brother
1064 | zip_bl_count[max_length]--;
1065 | /* The brother of the overflow item also moves one step up,
1066 | * but this does not affect bl_count[max_length]
1067 | */
1068 | overflow -= 2;
1069 | } while(overflow > 0);
1070 |
1071 | /* Now recompute all bit lengths, scanning in increasing frequency.
1072 | * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
1073 | * lengths instead of fixing only the wrong ones. This idea is taken
1074 | * from 'ar' written by Haruhiko Okumura.)
1075 | */
1076 | for(bits = max_length; bits != 0; bits--) {
1077 | n = zip_bl_count[bits];
1078 | while(n != 0) {
1079 | m = zip_heap[--h];
1080 | if(m > max_code)
1081 | continue;
1082 | if(tree[m].dl != bits) {
1083 | zip_opt_len += (bits - tree[m].dl) * tree[m].fc;
1084 | tree[m].fc = bits;
1085 | }
1086 | n--;
1087 | }
1088 | }
1089 | }
1090 |
1091 | /* ==========================================================================
1092 | * Generate the codes for a given tree and bit counts (which need not be
1093 | * optimal).
1094 | * IN assertion: the array bl_count contains the bit length statistics for
1095 | * the given tree and the field len is set for all tree elements.
1096 | * OUT assertion: the field code is set for all tree elements of non
1097 | * zero code length.
1098 | */
1099 | var zip_gen_codes = function(tree, // the tree to decorate
1100 | max_code) { // largest code with non zero frequency
1101 | var next_code = new Array(zip_MAX_BITS+1); // next code value for each bit length
1102 | var code = 0; // running code value
1103 | var bits; // bit index
1104 | var n; // code index
1105 |
1106 | /* The distribution counts are first used to generate the code values
1107 | * without bit reversal.
1108 | */
1109 | for(bits = 1; bits <= zip_MAX_BITS; bits++) {
1110 | code = ((code + zip_bl_count[bits-1]) << 1);
1111 | next_code[bits] = code;
1112 | }
1113 |
1114 | /* Check that the bit counts in bl_count are consistent. The last code
1115 | * must be all ones.
1116 | */
1117 | // Assert (code + encoder->bl_count[MAX_BITS]-1 == (1<> 1; n >= 1; n--)
1184 | zip_pqdownheap(tree, n);
1185 |
1186 | /* Construct the Huffman tree by repeatedly combining the least two
1187 | * frequent nodes.
1188 | */
1189 | do {
1190 | n = zip_heap[zip_SMALLEST];
1191 | zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--];
1192 | zip_pqdownheap(tree, zip_SMALLEST);
1193 |
1194 | m = zip_heap[zip_SMALLEST]; // m = node of next least frequency
1195 |
1196 | // keep the nodes sorted by frequency
1197 | zip_heap[--zip_heap_max] = n;
1198 | zip_heap[--zip_heap_max] = m;
1199 |
1200 | // Create a new node father of n and m
1201 | tree[node].fc = tree[n].fc + tree[m].fc;
1202 | // depth[node] = (char)(MAX(depth[n], depth[m]) + 1);
1203 | if(zip_depth[n] > zip_depth[m] + 1)
1204 | zip_depth[node] = zip_depth[n];
1205 | else
1206 | zip_depth[node] = zip_depth[m] + 1;
1207 | tree[n].dl = tree[m].dl = node;
1208 |
1209 | // and insert the new node in the heap
1210 | zip_heap[zip_SMALLEST] = node++;
1211 | zip_pqdownheap(tree, zip_SMALLEST);
1212 |
1213 | } while(zip_heap_len >= 2);
1214 |
1215 | zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST];
1216 |
1217 | /* At this point, the fields freq and dad are set. We can now
1218 | * generate the bit lengths.
1219 | */
1220 | zip_gen_bitlen(desc);
1221 |
1222 | // The field len is now set, we can generate the bit codes
1223 | zip_gen_codes(tree, max_code);
1224 | }
1225 |
1226 | /* ==========================================================================
1227 | * Scan a literal or distance tree to determine the frequencies of the codes
1228 | * in the bit length tree. Updates opt_len to take into account the repeat
1229 | * counts. (The contribution of the bit length codes will be added later
1230 | * during the construction of bl_tree.)
1231 | */
1232 | var zip_scan_tree = function(tree,// the tree to be scanned
1233 | max_code) { // and its largest code of non zero frequency
1234 | var n; // iterates over all tree elements
1235 | var prevlen = -1; // last emitted length
1236 | var curlen; // length of current code
1237 | var nextlen = tree[0].dl; // length of next code
1238 | var count = 0; // repeat count of the current code
1239 | var max_count = 7; // max repeat count
1240 | var min_count = 4; // min repeat count
1241 |
1242 | if(nextlen == 0) {
1243 | max_count = 138;
1244 | min_count = 3;
1245 | }
1246 | tree[max_code + 1].dl = 0xffff; // guard
1247 |
1248 | for(n = 0; n <= max_code; n++) {
1249 | curlen = nextlen;
1250 | nextlen = tree[n + 1].dl;
1251 | if(++count < max_count && curlen == nextlen)
1252 | continue;
1253 | else if(count < min_count)
1254 | zip_bl_tree[curlen].fc += count;
1255 | else if(curlen != 0) {
1256 | if(curlen != prevlen)
1257 | zip_bl_tree[curlen].fc++;
1258 | zip_bl_tree[zip_REP_3_6].fc++;
1259 | } else if(count <= 10)
1260 | zip_bl_tree[zip_REPZ_3_10].fc++;
1261 | else
1262 | zip_bl_tree[zip_REPZ_11_138].fc++;
1263 | count = 0; prevlen = curlen;
1264 | if(nextlen == 0) {
1265 | max_count = 138;
1266 | min_count = 3;
1267 | } else if(curlen == nextlen) {
1268 | max_count = 6;
1269 | min_count = 3;
1270 | } else {
1271 | max_count = 7;
1272 | min_count = 4;
1273 | }
1274 | }
1275 | }
1276 |
1277 | /* ==========================================================================
1278 | * Send a literal or distance tree in compressed form, using the codes in
1279 | * bl_tree.
1280 | */
1281 | var zip_send_tree = function(tree, // the tree to be scanned
1282 | max_code) { // and its largest code of non zero frequency
1283 | var n; // iterates over all tree elements
1284 | var prevlen = -1; // last emitted length
1285 | var curlen; // length of current code
1286 | var nextlen = tree[0].dl; // length of next code
1287 | var count = 0; // repeat count of the current code
1288 | var max_count = 7; // max repeat count
1289 | var min_count = 4; // min repeat count
1290 |
1291 | /* tree[max_code+1].dl = -1; */ /* guard already set */
1292 | if(nextlen == 0) {
1293 | max_count = 138;
1294 | min_count = 3;
1295 | }
1296 |
1297 | for(n = 0; n <= max_code; n++) {
1298 | curlen = nextlen;
1299 | nextlen = tree[n+1].dl;
1300 | if(++count < max_count && curlen == nextlen) {
1301 | continue;
1302 | } else if(count < min_count) {
1303 | do { zip_SEND_CODE(curlen, zip_bl_tree); } while(--count != 0);
1304 | } else if(curlen != 0) {
1305 | if(curlen != prevlen) {
1306 | zip_SEND_CODE(curlen, zip_bl_tree);
1307 | count--;
1308 | }
1309 | // Assert(count >= 3 && count <= 6, " 3_6?");
1310 | zip_SEND_CODE(zip_REP_3_6, zip_bl_tree);
1311 | zip_send_bits(count - 3, 2);
1312 | } else if(count <= 10) {
1313 | zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree);
1314 | zip_send_bits(count-3, 3);
1315 | } else {
1316 | zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree);
1317 | zip_send_bits(count-11, 7);
1318 | }
1319 | count = 0;
1320 | prevlen = curlen;
1321 | if(nextlen == 0) {
1322 | max_count = 138;
1323 | min_count = 3;
1324 | } else if(curlen == nextlen) {
1325 | max_count = 6;
1326 | min_count = 3;
1327 | } else {
1328 | max_count = 7;
1329 | min_count = 4;
1330 | }
1331 | }
1332 | }
1333 |
1334 | /* ==========================================================================
1335 | * Construct the Huffman tree for the bit lengths and return the index in
1336 | * bl_order of the last bit length code to send.
1337 | */
1338 | var zip_build_bl_tree = function() {
1339 | var max_blindex; // index of last bit length code of non zero freq
1340 |
1341 | // Determine the bit length frequencies for literal and distance trees
1342 | zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code);
1343 | zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code);
1344 |
1345 | // Build the bit length tree:
1346 | zip_build_tree(zip_bl_desc);
1347 | /* opt_len now includes the length of the tree representations, except
1348 | * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
1349 | */
1350 |
1351 | /* Determine the number of bit length codes to send. The pkzip format
1352 | * requires that at least 4 bit length codes be sent. (appnote.txt says
1353 | * 3 but the actual value used is 4.)
1354 | */
1355 | for(max_blindex = zip_BL_CODES-1; max_blindex >= 3; max_blindex--) {
1356 | if(zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break;
1357 | }
1358 | /* Update opt_len to include the bit length tree and counts */
1359 | zip_opt_len += 3*(max_blindex+1) + 5+5+4;
1360 | // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
1361 | // encoder->opt_len, encoder->static_len));
1362 |
1363 | return max_blindex;
1364 | }
1365 |
1366 | /* ==========================================================================
1367 | * Send the header for a block using dynamic Huffman trees: the counts, the
1368 | * lengths of the bit length codes, the literal tree and the distance tree.
1369 | * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
1370 | */
1371 | var zip_send_all_trees = function(lcodes, dcodes, blcodes) { // number of codes for each tree
1372 | var rank; // index in bl_order
1373 |
1374 | // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
1375 | // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
1376 | // "too many codes");
1377 | // Tracev((stderr, "\nbl counts: "));
1378 | zip_send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt
1379 | zip_send_bits(dcodes-1, 5);
1380 | zip_send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt
1381 | for(rank = 0; rank < blcodes; rank++) {
1382 | // Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
1383 | zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3);
1384 | }
1385 |
1386 | // send the literal tree
1387 | zip_send_tree(zip_dyn_ltree,lcodes-1);
1388 |
1389 | // send the distance tree
1390 | zip_send_tree(zip_dyn_dtree,dcodes-1);
1391 | }
1392 |
1393 | /* ==========================================================================
1394 | * Determine the best encoding for the current block: dynamic trees, static
1395 | * trees or store, and output the encoded block to the zip file.
1396 | */
1397 | var zip_flush_block = function(eof) { // true if this is the last block for a file
1398 | var opt_lenb, static_lenb; // opt_len and static_len in bytes
1399 | var max_blindex; // index of last bit length code of non zero freq
1400 | var stored_len; // length of input block
1401 |
1402 | stored_len = zip_strstart - zip_block_start;
1403 | zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items
1404 |
1405 | // Construct the literal and distance trees
1406 | zip_build_tree(zip_l_desc);
1407 | // Tracev((stderr, "\nlit data: dyn %ld, stat %ld",
1408 | // encoder->opt_len, encoder->static_len));
1409 |
1410 | zip_build_tree(zip_d_desc);
1411 | // Tracev((stderr, "\ndist data: dyn %ld, stat %ld",
1412 | // encoder->opt_len, encoder->static_len));
1413 | /* At this point, opt_len and static_len are the total bit lengths of
1414 | * the compressed block data, excluding the tree representations.
1415 | */
1416 |
1417 | /* Build the bit length tree for the above two trees, and get the index
1418 | * in bl_order of the last bit length code to send.
1419 | */
1420 | max_blindex = zip_build_bl_tree();
1421 |
1422 | // Determine the best encoding. Compute first the block length in bytes
1423 | opt_lenb = (zip_opt_len +3+7)>>3;
1424 | static_lenb = (zip_static_len+3+7)>>3;
1425 |
1426 | // Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
1427 | // opt_lenb, encoder->opt_len,
1428 | // static_lenb, encoder->static_len, stored_len,
1429 | // encoder->last_lit, encoder->last_dist));
1430 |
1431 | if(static_lenb <= opt_lenb)
1432 | opt_lenb = static_lenb;
1433 | if(stored_len + 4 <= opt_lenb // 4: two words for the lengths
1434 | && zip_block_start >= 0) {
1435 | var i;
1436 |
1437 | /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
1438 | * Otherwise we can't have processed more than WSIZE input bytes since
1439 | * the last block flush, because compression would have been
1440 | * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
1441 | * transform a block into a stored block.
1442 | */
1443 | zip_send_bits((zip_STORED_BLOCK<<1)+eof, 3); /* send block type */
1444 | zip_bi_windup(); /* align on byte boundary */
1445 | zip_put_short(stored_len);
1446 | zip_put_short(~stored_len);
1447 |
1448 | // copy block
1449 | /*
1450 | p = &window[block_start];
1451 | for(i = 0; i < stored_len; i++)
1452 | put_byte(p[i]);
1453 | */
1454 | for(i = 0; i < stored_len; i++)
1455 | zip_put_byte(zip_window[zip_block_start + i]);
1456 |
1457 | } else if(static_lenb == opt_lenb) {
1458 | zip_send_bits((zip_STATIC_TREES<<1)+eof, 3);
1459 | zip_compress_block(zip_static_ltree, zip_static_dtree);
1460 | } else {
1461 | zip_send_bits((zip_DYN_TREES<<1)+eof, 3);
1462 | zip_send_all_trees(zip_l_desc.max_code+1,
1463 | zip_d_desc.max_code+1,
1464 | max_blindex+1);
1465 | zip_compress_block(zip_dyn_ltree, zip_dyn_dtree);
1466 | }
1467 |
1468 | zip_init_block();
1469 |
1470 | if(eof != 0)
1471 | zip_bi_windup();
1472 | }
1473 |
1474 | /* ==========================================================================
1475 | * Save the match info and tally the frequency counts. Return true if
1476 | * the current block must be flushed.
1477 | */
1478 | var zip_ct_tally = function(
1479 | dist, // distance of matched string
1480 | lc) { // match length-MIN_MATCH or unmatched char (if dist==0)
1481 | zip_l_buf[zip_last_lit++] = lc;
1482 | if(dist == 0) {
1483 | // lc is the unmatched char
1484 | zip_dyn_ltree[lc].fc++;
1485 | } else {
1486 | // Here, lc is the match length - MIN_MATCH
1487 | dist--; // dist = match distance - 1
1488 | // Assert((ush)dist < (ush)MAX_DIST &&
1489 | // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
1490 | // (ush)D_CODE(dist) < (ush)D_CODES, "ct_tally: bad match");
1491 |
1492 | zip_dyn_ltree[zip_length_code[lc]+zip_LITERALS+1].fc++;
1493 | zip_dyn_dtree[zip_D_CODE(dist)].fc++;
1494 |
1495 | zip_d_buf[zip_last_dist++] = dist;
1496 | zip_flags |= zip_flag_bit;
1497 | }
1498 | zip_flag_bit <<= 1;
1499 |
1500 | // Output the flags if they fill a byte
1501 | if((zip_last_lit & 7) == 0) {
1502 | zip_flag_buf[zip_last_flags++] = zip_flags;
1503 | zip_flags = 0;
1504 | zip_flag_bit = 1;
1505 | }
1506 | // Try to guess if it is profitable to stop the current block here
1507 | if(zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) {
1508 | // Compute an upper bound for the compressed length
1509 | var out_length = zip_last_lit * 8;
1510 | var in_length = zip_strstart - zip_block_start;
1511 | var dcode;
1512 |
1513 | for(dcode = 0; dcode < zip_D_CODES; dcode++) {
1514 | out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]);
1515 | }
1516 | out_length >>= 3;
1517 | // Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
1518 | // encoder->last_lit, encoder->last_dist, in_length, out_length,
1519 | // 100L - out_length*100L/in_length));
1520 | if(zip_last_dist < parseInt(zip_last_lit/2) &&
1521 | out_length < parseInt(in_length/2))
1522 | return true;
1523 | }
1524 | return (zip_last_lit == zip_LIT_BUFSIZE-1 ||
1525 | zip_last_dist == zip_DIST_BUFSIZE);
1526 | /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
1527 | * on 16 bit machines and because stored blocks are restricted to
1528 | * 64K-1 bytes.
1529 | */
1530 | }
1531 |
1532 | /* ==========================================================================
1533 | * Send the block data compressed using the given Huffman trees
1534 | */
1535 | var zip_compress_block = function(
1536 | ltree, // literal tree
1537 | dtree) { // distance tree
1538 | var dist; // distance of matched string
1539 | var lc; // match length or unmatched char (if dist == 0)
1540 | var lx = 0; // running index in l_buf
1541 | var dx = 0; // running index in d_buf
1542 | var fx = 0; // running index in flag_buf
1543 | var flag = 0; // current flags
1544 | var code; // the code to send
1545 | var extra; // number of extra bits to send
1546 |
1547 | if(zip_last_lit != 0) do {
1548 | if((lx & 7) == 0)
1549 | flag = zip_flag_buf[fx++];
1550 | lc = zip_l_buf[lx++] & 0xff;
1551 | if((flag & 1) == 0) {
1552 | zip_SEND_CODE(lc, ltree); /* send a literal byte */
1553 | // Tracecv(isgraph(lc), (stderr," '%c' ", lc));
1554 | } else {
1555 | // Here, lc is the match length - MIN_MATCH
1556 | code = zip_length_code[lc];
1557 | zip_SEND_CODE(code+zip_LITERALS+1, ltree); // send the length code
1558 | extra = zip_extra_lbits[code];
1559 | if(extra != 0) {
1560 | lc -= zip_base_length[code];
1561 | zip_send_bits(lc, extra); // send the extra length bits
1562 | }
1563 | dist = zip_d_buf[dx++];
1564 | // Here, dist is the match distance - 1
1565 | code = zip_D_CODE(dist);
1566 | // Assert (code < D_CODES, "bad d_code");
1567 |
1568 | zip_SEND_CODE(code, dtree); // send the distance code
1569 | extra = zip_extra_dbits[code];
1570 | if(extra != 0) {
1571 | dist -= zip_base_dist[code];
1572 | zip_send_bits(dist, extra); // send the extra distance bits
1573 | }
1574 | } // literal or match pair ?
1575 | flag >>= 1;
1576 | } while(lx < zip_last_lit);
1577 |
1578 | zip_SEND_CODE(zip_END_BLOCK, ltree);
1579 | }
1580 |
1581 | /* ==========================================================================
1582 | * Send a value on a given number of bits.
1583 | * IN assertion: length <= 16 and value fits in length bits.
1584 | */
1585 | var zip_Buf_size = 16; // bit size of bi_buf
1586 | var zip_send_bits = function(
1587 | value, // value to send
1588 | length) { // number of bits
1589 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and
1590 | * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
1591 | * unused bits in value.
1592 | */
1593 | if(zip_bi_valid > zip_Buf_size - length) {
1594 | zip_bi_buf |= (value << zip_bi_valid);
1595 | zip_put_short(zip_bi_buf);
1596 | zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid));
1597 | zip_bi_valid += length - zip_Buf_size;
1598 | } else {
1599 | zip_bi_buf |= value << zip_bi_valid;
1600 | zip_bi_valid += length;
1601 | }
1602 | }
1603 |
1604 | /* ==========================================================================
1605 | * Reverse the first len bits of a code, using straightforward code (a faster
1606 | * method would use a table)
1607 | * IN assertion: 1 <= len <= 15
1608 | */
1609 | var zip_bi_reverse = function(
1610 | code, // the value to invert
1611 | len) { // its bit length
1612 | var res = 0;
1613 | do {
1614 | res |= code & 1;
1615 | code >>= 1;
1616 | res <<= 1;
1617 | } while(--len > 0);
1618 | return res >> 1;
1619 | }
1620 |
1621 | /* ==========================================================================
1622 | * Write out any remaining bits in an incomplete byte.
1623 | */
1624 | var zip_bi_windup = function() {
1625 | if(zip_bi_valid > 8) {
1626 | zip_put_short(zip_bi_buf);
1627 | } else if(zip_bi_valid > 0) {
1628 | zip_put_byte(zip_bi_buf);
1629 | }
1630 | zip_bi_buf = 0;
1631 | zip_bi_valid = 0;
1632 | }
1633 |
1634 | var zip_qoutbuf = function() {
1635 | if(zip_outcnt != 0) {
1636 | var q, i;
1637 | q = zip_new_queue();
1638 | if(zip_qhead == null)
1639 | zip_qhead = zip_qtail = q;
1640 | else
1641 | zip_qtail = zip_qtail.next = q;
1642 | q.len = zip_outcnt - zip_outoff;
1643 | // System.arraycopy(zip_outbuf, zip_outoff, q.ptr, 0, q.len);
1644 | for(i = 0; i < q.len; i++)
1645 | q.ptr[i] = zip_outbuf[zip_outoff + i];
1646 | zip_outcnt = zip_outoff = 0;
1647 | }
1648 | }
1649 |
1650 | var zip_deflate = function(str, level) {
1651 | var i, j;
1652 |
1653 | zip_deflate_data = str;
1654 | zip_deflate_pos = 0;
1655 | if(typeof level == "undefined")
1656 | level = zip_DEFAULT_LEVEL;
1657 | zip_deflate_start(level);
1658 |
1659 | var buff = new Array(1024);
1660 | var aout = [];
1661 | while((i = zip_deflate_internal(buff, 0, buff.length)) > 0) {
1662 | var cbuf = new Array(i);
1663 | for(j = 0; j < i; j++){
1664 | cbuf[j] = String.fromCharCode(buff[j]);
1665 | }
1666 | aout[aout.length] = cbuf.join("");
1667 | }
1668 | zip_deflate_data = null; // G.C.
1669 | return aout.join("");
1670 | }
1671 |
1672 | if (! ctx.RawDeflate) ctx.RawDeflate = {};
1673 | ctx.RawDeflate.deflate = zip_deflate;
1674 |
1675 | })(this);
1676 |
--------------------------------------------------------------------------------