2 Copyright (c) 2011 Juan Mellado
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 - "LZMA SDK" by Igor Pavlov
26 http://www.7-zip.org/sdk.html
31 SEA3D.LZMA = function () {
33 var LZMA = LZMA || {};
35 LZMA.OutWindow = function () {
41 LZMA.OutWindow.prototype.create = function ( windowSize ) {
43 if ( ( ! this._buffer ) || ( this._windowSize !== windowSize ) ) {
48 this._windowSize = windowSize;
54 LZMA.OutWindow.prototype.flush = function () {
56 var size = this._pos - this._streamPos;
61 this._stream.writeByte( this._buffer[ this._streamPos ++ ] );
64 if ( this._pos >= this._windowSize ) {
69 this._streamPos = this._pos;
75 LZMA.OutWindow.prototype.releaseStream = function () {
82 LZMA.OutWindow.prototype.setStream = function ( stream ) {
85 this._stream = stream;
89 LZMA.OutWindow.prototype.init = function ( solid ) {
100 LZMA.OutWindow.prototype.copyBlock = function ( distance, len ) {
102 var pos = this._pos - distance - 1;
105 pos += this._windowSize;
110 if ( pos >= this._windowSize ) {
115 this._buffer[ this._pos ++ ] = this._buffer[ pos ++ ];
116 if ( this._pos >= this._windowSize ) {
126 LZMA.OutWindow.prototype.putByte = function ( b ) {
128 this._buffer[ this._pos ++ ] = b;
129 if ( this._pos >= this._windowSize ) {
137 LZMA.OutWindow.prototype.getByte = function ( distance ) {
139 var pos = this._pos - distance - 1;
142 pos += this._windowSize;
145 return this._buffer[ pos ];
149 LZMA.RangeDecoder = function () {
152 LZMA.RangeDecoder.prototype.setStream = function ( stream ) {
154 this._stream = stream;
158 LZMA.RangeDecoder.prototype.releaseStream = function () {
164 LZMA.RangeDecoder.prototype.init = function () {
173 this._code = ( this._code << 8 ) | this._stream.readByte();
179 LZMA.RangeDecoder.prototype.decodeDirectBits = function ( numTotalBits ) {
181 var result = 0, i = numTotalBits, t;
186 t = ( this._code - this._range ) >>> 31;
187 this._code -= this._range & ( t - 1 );
188 result = ( result << 1 ) | ( 1 - t );
190 if ( ( this._range & 0xff000000 ) === 0 ) {
192 this._code = ( this._code << 8 ) | this._stream.readByte();
203 LZMA.RangeDecoder.prototype.decodeBit = function ( probs, index ) {
205 var prob = probs[ index ],
206 newBound = ( this._range >>> 11 ) * prob;
208 if ( ( this._code ^ 0x80000000 ) < ( newBound ^ 0x80000000 ) ) {
210 this._range = newBound;
211 probs[ index ] += ( 2048 - prob ) >>> 5;
212 if ( ( this._range & 0xff000000 ) === 0 ) {
214 this._code = ( this._code << 8 ) | this._stream.readByte();
222 this._range -= newBound;
223 this._code -= newBound;
224 probs[ index ] -= prob >>> 5;
225 if ( ( this._range & 0xff000000 ) === 0 ) {
227 this._code = ( this._code << 8 ) | this._stream.readByte();
235 LZMA.initBitModels = function ( probs, len ) {
245 LZMA.BitTreeDecoder = function ( numBitLevels ) {
248 this._numBitLevels = numBitLevels;
252 LZMA.BitTreeDecoder.prototype.init = function () {
254 LZMA.initBitModels( this._models, 1 << this._numBitLevels );
258 LZMA.BitTreeDecoder.prototype.decode = function ( rangeDecoder ) {
260 var m = 1, i = this._numBitLevels;
264 m = ( m << 1 ) | rangeDecoder.decodeBit( this._models, m );
267 return m - ( 1 << this._numBitLevels );
271 LZMA.BitTreeDecoder.prototype.reverseDecode = function ( rangeDecoder ) {
273 var m = 1, symbol = 0, i = 0, bit;
275 for ( ; i < this._numBitLevels; ++ i ) {
277 bit = rangeDecoder.decodeBit( this._models, m );
278 m = ( m << 1 ) | bit;
286 LZMA.reverseDecode2 = function ( models, startIndex, rangeDecoder, numBitLevels ) {
288 var m = 1, symbol = 0, i = 0, bit;
290 for ( ; i < numBitLevels; ++ i ) {
292 bit = rangeDecoder.decodeBit( models, startIndex + m );
293 m = ( m << 1 ) | bit;
301 LZMA.LenDecoder = function () {
306 this._highCoder = new LZMA.BitTreeDecoder( 8 );
307 this._numPosStates = 0;
311 LZMA.LenDecoder.prototype.create = function ( numPosStates ) {
313 for ( ; this._numPosStates < numPosStates; ++ this._numPosStates ) {
315 this._lowCoder[ this._numPosStates ] = new LZMA.BitTreeDecoder( 3 );
316 this._midCoder[ this._numPosStates ] = new LZMA.BitTreeDecoder( 3 );
322 LZMA.LenDecoder.prototype.init = function () {
324 var i = this._numPosStates;
325 LZMA.initBitModels( this._choice, 2 );
328 this._lowCoder[ i ].init();
329 this._midCoder[ i ].init();
332 this._highCoder.init();
336 LZMA.LenDecoder.prototype.decode = function ( rangeDecoder, posState ) {
338 if ( rangeDecoder.decodeBit( this._choice, 0 ) === 0 ) {
340 return this._lowCoder[ posState ].decode( rangeDecoder );
343 if ( rangeDecoder.decodeBit( this._choice, 1 ) === 0 ) {
345 return 8 + this._midCoder[ posState ].decode( rangeDecoder );
348 return 16 + this._highCoder.decode( rangeDecoder );
352 LZMA.Decoder2 = function () {
358 LZMA.Decoder2.prototype.init = function () {
360 LZMA.initBitModels( this._decoders, 0x300 );
364 LZMA.Decoder2.prototype.decodeNormal = function ( rangeDecoder ) {
370 symbol = ( symbol << 1 ) | rangeDecoder.decodeBit( this._decoders, symbol );
372 }while ( symbol < 0x100 );
374 return symbol & 0xff;
378 LZMA.Decoder2.prototype.decodeWithMatchByte = function ( rangeDecoder, matchByte ) {
380 var symbol = 1, matchBit, bit;
384 matchBit = ( matchByte >> 7 ) & 1;
386 bit = rangeDecoder.decodeBit( this._decoders, ( ( 1 + matchBit ) << 8 ) + symbol );
387 symbol = ( symbol << 1 ) | bit;
388 if ( matchBit !== bit ) {
390 while ( symbol < 0x100 ) {
392 symbol = ( symbol << 1 ) | rangeDecoder.decodeBit( this._decoders, symbol );
399 }while ( symbol < 0x100 );
401 return symbol & 0xff;
405 LZMA.LiteralDecoder = function () {
408 LZMA.LiteralDecoder.prototype.create = function ( numPosBits, numPrevBits ) {
413 && ( this._numPrevBits === numPrevBits )
414 && ( this._numPosBits === numPosBits ) ) {
419 this._numPosBits = numPosBits;
420 this._posMask = ( 1 << numPosBits ) - 1;
421 this._numPrevBits = numPrevBits;
425 i = 1 << ( this._numPrevBits + this._numPosBits );
428 this._coders[ i ] = new LZMA.Decoder2();
434 LZMA.LiteralDecoder.prototype.init = function () {
436 var i = 1 << ( this._numPrevBits + this._numPosBits );
439 this._coders[ i ].init();
445 LZMA.LiteralDecoder.prototype.getDecoder = function ( pos, prevByte ) {
447 return this._coders[ ( ( pos & this._posMask ) << this._numPrevBits )
448 + ( ( prevByte & 0xff ) >>> ( 8 - this._numPrevBits ) ) ];
452 LZMA.Decoder = function () {
454 this._outWindow = new LZMA.OutWindow();
455 this._rangeDecoder = new LZMA.RangeDecoder();
456 this._isMatchDecoders = [];
457 this._isRepDecoders = [];
458 this._isRepG0Decoders = [];
459 this._isRepG1Decoders = [];
460 this._isRepG2Decoders = [];
461 this._isRep0LongDecoders = [];
462 this._posSlotDecoder = [];
463 this._posDecoders = [];
464 this._posAlignDecoder = new LZMA.BitTreeDecoder( 4 );
465 this._lenDecoder = new LZMA.LenDecoder();
466 this._repLenDecoder = new LZMA.LenDecoder();
467 this._literalDecoder = new LZMA.LiteralDecoder();
468 this._dictionarySize = - 1;
469 this._dictionarySizeCheck = - 1;
471 this._posSlotDecoder[ 0 ] = new LZMA.BitTreeDecoder( 6 );
472 this._posSlotDecoder[ 1 ] = new LZMA.BitTreeDecoder( 6 );
473 this._posSlotDecoder[ 2 ] = new LZMA.BitTreeDecoder( 6 );
474 this._posSlotDecoder[ 3 ] = new LZMA.BitTreeDecoder( 6 );
478 LZMA.Decoder.prototype.setDictionarySize = function ( dictionarySize ) {
480 if ( dictionarySize < 0 ) {
485 if ( this._dictionarySize !== dictionarySize ) {
487 this._dictionarySize = dictionarySize;
488 this._dictionarySizeCheck = Math.max( this._dictionarySize, 1 );
489 this._outWindow.create( Math.max( this._dictionarySizeCheck, 4096 ) );
496 LZMA.Decoder.prototype.setLcLpPb = function ( lc, lp, pb ) {
498 var numPosStates = 1 << pb;
500 if ( lc > 8 || lp > 4 || pb > 4 ) {
506 this._literalDecoder.create( lp, lc );
508 this._lenDecoder.create( numPosStates );
509 this._repLenDecoder.create( numPosStates );
510 this._posStateMask = numPosStates - 1;
516 LZMA.Decoder.prototype.init = function () {
520 this._outWindow.init( false );
522 LZMA.initBitModels( this._isMatchDecoders, 192 );
523 LZMA.initBitModels( this._isRep0LongDecoders, 192 );
524 LZMA.initBitModels( this._isRepDecoders, 12 );
525 LZMA.initBitModels( this._isRepG0Decoders, 12 );
526 LZMA.initBitModels( this._isRepG1Decoders, 12 );
527 LZMA.initBitModels( this._isRepG2Decoders, 12 );
528 LZMA.initBitModels( this._posDecoders, 114 );
530 this._literalDecoder.init();
534 this._posSlotDecoder[ i ].init();
538 this._lenDecoder.init();
539 this._repLenDecoder.init();
540 this._posAlignDecoder.init();
541 this._rangeDecoder.init();
545 LZMA.Decoder.prototype.decode = function ( inStream, outStream, outSize ) {
547 var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0,
548 posState, decoder2, len, distance, posSlot, numDirectBits;
550 this._rangeDecoder.setStream( inStream );
551 this._outWindow.setStream( outStream );
555 while ( outSize < 0 || nowPos64 < outSize ) {
557 posState = nowPos64 & this._posStateMask;
559 if ( this._rangeDecoder.decodeBit( this._isMatchDecoders, ( state << 4 ) + posState ) === 0 ) {
561 decoder2 = this._literalDecoder.getDecoder( nowPos64 ++, prevByte );
565 prevByte = decoder2.decodeWithMatchByte( this._rangeDecoder, this._outWindow.getByte( rep0 ) );
569 prevByte = decoder2.decodeNormal( this._rangeDecoder );
572 this._outWindow.putByte( prevByte );
574 state = state < 4 ? 0 : state - ( state < 10 ? 3 : 6 );
578 if ( this._rangeDecoder.decodeBit( this._isRepDecoders, state ) === 1 ) {
581 if ( this._rangeDecoder.decodeBit( this._isRepG0Decoders, state ) === 0 ) {
583 if ( this._rangeDecoder.decodeBit( this._isRep0LongDecoders, ( state << 4 ) + posState ) === 0 ) {
585 state = state < 7 ? 9 : 11;
592 if ( this._rangeDecoder.decodeBit( this._isRepG1Decoders, state ) === 0 ) {
598 if ( this._rangeDecoder.decodeBit( this._isRepG2Decoders, state ) === 0 ) {
617 len = 2 + this._repLenDecoder.decode( this._rangeDecoder, posState );
618 state = state < 7 ? 8 : 11;
628 len = 2 + this._lenDecoder.decode( this._rangeDecoder, posState );
629 state = state < 7 ? 7 : 10;
631 posSlot = this._posSlotDecoder[ len <= 5 ? len - 2 : 3 ].decode( this._rangeDecoder );
632 if ( posSlot >= 4 ) {
634 numDirectBits = ( posSlot >> 1 ) - 1;
635 rep0 = ( 2 | ( posSlot & 1 ) ) << numDirectBits;
637 if ( posSlot < 14 ) {
639 rep0 += LZMA.reverseDecode2( this._posDecoders,
640 rep0 - posSlot - 1, this._rangeDecoder, numDirectBits );
644 rep0 += this._rangeDecoder.decodeDirectBits( numDirectBits - 4 ) << 4;
645 rep0 += this._posAlignDecoder.reverseDecode( this._rangeDecoder );
648 if ( rep0 === - 1 ) {
667 if ( rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck ) {
673 this._outWindow.copyBlock( rep0, len );
675 prevByte = this._outWindow.getByte( 0 );
681 this._outWindow.flush();
682 this._outWindow.releaseStream();
683 this._rangeDecoder.releaseStream();
689 LZMA.Decoder.prototype.setDecoderProperties = function ( properties ) {
691 var value, lc, lp, pb, dictionarySize;
693 if ( properties.size < 5 ) {
699 value = properties.readByte();
701 value = ~~ ( value / 9 );
703 pb = ~~ ( value / 5 );
705 if ( ! this.setLcLpPb( lc, lp, pb ) ) {
711 dictionarySize = properties.readByte();
712 dictionarySize |= properties.readByte() << 8;
713 dictionarySize |= properties.readByte() << 16;
714 dictionarySize += properties.readByte() * 16777216;
716 return this.setDictionarySize( dictionarySize );
720 LZMA.decompress = function ( properties, inStream, outStream, outSize ) {
722 var decoder = new LZMA.Decoder();
724 if ( ! decoder.setDecoderProperties( properties ) ) {
726 throw "Incorrect stream properties";
730 if ( ! decoder.decode( inStream, outStream, outSize ) ) {
732 throw "Error in data stream";
740 LZMA.decompressFile = function ( inStream, outStream ) {
742 var decoder = new LZMA.Decoder(), outSize;
744 if ( ! decoder.setDecoderProperties( inStream ) ) {
746 throw "Incorrect stream properties";
750 outSize = inStream.readByte();
751 outSize |= inStream.readByte() << 8;
752 outSize |= inStream.readByte() << 16;
753 outSize += inStream.readByte() * 16777216;
760 if ( ! decoder.decode( inStream, outStream, outSize ) ) {
762 throw "Error in data stream";
777 * @author Sunag / http://www.sunag.com.br/
780 SEA3D.File.LZMAUncompress = function ( data ) {
782 data = new Uint8Array( data );
787 readByte: function () {
789 return this.data[ this.position ++ ];
797 writeByte: function ( value ) {
799 this.data[ this.position ++ ] = value;
804 SEA3D.LZMA.decompressFile( inStream, outStream );
806 return new Uint8Array( outStream.data ).buffer;
810 SEA3D.File.setDecompressionEngine( 2, "lzma", SEA3D.File.LZMAUncompress );