Spaces:
Running
Running
| /* | |
| Copyright (c) 2011 Juan Mellado | |
| Permission is hereby granted, free of charge, to any person obtaining a copy | |
| of this software and associated documentation files (the "Software"), to deal | |
| in the Software without restriction, including without limitation the rights | |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| copies of the Software, and to permit persons to whom the Software is | |
| furnished to do so, subject to the following conditions: | |
| The above copyright notice and this permission notice shall be included in | |
| all copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| THE SOFTWARE. | |
| */ | |
| /* | |
| References: | |
| - "LZMA SDK" by Igor Pavlov | |
| http://www.7-zip.org/sdk.html | |
| */ | |
| ; | |
| SEA3D.LZMA = function () { | |
| var LZMA = LZMA || {}; | |
| LZMA.OutWindow = function () { | |
| this._windowSize = 0; | |
| }; | |
| LZMA.OutWindow.prototype.create = function ( windowSize ) { | |
| if ( ( ! this._buffer ) || ( this._windowSize !== windowSize ) ) { | |
| this._buffer = []; | |
| } | |
| this._windowSize = windowSize; | |
| this._pos = 0; | |
| this._streamPos = 0; | |
| }; | |
| LZMA.OutWindow.prototype.flush = function () { | |
| var size = this._pos - this._streamPos; | |
| if ( size !== 0 ) { | |
| while ( size -- ) { | |
| this._stream.writeByte( this._buffer[ this._streamPos ++ ] ); | |
| } | |
| if ( this._pos >= this._windowSize ) { | |
| this._pos = 0; | |
| } | |
| this._streamPos = this._pos; | |
| } | |
| }; | |
| LZMA.OutWindow.prototype.releaseStream = function () { | |
| this.flush(); | |
| this._stream = null; | |
| }; | |
| LZMA.OutWindow.prototype.setStream = function ( stream ) { | |
| this.releaseStream(); | |
| this._stream = stream; | |
| }; | |
| LZMA.OutWindow.prototype.init = function ( solid ) { | |
| if ( ! solid ) { | |
| this._streamPos = 0; | |
| this._pos = 0; | |
| } | |
| }; | |
| LZMA.OutWindow.prototype.copyBlock = function ( distance, len ) { | |
| var pos = this._pos - distance - 1; | |
| if ( pos < 0 ) { | |
| pos += this._windowSize; | |
| } | |
| while ( len -- ) { | |
| if ( pos >= this._windowSize ) { | |
| pos = 0; | |
| } | |
| this._buffer[ this._pos ++ ] = this._buffer[ pos ++ ]; | |
| if ( this._pos >= this._windowSize ) { | |
| this.flush(); | |
| } | |
| } | |
| }; | |
| LZMA.OutWindow.prototype.putByte = function ( b ) { | |
| this._buffer[ this._pos ++ ] = b; | |
| if ( this._pos >= this._windowSize ) { | |
| this.flush(); | |
| } | |
| }; | |
| LZMA.OutWindow.prototype.getByte = function ( distance ) { | |
| var pos = this._pos - distance - 1; | |
| if ( pos < 0 ) { | |
| pos += this._windowSize; | |
| } | |
| return this._buffer[ pos ]; | |
| }; | |
| LZMA.RangeDecoder = function () { | |
| }; | |
| LZMA.RangeDecoder.prototype.setStream = function ( stream ) { | |
| this._stream = stream; | |
| }; | |
| LZMA.RangeDecoder.prototype.releaseStream = function () { | |
| this._stream = null; | |
| }; | |
| LZMA.RangeDecoder.prototype.init = function () { | |
| var i = 5; | |
| this._code = 0; | |
| this._range = - 1; | |
| while ( i -- ) { | |
| this._code = ( this._code << 8 ) | this._stream.readByte(); | |
| } | |
| }; | |
| LZMA.RangeDecoder.prototype.decodeDirectBits = function ( numTotalBits ) { | |
| var result = 0, i = numTotalBits, t; | |
| while ( i -- ) { | |
| this._range >>>= 1; | |
| t = ( this._code - this._range ) >>> 31; | |
| this._code -= this._range & ( t - 1 ); | |
| result = ( result << 1 ) | ( 1 - t ); | |
| if ( ( this._range & 0xff000000 ) === 0 ) { | |
| this._code = ( this._code << 8 ) | this._stream.readByte(); | |
| this._range <<= 8; | |
| } | |
| } | |
| return result; | |
| }; | |
| LZMA.RangeDecoder.prototype.decodeBit = function ( probs, index ) { | |
| var prob = probs[ index ], | |
| newBound = ( this._range >>> 11 ) * prob; | |
| if ( ( this._code ^ 0x80000000 ) < ( newBound ^ 0x80000000 ) ) { | |
| this._range = newBound; | |
| probs[ index ] += ( 2048 - prob ) >>> 5; | |
| if ( ( this._range & 0xff000000 ) === 0 ) { | |
| this._code = ( this._code << 8 ) | this._stream.readByte(); | |
| this._range <<= 8; | |
| } | |
| return 0; | |
| } | |
| this._range -= newBound; | |
| this._code -= newBound; | |
| probs[ index ] -= prob >>> 5; | |
| if ( ( this._range & 0xff000000 ) === 0 ) { | |
| this._code = ( this._code << 8 ) | this._stream.readByte(); | |
| this._range <<= 8; | |
| } | |
| return 1; | |
| }; | |
| LZMA.initBitModels = function ( probs, len ) { | |
| while ( len -- ) { | |
| probs[ len ] = 1024; | |
| } | |
| }; | |
| LZMA.BitTreeDecoder = function ( numBitLevels ) { | |
| this._models = []; | |
| this._numBitLevels = numBitLevels; | |
| }; | |
| LZMA.BitTreeDecoder.prototype.init = function () { | |
| LZMA.initBitModels( this._models, 1 << this._numBitLevels ); | |
| }; | |
| LZMA.BitTreeDecoder.prototype.decode = function ( rangeDecoder ) { | |
| var m = 1, i = this._numBitLevels; | |
| while ( i -- ) { | |
| m = ( m << 1 ) | rangeDecoder.decodeBit( this._models, m ); | |
| } | |
| return m - ( 1 << this._numBitLevels ); | |
| }; | |
| LZMA.BitTreeDecoder.prototype.reverseDecode = function ( rangeDecoder ) { | |
| var m = 1, symbol = 0, i = 0, bit; | |
| for ( ; i < this._numBitLevels; ++ i ) { | |
| bit = rangeDecoder.decodeBit( this._models, m ); | |
| m = ( m << 1 ) | bit; | |
| symbol |= bit << i; | |
| } | |
| return symbol; | |
| }; | |
| LZMA.reverseDecode2 = function ( models, startIndex, rangeDecoder, numBitLevels ) { | |
| var m = 1, symbol = 0, i = 0, bit; | |
| for ( ; i < numBitLevels; ++ i ) { | |
| bit = rangeDecoder.decodeBit( models, startIndex + m ); | |
| m = ( m << 1 ) | bit; | |
| symbol |= bit << i; | |
| } | |
| return symbol; | |
| }; | |
| LZMA.LenDecoder = function () { | |
| this._choice = []; | |
| this._lowCoder = []; | |
| this._midCoder = []; | |
| this._highCoder = new LZMA.BitTreeDecoder( 8 ); | |
| this._numPosStates = 0; | |
| }; | |
| LZMA.LenDecoder.prototype.create = function ( numPosStates ) { | |
| for ( ; this._numPosStates < numPosStates; ++ this._numPosStates ) { | |
| this._lowCoder[ this._numPosStates ] = new LZMA.BitTreeDecoder( 3 ); | |
| this._midCoder[ this._numPosStates ] = new LZMA.BitTreeDecoder( 3 ); | |
| } | |
| }; | |
| LZMA.LenDecoder.prototype.init = function () { | |
| var i = this._numPosStates; | |
| LZMA.initBitModels( this._choice, 2 ); | |
| while ( i -- ) { | |
| this._lowCoder[ i ].init(); | |
| this._midCoder[ i ].init(); | |
| } | |
| this._highCoder.init(); | |
| }; | |
| LZMA.LenDecoder.prototype.decode = function ( rangeDecoder, posState ) { | |
| if ( rangeDecoder.decodeBit( this._choice, 0 ) === 0 ) { | |
| return this._lowCoder[ posState ].decode( rangeDecoder ); | |
| } | |
| if ( rangeDecoder.decodeBit( this._choice, 1 ) === 0 ) { | |
| return 8 + this._midCoder[ posState ].decode( rangeDecoder ); | |
| } | |
| return 16 + this._highCoder.decode( rangeDecoder ); | |
| }; | |
| LZMA.Decoder2 = function () { | |
| this._decoders = []; | |
| }; | |
| LZMA.Decoder2.prototype.init = function () { | |
| LZMA.initBitModels( this._decoders, 0x300 ); | |
| }; | |
| LZMA.Decoder2.prototype.decodeNormal = function ( rangeDecoder ) { | |
| var symbol = 1; | |
| do { | |
| symbol = ( symbol << 1 ) | rangeDecoder.decodeBit( this._decoders, symbol ); | |
| }while ( symbol < 0x100 ); | |
| return symbol & 0xff; | |
| }; | |
| LZMA.Decoder2.prototype.decodeWithMatchByte = function ( rangeDecoder, matchByte ) { | |
| var symbol = 1, matchBit, bit; | |
| do { | |
| matchBit = ( matchByte >> 7 ) & 1; | |
| matchByte <<= 1; | |
| bit = rangeDecoder.decodeBit( this._decoders, ( ( 1 + matchBit ) << 8 ) + symbol ); | |
| symbol = ( symbol << 1 ) | bit; | |
| if ( matchBit !== bit ) { | |
| while ( symbol < 0x100 ) { | |
| symbol = ( symbol << 1 ) | rangeDecoder.decodeBit( this._decoders, symbol ); | |
| } | |
| break; | |
| } | |
| }while ( symbol < 0x100 ); | |
| return symbol & 0xff; | |
| }; | |
| LZMA.LiteralDecoder = function () { | |
| }; | |
| LZMA.LiteralDecoder.prototype.create = function ( numPosBits, numPrevBits ) { | |
| var i; | |
| if ( this._coders | |
| && ( this._numPrevBits === numPrevBits ) | |
| && ( this._numPosBits === numPosBits ) ) { | |
| return; | |
| } | |
| this._numPosBits = numPosBits; | |
| this._posMask = ( 1 << numPosBits ) - 1; | |
| this._numPrevBits = numPrevBits; | |
| this._coders = []; | |
| i = 1 << ( this._numPrevBits + this._numPosBits ); | |
| while ( i -- ) { | |
| this._coders[ i ] = new LZMA.Decoder2(); | |
| } | |
| }; | |
| LZMA.LiteralDecoder.prototype.init = function () { | |
| var i = 1 << ( this._numPrevBits + this._numPosBits ); | |
| while ( i -- ) { | |
| this._coders[ i ].init(); | |
| } | |
| }; | |
| LZMA.LiteralDecoder.prototype.getDecoder = function ( pos, prevByte ) { | |
| return this._coders[ ( ( pos & this._posMask ) << this._numPrevBits ) | |
| + ( ( prevByte & 0xff ) >>> ( 8 - this._numPrevBits ) ) ]; | |
| }; | |
| LZMA.Decoder = function () { | |
| this._outWindow = new LZMA.OutWindow(); | |
| this._rangeDecoder = new LZMA.RangeDecoder(); | |
| this._isMatchDecoders = []; | |
| this._isRepDecoders = []; | |
| this._isRepG0Decoders = []; | |
| this._isRepG1Decoders = []; | |
| this._isRepG2Decoders = []; | |
| this._isRep0LongDecoders = []; | |
| this._posSlotDecoder = []; | |
| this._posDecoders = []; | |
| this._posAlignDecoder = new LZMA.BitTreeDecoder( 4 ); | |
| this._lenDecoder = new LZMA.LenDecoder(); | |
| this._repLenDecoder = new LZMA.LenDecoder(); | |
| this._literalDecoder = new LZMA.LiteralDecoder(); | |
| this._dictionarySize = - 1; | |
| this._dictionarySizeCheck = - 1; | |
| this._posSlotDecoder[ 0 ] = new LZMA.BitTreeDecoder( 6 ); | |
| this._posSlotDecoder[ 1 ] = new LZMA.BitTreeDecoder( 6 ); | |
| this._posSlotDecoder[ 2 ] = new LZMA.BitTreeDecoder( 6 ); | |
| this._posSlotDecoder[ 3 ] = new LZMA.BitTreeDecoder( 6 ); | |
| }; | |
| LZMA.Decoder.prototype.setDictionarySize = function ( dictionarySize ) { | |
| if ( dictionarySize < 0 ) { | |
| return false; | |
| } | |
| if ( this._dictionarySize !== dictionarySize ) { | |
| this._dictionarySize = dictionarySize; | |
| this._dictionarySizeCheck = Math.max( this._dictionarySize, 1 ); | |
| this._outWindow.create( Math.max( this._dictionarySizeCheck, 4096 ) ); | |
| } | |
| return true; | |
| }; | |
| LZMA.Decoder.prototype.setLcLpPb = function ( lc, lp, pb ) { | |
| var numPosStates = 1 << pb; | |
| if ( lc > 8 || lp > 4 || pb > 4 ) { | |
| return false; | |
| } | |
| this._literalDecoder.create( lp, lc ); | |
| this._lenDecoder.create( numPosStates ); | |
| this._repLenDecoder.create( numPosStates ); | |
| this._posStateMask = numPosStates - 1; | |
| return true; | |
| }; | |
| LZMA.Decoder.prototype.init = function () { | |
| var i = 4; | |
| this._outWindow.init( false ); | |
| LZMA.initBitModels( this._isMatchDecoders, 192 ); | |
| LZMA.initBitModels( this._isRep0LongDecoders, 192 ); | |
| LZMA.initBitModels( this._isRepDecoders, 12 ); | |
| LZMA.initBitModels( this._isRepG0Decoders, 12 ); | |
| LZMA.initBitModels( this._isRepG1Decoders, 12 ); | |
| LZMA.initBitModels( this._isRepG2Decoders, 12 ); | |
| LZMA.initBitModels( this._posDecoders, 114 ); | |
| this._literalDecoder.init(); | |
| while ( i -- ) { | |
| this._posSlotDecoder[ i ].init(); | |
| } | |
| this._lenDecoder.init(); | |
| this._repLenDecoder.init(); | |
| this._posAlignDecoder.init(); | |
| this._rangeDecoder.init(); | |
| }; | |
| LZMA.Decoder.prototype.decode = function ( inStream, outStream, outSize ) { | |
| var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0, | |
| posState, decoder2, len, distance, posSlot, numDirectBits; | |
| this._rangeDecoder.setStream( inStream ); | |
| this._outWindow.setStream( outStream ); | |
| this.init(); | |
| while ( outSize < 0 || nowPos64 < outSize ) { | |
| posState = nowPos64 & this._posStateMask; | |
| if ( this._rangeDecoder.decodeBit( this._isMatchDecoders, ( state << 4 ) + posState ) === 0 ) { | |
| decoder2 = this._literalDecoder.getDecoder( nowPos64 ++, prevByte ); | |
| if ( state >= 7 ) { | |
| prevByte = decoder2.decodeWithMatchByte( this._rangeDecoder, this._outWindow.getByte( rep0 ) ); | |
| } else { | |
| prevByte = decoder2.decodeNormal( this._rangeDecoder ); | |
| } | |
| this._outWindow.putByte( prevByte ); | |
| state = state < 4 ? 0 : state - ( state < 10 ? 3 : 6 ); | |
| } else { | |
| if ( this._rangeDecoder.decodeBit( this._isRepDecoders, state ) === 1 ) { | |
| len = 0; | |
| if ( this._rangeDecoder.decodeBit( this._isRepG0Decoders, state ) === 0 ) { | |
| if ( this._rangeDecoder.decodeBit( this._isRep0LongDecoders, ( state << 4 ) + posState ) === 0 ) { | |
| state = state < 7 ? 9 : 11; | |
| len = 1; | |
| } | |
| } else { | |
| if ( this._rangeDecoder.decodeBit( this._isRepG1Decoders, state ) === 0 ) { | |
| distance = rep1; | |
| } else { | |
| if ( this._rangeDecoder.decodeBit( this._isRepG2Decoders, state ) === 0 ) { | |
| distance = rep2; | |
| } else { | |
| distance = rep3; | |
| rep3 = rep2; | |
| } | |
| rep2 = rep1; | |
| } | |
| rep1 = rep0; | |
| rep0 = distance; | |
| } | |
| if ( len === 0 ) { | |
| len = 2 + this._repLenDecoder.decode( this._rangeDecoder, posState ); | |
| state = state < 7 ? 8 : 11; | |
| } | |
| } else { | |
| rep3 = rep2; | |
| rep2 = rep1; | |
| rep1 = rep0; | |
| len = 2 + this._lenDecoder.decode( this._rangeDecoder, posState ); | |
| state = state < 7 ? 7 : 10; | |
| posSlot = this._posSlotDecoder[ len <= 5 ? len - 2 : 3 ].decode( this._rangeDecoder ); | |
| if ( posSlot >= 4 ) { | |
| numDirectBits = ( posSlot >> 1 ) - 1; | |
| rep0 = ( 2 | ( posSlot & 1 ) ) << numDirectBits; | |
| if ( posSlot < 14 ) { | |
| rep0 += LZMA.reverseDecode2( this._posDecoders, | |
| rep0 - posSlot - 1, this._rangeDecoder, numDirectBits ); | |
| } else { | |
| rep0 += this._rangeDecoder.decodeDirectBits( numDirectBits - 4 ) << 4; | |
| rep0 += this._posAlignDecoder.reverseDecode( this._rangeDecoder ); | |
| if ( rep0 < 0 ) { | |
| if ( rep0 === - 1 ) { | |
| break; | |
| } | |
| return false; | |
| } | |
| } | |
| } else { | |
| rep0 = posSlot; | |
| } | |
| } | |
| if ( rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck ) { | |
| return false; | |
| } | |
| this._outWindow.copyBlock( rep0, len ); | |
| nowPos64 += len; | |
| prevByte = this._outWindow.getByte( 0 ); | |
| } | |
| } | |
| this._outWindow.flush(); | |
| this._outWindow.releaseStream(); | |
| this._rangeDecoder.releaseStream(); | |
| return true; | |
| }; | |
| LZMA.Decoder.prototype.setDecoderProperties = function ( properties ) { | |
| var value, lc, lp, pb, dictionarySize; | |
| if ( properties.size < 5 ) { | |
| return false; | |
| } | |
| value = properties.readByte(); | |
| lc = value % 9; | |
| value = ~~ ( value / 9 ); | |
| lp = value % 5; | |
| pb = ~~ ( value / 5 ); | |
| if ( ! this.setLcLpPb( lc, lp, pb ) ) { | |
| return false; | |
| } | |
| dictionarySize = properties.readByte(); | |
| dictionarySize |= properties.readByte() << 8; | |
| dictionarySize |= properties.readByte() << 16; | |
| dictionarySize += properties.readByte() * 16777216; | |
| return this.setDictionarySize( dictionarySize ); | |
| }; | |
| LZMA.decompress = function ( properties, inStream, outStream, outSize ) { | |
| var decoder = new LZMA.Decoder(); | |
| if ( ! decoder.setDecoderProperties( properties ) ) { | |
| throw "Incorrect stream properties"; | |
| } | |
| if ( ! decoder.decode( inStream, outStream, outSize ) ) { | |
| throw "Error in data stream"; | |
| } | |
| return true; | |
| }; | |
| LZMA.decompressFile = function ( inStream, outStream ) { | |
| var decoder = new LZMA.Decoder(), outSize; | |
| if ( ! decoder.setDecoderProperties( inStream ) ) { | |
| throw "Incorrect stream properties"; | |
| } | |
| outSize = inStream.readByte(); | |
| outSize |= inStream.readByte() << 8; | |
| outSize |= inStream.readByte() << 16; | |
| outSize += inStream.readByte() * 16777216; | |
| inStream.readByte(); | |
| inStream.readByte(); | |
| inStream.readByte(); | |
| inStream.readByte(); | |
| if ( ! decoder.decode( inStream, outStream, outSize ) ) { | |
| throw "Error in data stream"; | |
| } | |
| return true; | |
| }; | |
| return LZMA; | |
| }(); | |
| /** | |
| * SEA3D LZMA | |
| * @author Sunag / http://www.sunag.com.br/ | |
| */ | |
| SEA3D.File.LZMAUncompress = function ( data ) { | |
| data = new Uint8Array( data ); | |
| var inStream = { | |
| data: data, | |
| position: 0, | |
| readByte: function () { | |
| return this.data[ this.position ++ ]; | |
| } | |
| }; | |
| var outStream = { | |
| data: [], | |
| position: 0, | |
| writeByte: function ( value ) { | |
| this.data[ this.position ++ ] = value; | |
| } | |
| }; | |
| SEA3D.LZMA.decompressFile( inStream, outStream ); | |
| return new Uint8Array( outStream.data ).buffer; | |
| }; | |
| SEA3D.File.setDecompressionEngine( 2, "lzma", SEA3D.File.LZMAUncompress ); | |