Advertisement
rg443

js_lzw - javascript lzw implementation

Jan 27th, 2013
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // https://github.com/saw/JS_LZW
  2. // https://raw.github.com/saw/JS_LZW/master/lzw.js
  3. /*
  4. var size = saw.lzw.strSize,
  5. decode = saw.lzw.decode,
  6. encode = saw.lzw.encode;
  7. var encoded = encode(val);
  8. var decoded = decode(encoded);
  9. size(val);
  10. size(encoded);
  11. */
  12.  
  13. (function(){
  14.    
  15.     var STARTPOINT = 256;
  16.    
  17.     //create "saw" global if not there
  18.     if(window.saw === undefined){
  19.         window.saw = {};
  20.     }
  21.     /**
  22.      * Returns a pre-popuated dictionary to begin encoding
  23.      * @private
  24.      * @method getDic
  25.      * @return {Object} result a hash table with ascii letters as keys
  26.      */
  27.     function getDic(){
  28.         var result = {};
  29.         for (var i=0; i < STARTPOINT; i++) {
  30.             var ch = String.fromCharCode(i);
  31.             result[ch] = i;
  32.         };
  33.         return result;
  34.     }
  35.    
  36.     /**
  37.      * Prepopulates translation table
  38.      * @private
  39.      * @method tTable
  40.      * @return {Object} translation table (hash table)
  41.      */
  42.     function tTable(){
  43.         var result = {};
  44.         for (var i=0; i < STARTPOINT; i++) {
  45.             var ch = String.fromCharCode(i);
  46.             result[i] = ch;
  47.         };
  48.         return result;
  49.     }
  50.    
  51.    
  52.     //Define the object and public methods
  53.     var LZW = {
  54.        
  55.         /**
  56.          * Encodes the string as an LZW compressed binary stream...except
  57.          * because we can't really use binary in javascript we are using the unicode
  58.          * character specified by the decimal code output by the algorithm in each place
  59.          *
  60.          * @method encode
  61.          * @static
  62.          * @param {String} str The string to encode
  63.          * @return {String} str The encoded string
  64.          */
  65.         encode:function(str){
  66.             var index = STARTPOINT, //start at 256, the first 255 are the ascii set
  67.            
  68.             //initialize the dictionary
  69.             dictionary = getDic(),
  70.             //arr to hold output string
  71.             outStr = [],
  72.            
  73.             //this will be the buffer
  74.             s = '';
  75.  
  76.             var len = str.length, //for performance
  77.             s = str[0]; //lets start
  78.            
  79.             for(var i=1; i < len; i++){
  80.                 var c = str[i];
  81.                
  82.                 if(dictionary[s+c]){ //already in the dictionary
  83.                     s = s+c;
  84.                 }else{ //need to add it to the dictionary
  85.                     var code = ++index;
  86.                    
  87.                     outStr.push(String.fromCharCode(dictionary[s]));
  88.                     dictionary[s+c] = code;
  89.                     s = c;
  90.                 }
  91.             }
  92.             for(var c in s ){
  93.                 outStr.push(s[c]);
  94.             }
  95.            
  96.  
  97.        
  98.             return outStr.join('');
  99.         },
  100.        
  101.         decode:function(str){
  102.            
  103.             //init translation table
  104.              var table = tTable(),
  105.              
  106.              //buffer will store the string we are working on
  107.              buffer = '',
  108.              
  109.              //store the characters in an array as they are added
  110.              outStr = [],
  111.              
  112.              //init first_code
  113.              first_code = str[0].charCodeAt(0),
  114.              
  115.              //get string length for loop
  116.              len = str.length,
  117.              
  118.              //counter so we know where to start after the base table
  119.              counter = STARTPOINT-1,
  120.              
  121.              //this will be handy for the case where next_code does not exist in the table
  122.              character = '';
  123.              
  124.              var decodearr= [];
  125.              //main decode loop
  126.              for (var i=0; i < len; i++) {
  127.                  var next_code = str[i].charCodeAt(0);
  128.                  if(!table[next_code]){ //handles the exception case
  129.                      buffer = table[first_code];
  130.                      buffer = buffer + character;
  131.                  }else{
  132.                      //add decoded char to buffer
  133.                      buffer = table[next_code];
  134.                  }
  135.                  
  136.                  //add buffer to output
  137.                  outStr.push(buffer);
  138.                  
  139.                  
  140.                  character = buffer[0];
  141.                  //add new substring to table
  142.                  table[++counter] = table[first_code] +
  143.                                     character;
  144.                                    
  145.                  //time for the next char
  146.                  first_code = next_code;
  147.              };
  148.              
  149.              return outStr.join('');
  150.         },
  151.        
  152.         /**
  153.          * Utitilty method that returns the size of a unicode string in bytes
  154.          * @method strSize
  155.          * @param {String} str The string to evaluate
  156.          * @return {Number} num the length of the string in bytes
  157.          */
  158.         strSize:function(str){
  159.  
  160.             return encodeURIComponent(str).replace(/%../g, 'x').length;
  161.         }
  162.        
  163.     };
  164.    
  165.     window.saw.lzw = LZW;
  166.  
  167.  
  168. }());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement