SEA3DLZMA.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. /*
  2. Copyright (c) 2011 Juan Mellado
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. /*
  20. References:
  21. - "LZMA SDK" by Igor Pavlov
  22. http://www.7-zip.org/sdk.html
  23. */
  24. var LZMA = LZMA || {};
  25. LZMA.OutWindow = function(){
  26. this._windowSize = 0;
  27. };
  28. LZMA.OutWindow.prototype.create = function(windowSize){
  29. if ( (!this._buffer) || (this._windowSize !== windowSize) ){
  30. this._buffer = [];
  31. }
  32. this._windowSize = windowSize;
  33. this._pos = 0;
  34. this._streamPos = 0;
  35. };
  36. LZMA.OutWindow.prototype.flush = function(){
  37. var size = this._pos - this._streamPos;
  38. if (size !== 0){
  39. while(size --){
  40. this._stream.writeByte(this._buffer[this._streamPos ++]);
  41. }
  42. if (this._pos >= this._windowSize){
  43. this._pos = 0;
  44. }
  45. this._streamPos = this._pos;
  46. }
  47. };
  48. LZMA.OutWindow.prototype.releaseStream = function(){
  49. this.flush();
  50. this._stream = null;
  51. };
  52. LZMA.OutWindow.prototype.setStream = function(stream){
  53. this.releaseStream();
  54. this._stream = stream;
  55. };
  56. LZMA.OutWindow.prototype.init = function(solid){
  57. if (!solid){
  58. this._streamPos = 0;
  59. this._pos = 0;
  60. }
  61. };
  62. LZMA.OutWindow.prototype.copyBlock = function(distance, len){
  63. var pos = this._pos - distance - 1;
  64. if (pos < 0){
  65. pos += this._windowSize;
  66. }
  67. while(len --){
  68. if (pos >= this._windowSize){
  69. pos = 0;
  70. }
  71. this._buffer[this._pos ++] = this._buffer[pos ++];
  72. if (this._pos >= this._windowSize){
  73. this.flush();
  74. }
  75. }
  76. };
  77. LZMA.OutWindow.prototype.putByte = function(b){
  78. this._buffer[this._pos ++] = b;
  79. if (this._pos >= this._windowSize){
  80. this.flush();
  81. }
  82. };
  83. LZMA.OutWindow.prototype.getByte = function(distance){
  84. var pos = this._pos - distance - 1;
  85. if (pos < 0){
  86. pos += this._windowSize;
  87. }
  88. return this._buffer[pos];
  89. };
  90. LZMA.RangeDecoder = function(){
  91. };
  92. LZMA.RangeDecoder.prototype.setStream = function(stream){
  93. this._stream = stream;
  94. };
  95. LZMA.RangeDecoder.prototype.releaseStream = function(){
  96. this._stream = null;
  97. };
  98. LZMA.RangeDecoder.prototype.init = function(){
  99. var i = 5;
  100. this._code = 0;
  101. this._range = -1;
  102. while(i --){
  103. this._code = (this._code << 8) | this._stream.readByte();
  104. }
  105. };
  106. LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits){
  107. var result = 0, i = numTotalBits, t;
  108. while(i --){
  109. this._range >>>= 1;
  110. t = (this._code - this._range) >>> 31;
  111. this._code -= this._range & (t - 1);
  112. result = (result << 1) | (1 - t);
  113. if ( (this._range & 0xff000000) === 0){
  114. this._code = (this._code << 8) | this._stream.readByte();
  115. this._range <<= 8;
  116. }
  117. }
  118. return result;
  119. };
  120. LZMA.RangeDecoder.prototype.decodeBit = function(probs, index){
  121. var prob = probs[index],
  122. newBound = (this._range >>> 11) * prob;
  123. if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ){
  124. this._range = newBound;
  125. probs[index] += (2048 - prob) >>> 5;
  126. if ( (this._range & 0xff000000) === 0){
  127. this._code = (this._code << 8) | this._stream.readByte();
  128. this._range <<= 8;
  129. }
  130. return 0;
  131. }
  132. this._range -= newBound;
  133. this._code -= newBound;
  134. probs[index] -= prob >>> 5;
  135. if ( (this._range & 0xff000000) === 0){
  136. this._code = (this._code << 8) | this._stream.readByte();
  137. this._range <<= 8;
  138. }
  139. return 1;
  140. };
  141. LZMA.initBitModels = function(probs, len){
  142. while(len --){
  143. probs[len] = 1024;
  144. }
  145. };
  146. LZMA.BitTreeDecoder = function(numBitLevels){
  147. this._models = [];
  148. this._numBitLevels = numBitLevels;
  149. };
  150. LZMA.BitTreeDecoder.prototype.init = function(){
  151. LZMA.initBitModels(this._models, 1 << this._numBitLevels);
  152. };
  153. LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder){
  154. var m = 1, i = this._numBitLevels;
  155. while(i --){
  156. m = (m << 1) | rangeDecoder.decodeBit(this._models, m);
  157. }
  158. return m - (1 << this._numBitLevels);
  159. };
  160. LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder){
  161. var m = 1, symbol = 0, i = 0, bit;
  162. for (; i < this._numBitLevels; ++ i){
  163. bit = rangeDecoder.decodeBit(this._models, m);
  164. m = (m << 1) | bit;
  165. symbol |= bit << i;
  166. }
  167. return symbol;
  168. };
  169. LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels){
  170. var m = 1, symbol = 0, i = 0, bit;
  171. for (; i < numBitLevels; ++ i){
  172. bit = rangeDecoder.decodeBit(models, startIndex + m);
  173. m = (m << 1) | bit;
  174. symbol |= bit << i;
  175. }
  176. return symbol;
  177. };
  178. LZMA.LenDecoder = function(){
  179. this._choice = [];
  180. this._lowCoder = [];
  181. this._midCoder = [];
  182. this._highCoder = new LZMA.BitTreeDecoder(8);
  183. this._numPosStates = 0;
  184. };
  185. LZMA.LenDecoder.prototype.create = function(numPosStates){
  186. for (; this._numPosStates < numPosStates; ++ this._numPosStates){
  187. this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
  188. this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
  189. }
  190. };
  191. LZMA.LenDecoder.prototype.init = function(){
  192. var i = this._numPosStates;
  193. LZMA.initBitModels(this._choice, 2);
  194. while(i --){
  195. this._lowCoder[i].init();
  196. this._midCoder[i].init();
  197. }
  198. this._highCoder.init();
  199. };
  200. LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState){
  201. if (rangeDecoder.decodeBit(this._choice, 0) === 0){
  202. return this._lowCoder[posState].decode(rangeDecoder);
  203. }
  204. if (rangeDecoder.decodeBit(this._choice, 1) === 0){
  205. return 8 + this._midCoder[posState].decode(rangeDecoder);
  206. }
  207. return 16 + this._highCoder.decode(rangeDecoder);
  208. };
  209. LZMA.Decoder2 = function(){
  210. this._decoders = [];
  211. };
  212. LZMA.Decoder2.prototype.init = function(){
  213. LZMA.initBitModels(this._decoders, 0x300);
  214. };
  215. LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder){
  216. var symbol = 1;
  217. do{
  218. symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
  219. }while(symbol < 0x100);
  220. return symbol & 0xff;
  221. };
  222. LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte){
  223. var symbol = 1, matchBit, bit;
  224. do{
  225. matchBit = (matchByte >> 7) & 1;
  226. matchByte <<= 1;
  227. bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol);
  228. symbol = (symbol << 1) | bit;
  229. if (matchBit !== bit){
  230. while(symbol < 0x100){
  231. symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
  232. }
  233. break;
  234. }
  235. }while(symbol < 0x100);
  236. return symbol & 0xff;
  237. };
  238. LZMA.LiteralDecoder = function(){
  239. };
  240. LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits){
  241. var i;
  242. if (this._coders
  243. && (this._numPrevBits === numPrevBits)
  244. && (this._numPosBits === numPosBits) ){
  245. return;
  246. }
  247. this._numPosBits = numPosBits;
  248. this._posMask = (1 << numPosBits) - 1;
  249. this._numPrevBits = numPrevBits;
  250. this._coders = [];
  251. i = 1 << (this._numPrevBits + this._numPosBits);
  252. while(i --){
  253. this._coders[i] = new LZMA.Decoder2();
  254. }
  255. };
  256. LZMA.LiteralDecoder.prototype.init = function(){
  257. var i = 1 << (this._numPrevBits + this._numPosBits);
  258. while(i --){
  259. this._coders[i].init();
  260. }
  261. };
  262. LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte){
  263. return this._coders[( (pos & this._posMask) << this._numPrevBits)
  264. + ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )];
  265. };
  266. LZMA.Decoder = function(){
  267. this._outWindow = new LZMA.OutWindow();
  268. this._rangeDecoder = new LZMA.RangeDecoder();
  269. this._isMatchDecoders = [];
  270. this._isRepDecoders = [];
  271. this._isRepG0Decoders = [];
  272. this._isRepG1Decoders = [];
  273. this._isRepG2Decoders = [];
  274. this._isRep0LongDecoders = [];
  275. this._posSlotDecoder = [];
  276. this._posDecoders = [];
  277. this._posAlignDecoder = new LZMA.BitTreeDecoder(4);
  278. this._lenDecoder = new LZMA.LenDecoder();
  279. this._repLenDecoder = new LZMA.LenDecoder();
  280. this._literalDecoder = new LZMA.LiteralDecoder();
  281. this._dictionarySize = -1;
  282. this._dictionarySizeCheck = -1;
  283. this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6);
  284. this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6);
  285. this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6);
  286. this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6);
  287. };
  288. LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize){
  289. if (dictionarySize < 0){
  290. return false;
  291. }
  292. if (this._dictionarySize !== dictionarySize){
  293. this._dictionarySize = dictionarySize;
  294. this._dictionarySizeCheck = Math.max(this._dictionarySize, 1);
  295. this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) );
  296. }
  297. return true;
  298. };
  299. LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb){
  300. var numPosStates = 1 << pb;
  301. if (lc > 8 || lp > 4 || pb > 4){
  302. return false;
  303. }
  304. this._literalDecoder.create(lp, lc);
  305. this._lenDecoder.create(numPosStates);
  306. this._repLenDecoder.create(numPosStates);
  307. this._posStateMask = numPosStates - 1;
  308. return true;
  309. };
  310. LZMA.Decoder.prototype.init = function(){
  311. var i = 4;
  312. this._outWindow.init(false);
  313. LZMA.initBitModels(this._isMatchDecoders, 192);
  314. LZMA.initBitModels(this._isRep0LongDecoders, 192);
  315. LZMA.initBitModels(this._isRepDecoders, 12);
  316. LZMA.initBitModels(this._isRepG0Decoders, 12);
  317. LZMA.initBitModels(this._isRepG1Decoders, 12);
  318. LZMA.initBitModels(this._isRepG2Decoders, 12);
  319. LZMA.initBitModels(this._posDecoders, 114);
  320. this._literalDecoder.init();
  321. while(i --){
  322. this._posSlotDecoder[i].init();
  323. }
  324. this._lenDecoder.init();
  325. this._repLenDecoder.init();
  326. this._posAlignDecoder.init();
  327. this._rangeDecoder.init();
  328. };
  329. LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize){
  330. var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0,
  331. posState, decoder2, len, distance, posSlot, numDirectBits;
  332. this._rangeDecoder.setStream(inStream);
  333. this._outWindow.setStream(outStream);
  334. this.init();
  335. while(outSize < 0 || nowPos64 < outSize){
  336. posState = nowPos64 & this._posStateMask;
  337. if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0){
  338. decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte);
  339. if (state >= 7){
  340. prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) );
  341. }else{
  342. prevByte = decoder2.decodeNormal(this._rangeDecoder);
  343. }
  344. this._outWindow.putByte(prevByte);
  345. state = state < 4? 0: state - (state < 10? 3: 6);
  346. }else{
  347. if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1){
  348. len = 0;
  349. if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0){
  350. if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0){
  351. state = state < 7? 9: 11;
  352. len = 1;
  353. }
  354. }else{
  355. if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0){
  356. distance = rep1;
  357. }else{
  358. if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0){
  359. distance = rep2;
  360. }else{
  361. distance = rep3;
  362. rep3 = rep2;
  363. }
  364. rep2 = rep1;
  365. }
  366. rep1 = rep0;
  367. rep0 = distance;
  368. }
  369. if (len === 0){
  370. len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState);
  371. state = state < 7? 8: 11;
  372. }
  373. }else{
  374. rep3 = rep2;
  375. rep2 = rep1;
  376. rep1 = rep0;
  377. len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState);
  378. state = state < 7? 7: 10;
  379. posSlot = this._posSlotDecoder[len <= 5? len - 2: 3].decode(this._rangeDecoder);
  380. if (posSlot >= 4){
  381. numDirectBits = (posSlot >> 1) - 1;
  382. rep0 = (2 | (posSlot & 1) ) << numDirectBits;
  383. if (posSlot < 14){
  384. rep0 += LZMA.reverseDecode2(this._posDecoders,
  385. rep0 - posSlot - 1, this._rangeDecoder, numDirectBits);
  386. }else{
  387. rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4;
  388. rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder);
  389. if (rep0 < 0){
  390. if (rep0 === -1){
  391. break;
  392. }
  393. return false;
  394. }
  395. }
  396. }else{
  397. rep0 = posSlot;
  398. }
  399. }
  400. if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck){
  401. return false;
  402. }
  403. this._outWindow.copyBlock(rep0, len);
  404. nowPos64 += len;
  405. prevByte = this._outWindow.getByte(0);
  406. }
  407. }
  408. this._outWindow.flush();
  409. this._outWindow.releaseStream();
  410. this._rangeDecoder.releaseStream();
  411. return true;
  412. };
  413. LZMA.Decoder.prototype.setDecoderProperties = function(properties){
  414. var value, lc, lp, pb, dictionarySize;
  415. if (properties.size < 5){
  416. return false;
  417. }
  418. value = properties.readByte();
  419. lc = value % 9;
  420. value = ~~(value / 9);
  421. lp = value % 5;
  422. pb = ~~(value / 5);
  423. if ( !this.setLcLpPb(lc, lp, pb) ){
  424. return false;
  425. }
  426. dictionarySize = properties.readByte();
  427. dictionarySize |= properties.readByte() << 8;
  428. dictionarySize |= properties.readByte() << 16;
  429. dictionarySize += properties.readByte() * 16777216;
  430. return this.setDictionarySize(dictionarySize);
  431. };
  432. LZMA.decompress = function(properties, inStream, outStream, outSize){
  433. var decoder = new LZMA.Decoder();
  434. if ( !decoder.setDecoderProperties(properties) ){
  435. throw "Incorrect stream properties";
  436. }
  437. if ( !decoder.decode(inStream, outStream, outSize) ){
  438. throw "Error in data stream";
  439. }
  440. return true;
  441. };
  442. LZMA.decompressFile = function(inStream, outStream){
  443. var decoder = new LZMA.Decoder(), outSize;
  444. if ( !decoder.setDecoderProperties(inStream) ){
  445. throw "Incorrect stream properties";
  446. }
  447. outSize = inStream.readByte();
  448. outSize |= inStream.readByte() << 8;
  449. outSize |= inStream.readByte() << 16;
  450. outSize += inStream.readByte() * 16777216;
  451. inStream.readByte();
  452. inStream.readByte();
  453. inStream.readByte();
  454. inStream.readByte();
  455. if ( !decoder.decode(inStream, outStream, outSize) ){
  456. throw "Error in data stream";
  457. }
  458. return true;
  459. };
  460. /**
  461. * SEA3D LZMA
  462. * @author Sunag / http://www.sunag.com.br/
  463. */
  464. SEA3D.File.LZMAUncompress = function( data ) {
  465. data = new Uint8Array( data );
  466. var inStream = {
  467. data: data,
  468. position: 0,
  469. readByte: function() {
  470. return this.data[ this.position ++ ];
  471. }
  472. }
  473. var outStream = {
  474. data: [],
  475. position: 0,
  476. writeByte: function( value ) {
  477. this.data[ this.position ++ ] = value;
  478. }
  479. }
  480. LZMA.decompressFile( inStream, outStream );
  481. return new Uint8Array( outStream.data ).buffer;
  482. }
  483. SEA3D.File.setDecompressionEngine( 2, "lzma", SEA3D.File.LZMAUncompress );