-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
index.js
83 lines (74 loc) · 2.29 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
* @fileoverview LZW compressor module from Glize library.
*
* @see https://google.github.io/styleguide/javascriptguide.xml
* @see https://developers.google.com/closure/compiler/docs/js-for-compiler
* @see https://en.wikipedia.org/wiki/Lempel–Ziv–Welch
* @see https://github.com/Datamart/Glize
* @module lzw-compressor
*/
import { uint32 } from 'uint';
/**
* Compress data string using LZW lossless data compression algorithm.
* @param {string} str Data to compress.
* @return {string} Returns compressed data.
* @method
* @example
* const result = compress(
* 'Any string of any length. Any string of any length. Any string of any length.');
* console.log(result);
* //> Any string of aā leĈth. ĀĂĄĆĈĊČĎĂđēĕėďĚćĉċčďġgĔ.
*/
export const compress = (str) => {
const dict = {};
const data = str.split('');
const out = [];
let code = 256;
let phrase = data.shift();
while (data.length) {
const next = data.shift();
if (null != dict[phrase + next]) {
phrase += next;
} else {
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
dict[phrase + next] = code++;
phrase = next;
}
}
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
const length = uint32(out.length);
for (let i = 0; i < length; ++i) {
out[i] = String.fromCharCode(/** @type {number} */ (out[i]));
}
return out.join('');
};
/**
* Decompress data string compressed with the LZW algorithm.
* @param {string} str Data to compress.
* @return {string} Returns compressed data.
* @method
* @example
* const result = decompress('Any string of aā leĈth. ĀĂĄĆĈĊČĎĂđēĕėďĚćĉċčďġgĔ.');
* console.log(result);
* //> Any string of any length. Any string of any length. Any string of any length.
*/
export const decompress = (str) => {
const dict = {};
const data = str.split('');
const out = [data.shift()];
const length = uint32(data.length);
let code = 256;
let chr = out[0];
let tmp = chr;
for (let i = 0; i < length; ++i) {
const next = data[i].charCodeAt(0);
const phrase = next < 256 ?
data[i] :
(dict[next] ? dict[next] : (tmp + chr));
out.push(phrase);
chr = phrase.charAt(0);
dict[code++] = tmp + chr;
tmp = phrase;
}
return out.join('');
};