lzw.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. define("dojox/encoding/compression/lzw", [
  2. "dojo/_base/lang", // dojo.extend
  3. "../bits"
  4. ], function(lang, bits) {
  5. var lzw = lang.getObject("dojox.encoding.compression.lzw", true);
  6. /*=====
  7. lzw = dojox.encoding.compression.lzw;
  8. =====*/
  9. var _bits = function(x){
  10. var w = 1;
  11. for(var v = 2; x >= v; v <<= 1, ++w);
  12. return w;
  13. };
  14. lzw.Encoder = function(n){
  15. this.size = n;
  16. this.init();
  17. };
  18. lang.extend(lzw.Encoder, {
  19. init: function(){
  20. this.dict = {};
  21. for(var i = 0; i < this.size; ++i){
  22. this.dict[String.fromCharCode(i)] = i;
  23. }
  24. this.width = _bits(this.code = this.size);
  25. this.p = "";
  26. },
  27. encode: function(value, stream){
  28. var c = String.fromCharCode(value), p = this.p + c, r = 0;
  29. // if already in the dictionary
  30. if(p in this.dict){
  31. this.p = p;
  32. return r;
  33. }
  34. stream.putBits(this.dict[this.p], this.width);
  35. // if we need to increase the code length
  36. if((this.code & (this.code + 1)) == 0){
  37. stream.putBits(this.code++, r = this.width++);
  38. }
  39. // add new string
  40. this.dict[p] = this.code++;
  41. this.p = c;
  42. return r + this.width;
  43. },
  44. flush: function(stream){
  45. if(this.p.length == 0){
  46. return 0;
  47. }
  48. stream.putBits(this.dict[this.p], this.width);
  49. this.p = "";
  50. return this.width;
  51. }
  52. });
  53. lzw.Decoder = function(n){
  54. this.size = n;
  55. this.init();
  56. };
  57. lang.extend(lzw.Decoder, {
  58. init: function(){
  59. this.codes = new Array(this.size);
  60. for(var i = 0; i < this.size; ++i){
  61. this.codes[i] = String.fromCharCode(i);
  62. }
  63. this.width = _bits(this.size);
  64. this.p = -1;
  65. },
  66. decode: function(stream){
  67. var c = stream.getBits(this.width), v;
  68. if(c < this.codes.length){
  69. v = this.codes[c];
  70. if(this.p >= 0){
  71. this.codes.push(this.codes[this.p] + v.substr(0, 1));
  72. }
  73. }else{
  74. if((c & (c + 1)) == 0){
  75. this.codes.push("");
  76. ++this.width;
  77. return "";
  78. }
  79. var x = this.codes[this.p];
  80. v = x + x.substr(0, 1);
  81. this.codes.push(v);
  82. }
  83. this.p = c;
  84. return v;
  85. }
  86. });
  87. return lzw;
  88. });