richard-to
3/11/2014 - 7:14 AM

Experimenting with modified Huffman codes to compress sprite image data

Experimenting with modified Huffman codes to compress sprite image data

var waterData = [55,56,56,56,56,56,56,57,55,56,56,56,56,55,55,56,56,56,57,56,56,56,56,56,55,55,56,57,57,56,56,56,55,55,55,56,56,56,56,57,55,56,56,56,56,56,55,56,56,56,57,56,56,56,56,56,55,55,56,56,57,56,56,56,56,56,55,56,56,56,56,56,57,55,56,56,56,56,55,55,57,57,57,56,56,56,56,55,55,56,56,56,57,56,56,56,56,56,56,55,55,57,56,56,57,55,56,56,56,55,55,55,57,56,56,57,57,57,56,55,56,56,56,57,57,56,56,56,57,57,57,57,55,56,57,57,57,55,56,56,56,55,56,57,56,56,56,56,56,57,57,55,57,57,57,57,57,57,57,57,56,56,56,57,56,55,56,56,56,55,57,56,55,56,57,57,56,56,56,56,56,55,55,55,55,55,55,56,56,56,56,57,56,56,56,57,56,55,55,55,55,56,57,56,55,55,55,55,55,56,56,56,55,55,57,56,56,56,55,55,56,56,56,57,55,55,55,55,55,55,56,56,55,55,55,56,55,55,56,56,55,55,56,55,55,56,57,56,56,56,56,55,55,55,55,55,56,55,55,56,56,57,57,56,56,56,55,55,55,57,56,56,56,55,55,55,57,57,57,56,56,56,56,55,56,56,56,56,56,55,55,56,56,56,57,56,56,56,57,55,57,57,57,57,56,56,55,57,57,56,56,56,56,56,56,55,56,56,56,56,56,56,55,56,56,56,57,57,57,57,57,55,57,56,56,57,56,56,55,55,57,57,56,56,56,55,55,55,56,56,57,57,56,56,55,56,56,56,56,56,57,57,57,55,57,56,56,56,57,57,57,55,55,55,55,55,55,55,56,56,56,57,57,56,57,56,55,56,56,56,56,56,57,56,56,55,57,57,56,56,56,56,55,55,56,56,57,55,55,57,57,57,57,57,56,56,57,57,57,55,55,55,56,57,57,56,56,56,55,57,56,56,56,55,55,56,56,56,56,56,55,55,56,56,57,57,56,56,55,55,55,57,57,56,55,55,56,56,56,56,55,57,56,56,56,55,56,56,56,56,56,56,57,55,56,56,57,57,56,56,55,56,56,56,56,57,57,57,55,56,56,56,55,55,55,55,55,55,56,56,56,56,56,56,57,55,56,56,56,57,56,56,56,56,56,56,56,56,57,56,56,55,55,55,55,56,56,57,57,55,56,56,56,56,56,57,57,55,55,56,56,57,56,56,56,56,56,56,56,56,57,56,56,55,55,57,57,56,56,56,57,55,56,56,56,56,56,57,56,56,55,55,56,55,55,55,56,56,56,56,56,56,57,57,57,55,56,56,56,56,56,56,57,55,55,55,56,56,57,57,56,56,56,56,55,56,57,56,56,56,56,56,56,56,56,56,57,55,56,56,56,56,56,56,57,56,56,57,55,55,57,56,56,56,55,55,57,57,57,56,55,55,56,56,56,55,55,55,55,56,56,56,56,56,56,57,57,56,56,56,55,55,55,56,56,55,56,57,57,56,57,57,56,55,55,55,55,55,56,55,55,56,56,56,56,56,56,57,56,56,55,55,56,57,57,55,55,56,56,57,57,56,56,57,56,57,57,56,55,57,57,57,55,56,56,56,56,56,56,57,56,55,55,56,56,56,55,57,55,56,57,56,56,56,56,56,57,57,56,56,55,56,56,56,55,56,56,56,56,56,55,55,55,55,56,56,56,56,55,55,57,57,56,56,56,56,55,55,57,56,56,56,55,56,56,56,55,57,56,55,55,55,56,57,56,56,56,56,56,56,56,55,57,56,56,56,56,55,55,56,56,56,56,55,55,56,56,57,55,55,55,55,56,57,57,57,57,56,56,56,56,56,56,55,57,57,55,55,55,55,56,56,56,56,55,55,56,56,57,57,56,55,55,55,55,56,56,56,57,57,57,56,56,56,56,55,55,56,55,57,56,56,56,56,56,56,55,55,56,57,57,56,55,55,57,57,55,55,56,56,56,56,57,57,56,56,55,55,55,55,55,57,56,56,56,56,56,56,56,55,57,56,56,56,55,57,57,56,56,56,55,56,56,56,56,56,55,55,57,57,56,55,55,57,57,56,56,56,56,57,57,55,56,56,56,55,55,57,57,56,56,56,55,55,55,56,55,55,55,56,56,56,56,56,55,55,57,56,56,56,57,57,56,55,56,56,56,55,57,57,56,56,56,56,56,56,56,55,55,56,57,56,56,56,56,56,56,55,55,57,56,56,55,55,55,55,56,56,55,55,57,56,56,56,56,56,56,56,56,55,56,56,56,57,56,56,56,56,56,56,55,55,57,56];

