mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-11-17 03:27:57 +01:00
518 lines
12 KiB
JavaScript
518 lines
12 KiB
JavaScript
|
|
||
|
var LZMA = LZMA || {};
|
||
|
|
||
|
// browserify support
|
||
|
if ( typeof module === 'object' ) {
|
||
|
|
||
|
module.exports = 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;
|
||
|
};
|