Last active
December 17, 2024 09:31
-
-
Save alenaksu/c3b1fee18cb2edcb7eec3f64407955a0 to your computer and use it in GitHub Desktop.
LZW Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
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