var cliffData = [52,52,52,53,52,54,54,54,52,52,52,53,53,52,52,52,54,54,52,52,52,53,52,52,52,52,52,52,53,53,52,52,54,54,52,53,52,54,54,52,52,52,52,53,53,53,52,54,54,54,54,54,52,53,52,54,54,54,52,52,53,53,53,52,54,54,52,53,53,52,52,52,52,13,13,53,53,53,52,52,54,54,54,52,52,53,52,54,54,52,52,53,53,52,53,53,52,54,52,52,53,52,52,13,13,13,53,53,52,53,53,52,52,52,52,52,52,53,52,52,52,52,53,53,54,54,52,53,52,52,52,53,53,53,52,53,53,53,53,52,52,53,53,52,52,52,52,13,13,53,52,52,52,52,53,52,54,52,53,53,52,13,13,53,52,53,53,53,52,52,13,13,53,53,53,52,52,13,13,13,53,53,52,52,52,52,53,52,52,13,53,52,52,13,53,52,53,53,52,54,52,52,13,13,53,52,53,53,53,13,13,13,53,52,13,13,13,53,52,13,13,53,52,52,53,53,54,52,53,52,54,54,52,13,13,53,53,52,52,52,53,53,53,53,53,52,13,53,53,54,52,13,13,53,52,52,54,54,54,52,53,52,52,52,52,13,13,53,52,54,54,54,52,53,53,53,53,53,53,53,54,52,52,13,53,52,54,54,52,52,52,13,53,53,52,52,13,13,13,52,52,54,54,52,52,53,52,52,52,53,53,53,52,52,13,13,53,52,54,54,52,13,13,13,53,53,52,52,13,53,53,52,54,54,52,52,53,52,52,54,54,52,52,53,52,13,13,53,52,54,54,54,53,53,13,13,53,53,53,52,53,53,52,52,52,52,52,53,52,52,54,54,54,52,52,53,52,13,13,53,52,54,54,52,53,53,53,53,53,53,53,53,53,52,52,52,52,52,52,53,52,52,54,54,52,52,53,53,53,13,13,53,52,52,52,52,52,52,53,53,52,52,53,53,13,13,13,13,52,53,53,53,53,52,54,54,52,52,53,53,52,53,53,53,52,52,52,52,54,54,53,53,52,54,52,53,13,13,13,53,53,53,52,52,53,53,52,52,52,53,53,52,52,52,52,53,52,52,52,52,54,54,52,53,54,54,52,53,53,53,53,53,54,54,54,52,52,53,52,52,53,53,53,54,54,54,52,53,52,52,13,13,52,52,52,53,52,52,52,52,53,53,52,52,54,52,52,52,13,53,52,53,54,52,53,52,54,52,52,53,52,52,13,13,52,52,52,53,52,52,52,52,53,53,52,52,52,52,52,52,52,53,53,54,54,52,53,52,52,52,52,52,53,53,53,13,52,52,53,53,52,52,52,13,53,53,53,52,13,13,13,53,53,53,53,54,54,52,53,52,52,13,13,13,53,53,53,13,52,52,53,52,52,52,13,13,53,52,53,53,13,13,53,53,54,53,53,52,52,52,52,53,13,13,13,53,53,52,52,53,52,52,53,52,52,13,13,53,53,52,52,53,13,13,53,52,54,52,53,53,13,13,13,53,53,53,53,52,52,52,52,53,52,13,53,13,13,13,53,53,52,54,52,53,53,53,53,54,54,52,53,53,13,13,13,53,54,52,52,52,52,52,53,53,13,13,53,53,53,53,53,52,54,54,52,53,53,54,53,53,52,13,52,53,53,13,53,53,54,52,52,52,52,13,53,52,13,13,53,53,53,52,52,54,54,54,52,53,54,54,52,53,53,52,13,53,53,53,53,52,52,52,52,13,13,13,53,52,13,13,53,52,53,52,52,52,52,52,53,52,52,52,52,52,53,53,53,53,52,52,53,52,52,52,13,13,13,53,53,52,53,53,52,52,53,52,52,52,52,52,53,52,13,13,13,52,53,52,52,53,52,52,53,52,52,13,13,13,53,53,54,54,53,52,54,54,53,52,52,52,52,53,53,13,13,13,53,53,53,54,54,52,53,52,53,52,52,53,53,53,53,52,54,54,52,54,54,52,52,53,13,13,13,13,53,13,13,53,52,52,54,54,52,52,53,13,53,53,53,52,52,53,53,52,52,52,52,54,52,52,52,53,53,13,13,13,53,53,53,53,52,54,54,52,52,13,53,53,53,52,54,52,52,52,53,53,52,52,52,52,52,52,13,13,53,53,53,53,53,53,53,52,52,52,52,52,52,13,53,53,52,54,54,52,52,13,13,53,52,13,52,52,52,13,13,13,53,52,54,52,52,53,53,52,52,52,52,52,13,13,53,53,52,54,52,52,52,13,53,53,13,13,52,52,13,13,53,53,52,54,54,52,52,52,53,53,53,53,53,53,53,53,53,52,52,52,52,52,13,13,53,52,13,13];

