PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/js/ctm/lzma.js

http://github.com/mrdoob/three.js
JavaScript | 510 lines | 418 code | 92 blank | 0 comment | 48 complexity | bb8e7414f707bfd6e7ae94437cf90d56 MD5 | raw file
Possible License(s): MIT, CC-BY-3.0, Apache-2.0
  1. var LZMA = LZMA || {};
  2. LZMA.OutWindow = function(){
  3. this._windowSize = 0;
  4. };
  5. LZMA.OutWindow.prototype.create = function(windowSize){
  6. if ( (!this._buffer) || (this._windowSize !== windowSize) ){
  7. this._buffer = [];
  8. }
  9. this._windowSize = windowSize;
  10. this._pos = 0;
  11. this._streamPos = 0;
  12. };
  13. LZMA.OutWindow.prototype.flush = function(){
  14. var size = this._pos - this._streamPos;
  15. if (size !== 0){
  16. while(size --){
  17. this._stream.writeByte(this._buffer[this._streamPos ++]);
  18. }
  19. if (this._pos >= this._windowSize){
  20. this._pos = 0;
  21. }
  22. this._streamPos = this._pos;
  23. }
  24. };
  25. LZMA.OutWindow.prototype.releaseStream = function(){
  26. this.flush();
  27. this._stream = null;
  28. };
  29. LZMA.OutWindow.prototype.setStream = function(stream){
  30. this.releaseStream();
  31. this._stream = stream;
  32. };
  33. LZMA.OutWindow.prototype.init = function(solid){
  34. if (!solid){
  35. this._streamPos = 0;
  36. this._pos = 0;
  37. }
  38. };
  39. LZMA.OutWindow.prototype.copyBlock = function(distance, len){
  40. var pos = this._pos - distance - 1;
  41. if (pos < 0){
  42. pos += this._windowSize;
  43. }
  44. while(len --){
  45. if (pos >= this._windowSize){
  46. pos = 0;
  47. }
  48. this._buffer[this._pos ++] = this._buffer[pos ++];
  49. if (this._pos >= this._windowSize){
  50. this.flush();
  51. }
  52. }
  53. };
  54. LZMA.OutWindow.prototype.putByte = function(b){
  55. this._buffer[this._pos ++] = b;
  56. if (this._pos >= this._windowSize){
  57. this.flush();
  58. }
  59. };
  60. LZMA.OutWindow.prototype.getByte = function(distance){
  61. var pos = this._pos - distance - 1;
  62. if (pos < 0){
  63. pos += this._windowSize;
  64. }
  65. return this._buffer[pos];
  66. };
  67. LZMA.RangeDecoder = function(){
  68. };
  69. LZMA.RangeDecoder.prototype.setStream = function(stream){
  70. this._stream = stream;
  71. };
  72. LZMA.RangeDecoder.prototype.releaseStream = function(){
  73. this._stream = null;
  74. };
  75. LZMA.RangeDecoder.prototype.init = function(){
  76. var i = 5;
  77. this._code = 0;
  78. this._range = -1;
  79. while(i --){
  80. this._code = (this._code << 8) | this._stream.readByte();
  81. }
  82. };
  83. LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits){
  84. var result = 0, i = numTotalBits, t;
  85. while(i --){
  86. this._range >>>= 1;
  87. t = (this._code - this._range) >>> 31;
  88. this._code -= this._range & (t - 1);
  89. result = (result << 1) | (1 - t);
  90. if ( (this._range & 0xff000000) === 0){
  91. this._code = (this._code << 8) | this._stream.readByte();
  92. this._range <<= 8;
  93. }
  94. }
  95. return result;
  96. };
  97. LZMA.RangeDecoder.prototype.decodeBit = function(probs, index){
  98. var prob = probs[index],
  99. newBound = (this._range >>> 11) * prob;
  100. if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ){
  101. this._range = newBound;
  102. probs[index] += (2048 - prob) >>> 5;
  103. if ( (this._range & 0xff000000) === 0){
  104. this._code = (this._code << 8) | this._stream.readByte();
  105. this._range <<= 8;
  106. }
  107. return 0;
  108. }
  109. this._range -= newBound;
  110. this._code -= newBound;
  111. probs[index] -= prob >>> 5;
  112. if ( (this._range & 0xff000000) === 0){
  113. this._code = (this._code << 8) | this._stream.readByte();
  114. this._range <<= 8;
  115. }
  116. return 1;
  117. };
  118. LZMA.initBitModels = function(probs, len){
  119. while(len --){
  120. probs[len] = 1024;
  121. }
  122. };
  123. LZMA.BitTreeDecoder = function(numBitLevels){
  124. this._models = [];
  125. this._numBitLevels = numBitLevels;
  126. };
  127. LZMA.BitTreeDecoder.prototype.init = function(){
  128. LZMA.initBitModels(this._models, 1 << this._numBitLevels);
  129. };
  130. LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder){
  131. var m = 1, i = this._numBitLevels;
  132. while(i --){
  133. m = (m << 1) | rangeDecoder.decodeBit(this._models, m);
  134. }
  135. return m - (1 << this._numBitLevels);
  136. };
  137. LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder){
  138. var m = 1, symbol = 0, i = 0, bit;
  139. for (; i < this._numBitLevels; ++ i){
  140. bit = rangeDecoder.decodeBit(this._models, m);
  141. m = (m << 1) | bit;
  142. symbol |= bit << i;
  143. }
  144. return symbol;
  145. };
  146. LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels){
  147. var m = 1, symbol = 0, i = 0, bit;
  148. for (; i < numBitLevels; ++ i){
  149. bit = rangeDecoder.decodeBit(models, startIndex + m);
  150. m = (m << 1) | bit;
  151. symbol |= bit << i;
  152. }
  153. return symbol;
  154. };
  155. LZMA.LenDecoder = function(){
  156. this._choice = [];
  157. this._lowCoder = [];
  158. this._midCoder = [];
  159. this._highCoder = new LZMA.BitTreeDecoder(8);
  160. this._numPosStates = 0;
  161. };
  162. LZMA.LenDecoder.prototype.create = function(numPosStates){
  163. for (; this._numPosStates < numPosStates; ++ this._numPosStates){
  164. this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
  165. this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
  166. }
  167. };
  168. LZMA.LenDecoder.prototype.init = function(){
  169. var i = this._numPosStates;
  170. LZMA.initBitModels(this._choice, 2);
  171. while(i --){
  172. this._lowCoder[i].init();
  173. this._midCoder[i].init();
  174. }
  175. this._highCoder.init();
  176. };
  177. LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState){
  178. if (rangeDecoder.decodeBit(this._choice, 0) === 0){
  179. return this._lowCoder[posState].decode(rangeDecoder);
  180. }
  181. if (rangeDecoder.decodeBit(this._choice, 1) === 0){
  182. return 8 + this._midCoder[posState].decode(rangeDecoder);
  183. }
  184. return 16 + this._highCoder.decode(rangeDecoder);
  185. };
  186. LZMA.Decoder2 = function(){
  187. this._decoders = [];
  188. };
  189. LZMA.Decoder2.prototype.init = function(){
  190. LZMA.initBitModels(this._decoders, 0x300);
  191. };
  192. LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder){
  193. var symbol = 1;
  194. do{
  195. symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
  196. }while(symbol < 0x100);
  197. return symbol & 0xff;
  198. };
  199. LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte){
  200. var symbol = 1, matchBit, bit;
  201. do{
  202. matchBit = (matchByte >> 7) & 1;
  203. matchByte <<= 1;
  204. bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol);
  205. symbol = (symbol << 1) | bit;
  206. if (matchBit !== bit){
  207. while(symbol < 0x100){
  208. symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
  209. }
  210. break;
  211. }
  212. }while(symbol < 0x100);
  213. return symbol & 0xff;
  214. };
  215. LZMA.LiteralDecoder = function(){
  216. };
  217. LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits){
  218. var i;
  219. if (this._coders
  220. && (this._numPrevBits === numPrevBits)
  221. && (this._numPosBits === numPosBits) ){
  222. return;
  223. }
  224. this._numPosBits = numPosBits;
  225. this._posMask = (1 << numPosBits) - 1;
  226. this._numPrevBits = numPrevBits;
  227. this._coders = [];
  228. i = 1 << (this._numPrevBits + this._numPosBits);
  229. while(i --){
  230. this._coders[i] = new LZMA.Decoder2();
  231. }
  232. };
  233. LZMA.LiteralDecoder.prototype.init = function(){
  234. var i = 1 << (this._numPrevBits + this._numPosBits);
  235. while(i --){
  236. this._coders[i].init();
  237. }
  238. };
  239. LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte){
  240. return this._coders[( (pos & this._posMask) << this._numPrevBits)
  241. + ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )];
  242. };
  243. LZMA.Decoder = function(){
  244. this._outWindow = new LZMA.OutWindow();
  245. this._rangeDecoder = new LZMA.RangeDecoder();
  246. this._isMatchDecoders = [];
  247. this._isRepDecoders = [];
  248. this._isRepG0Decoders = [];
  249. this._isRepG1Decoders = [];
  250. this._isRepG2Decoders = [];
  251. this._isRep0LongDecoders = [];
  252. this._posSlotDecoder = [];
  253. this._posDecoders = [];
  254. this._posAlignDecoder = new LZMA.BitTreeDecoder(4);
  255. this._lenDecoder = new LZMA.LenDecoder();
  256. this._repLenDecoder = new LZMA.LenDecoder();
  257. this._literalDecoder = new LZMA.LiteralDecoder();
  258. this._dictionarySize = -1;
  259. this._dictionarySizeCheck = -1;
  260. this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6);
  261. this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6);
  262. this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6);
  263. this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6);
  264. };
  265. LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize){
  266. if (dictionarySize < 0){
  267. return false;
  268. }
  269. if (this._dictionarySize !== dictionarySize){
  270. this._dictionarySize = dictionarySize;
  271. this._dictionarySizeCheck = Math.max(this._dictionarySize, 1);
  272. this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) );
  273. }
  274. return true;
  275. };
  276. LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb){
  277. var numPosStates = 1 << pb;
  278. if (lc > 8 || lp > 4 || pb > 4){
  279. return false;
  280. }
  281. this._literalDecoder.create(lp, lc);
  282. this._lenDecoder.create(numPosStates);
  283. this._repLenDecoder.create(numPosStates);
  284. this._posStateMask = numPosStates - 1;
  285. return true;
  286. };
  287. LZMA.Decoder.prototype.init = function(){
  288. var i = 4;
  289. this._outWindow.init(false);
  290. LZMA.initBitModels(this._isMatchDecoders, 192);
  291. LZMA.initBitModels(this._isRep0LongDecoders, 192);
  292. LZMA.initBitModels(this._isRepDecoders, 12);
  293. LZMA.initBitModels(this._isRepG0Decoders, 12);
  294. LZMA.initBitModels(this._isRepG1Decoders, 12);
  295. LZMA.initBitModels(this._isRepG2Decoders, 12);
  296. LZMA.initBitModels(this._posDecoders, 114);
  297. this._literalDecoder.init();
  298. while(i --){
  299. this._posSlotDecoder[i].init();
  300. }
  301. this._lenDecoder.init();
  302. this._repLenDecoder.init();
  303. this._posAlignDecoder.init();
  304. this._rangeDecoder.init();
  305. };
  306. LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize){
  307. var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0,
  308. posState, decoder2, len, distance, posSlot, numDirectBits;
  309. this._rangeDecoder.setStream(inStream);
  310. this._outWindow.setStream(outStream);
  311. this.init();
  312. while(outSize < 0 || nowPos64 < outSize){
  313. posState = nowPos64 & this._posStateMask;
  314. if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0){
  315. decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte);
  316. if (state >= 7){
  317. prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) );
  318. }else{
  319. prevByte = decoder2.decodeNormal(this._rangeDecoder);
  320. }
  321. this._outWindow.putByte(prevByte);
  322. state = state < 4? 0: state - (state < 10? 3: 6);
  323. }else{
  324. if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1){
  325. len = 0;
  326. if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0){
  327. if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0){
  328. state = state < 7? 9: 11;
  329. len = 1;
  330. }
  331. }else{
  332. if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0){
  333. distance = rep1;
  334. }else{
  335. if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0){
  336. distance = rep2;
  337. }else{
  338. distance = rep3;
  339. rep3 = rep2;
  340. }
  341. rep2 = rep1;
  342. }
  343. rep1 = rep0;
  344. rep0 = distance;
  345. }
  346. if (len === 0){
  347. len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState);
  348. state = state < 7? 8: 11;
  349. }
  350. }else{
  351. rep3 = rep2;
  352. rep2 = rep1;
  353. rep1 = rep0;
  354. len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState);
  355. state = state < 7? 7: 10;
  356. posSlot = this._posSlotDecoder[len <= 5? len - 2: 3].decode(this._rangeDecoder);
  357. if (posSlot >= 4){
  358. numDirectBits = (posSlot >> 1) - 1;
  359. rep0 = (2 | (posSlot & 1) ) << numDirectBits;
  360. if (posSlot < 14){
  361. rep0 += LZMA.reverseDecode2(this._posDecoders,
  362. rep0 - posSlot - 1, this._rangeDecoder, numDirectBits);
  363. }else{
  364. rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4;
  365. rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder);
  366. if (rep0 < 0){
  367. if (rep0 === -1){
  368. break;
  369. }
  370. return false;
  371. }
  372. }
  373. }else{
  374. rep0 = posSlot;
  375. }
  376. }
  377. if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck){
  378. return false;
  379. }
  380. this._outWindow.copyBlock(rep0, len);
  381. nowPos64 += len;
  382. prevByte = this._outWindow.getByte(0);
  383. }
  384. }
  385. this._outWindow.flush();
  386. this._outWindow.releaseStream();
  387. this._rangeDecoder.releaseStream();
  388. return true;
  389. };
  390. LZMA.Decoder.prototype.setDecoderProperties = function(properties){
  391. var value, lc, lp, pb, dictionarySize;
  392. if (properties.size < 5){
  393. return false;
  394. }
  395. value = properties.readByte();
  396. lc = value % 9;
  397. value = ~~(value / 9);
  398. lp = value % 5;
  399. pb = ~~(value / 5);
  400. if ( !this.setLcLpPb(lc, lp, pb) ){
  401. return false;
  402. }
  403. dictionarySize = properties.readByte();
  404. dictionarySize |= properties.readByte() << 8;
  405. dictionarySize |= properties.readByte() << 16;
  406. dictionarySize += properties.readByte() * 16777216;
  407. return this.setDictionarySize(dictionarySize);
  408. };
  409. LZMA.decompress = function(properties, inStream, outStream, outSize){
  410. var decoder = new LZMA.Decoder();
  411. if ( !decoder.setDecoderProperties(properties) ){
  412. throw "Incorrect stream properties";
  413. }
  414. if ( !decoder.decode(inStream, outStream, outSize) ){
  415. throw "Error in data stream";
  416. }
  417. return true;
  418. };