SEA3DLZMA.js 16 KB

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