var grassData = [47,47,47,47,47,48,48,48,47,47,47,47,47,49,49,49,49,49,47,49,49,47,47,47,49,49,49,49,47,47,47,49,47,49,47,47,47,48,49,49,49,49,47,47,47,47,49,49,49,49,47,49,48,47,47,47,49,49,49,49,47,47,49,49,47,48,48,49,47,47,47,49,49,50,47,48,48,47,47,49,47,47,49,49,47,47,47,48,49,49,47,47,47,48,49,49,47,49,49,48,49,49,47,50,50,47,49,48,48,48,49,47,47,49,49,49,47,48,49,48,49,49,47,48,48,49,49,49,47,47,49,49,49,49,49,49,49,47,49,48,49,49,49,49,47,49,49,47,48,49,49,49,49,50,47,48,48,49,49,47,47,47,47,49,49,50,50,50,50,47,47,49,49,49,49,49,47,49,50,47,49,49,49,50,50,50,47,49,49,49,49,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,49,49,49,49,50,47,47,47,49,50,47,47,49,49,49,49,50,47,47,47,47,47,47,48,48,48,49,48,49,48,48,47,47,50,50,50,47,47,47,47,47,47,47,47,49,49,50,50,50,47,49,49,48,48,48,48,49,49,48,48,48,48,49,47,47,47,47,47,47,48,48,48,48,48,49,47,47,50,47,47,47,47,49,49,48,49,49,49,49,49,49,49,49,48,49,49,47,47,47,48,48,48,48,49,49,49,49,49,47,47,47,48,49,49,49,49,47,49,51,51,49,49,49,49,49,49,49,49,47,47,47,48,48,49,48,49,49,49,49,49,47,47,48,48,49,49,47,47,47,47,47,47,47,51,49,49,49,49,49,49,49,47,48,48,49,49,49,49,49,49,50,47,47,48,48,48,49,49,47,47,48,48,49,47,47,47,47,51,51,49,49,49,49,47,49,49,48,49,49,49,50,50,47,47,47,48,49,49,49,47,47,49,48,49,49,49,49,49,51,47,47,51,49,49,51,47,49,49,49,49,49,49,50,47,47,47,49,48,49,49,50,47,47,49,49,49,49,51,51,47,47,47,47,47,51,51,51,47,49,49,49,49,49,50,50,47,47,47,47,47,47,50,47,47,47,47,47,47,47,47,47,47,49,49,47,47,47,47,47,47,49,49,50,49,50,47,47,49,48,49,49,49,47,47,47,47,47,47,47,48,48,49,49,49,49,51,47,47,48,49,48,49,47,47,47,47,47,47,49,48,48,49,49,49,49,49,49,47,47,47,48,48,49,49,51,49,51,47,47,48,48,48,48,49,47,48,47,47,49,47,47,47,48,49,50,49,50,50,49,47,47,49,49,49,49,49,51,47,47,47,48,48,48,49,49,49,47,48,48,48,48,49,47,47,47,47,47,47,47,47,47,47,49,51,49,51,51,47,47,47,47,49,48,49,49,49,49,49,47,48,48,48,49,48,49,47,47,49,48,48,48,47,47,47,47,47,47,47,47,47,47,48,49,48,49,49,49,49,49,51,47,49,49,49,49,49,49,47,47,48,48,49,49,47,47,47,47,47,47,47,47,49,47,49,49,49,49,49,49,49,49,47,47,49,49,49,49,49,49,49,47,47,49,49,49,49,49,49,47,47,48,48,48,49,47,49,49,49,49,49,49,49,49,51,47,47,50,50,49,49,49,49,47,47,49,49,49,49,49,49,47,48,48,49,49,49,47,47,51,51,49,49,51,51,51,47,47,47,47,47,49,49,50,50,47,47,49,49,49,49,49,49,48,49,49,49,49,49,47,47,47,47,47,51,47,47,47,47,48,47,47,47,50,50,50,47,48,47,47,49,49,49,49,47,49,49,49,49,49,50,47,47,47,47,47,49,49,47,47,48,48,49,47,47,48,47,47,47,48,49,49,47,49,49,51,47,49,49,49,49,50,47,47,47,48,49,48,49,49,47,48,49,49,49,47,48,48,49,47,47,47,49,49,47,49,50,47,47,47,49,49,50,47,47,47,48,48,49,49,49,47,47,49,49,49,49,47,47,48,49,49,47,47,49,51,47,50,47,47,47,47,47,50,47,47,47,48,48,49,49,49,50,47,47,47,49,49,50,47,47,49,49,49,49,47,47,51,47,47,47,47,47,47,47,47,47,49,49,49,49,50,50,50,47,48,48,47,47,50,50,47,47,47,50,49,49,49,47,47,47,49,49,49,47,47,47,47,47,47,49,49,50,50,47,47,47,48,49,49,47,47,47,47,47,47,47,50,49,50,47,47,47,47,50,50,47,47,47,47,47,49,49,49,47,47,47,47,47,47,47,51,47,47,47,47,47,47,47,49,49,51,47,47,47,47,49,49,49];
        
