SEA3DLZMA.js 15 KB

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