111 lines
2.7 KiB
JavaScript
111 lines
2.7 KiB
JavaScript
'use strict';
|
|
/**
|
|
Namespace for LZW compression and decompression.
|
|
Methods:
|
|
LZW.compress(uncompressed)
|
|
LZW.decompress(compressed)
|
|
*/
|
|
class LZW
|
|
{
|
|
/**
|
|
Perform the LZW compression
|
|
uncompressed - String. The string on which to perform the compression.
|
|
*/
|
|
static compress(uncompressed)
|
|
{
|
|
// Initialize dictionary
|
|
let dictionary = {};
|
|
for (let i = 0; i < 256; i++)
|
|
{
|
|
dictionary[String.fromCharCode(i)] = i;
|
|
}
|
|
|
|
let word = '';
|
|
let result = [];
|
|
let dictSize = 256;
|
|
|
|
for (let i = 0, len = uncompressed.length; i < len; i++)
|
|
{
|
|
let curChar = uncompressed[i];
|
|
let joinedWord = word + curChar;
|
|
|
|
// Do not use dictionary[joinedWord] because javascript objects
|
|
// will return values for myObject['toString']
|
|
if (dictionary.hasOwnProperty(joinedWord))
|
|
{
|
|
word = joinedWord;
|
|
}
|
|
else
|
|
{
|
|
result.push(dictionary[word]);
|
|
// Add wc to the dictionary.
|
|
dictionary[joinedWord] = dictSize++;
|
|
word = curChar;
|
|
}
|
|
}
|
|
|
|
if (word !== '')
|
|
{
|
|
result.push(dictionary[word]);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
Decompress LZW array generated by LZW.compress()
|
|
compressed - Array. The array that holds LZW compressed data.
|
|
*/
|
|
static decompress(compressed)
|
|
{
|
|
// Initialize Dictionary (inverse of compress)
|
|
let dictionary = {};
|
|
for (let i = 0; i < 256; i++)
|
|
{
|
|
dictionary[i] = String.fromCharCode(i);
|
|
}
|
|
|
|
let word = String.fromCharCode(compressed[0]);
|
|
let result = word;
|
|
let entry = '';
|
|
let dictSize = 256;
|
|
|
|
for (let i = 1, len = compressed.length; i < len; i++)
|
|
{
|
|
let curNumber = compressed[i];
|
|
|
|
if (dictionary[curNumber] !== undefined)
|
|
{
|
|
entry = dictionary[curNumber];
|
|
}
|
|
else
|
|
{
|
|
if (curNumber === dictSize)
|
|
{
|
|
entry = word + word[0];
|
|
}
|
|
else
|
|
{
|
|
throw 'Error in processing';
|
|
return null;
|
|
}
|
|
}
|
|
|
|
result += entry;
|
|
|
|
// Add word + entry[0] to dictionary
|
|
dictionary[dictSize++] = word + entry[0];
|
|
|
|
word = entry;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
let comp = LZW.compress('TOBEORNOTTOBEORTOBEORNOT');
|
|
let decomp = LZW.decompress(comp);
|
|
|
|
console.log(`${comp}
|
|
${decomp}`);
|