var corrinaData = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,1,1,1,1,1,1,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,5,6,7,1,8,9,1,2,4,5,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,5,10,7,1,9,8,1,5,6,7,1,9,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,11,12,7,2,7,3,8,9,1,5,10,7,1,9,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,8,11,11,11,9,13,9,13,11,11,13,11,13,13,11,11,9,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,9,13,11,13,11,13,13,13,11,13,11,13,11,13,13,11,9,9,1,0,0,0,0,0,0,0,0,0,0,0,0,1,8,11,11,8,8,9,11,13,11,13,9,8,9,9,11,13,11,9,1,0,0,0,0,0,0,0,0,0,0,0,0,1,8,13,1,1,1,1,9,8,9,8,9,1,1,1,13,11,13,9,1,0,0,0,0,0,0,0,0,0,0,0,0,1,8,11,1,14,14,14,1,1,1,1,1,15,16,14,1,11,13,9,9,1,0,0,0,0,0,0,0,0,0,0,0,1,9,11,1,14,15,14,16,14,15,15,14,17,16,15,1,13,11,11,9,1,0,0,0,0,0,0,0,0,0,0,0,1,1,9,1,15,16,16,16,17,17,18,16,17,15,16,1,11,11,11,9,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,15,19,19,19,18,17,19,19,19,17,16,1,9,13,13,9,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,18,18,20,21,17,16,17,21,20,15,14,1,9,13,13,11,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,15,17,20,21,16,16,16,21,20,17,15,1,9,11,11,11,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,15,14,17,17,16,18,17,14,18,18,15,1,9,11,13,11,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,15,18,15,17,17,17,15,15,15,1,1,9,9,13,11,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,14,17,22,22,22,15,14,1,1,1,9,9,9,9,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,7,1,1,15,15,14,1,1,7,1,1,1,1,9,9,1,0,0,0,0,0,0,0,0,0,0,0,0,1,23,23,12,7,1,24,25,26,25,24,1,7,1,24,24,1,1,9,1,0,0,0,0,0,0,0,0,0,0,0,1,24,27,25,12,2,1,24,25,14,27,24,1,2,1,25,25,24,1,9,1,0,0,0,0,0,0,0,0,0,0,0,1,23,25,1,7,2,1,24,27,25,27,24,1,5,5,1,27,23,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,24,27,1,7,2,5,1,24,24,25,12,7,28,28,1,25,24,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,23,25,1,7,5,5,7,12,1,12,7,7,5,7,1,27,23,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,24,27,1,7,7,2,5,7,29,7,2,2,2,7,1,25,24,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,23,25,1,1,7,5,2,5,30,5,2,2,7,1,1,27,24,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,31,17,1,1,7,32,33,32,34,34,34,32,7,1,1,17,31,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,35,36,1,1,1,7,2,5,30,5,2,2,1,1,1,36,35,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,37,17,1,1,1,7,38,5,39,5,2,5,1,1,1,40,31,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,31,17,1,1,7,28,38,5,30,5,41,2,5,1,1,40,37,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,7,28,2,41,5,39,5,2,38,7,7,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,28,2,38,5,5,30,41,2,41,41,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,28,38,5,38,2,39,2,41,2,38,7,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,7,2,41,5,5,2,12,2,41,2,38,5,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,28,38,2,2,38,2,42,2,2,38,2,38,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,7,28,7,7,43,28,29,7,28,7,7,7,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,42,44,1,0,1,44,44,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,44,42,1,0,1,44,42,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,45,45,1,0,1,45,45,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,46,46,1,0,1,46,46,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,46,46,1,0,1,46,46,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0];

