Skip to content

Instantly share code, notes, and snippets.

@alenaksu
Last active December 17, 2024 09:31
Show Gist options
  • Save alenaksu/c3b1fee18cb2edcb7eec3f64407955a0 to your computer and use it in GitHub Desktop.
Save alenaksu/c3b1fee18cb2edcb7eec3f64407955a0 to your computer and use it in GitHub Desktop.
LZW Implementation
/**
Namespace for LZW compression and decompression.
Methods:
LZW.compress(uncompressed)
LZW.decompress(compressed)
*/
function createDictionary({ size = 256, inverse = false } = {}) {
const dictionary = new Map();
for (let i = 0; i < size; i++) {
if (inverse) dictionary.set(i, String.fromCharCode(i));
else dictionary.set(String.fromCharCode(i), i);
}
return dictionary;
}
/**
Perform the LZW compression
uncompressed - String. The string on which to perform the compression.
*/
function compress(uncompressed) {
// Initialize dictionary
const dictionary = createDictionary();
let word = '';
const result = [];
let dictSize = dictionary.size;
for (let i = 0, len = uncompressed.length; i < len; i++) {
const curChar = uncompressed[i];
const joinedWord = word + curChar;
if (dictionary.has(joinedWord)) {
word = joinedWord;
} else {
result.push(dictionary.get(word));
// Add wc to the dictionary.
dictionary.set(joinedWord, dictSize++);
word = curChar;
}
}
if (word !== '') {
result.push(dictionary.get(word));
}
return String.fromCharCode(...result);
}
/**
Decompress LZW array generated by LZW.compress()
compressed - Array. The array that holds LZW compressed data.
*/
function decompress(compressed) {
// Initialize Dictionary (inverse of compress)
const dictionary = createDictionary({ inverse: true });
let word = compressed[0];
let result = word;
let entry = '';
let dictSize = dictionary.size;
for (let i = 1, len = compressed.length; i < len; i++) {
const curNumber = compressed.charCodeAt(i);
if (dictionary.has(curNumber)) {
entry = dictionary.get(curNumber);
} else {
if (curNumber === dictSize) {
entry = word + word[0];
} else {
throw new Error(`Character not in dictionary: ${curNumber}`);
}
}
result += entry;
// Add word + entry[0] to dictionary
dictionary.set(dictSize++, word + entry[0]);
word = entry;
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment