|
|
@@ -1,91 +1,105 @@ |
|
|
//LZW Compression/Decompression for Strings |
|
|
/* |
|
|
LZW Compression/Decompression for Strings |
|
|
Implementation of LZW algorithms from: |
|
|
http://rosettacode.org/wiki/LZW_compression#JavaScript |
|
|
|
|
|
Usage: |
|
|
var a = 'a very very long string to be squashed'; |
|
|
var b = a.compress(); // 'a veryāăąlong striċ to bečquashed' |
|
|
var c = b.uncompress(); // 'a very very long string to be squashed' |
|
|
console.log(a === c); // True |
|
|
|
|
|
var d = a.compress(true); // return as Array |
|
|
console.log(d); // [97, 32, 118 .... 101, 100] an Array of ASCII codes |
|
|
|
|
|
*/ |
|
|
|
|
|
String.prototype.compress = function (asArray) { |
|
|
"use strict"; |
|
|
// Build the dictionary. |
|
|
asArray = (asArray === true); |
|
|
var i, |
|
|
dictionary = {}, |
|
|
uncompressed = this, |
|
|
c, |
|
|
wc, |
|
|
w = "", |
|
|
result = [], |
|
|
ASCII = '', |
|
|
dictSize = 256; |
|
|
for (i = 0; i < 256; i += 1) { |
|
|
dictionary[String.fromCharCode(i)] = i; |
|
|
} |
|
|
"use strict"; |
|
|
// Build the dictionary. |
|
|
asArray = (asArray === true); |
|
|
var i, |
|
|
dictionary = {}, |
|
|
uncompressed = this, |
|
|
c, |
|
|
wc, |
|
|
w = "", |
|
|
result = [], |
|
|
ASCII = '', |
|
|
dictSize = 256; |
|
|
for (i = 0; i < 256; i += 1) { |
|
|
dictionary[String.fromCharCode(i)] = i; |
|
|
} |
|
|
|
|
|
for (i = 0; i < uncompressed.length; i += 1) { |
|
|
c = uncompressed.charAt(i); |
|
|
wc = w + c; |
|
|
//Do not use dictionary[wc] because javascript arrays |
|
|
//will return values for array['pop'], array['push'] etc |
|
|
// if (dictionary[wc]) { |
|
|
if (dictionary.hasOwnProperty(wc)) { |
|
|
w = wc; |
|
|
} else { |
|
|
result.push(dictionary[w]); |
|
|
ASCII += String.fromCharCode(dictionary[w]); |
|
|
// Add wc to the dictionary. |
|
|
dictionary[wc] = dictSize++; |
|
|
w = String(c); |
|
|
} |
|
|
} |
|
|
for (i = 0; i < uncompressed.length; i += 1) { |
|
|
c = uncompressed.charAt(i); |
|
|
wc = w + c; |
|
|
//Do not use dictionary[wc] because javascript arrays |
|
|
//will return values for array['pop'], array['push'] etc |
|
|
// if (dictionary[wc]) { |
|
|
if (dictionary.hasOwnProperty(wc)) { |
|
|
w = wc; |
|
|
} else { |
|
|
result.push(dictionary[w]); |
|
|
ASCII += String.fromCharCode(dictionary[w]); |
|
|
// Add wc to the dictionary. |
|
|
dictionary[wc] = dictSize++; |
|
|
w = String(c); |
|
|
} |
|
|
} |
|
|
|
|
|
// Output the code for w. |
|
|
if (w !== "") { |
|
|
result.push(dictionary[w]); |
|
|
ASCII += String.fromCharCode(dictionary[w]); |
|
|
} |
|
|
return asArray ? result : ASCII; |
|
|
// Output the code for w. |
|
|
if (w !== "") { |
|
|
result.push(dictionary[w]); |
|
|
ASCII += String.fromCharCode(dictionary[w]); |
|
|
} |
|
|
return asArray ? result : ASCII; |
|
|
}; |
|
|
|
|
|
String.prototype.decompress = function () { |
|
|
"use strict"; |
|
|
// Build the dictionary. |
|
|
var i, tmp = [], |
|
|
dictionary = [], |
|
|
compressed = this, |
|
|
w, |
|
|
result, |
|
|
k, |
|
|
entry = "", |
|
|
dictSize = 256; |
|
|
for (i = 0; i < 256; i += 1) { |
|
|
dictionary[i] = String.fromCharCode(i); |
|
|
} |
|
|
"use strict"; |
|
|
// Build the dictionary. |
|
|
var i, tmp = [], |
|
|
dictionary = [], |
|
|
compressed = this, |
|
|
w, |
|
|
result, |
|
|
k, |
|
|
entry = "", |
|
|
dictSize = 256; |
|
|
for (i = 0; i < 256; i += 1) { |
|
|
dictionary[i] = String.fromCharCode(i); |
|
|
} |
|
|
|
|
|
if(compressed && typeof compressed === 'string') { |
|
|
// convert string into Array. |
|
|
for(i = 0; i < compressed.length; i += 1) { |
|
|
tmp.push(compressed[i].charCodeAt(0)); |
|
|
} |
|
|
compressed = tmp; |
|
|
tmp = null; |
|
|
} |
|
|
if(compressed && typeof compressed === 'string') { |
|
|
// convert string into Array. |
|
|
for(i = 0; i < compressed.length; i += 1) { |
|
|
tmp.push(compressed[i].charCodeAt(0)); |
|
|
} |
|
|
compressed = tmp; |
|
|
tmp = null; |
|
|
} |
|
|
|
|
|
w = String.fromCharCode(compressed[0]); |
|
|
result = w; |
|
|
for (i = 1; i < compressed.length; i += 1) { |
|
|
k = compressed[i]; |
|
|
if (dictionary[k]) { |
|
|
entry = dictionary[k]; |
|
|
} else { |
|
|
if (k === dictSize) { |
|
|
entry = w + w.charAt(0); |
|
|
} else { |
|
|
return null; |
|
|
} |
|
|
} |
|
|
w = String.fromCharCode(compressed[0]); |
|
|
result = w; |
|
|
for (i = 1; i < compressed.length; i += 1) { |
|
|
k = compressed[i]; |
|
|
if (dictionary[k]) { |
|
|
entry = dictionary[k]; |
|
|
} else { |
|
|
if (k === dictSize) { |
|
|
entry = w + w.charAt(0); |
|
|
} else { |
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
result += entry; |
|
|
result += entry; |
|
|
|
|
|
// Add w+entry[0] to the dictionary. |
|
|
dictionary[dictSize++] = w + entry.charAt(0); |
|
|
// Add w+entry[0] to the dictionary. |
|
|
dictionary[dictSize++] = w + entry.charAt(0); |
|
|
|
|
|
w = entry; |
|
|
} |
|
|
return result; |
|
|
w = entry; |
|
|
} |
|
|
return result; |
|
|
}; |