var sethData = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,58,58,59,58,59,58,58,59,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,58,60,58,60,58,58,58,58,58,58,58,60,58,58,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,58,58,58,60,58,61,61,58,61,58,61,59,58,61,61,60,58,59,1,0,0,0,0,0,0,0,0,0,0,0,0,1,60,58,61,61,59,61,59,61,59,61,61,59,61,59,61,58,60,58,1,0,0,0,0,0,0,0,0,0,0,0,0,1,58,58,61,61,61,61,59,59,59,59,59,59,61,59,61,59,61,58,58,0,0,0,0,0,0,0,0,0,0,0,1,58,58,60,59,59,61,61,59,59,59,61,59,61,59,61,61,59,61,60,58,1,0,0,0,0,0,0,0,0,0,0,1,60,58,61,61,59,58,59,61,61,58,59,61,61,61,61,59,61,58,58,59,1,0,0,0,0,0,0,0,0,0,0,1,60,59,58,58,58,59,61,58,60,58,58,58,59,58,58,58,58,58,58,58,1,0,0,0,0,0,0,0,0,0,0,1,58,58,61,58,59,1,58,60,1,1,1,58,58,58,1,1,1,58,59,58,1,0,0,0,0,0,0,0,0,0,0,0,1,1,58,1,1,62,1,1,62,63,62,1,58,1,62,63,62,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,62,63,62,62,62,62,62,63,62,1,62,62,64,63,64,62,1,0,0,0,0,0,0,0,0,0,0,0,0,1,62,62,63,63,63,64,62,64,63,64,64,63,64,64,63,64,62,64,1,0,0,0,0,0,0,0,0,0,0,0,0,1,62,65,64,1,1,1,1,1,64,63,1,1,1,1,1,63,62,62,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,20,20,20,1,1,3,1,20,20,20,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,62,62,1,20,66,20,1,63,63,1,20,66,20,1,62,64,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,65,64,1,1,1,1,1,63,64,1,1,1,1,1,64,62,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,62,64,63,63,64,63,63,64,63,64,64,63,64,63,63,62,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,62,62,64,64,64,63,64,64,63,64,63,64,64,62,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,62,64,63,64,63,64,64,62,62,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,66,66,1,63,62,63,64,63,63,62,1,66,66,67,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,67,67,67,66,66,1,63,62,63,62,3,68,66,66,67,67,67,69,1,1,0,0,0,0,0,0,0,0,0,1,67,67,67,69,69,67,66,66,1,1,1,1,1,66,66,67,67,70,69,67,67,71,1,0,0,0,0,0,0,0,1,67,69,69,70,70,67,70,67,67,1,66,20,66,1,67,69,70,70,67,70,70,70,67,67,1,0,0,0,0,0,0,1,67,69,70,67,68,70,70,69,67,1,66,72,66,1,71,69,69,70,69,68,67,70,70,71,1,0,0,0,0,0,1,67,70,70,69,67,1,67,67,70,71,1,73,74,66,1,69,70,70,71,67,1,67,69,70,70,69,1,0,0,0,0,1,67,69,70,69,67,1,71,70,1,67,1,66,72,66,1,67,1,70,67,70,1,71,69,67,70,71,1,0,0,0,1,67,69,70,69,67,67,1,69,70,69,69,1,66,20,66,1,69,70,71,67,67,1,67,67,69,70,71,67,1,0,0,1,67,69,70,67,67,1,1,67,70,70,67,1,66,74,66,1,67,70,70,69,67,1,1,67,67,70,70,67,1,0,0,1,67,67,67,67,1,1,1,69,70,1,67,1,66,20,66,1,71,1,70,67,71,1,1,1,70,69,69,71,1,0,0,1,1,1,1,1,1,1,1,67,70,69,1,1,66,20,73,1,67,70,70,67,67,1,1,1,67,67,67,69,1,0,0,1,66,66,66,66,1,1,1,67,69,67,1,66,66,72,66,1,67,69,70,69,71,1,1,1,1,1,1,1,1,0,0,1,66,1,1,1,1,1,1,71,70,69,1,73,20,20,66,1,67,70,70,67,71,1,1,1,66,66,66,66,1,0,0,1,1,64,63,64,64,63,1,67,70,67,1,66,74,20,66,1,67,69,70,69,71,1,63,1,1,1,1,66,1,0,0,0,1,64,64,63,63,62,1,67,69,67,1,1,1,1,66,1,1,67,67,69,67,1,62,64,63,64,1,1,0,0,0,0,1,62,63,64,64,62,1,67,67,1,1,75,75,76,66,66,1,1,67,69,67,1,62,63,64,65,62,1,0,0,0,0,0,1,62,62,1,1,1,1,1,1,76,76,77,76,76,75,78,1,69,67,1,1,1,1,62,63,1,0,0,0,0,0,0,0,1,1,0,0,1,76,75,76,78,77,1,1,1,1,77,75,1,1,75,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,75,76,77,77,75,1,1,1,1,76,77,77,78,75,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,78,77,76,76,75,1,1,1,1,76,75,77,77,76,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,75,77,77,75,75,1,1,1,1,76,77,77,75,75,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,76,75,76,76,75,1,1,1,1,75,76,75,76,75,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,75,75,75,75,76,1,1,1,1,75,75,76,75,75,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,66,12,66,73,66,66,1,1,1,1,66,66,73,12,66,66,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0];
var HuffmanTableBuilder = function() {};
 
// Calculates histogram data needed to build huffman table
// TODO(richard-to): Dynamically figure out max Table size instead?
//                   Would require looping through data an extra time.
HuffmanTableBuilder.prototype._buildHistogram = function(dataList, maxValue) {
    
    var histogram = [];
    var orderedIndex = [];
    var orderedDist = [];            
    var max = 0;
    var count = 0.0;
 
    // Allocate default array of X length to 0
    for (var i = 0; i < maxValue; ++i) {
        histogram.push(0);
        orderedIndex.push(i);
    }
 
    // Count data points in list of data arrays
    for (var i = 0; i < dataList.length; ++i) {
        count += dataList[i].length;
    }
 
    // Populate histogram and find highest value in histogram
    // Note that highest value is not the value with the most occurences
    for (var i = 0; i < dataList.length; ++i) {
        var data = dataList[i];
        for (var g = 0; g < data.length; ++g) {
            ++histogram[data[g]];
            if (data[g] > max) {
                max = data[g];
            }
        }
    }
    
    // Sort pixels based on histogram counts
    orderedIndex.sort(function(a, b) {
        return histogram[b] - histogram[a];
    });
 
    // Sort distribution based on counts and calculate percentage as rounded int
    // Example: .885 will equal 89
    for (var i = 0; i < orderedIndex.length; ++i) {
        orderedDist.push(Math.round((histogram[orderedIndex[i]] / count) * 100));
    }
 
    return {
        data: histogram,
        orderedIndex: orderedIndex,
        orderedDist: orderedDist,
        max: max,
        count: count
    };            
};
 
