From 25dc6aabe5e16ac0a563d69817eb8a1e4b5b8968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20Falc=C3=A3o?= Date: Mon, 11 May 2015 01:31:22 -0300 Subject: [PATCH] LZW Encoding/Decoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lempel–Ziv–Welch (LZW) is a universal lossless data compression algorithm. It is an improved implementation of the LZ78 algorithm. --- src/compression/LZW/LZW.js | 95 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/compression/LZW/LZW.js diff --git a/src/compression/LZW/LZW.js b/src/compression/LZW/LZW.js new file mode 100644 index 00000000..9c1f9c06 --- /dev/null +++ b/src/compression/LZW/LZW.js @@ -0,0 +1,95 @@ +/** + * LZW Encoding/Decoding + * + * Lempel–Ziv–Welch (LZW) is a universal lossless data + * compression algorithm. It is an improved implementation + * of the LZ78 algorithm. + * + * @example + * var lzwModule = require('path-to-algorithms/src/compression'+ + * '/LZW/LZW'); + * var lzw = new lzwModule.LZW(); + * + * var compressed = lzw.compress("ABCABCABCABCABCABC"); + * console.log(compressed); + * + * var decompressed = lzw.decompress(compressed); + * console.log(decompressed); + * + * @module compression/LZW/LZW + */ +(function (exports) { + 'use strict'; + + exports.LZW = function () { + this.dictionarySize = 256; + }; + + exports.LZW.compress = function (data) { + var i; + var dictionary = {}; + var character; + var wc; + var w = ''; + var result = []; + + for (i = 0; i < this.dictionarySize; i = i + 1) { + dictionary[String.fromCharCode(i)] = i; + } + + for (i = 0; i < data.length; i = i + 1) { + character = data.charAt(i); + wc = w + character; + if (dictionary.hasOwnProperty(wc)) { + w = wc; + } else { + result.push(dictionary[w]); + dictionary[wc] = this.dictionarySize; + this.dictionarySize = this.dictionarySize + 1; + w = String(character); + } + } + + if (w !== '') { + result.push(dictionary[w]); + } + + return result; + }; + + exports.LZW.decompress = function (compressedData) { + var i; + var dictionary = []; + var w; + var result; + var key; + var entry = ''; + + for (i = 0; i < this.dictionarySize; i = i + 1) { + dictionary[i] = String.fromCharCode(i); + } + + w = String.fromCharCode(compressedData[0]); + result = w; + + for (i = 1; i < compressedData.length; i = i + 1) { + key = compressedData[i]; + if (dictionary[key]) { + entry = dictionary[key]; + } else { + if (key === this.dictionarySize) { + entry = w + w.charAt(0); + } else { + return null; + } + } + + result += entry; + dictionary[this.dictionarySize] = w + entry.charAt(0); + this.dictionarySize = this.dictionarySize + 1; + w = entry; + } + + return result; + }; +})(typeof window === 'undefined' ? module.exports : window);