// Recursively run Huffman algorithm to encoding table
// Probably not as efficient as it could be...
HuffmanTableBuilder.prototype._huffman = function(dist, codeKeys) {
    var codeKeysLen = codeKeys.length;
    var length = dist.length;
 
    // If number of values in sub distribution matches
    // the number of code keys, then we can stop.
    //
    // It is very important to make sure the distribution
    // array ends exactly at the number of keys or an 
    // error will be thrown.
    if (length == codeKeysLen) {
        return codeKeys.slice(0);
    } else {
 
        // First get the distribution minus the X lowest
        // values that we will sum together
        var subDist = dist.slice(0, -codeKeysLen);
        var subDistLen = subDist.length;
        var index = subDistLen;                
        var value = 0;
        
        // Add X values to form one value
        for (var i = 1; i <= codeKeysLen; ++i) {
            value += dist[length - i];
        }
        
        // Now let's place it in the right place
        // in the array
        //
        // Definitely think there is a more efficient
        // way to do this part.
        for (var i = 0; i < subDistLen; ++i) {
            if (value > subDist[i]) {
                subDist.splice(i, 0, value);
                index = i;
                break;
            }
        }
 
        // If we could not find a spot for the new
        // value, will place it as the end of the array
        if (subDist.length == subDistLen) {
            subDist.push(value);
        }
 
        // Recursively call _huffman again
        var codeTable = this._huffman(subDist, codeKeys);
 
        // Now build up the code table from previous results
        var code = codeTable.splice(index, 1);                
        for (var i = 0; i < codeKeysLen; ++i) {
            codeTable.push(code + codeKeys[i]);
        }
 
        return codeTable;
    }
};
 
HuffmanTableBuilder.prototype._buildDecoderTable = function(encoderTable) {
    var decoderTable = {};
    for (var i = 0; i < encoderTable.length; ++i) {
        decoderTable[encoderTable[i]] = i;
    }
    return decoderTable;
};
 
HuffmanTableBuilder.prototype._organizeEncoderTable = function(orderedIndex, codeTable) {
    var encoderTable = [];
    for (var i = 0; i < codeTable.length; ++i) {
        encoderTable[orderedIndex[i]] = codeTable[i];
    }
    return encoderTable;
};
 
HuffmanTableBuilder.prototype.build = function(dataList, codeKeys, maxValue) {
 
    codeKeysLen = codeKeys.length - 1;           
    var histogram = this._buildHistogram(dataList, maxValue);
 
 
    // Need to pad ordered histogram dist to make sure
    // the final step leads to [codeKeysLen + 1] array
    // values left.
    //
    // This currently doesn't work in the 
    // case where you have all values used. It should
    // then extend the array with enough 0 values,
    // but doesn't current do that.
    var slicePoint = codeKeysLen + 1;
    while (histogram.max > slicePoint) {
        slicePoint += codeKeysLen;
    }
 
    // This returns the huffman table with the data indexes ordered
    // For this to work we need to match the code values
    // with the appropriate array index
    var codeTable = this._huffman(
        histogram.orderedDist.slice(0, slicePoint), codeKeys);
 
    var encoderTable = this._organizeEncoderTable(
        histogram.orderedIndex, codeTable);
 
    // Build a table for decoding the encoded result
    var decoderTable = this._buildDecoderTable(encoderTable);                        
 
    return {
        encoderTable: encoderTable,
        decoderTable: decoderTable 
    };
};  
 
var Huffman = {
    encode: function(data, encoderTable) {
        var encodedString = "";
        for (var i = 0; i < data.length; ++i) {
            encodedString += encoderTable[data[i]];
        }
        return encodedString;
    },
    decode: function(encodedData, decoderTable) {
        var decodedData = [];
        var currentKey = "";                
        for (var i = 0; i < encodedData.length; ++i) {
            currentKey += encodedData[i];
            if (decoderTable[currentKey] !== undefined) {
                decodedData.push(decoderTable[currentKey]);
                currentKey = "";
            }
        }
        return decodedData;
    },
    verify: function(originalData, decodedData) {
        if (decodedData.length != originalData.length) {
            return false;
        }
 
        for (var i = 0; i < decodedData.length; ++i) {
            if (decodedData[i] != originalData[i]) {
                return false;
            }
        }
        return true;
    }
};
var dataList = [waterData, cliffData, grassData, corrinaData, sethData];
 
var maxValue = 255;
var codeKeys = [
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
    "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z"];        
 
var huffmanTableBuilder = new HuffmanTableBuilder();
var huffmanTables = huffmanTableBuilder.build(dataList, codeKeys, maxValue);
for (var i = 0; i < dataList.length; ++i) {
    var encodedData = Huffman.encode(dataList[i], huffmanTables.encoderTable);
    var decodedData = Huffman.decode(encodedData, huffmanTables.decoderTable);            
    var valid = Huffman.verify(dataList[i], decodedData);
    console.log("Unencoded data length: " + dataList[i].length);
    console.log("Encoded data length: " + encodedData.length);
    console.log("Valid Encoding: " + valid);
}