|
/* |
|
The LZMA impementation is forked from https://npm.is/lzma-js, converted to an ES module and with some features stripped off (e.g. async mode, worker support) |
|
|
|
Here's the according MIT license: |
|
|
|
© 2016 Nathan Rugg <[email protected]> |
|
|
|
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. |
|
*/ |
|
|
|
import * as base64 from './base64.js' |
|
|
|
const __4294967296 = 4294967296, |
|
N1_longLit = [4294967295, -__4294967296], |
|
MIN_VALUE = [0, -9223372036854775808], |
|
P0_longLit = [0, 0], |
|
P1_longLit = [1, 0] |
|
|
|
function add(a, b) { |
|
return create(a[0] + b[0], a[1] + b[1]) |
|
} |
|
|
|
function initDim(len) { |
|
// NOTE: This is MUCH faster than "initDim(len)" in newer versions of v8 (starting with Node.js 0.11.15, which uses v8 3.28.73). |
|
var a = [] |
|
a[len - 1] = undefined |
|
return a |
|
} |
|
function and(a, b) { |
|
return makeFromBits( |
|
~~Math.max(Math.min(a[1] / __4294967296, 2147483647), -2147483648) & |
|
~~Math.max(Math.min(b[1] / __4294967296, 2147483647), -2147483648), |
|
lowBits_0(a) & lowBits_0(b) |
|
) |
|
} |
|
function compare(a, b) { |
|
var nega, negb |
|
if (a[0] == b[0] && a[1] == b[1]) { |
|
return 0 |
|
} |
|
nega = a[1] < 0 |
|
negb = b[1] < 0 |
|
if (nega && !negb) { |
|
return -1 |
|
} |
|
if (!nega && negb) { |
|
return 1 |
|
} |
|
if (sub(a, b)[1] < 0) { |
|
return -1 |
|
} |
|
return 1 |
|
} |
|
|
|
function create(valueLow, valueHigh) { |
|
var diffHigh, diffLow |
|
valueHigh %= 1.8446744073709552e19 |
|
valueLow %= 1.8446744073709552e19 |
|
diffHigh = valueHigh % __4294967296 |
|
diffLow = Math.floor(valueLow / __4294967296) * __4294967296 |
|
valueHigh = valueHigh - diffHigh + diffLow |
|
valueLow = valueLow - diffLow + diffHigh |
|
while (valueLow < 0) { |
|
valueLow += __4294967296 |
|
valueHigh -= __4294967296 |
|
} |
|
while (valueLow > 4294967295) { |
|
valueLow -= __4294967296 |
|
valueHigh += __4294967296 |
|
} |
|
valueHigh = valueHigh % 1.8446744073709552e19 |
|
while (valueHigh > 9223372032559808512) { |
|
valueHigh -= 1.8446744073709552e19 |
|
} |
|
while (valueHigh < -9223372036854775808) { |
|
valueHigh += 1.8446744073709552e19 |
|
} |
|
return [valueLow, valueHigh] |
|
} |
|
function eq(a, b) { |
|
return a[0] == b[0] && a[1] == b[1] |
|
} |
|
function fromInt(value) { |
|
if (value >= 0) { |
|
return [value, 0] |
|
} else { |
|
return [value + __4294967296, -__4294967296] |
|
} |
|
} |
|
|
|
function lowBits_0(a) { |
|
if (a[0] >= 2147483648) { |
|
return ~~Math.max(Math.min(a[0] - __4294967296, 2147483647), -2147483648) |
|
} else { |
|
return ~~Math.max(Math.min(a[0], 2147483647), -2147483648) |
|
} |
|
} |
|
function makeFromBits(highBits, lowBits) { |
|
var high, low |
|
high = highBits * __4294967296 |
|
low = lowBits |
|
if (lowBits < 0) { |
|
low += __4294967296 |
|
} |
|
return [low, high] |
|
} |
|
|
|
function pwrAsDouble(n) { |
|
if (n <= 30) { |
|
return 1 << n |
|
} else { |
|
return pwrAsDouble(30) * pwrAsDouble(n - 30) |
|
} |
|
} |
|
|
|
function shl(a, n) { |
|
var diff, newHigh, newLow, twoToN |
|
n &= 63 |
|
if (eq(a, MIN_VALUE)) { |
|
if (!n) { |
|
return a |
|
} |
|
return P0_longLit |
|
} |
|
if (a[1] < 0) { |
|
throw new Error('Neg') |
|
} |
|
twoToN = pwrAsDouble(n) |
|
newHigh = (a[1] * twoToN) % 1.8446744073709552e19 |
|
newLow = a[0] * twoToN |
|
diff = newLow - (newLow % __4294967296) |
|
newHigh += diff |
|
newLow -= diff |
|
if (newHigh >= 9223372036854775807) { |
|
newHigh -= 1.8446744073709552e19 |
|
} |
|
return [newLow, newHigh] |
|
} |
|
|
|
function shr(a, n) { |
|
var shiftFact |
|
n &= 63 |
|
shiftFact = pwrAsDouble(n) |
|
return create(Math.floor(a[0] / shiftFact), a[1] / shiftFact) |
|
} |
|
|
|
function shru(a, n) { |
|
var sr |
|
n &= 63 |
|
sr = shr(a, n) |
|
if (a[1] < 0) { |
|
sr = add(sr, shl([2, 0], 63 - n)) |
|
} |
|
return sr |
|
} |
|
function sub(a, b) { |
|
return create(a[0] - b[0], a[1] - b[1]) |
|
} |
|
|
|
function $ByteArrayInputStream(this$static, buf) { |
|
this$static.buf = buf |
|
this$static.pos = 0 |
|
this$static.count = buf.length |
|
return this$static |
|
} |
|
function $read(this$static) { |
|
if (this$static.pos >= this$static.count) return -1 |
|
return this$static.buf[this$static.pos++] & 255 |
|
} |
|
function $read_0(this$static, buf, off, len) { |
|
if (this$static.pos >= this$static.count) return -1 |
|
len = Math.min(len, this$static.count - this$static.pos) |
|
arraycopy(this$static.buf, this$static.pos, buf, off, len) |
|
this$static.pos += len |
|
return len |
|
} |
|
function $ByteArrayOutputStream(this$static) { |
|
this$static.buf = initDim(32) |
|
this$static.count = 0 |
|
return this$static |
|
} |
|
|
|
function $toByteArray(this$static) { |
|
var data = this$static.buf |
|
data.length = this$static.count |
|
return data |
|
} |
|
function $write(this$static, b) { |
|
this$static.buf[this$static.count++] = (b << 24) >> 24 |
|
} |
|
function $write_0(this$static, buf, off, len) { |
|
arraycopy(buf, off, this$static.buf, this$static.count, len) |
|
this$static.count += len |
|
} |
|
function $getChars(this$static, srcBegin, srcEnd, dst, dstBegin) { |
|
var srcIdx |
|
for (srcIdx = srcBegin; srcIdx < srcEnd; ++srcIdx) { |
|
dst[dstBegin++] = this$static.charCodeAt(srcIdx) |
|
} |
|
} |
|
function arraycopy(src, srcOfs, dest, destOfs, len) { |
|
for (var i = 0; i < len; ++i) { |
|
dest[destOfs + i] = src[srcOfs + i] |
|
} |
|
} |
|
function $configure(this$static, encoder) { |
|
$SetDictionarySize_0(encoder, 1 << this$static.s) |
|
encoder._numFastBytes = this$static.f |
|
$SetMatchFinder(encoder, this$static.m) |
|
|
|
// lc is always 3 |
|
// lp is always 0 |
|
// pb is always 2 |
|
encoder._numLiteralPosStateBits = 0 |
|
encoder._numLiteralContextBits = 3 |
|
encoder._posStateBits = 2 |
|
encoder._posStateMask = 3 |
|
} |
|
|
|
function $init(this$static, input, output, length_0, mode, enableEndMark) { |
|
var encoder, i |
|
if (compare(length_0, N1_longLit) < 0) |
|
throw new Error('invalid length ' + length_0) |
|
this$static.length_0 = length_0 |
|
encoder = $Encoder({}) |
|
$configure(mode, encoder) |
|
encoder._writeEndMark = enableEndMark |
|
$WriteCoderProperties(encoder, output) |
|
for (i = 0; i < 64; i += 8) $write(output, lowBits_0(shr(length_0, i)) & 255) |
|
this$static.chunker = |
|
((encoder._needReleaseMFStream = 0), |
|
((encoder._inStream = input), |
|
(encoder._finished = 0), |
|
$Create_2(encoder), |
|
(encoder._rangeEncoder.Stream = output), |
|
$Init_4(encoder), |
|
$FillDistancesPrices(encoder), |
|
$FillAlignPrices(encoder), |
|
(encoder._lenEncoder._tableSize = encoder._numFastBytes + 1 - 2), |
|
$UpdateTables(encoder._lenEncoder, 1 << encoder._posStateBits), |
|
(encoder._repMatchLenEncoder._tableSize = encoder._numFastBytes + 1 - 2), |
|
$UpdateTables(encoder._repMatchLenEncoder, 1 << encoder._posStateBits), |
|
(encoder.nowPos64 = P0_longLit), |
|
undefined), |
|
$Chunker_0({}, encoder)) |
|
} |
|
|
|
function $LZMAByteArrayCompressor(this$static, data, mode, enableEndMark) { |
|
this$static.output = $ByteArrayOutputStream({}) |
|
$init( |
|
this$static, |
|
$ByteArrayInputStream({}, data), |
|
this$static.output, |
|
fromInt(data.length), |
|
mode, |
|
enableEndMark |
|
) |
|
return this$static |
|
} |
|
function $init_0(this$static, input, output) { |
|
var decoder, |
|
hex_length = '', |
|
i, |
|
properties = [], |
|
r, |
|
tmp_length |
|
|
|
for (i = 0; i < 5; ++i) { |
|
r = $read(input) |
|
if (r == -1) throw new Error('truncated input') |
|
properties[i] = (r << 24) >> 24 |
|
} |
|
|
|
decoder = $Decoder({}) |
|
if (!$SetDecoderProperties(decoder, properties)) { |
|
throw new Error('corrupted input') |
|
} |
|
for (i = 0; i < 64; i += 8) { |
|
r = $read(input) |
|
if (r == -1) throw new Error('truncated input') |
|
r = r.toString(16) |
|
if (r.length == 1) r = '0' + r |
|
hex_length = r + '' + hex_length |
|
} |
|
|
|
// Was the length set in the header (if it was compressed from a stream, the length is all f"s). |
|
if (/^0+$|^f+$/i.test(hex_length)) { |
|
// The length is unknown, so set to -1. |
|
this$static.length_0 = N1_longLit |
|
} else { |
|
// NOTE: If there is a problem with the decoder because of the length, you can always set the length to -1 (N1_longLit) which means unknown. |
|
tmp_length = parseInt(hex_length, 16) |
|
// If the length is too long to handle, just set it to unknown. |
|
if (tmp_length > 4294967295) { |
|
this$static.length_0 = N1_longLit |
|
} else { |
|
this$static.length_0 = fromInt(tmp_length) |
|
} |
|
} |
|
|
|
this$static.chunker = $CodeInChunks( |
|
decoder, |
|
input, |
|
output, |
|
this$static.length_0 |
|
) |
|
} |
|
|
|
function $LZMAByteArrayDecompressor(this$static, data) { |
|
this$static.output = $ByteArrayOutputStream({}) |
|
$init_0(this$static, $ByteArrayInputStream({}, data), this$static.output) |
|
return this$static |
|
} |
|
function $Create_4(this$static, keepSizeBefore, keepSizeAfter, keepSizeReserv) { |
|
var blockSize |
|
this$static._keepSizeBefore = keepSizeBefore |
|
this$static._keepSizeAfter = keepSizeAfter |
|
blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv |
|
if (this$static._bufferBase == null || this$static._blockSize != blockSize) { |
|
this$static._bufferBase = null |
|
this$static._blockSize = blockSize |
|
this$static._bufferBase = initDim(this$static._blockSize) |
|
} |
|
this$static._pointerToLastSafePosition = |
|
this$static._blockSize - keepSizeAfter |
|
} |
|
|
|
function $GetIndexByte(this$static, index) { |
|
return this$static._bufferBase[ |
|
this$static._bufferOffset + this$static._pos + index |
|
] |
|
} |
|
|
|
function $GetMatchLen(this$static, index, distance, limit) { |
|
var i, pby |
|
if (this$static._streamEndWasReached) { |
|
if (this$static._pos + index + limit > this$static._streamPos) { |
|
limit = this$static._streamPos - (this$static._pos + index) |
|
} |
|
} |
|
++distance |
|
pby = this$static._bufferOffset + this$static._pos + index |
|
for ( |
|
i = 0; |
|
i < limit && |
|
this$static._bufferBase[pby + i] == |
|
this$static._bufferBase[pby + i - distance]; |
|
++i |
|
) {} |
|
return i |
|
} |
|
|
|
function $GetNumAvailableBytes(this$static) { |
|
return this$static._streamPos - this$static._pos |
|
} |
|
|
|
function $MoveBlock(this$static) { |
|
var i, numBytes, offset |
|
offset = |
|
this$static._bufferOffset + this$static._pos - this$static._keepSizeBefore |
|
if (offset > 0) { |
|
--offset |
|
} |
|
numBytes = this$static._bufferOffset + this$static._streamPos - offset |
|
for (i = 0; i < numBytes; ++i) { |
|
this$static._bufferBase[i] = this$static._bufferBase[offset + i] |
|
} |
|
this$static._bufferOffset -= offset |
|
} |
|
|
|
function $MovePos_1(this$static) { |
|
var pointerToPostion |
|
++this$static._pos |
|
if (this$static._pos > this$static._posLimit) { |
|
pointerToPostion = this$static._bufferOffset + this$static._pos |
|
if (pointerToPostion > this$static._pointerToLastSafePosition) { |
|
$MoveBlock(this$static) |
|
} |
|
$ReadBlock(this$static) |
|
} |
|
} |
|
|
|
function $ReadBlock(this$static) { |
|
var numReadBytes, pointerToPostion, size |
|
if (this$static._streamEndWasReached) return |
|
while (1) { |
|
size = |
|
-this$static._bufferOffset + |
|
this$static._blockSize - |
|
this$static._streamPos |
|
if (!size) return |
|
numReadBytes = $read_0( |
|
this$static._stream, |
|
this$static._bufferBase, |
|
this$static._bufferOffset + this$static._streamPos, |
|
size |
|
) |
|
if (numReadBytes == -1) { |
|
this$static._posLimit = this$static._streamPos |
|
pointerToPostion = this$static._bufferOffset + this$static._posLimit |
|
if (pointerToPostion > this$static._pointerToLastSafePosition) { |
|
this$static._posLimit = |
|
this$static._pointerToLastSafePosition - this$static._bufferOffset |
|
} |
|
this$static._streamEndWasReached = 1 |
|
return |
|
} |
|
this$static._streamPos += numReadBytes |
|
if ( |
|
this$static._streamPos >= |
|
this$static._pos + this$static._keepSizeAfter |
|
) { |
|
this$static._posLimit = |
|
this$static._streamPos - this$static._keepSizeAfter |
|
} |
|
} |
|
} |
|
|
|
function $ReduceOffsets(this$static, subValue) { |
|
this$static._bufferOffset += subValue |
|
this$static._posLimit -= subValue |
|
this$static._pos -= subValue |
|
this$static._streamPos -= subValue |
|
} |
|
|
|
var CrcTable = (function() { |
|
var i, |
|
j, |
|
r, |
|
CrcTable = [] |
|
for (i = 0; i < 256; ++i) { |
|
r = i |
|
for (j = 0; j < 8; ++j) |
|
if ((r & 1) != 0) { |
|
r = (r >>> 1) ^ -306674912 |
|
} else { |
|
r >>>= 1 |
|
} |
|
CrcTable[i] = r |
|
} |
|
return CrcTable |
|
})() |
|
|
|
function $Create_3( |
|
this$static, |
|
historySize, |
|
keepAddBufferBefore, |
|
matchMaxLen, |
|
keepAddBufferAfter |
|
) { |
|
var cyclicBufferSize, hs, windowReservSize |
|
if (historySize < 1073741567) { |
|
this$static._cutValue = 16 + (matchMaxLen >> 1) |
|
windowReservSize = |
|
~~( |
|
(historySize + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / |
|
2 |
|
) + 256 |
|
$Create_4( |
|
this$static, |
|
historySize + keepAddBufferBefore, |
|
matchMaxLen + keepAddBufferAfter, |
|
windowReservSize |
|
) |
|
this$static._matchMaxLen = matchMaxLen |
|
cyclicBufferSize = historySize + 1 |
|
if (this$static._cyclicBufferSize != cyclicBufferSize) { |
|
this$static._son = initDim( |
|
(this$static._cyclicBufferSize = cyclicBufferSize) * 2 |
|
) |
|
} |
|
|
|
hs = 65536 |
|
if (this$static.HASH_ARRAY) { |
|
hs = historySize - 1 |
|
hs |= hs >> 1 |
|
hs |= hs >> 2 |
|
hs |= hs >> 4 |
|
hs |= hs >> 8 |
|
hs >>= 1 |
|
hs |= 65535 |
|
if (hs > 16777216) hs >>= 1 |
|
this$static._hashMask = hs |
|
++hs |
|
hs += this$static.kFixHashSize |
|
} |
|
|
|
if (hs != this$static._hashSizeSum) { |
|
this$static._hash = initDim((this$static._hashSizeSum = hs)) |
|
} |
|
} |
|
} |
|
|
|
function $GetMatches(this$static, distances) { |
|
var count, |
|
cur, |
|
curMatch, |
|
curMatch2, |
|
curMatch3, |
|
cyclicPos, |
|
delta, |
|
hash2Value, |
|
hash3Value, |
|
hashValue, |
|
len, |
|
len0, |
|
len1, |
|
lenLimit, |
|
matchMinPos, |
|
maxLen, |
|
offset, |
|
pby1, |
|
ptr0, |
|
ptr1, |
|
temp |
|
if (this$static._pos + this$static._matchMaxLen <= this$static._streamPos) { |
|
lenLimit = this$static._matchMaxLen |
|
} else { |
|
lenLimit = this$static._streamPos - this$static._pos |
|
if (lenLimit < this$static.kMinMatchCheck) { |
|
$MovePos_0(this$static) |
|
return 0 |
|
} |
|
} |
|
offset = 0 |
|
matchMinPos = |
|
this$static._pos > this$static._cyclicBufferSize |
|
? this$static._pos - this$static._cyclicBufferSize |
|
: 0 |
|
cur = this$static._bufferOffset + this$static._pos |
|
maxLen = 1 |
|
hash2Value = 0 |
|
hash3Value = 0 |
|
if (this$static.HASH_ARRAY) { |
|
temp = |
|
CrcTable[this$static._bufferBase[cur] & 255] ^ |
|
(this$static._bufferBase[cur + 1] & 255) |
|
hash2Value = temp & 1023 |
|
temp ^= (this$static._bufferBase[cur + 2] & 255) << 8 |
|
hash3Value = temp & 65535 |
|
hashValue = |
|
(temp ^ (CrcTable[this$static._bufferBase[cur + 3] & 255] << 5)) & |
|
this$static._hashMask |
|
} else { |
|
hashValue = |
|
(this$static._bufferBase[cur] & 255) ^ |
|
((this$static._bufferBase[cur + 1] & 255) << 8) |
|
} |
|
|
|
curMatch = this$static._hash[this$static.kFixHashSize + hashValue] || 0 |
|
if (this$static.HASH_ARRAY) { |
|
curMatch2 = this$static._hash[hash2Value] || 0 |
|
curMatch3 = this$static._hash[1024 + hash3Value] || 0 |
|
this$static._hash[hash2Value] = this$static._pos |
|
this$static._hash[1024 + hash3Value] = this$static._pos |
|
if (curMatch2 > matchMinPos) { |
|
if ( |
|
this$static._bufferBase[this$static._bufferOffset + curMatch2] == |
|
this$static._bufferBase[cur] |
|
) { |
|
distances[offset++] = maxLen = 2 |
|
distances[offset++] = this$static._pos - curMatch2 - 1 |
|
} |
|
} |
|
if (curMatch3 > matchMinPos) { |
|
if ( |
|
this$static._bufferBase[this$static._bufferOffset + curMatch3] == |
|
this$static._bufferBase[cur] |
|
) { |
|
if (curMatch3 == curMatch2) { |
|
offset -= 2 |
|
} |
|
distances[offset++] = maxLen = 3 |
|
distances[offset++] = this$static._pos - curMatch3 - 1 |
|
curMatch2 = curMatch3 |
|
} |
|
} |
|
if (offset != 0 && curMatch2 == curMatch) { |
|
offset -= 2 |
|
maxLen = 1 |
|
} |
|
} |
|
this$static._hash[this$static.kFixHashSize + hashValue] = this$static._pos |
|
ptr0 = (this$static._cyclicBufferPos << 1) + 1 |
|
ptr1 = this$static._cyclicBufferPos << 1 |
|
len0 = len1 = this$static.kNumHashDirectBytes |
|
if (this$static.kNumHashDirectBytes != 0) { |
|
if (curMatch > matchMinPos) { |
|
if ( |
|
this$static._bufferBase[ |
|
this$static._bufferOffset + curMatch + this$static.kNumHashDirectBytes |
|
] != this$static._bufferBase[cur + this$static.kNumHashDirectBytes] |
|
) { |
|
distances[offset++] = maxLen = this$static.kNumHashDirectBytes |
|
distances[offset++] = this$static._pos - curMatch - 1 |
|
} |
|
} |
|
} |
|
count = this$static._cutValue |
|
while (1) { |
|
if (curMatch <= matchMinPos || count-- == 0) { |
|
this$static._son[ptr0] = this$static._son[ptr1] = 0 |
|
break |
|
} |
|
delta = this$static._pos - curMatch |
|
cyclicPos = |
|
(delta <= this$static._cyclicBufferPos |
|
? this$static._cyclicBufferPos - delta |
|
: this$static._cyclicBufferPos - |
|
delta + |
|
this$static._cyclicBufferSize) << 1 |
|
pby1 = this$static._bufferOffset + curMatch |
|
len = len0 < len1 ? len0 : len1 |
|
if ( |
|
this$static._bufferBase[pby1 + len] == this$static._bufferBase[cur + len] |
|
) { |
|
while (++len != lenLimit) { |
|
if ( |
|
this$static._bufferBase[pby1 + len] != |
|
this$static._bufferBase[cur + len] |
|
) { |
|
break |
|
} |
|
} |
|
if (maxLen < len) { |
|
distances[offset++] = maxLen = len |
|
distances[offset++] = delta - 1 |
|
if (len == lenLimit) { |
|
this$static._son[ptr1] = this$static._son[cyclicPos] |
|
this$static._son[ptr0] = this$static._son[cyclicPos + 1] |
|
break |
|
} |
|
} |
|
} |
|
if ( |
|
(this$static._bufferBase[pby1 + len] & 255) < |
|
(this$static._bufferBase[cur + len] & 255) |
|
) { |
|
this$static._son[ptr1] = curMatch |
|
ptr1 = cyclicPos + 1 |
|
curMatch = this$static._son[ptr1] |
|
len1 = len |
|
} else { |
|
this$static._son[ptr0] = curMatch |
|
ptr0 = cyclicPos |
|
curMatch = this$static._son[ptr0] |
|
len0 = len |
|
} |
|
} |
|
$MovePos_0(this$static) |
|
return offset |
|
} |
|
|
|
function $Init_5(this$static) { |
|
this$static._bufferOffset = 0 |
|
this$static._pos = 0 |
|
this$static._streamPos = 0 |
|
this$static._streamEndWasReached = 0 |
|
$ReadBlock(this$static) |
|
this$static._cyclicBufferPos = 0 |
|
$ReduceOffsets(this$static, -1) |
|
} |
|
|
|
function $MovePos_0(this$static) { |
|
var subValue |
|
if (++this$static._cyclicBufferPos >= this$static._cyclicBufferSize) { |
|
this$static._cyclicBufferPos = 0 |
|
} |
|
$MovePos_1(this$static) |
|
if (this$static._pos == 1073741823) { |
|
subValue = this$static._pos - this$static._cyclicBufferSize |
|
$NormalizeLinks( |
|
this$static._son, |
|
this$static._cyclicBufferSize * 2, |
|
subValue |
|
) |
|
$NormalizeLinks(this$static._hash, this$static._hashSizeSum, subValue) |
|
$ReduceOffsets(this$static, subValue) |
|
} |
|
} |
|
|
|
// NOTE: This is only called after reading one whole gigabyte. |
|
function $NormalizeLinks(items, numItems, subValue) { |
|
var i, value |
|
for (i = 0; i < numItems; ++i) { |
|
value = items[i] || 0 |
|
if (value <= subValue) { |
|
value = 0 |
|
} else { |
|
value -= subValue |
|
} |
|
items[i] = value |
|
} |
|
} |
|
|
|
function $SetType(this$static, numHashBytes) { |
|
this$static.HASH_ARRAY = numHashBytes > 2 |
|
if (this$static.HASH_ARRAY) { |
|
this$static.kNumHashDirectBytes = 0 |
|
this$static.kMinMatchCheck = 4 |
|
this$static.kFixHashSize = 66560 |
|
} else { |
|
this$static.kNumHashDirectBytes = 2 |
|
this$static.kMinMatchCheck = 3 |
|
this$static.kFixHashSize = 0 |
|
} |
|
} |
|
|
|
function $Skip(this$static, num) { |
|
var count, |
|
cur, |
|
curMatch, |
|
cyclicPos, |
|
delta, |
|
hash2Value, |
|
hash3Value, |
|
hashValue, |
|
len, |
|
len0, |
|
len1, |
|
lenLimit, |
|
matchMinPos, |
|
pby1, |
|
ptr0, |
|
ptr1, |
|
temp |
|
do { |
|
if (this$static._pos + this$static._matchMaxLen <= this$static._streamPos) { |
|
lenLimit = this$static._matchMaxLen |
|
} else { |
|
lenLimit = this$static._streamPos - this$static._pos |
|
if (lenLimit < this$static.kMinMatchCheck) { |
|
$MovePos_0(this$static) |
|
continue |
|
} |
|
} |
|
matchMinPos = |
|
this$static._pos > this$static._cyclicBufferSize |
|
? this$static._pos - this$static._cyclicBufferSize |
|
: 0 |
|
cur = this$static._bufferOffset + this$static._pos |
|
if (this$static.HASH_ARRAY) { |
|
temp = |
|
CrcTable[this$static._bufferBase[cur] & 255] ^ |
|
(this$static._bufferBase[cur + 1] & 255) |
|
hash2Value = temp & 1023 |
|
this$static._hash[hash2Value] = this$static._pos |
|
temp ^= (this$static._bufferBase[cur + 2] & 255) << 8 |
|
hash3Value = temp & 65535 |
|
this$static._hash[1024 + hash3Value] = this$static._pos |
|
hashValue = |
|
(temp ^ (CrcTable[this$static._bufferBase[cur + 3] & 255] << 5)) & |
|
this$static._hashMask |
|
} else { |
|
hashValue = |
|
(this$static._bufferBase[cur] & 255) ^ |
|
((this$static._bufferBase[cur + 1] & 255) << 8) |
|
} |
|
curMatch = this$static._hash[this$static.kFixHashSize + hashValue] |
|
this$static._hash[this$static.kFixHashSize + hashValue] = this$static._pos |
|
ptr0 = (this$static._cyclicBufferPos << 1) + 1 |
|
ptr1 = this$static._cyclicBufferPos << 1 |
|
len0 = len1 = this$static.kNumHashDirectBytes |
|
count = this$static._cutValue |
|
while (1) { |
|
if (curMatch <= matchMinPos || count-- == 0) { |
|
this$static._son[ptr0] = this$static._son[ptr1] = 0 |
|
break |
|
} |
|
delta = this$static._pos - curMatch |
|
cyclicPos = |
|
(delta <= this$static._cyclicBufferPos |
|
? this$static._cyclicBufferPos - delta |
|
: this$static._cyclicBufferPos - |
|
delta + |
|
this$static._cyclicBufferSize) << 1 |
|
pby1 = this$static._bufferOffset + curMatch |
|
len = len0 < len1 ? len0 : len1 |
|
if ( |
|
this$static._bufferBase[pby1 + len] == |
|
this$static._bufferBase[cur + len] |
|
) { |
|
while (++len != lenLimit) { |
|
if ( |
|
this$static._bufferBase[pby1 + len] != |
|
this$static._bufferBase[cur + len] |
|
) { |
|
break |
|
} |
|
} |
|
if (len == lenLimit) { |
|
this$static._son[ptr1] = this$static._son[cyclicPos] |
|
this$static._son[ptr0] = this$static._son[cyclicPos + 1] |
|
break |
|
} |
|
} |
|
if ( |
|
(this$static._bufferBase[pby1 + len] & 255) < |
|
(this$static._bufferBase[cur + len] & 255) |
|
) { |
|
this$static._son[ptr1] = curMatch |
|
ptr1 = cyclicPos + 1 |
|
curMatch = this$static._son[ptr1] |
|
len1 = len |
|
} else { |
|
this$static._son[ptr0] = curMatch |
|
ptr0 = cyclicPos |
|
curMatch = this$static._son[ptr0] |
|
len0 = len |
|
} |
|
} |
|
$MovePos_0(this$static) |
|
} while (--num != 0) |
|
} |
|
function $CopyBlock(this$static, distance, len) { |
|
var pos = this$static._pos - distance - 1 |
|
if (pos < 0) { |
|
pos += this$static._windowSize |
|
} |
|
for (; len != 0; --len) { |
|
if (pos >= this$static._windowSize) { |
|
pos = 0 |
|
} |
|
this$static._buffer[this$static._pos++] = this$static._buffer[pos++] |
|
if (this$static._pos >= this$static._windowSize) { |
|
$Flush_0(this$static) |
|
} |
|
} |
|
} |
|
|
|
function $Create_5(this$static, windowSize) { |
|
if (this$static._buffer == null || this$static._windowSize != windowSize) { |
|
this$static._buffer = initDim(windowSize) |
|
} |
|
this$static._windowSize = windowSize |
|
this$static._pos = 0 |
|
this$static._streamPos = 0 |
|
} |
|
|
|
function $Flush_0(this$static) { |
|
var size = this$static._pos - this$static._streamPos |
|
if (!size) { |
|
return |
|
} |
|
$write_0( |
|
this$static._stream, |
|
this$static._buffer, |
|
this$static._streamPos, |
|
size |
|
) |
|
if (this$static._pos >= this$static._windowSize) { |
|
this$static._pos = 0 |
|
} |
|
this$static._streamPos = this$static._pos |
|
} |
|
|
|
function $GetByte(this$static, distance) { |
|
var pos = this$static._pos - distance - 1 |
|
if (pos < 0) { |
|
pos += this$static._windowSize |
|
} |
|
return this$static._buffer[pos] |
|
} |
|
|
|
function $PutByte(this$static, b) { |
|
this$static._buffer[this$static._pos++] = b |
|
if (this$static._pos >= this$static._windowSize) { |
|
$Flush_0(this$static) |
|
} |
|
} |
|
|
|
function $ReleaseStream(this$static) { |
|
$Flush_0(this$static) |
|
this$static._stream = null |
|
} |
|
function GetLenToPosState(len) { |
|
len -= 2 |
|
if (len < 4) { |
|
return len |
|
} |
|
return 3 |
|
} |
|
|
|
function StateUpdateChar(index) { |
|
if (index < 4) { |
|
return 0 |
|
} |
|
if (index < 10) { |
|
return index - 3 |
|
} |
|
return index - 6 |
|
} |
|
function $Chunker_0(this$static, encoder) { |
|
this$static.encoder = encoder |
|
this$static.decoder = null |
|
this$static.alive = 1 |
|
return this$static |
|
} |
|
function $Chunker(this$static, decoder) { |
|
this$static.decoder = decoder |
|
this$static.encoder = null |
|
this$static.alive = 1 |
|
return this$static |
|
} |
|
function $processChunk(this$static) { |
|
if (!this$static.alive) { |
|
throw new Error('bad state') |
|
} |
|
|
|
if (this$static.encoder) { |
|
$processEncoderChunk(this$static) |
|
} else { |
|
$processDecoderChunk(this$static) |
|
} |
|
|
|
return this$static.alive |
|
} |
|
function $processDecoderChunk(this$static) { |
|
var result = $CodeOneChunk(this$static.decoder) |
|
if (result == -1) { |
|
throw new Error('corrupted input') |
|
} |
|
this$static.inBytesProcessed = N1_longLit |
|
this$static.outBytesProcessed = this$static.decoder.nowPos64 |
|
if ( |
|
result || |
|
(compare(this$static.decoder.outSize, P0_longLit) >= 0 && |
|
compare(this$static.decoder.nowPos64, this$static.decoder.outSize) >= 0) |
|
) { |
|
$Flush_0(this$static.decoder.m_OutWindow) |
|
$ReleaseStream(this$static.decoder.m_OutWindow) |
|
this$static.decoder.m_RangeDecoder.Stream = null |
|
this$static.alive = 0 |
|
} |
|
} |
|
function $processEncoderChunk(this$static) { |
|
$CodeOneBlock( |
|
this$static.encoder, |
|
this$static.encoder.processedInSize, |
|
this$static.encoder.processedOutSize, |
|
this$static.encoder.finished |
|
) |
|
this$static.inBytesProcessed = this$static.encoder.processedInSize[0] |
|
if (this$static.encoder.finished[0]) { |
|
$ReleaseStreams(this$static.encoder) |
|
this$static.alive = 0 |
|
} |
|
} |
|
function $CodeInChunks(this$static, inStream, outStream, outSize) { |
|
this$static.m_RangeDecoder.Stream = inStream |
|
$ReleaseStream(this$static.m_OutWindow) |
|
this$static.m_OutWindow._stream = outStream |
|
$Init_1(this$static) |
|
this$static.state = 0 |
|
this$static.rep0 = 0 |
|
this$static.rep1 = 0 |
|
this$static.rep2 = 0 |
|
this$static.rep3 = 0 |
|
this$static.outSize = outSize |
|
this$static.nowPos64 = P0_longLit |
|
this$static.prevByte = 0 |
|
return $Chunker({}, this$static) |
|
} |
|
|
|
function $CodeOneChunk(this$static) { |
|
var decoder2, distance, len, numDirectBits, posSlot, posState |
|
posState = lowBits_0(this$static.nowPos64) & this$static.m_PosStateMask |
|
if ( |
|
!$DecodeBit( |
|
this$static.m_RangeDecoder, |
|
this$static.m_IsMatchDecoders, |
|
(this$static.state << 4) + posState |
|
) |
|
) { |
|
decoder2 = $GetDecoder( |
|
this$static.m_LiteralDecoder, |
|
lowBits_0(this$static.nowPos64), |
|
this$static.prevByte |
|
) |
|
if (this$static.state < 7) { |
|
this$static.prevByte = $DecodeNormal(decoder2, this$static.m_RangeDecoder) |
|
} else { |
|
this$static.prevByte = $DecodeWithMatchByte( |
|
decoder2, |
|
this$static.m_RangeDecoder, |
|
$GetByte(this$static.m_OutWindow, this$static.rep0) |
|
) |
|
} |
|
$PutByte(this$static.m_OutWindow, this$static.prevByte) |
|
this$static.state = StateUpdateChar(this$static.state) |
|
this$static.nowPos64 = add(this$static.nowPos64, P1_longLit) |
|
} else { |
|
if ( |
|
$DecodeBit( |
|
this$static.m_RangeDecoder, |
|
this$static.m_IsRepDecoders, |
|
this$static.state |
|
) |
|
) { |
|
len = 0 |
|
if ( |
|
!$DecodeBit( |
|
this$static.m_RangeDecoder, |
|
this$static.m_IsRepG0Decoders, |
|
this$static.state |
|
) |
|
) { |
|
if ( |
|
!$DecodeBit( |
|
this$static.m_RangeDecoder, |
|
this$static.m_IsRep0LongDecoders, |
|
(this$static.state << 4) + posState |
|
) |
|
) { |
|
this$static.state = this$static.state < 7 ? 9 : 11 |
|
len = 1 |
|
} |
|
} else { |
|
if ( |
|
!$DecodeBit( |
|
this$static.m_RangeDecoder, |
|
this$static.m_IsRepG1Decoders, |
|
this$static.state |
|
) |
|
) { |
|
distance = this$static.rep1 |
|
} else { |
|
if ( |
|
!$DecodeBit( |
|
this$static.m_RangeDecoder, |
|
this$static.m_IsRepG2Decoders, |
|
this$static.state |
|
) |
|
) { |
|
distance = this$static.rep2 |
|
} else { |
|
distance = this$static.rep3 |
|
this$static.rep3 = this$static.rep2 |
|
} |
|
this$static.rep2 = this$static.rep1 |
|
} |
|
this$static.rep1 = this$static.rep0 |
|
this$static.rep0 = distance |
|
} |
|
if (!len) { |
|
len = |
|
$Decode( |
|
this$static.m_RepLenDecoder, |
|
this$static.m_RangeDecoder, |
|
posState |
|
) + 2 |
|
this$static.state = this$static.state < 7 ? 8 : 11 |
|
} |
|
} else { |
|
this$static.rep3 = this$static.rep2 |
|
this$static.rep2 = this$static.rep1 |
|
this$static.rep1 = this$static.rep0 |
|
len = |
|
2 + |
|
$Decode(this$static.m_LenDecoder, this$static.m_RangeDecoder, posState) |
|
this$static.state = this$static.state < 7 ? 7 : 10 |
|
posSlot = $Decode_0( |
|
this$static.m_PosSlotDecoder[GetLenToPosState(len)], |
|
this$static.m_RangeDecoder |
|
) |
|
if (posSlot >= 4) { |
|
numDirectBits = (posSlot >> 1) - 1 |
|
this$static.rep0 = (2 | (posSlot & 1)) << numDirectBits |
|
if (posSlot < 14) { |
|
this$static.rep0 += ReverseDecode( |
|
this$static.m_PosDecoders, |
|
this$static.rep0 - posSlot - 1, |
|
this$static.m_RangeDecoder, |
|
numDirectBits |
|
) |
|
} else { |
|
this$static.rep0 += |
|
$DecodeDirectBits(this$static.m_RangeDecoder, numDirectBits - 4) << |
|
4 |
|
this$static.rep0 += $ReverseDecode( |
|
this$static.m_PosAlignDecoder, |
|
this$static.m_RangeDecoder |
|
) |
|
if (this$static.rep0 < 0) { |
|
if (this$static.rep0 == -1) { |
|
return 1 |
|
} |
|
return -1 |
|
} |
|
} |
|
} else this$static.rep0 = posSlot |
|
} |
|
if ( |
|
compare(fromInt(this$static.rep0), this$static.nowPos64) >= 0 || |
|
this$static.rep0 >= this$static.m_DictionarySizeCheck |
|
) { |
|
return -1 |
|
} |
|
$CopyBlock(this$static.m_OutWindow, this$static.rep0, len) |
|
this$static.nowPos64 = add(this$static.nowPos64, fromInt(len)) |
|
this$static.prevByte = $GetByte(this$static.m_OutWindow, 0) |
|
} |
|
return 0 |
|
} |
|
|
|
function $Decoder(this$static) { |
|
this$static.m_OutWindow = {} |
|
this$static.m_RangeDecoder = {} |
|
this$static.m_IsMatchDecoders = initDim(192) |
|
this$static.m_IsRepDecoders = initDim(12) |
|
this$static.m_IsRepG0Decoders = initDim(12) |
|
this$static.m_IsRepG1Decoders = initDim(12) |
|
this$static.m_IsRepG2Decoders = initDim(12) |
|
this$static.m_IsRep0LongDecoders = initDim(192) |
|
this$static.m_PosSlotDecoder = initDim(4) |
|
this$static.m_PosDecoders = initDim(114) |
|
this$static.m_PosAlignDecoder = $BitTreeDecoder({}, 4) |
|
this$static.m_LenDecoder = $Decoder$LenDecoder({}) |
|
this$static.m_RepLenDecoder = $Decoder$LenDecoder({}) |
|
this$static.m_LiteralDecoder = {} |
|
for (var i = 0; i < 4; ++i) { |
|
this$static.m_PosSlotDecoder[i] = $BitTreeDecoder({}, 6) |
|
} |
|
return this$static |
|
} |
|
|
|
function $Init_1(this$static) { |
|
this$static.m_OutWindow._streamPos = 0 |
|
this$static.m_OutWindow._pos = 0 |
|
InitBitModels(this$static.m_IsMatchDecoders) |
|
InitBitModels(this$static.m_IsRep0LongDecoders) |
|
InitBitModels(this$static.m_IsRepDecoders) |
|
InitBitModels(this$static.m_IsRepG0Decoders) |
|
InitBitModels(this$static.m_IsRepG1Decoders) |
|
InitBitModels(this$static.m_IsRepG2Decoders) |
|
InitBitModels(this$static.m_PosDecoders) |
|
$Init_0(this$static.m_LiteralDecoder) |
|
for (var i = 0; i < 4; ++i) { |
|
InitBitModels(this$static.m_PosSlotDecoder[i].Models) |
|
} |
|
$Init(this$static.m_LenDecoder) |
|
$Init(this$static.m_RepLenDecoder) |
|
InitBitModels(this$static.m_PosAlignDecoder.Models) |
|
$Init_8(this$static.m_RangeDecoder) |
|
} |
|
|
|
function $SetDecoderProperties(this$static, properties) { |
|
var dictionarySize, i, lc, lp, pb, remainder, val |
|
if (properties.length < 5) return 0 |
|
val = properties[0] & 255 |
|
lc = val % 9 |
|
remainder = ~~(val / 9) |
|
lp = remainder % 5 |
|
pb = ~~(remainder / 5) |
|
dictionarySize = 0 |
|
for (i = 0; i < 4; ++i) { |
|
dictionarySize += (properties[1 + i] & 255) << (i * 8) |
|
} |
|
// NOTE: If the input is bad, it might call for an insanely large dictionary size, which would crash the script. |
|
if (dictionarySize > 99999999 || !$SetLcLpPb(this$static, lc, lp, pb)) { |
|
return 0 |
|
} |
|
return $SetDictionarySize(this$static, dictionarySize) |
|
} |
|
|
|
function $SetDictionarySize(this$static, dictionarySize) { |
|
if (dictionarySize < 0) { |
|
return 0 |
|
} |
|
if (this$static.m_DictionarySize != dictionarySize) { |
|
this$static.m_DictionarySize = dictionarySize |
|
this$static.m_DictionarySizeCheck = Math.max( |
|
this$static.m_DictionarySize, |
|
1 |
|
) |
|
$Create_5( |
|
this$static.m_OutWindow, |
|
Math.max(this$static.m_DictionarySizeCheck, 4096) |
|
) |
|
} |
|
return 1 |
|
} |
|
|
|
function $SetLcLpPb(this$static, lc, lp, pb) { |
|
if (lc > 8 || lp > 4 || pb > 4) { |
|
return 0 |
|
} |
|
$Create_0(this$static.m_LiteralDecoder, lp, lc) |
|
var numPosStates = 1 << pb |
|
$Create(this$static.m_LenDecoder, numPosStates) |
|
$Create(this$static.m_RepLenDecoder, numPosStates) |
|
this$static.m_PosStateMask = numPosStates - 1 |
|
return 1 |
|
} |
|
|
|
function $Create(this$static, numPosStates) { |
|
for ( |
|
; |
|
this$static.m_NumPosStates < numPosStates; |
|
++this$static.m_NumPosStates |
|
) { |
|
this$static.m_LowCoder[this$static.m_NumPosStates] = $BitTreeDecoder({}, 3) |
|
this$static.m_MidCoder[this$static.m_NumPosStates] = $BitTreeDecoder({}, 3) |
|
} |
|
} |
|
|
|
function $Decode(this$static, rangeDecoder, posState) { |
|
if (!$DecodeBit(rangeDecoder, this$static.m_Choice, 0)) { |
|
return $Decode_0(this$static.m_LowCoder[posState], rangeDecoder) |
|
} |
|
var symbol = 8 |
|
if (!$DecodeBit(rangeDecoder, this$static.m_Choice, 1)) { |
|
symbol += $Decode_0(this$static.m_MidCoder[posState], rangeDecoder) |
|
} else { |
|
symbol += 8 + $Decode_0(this$static.m_HighCoder, rangeDecoder) |
|
} |
|
return symbol |
|
} |
|
|
|
function $Decoder$LenDecoder(this$static) { |
|
this$static.m_Choice = initDim(2) |
|
this$static.m_LowCoder = initDim(16) |
|
this$static.m_MidCoder = initDim(16) |
|
this$static.m_HighCoder = $BitTreeDecoder({}, 8) |
|
this$static.m_NumPosStates = 0 |
|
return this$static |
|
} |
|
|
|
function $Init(this$static) { |
|
InitBitModels(this$static.m_Choice) |
|
for (var posState = 0; posState < this$static.m_NumPosStates; ++posState) { |
|
InitBitModels(this$static.m_LowCoder[posState].Models) |
|
InitBitModels(this$static.m_MidCoder[posState].Models) |
|
} |
|
InitBitModels(this$static.m_HighCoder.Models) |
|
} |
|
|
|
function $Create_0(this$static, numPosBits, numPrevBits) { |
|
var i, numStates |
|
if ( |
|
this$static.m_Coders != null && |
|
this$static.m_NumPrevBits == numPrevBits && |
|
this$static.m_NumPosBits == numPosBits |
|
) |
|
return |
|
this$static.m_NumPosBits = numPosBits |
|
this$static.m_PosMask = (1 << numPosBits) - 1 |
|
this$static.m_NumPrevBits = numPrevBits |
|
numStates = 1 << (this$static.m_NumPrevBits + this$static.m_NumPosBits) |
|
this$static.m_Coders = initDim(numStates) |
|
for (i = 0; i < numStates; ++i) |
|
this$static.m_Coders[i] = $Decoder$LiteralDecoder$Decoder2({}) |
|
} |
|
|
|
function $GetDecoder(this$static, pos, prevByte) { |
|
return this$static.m_Coders[ |
|
((pos & this$static.m_PosMask) << this$static.m_NumPrevBits) + |
|
((prevByte & 255) >>> (8 - this$static.m_NumPrevBits)) |
|
] |
|
} |
|
|
|
function $Init_0(this$static) { |
|
var i, numStates |
|
numStates = 1 << (this$static.m_NumPrevBits + this$static.m_NumPosBits) |
|
for (i = 0; i < numStates; ++i) { |
|
InitBitModels(this$static.m_Coders[i].m_Decoders) |
|
} |
|
} |
|
|
|
function $DecodeNormal(this$static, rangeDecoder) { |
|
var symbol = 1 |
|
do { |
|
symbol = |
|
(symbol << 1) | $DecodeBit(rangeDecoder, this$static.m_Decoders, symbol) |
|
} while (symbol < 256) |
|
return (symbol << 24) >> 24 |
|
} |
|
|
|
function $DecodeWithMatchByte(this$static, rangeDecoder, matchByte) { |
|
var bit, |
|
matchBit, |
|
symbol = 1 |
|
do { |
|
matchBit = (matchByte >> 7) & 1 |
|
matchByte <<= 1 |
|
bit = $DecodeBit( |
|
rangeDecoder, |
|
this$static.m_Decoders, |
|
((1 + matchBit) << 8) + symbol |
|
) |
|
symbol = (symbol << 1) | bit |
|
if (matchBit != bit) { |
|
while (symbol < 256) { |
|
symbol = |
|
(symbol << 1) | |
|
$DecodeBit(rangeDecoder, this$static.m_Decoders, symbol) |
|
} |
|
break |
|
} |
|
} while (symbol < 256) |
|
return (symbol << 24) >> 24 |
|
} |
|
|
|
function $Decoder$LiteralDecoder$Decoder2(this$static) { |
|
this$static.m_Decoders = initDim(768) |
|
return this$static |
|
} |
|
var g_FastPos = (function() { |
|
var j, |
|
k, |
|
slotFast, |
|
c = 2, |
|
g_FastPos = [0, 1] |
|
for (slotFast = 2; slotFast < 22; ++slotFast) { |
|
k = 1 << ((slotFast >> 1) - 1) |
|
for (j = 0; j < k; ++j, ++c) g_FastPos[c] = (slotFast << 24) >> 24 |
|
} |
|
return g_FastPos |
|
})() |
|
|
|
function $Backward(this$static, cur) { |
|
var backCur, backMem, posMem, posPrev |
|
this$static._optimumEndIndex = cur |
|
posMem = this$static._optimum[cur].PosPrev |
|
backMem = this$static._optimum[cur].BackPrev |
|
do { |
|
if (this$static._optimum[cur].Prev1IsChar) { |
|
$MakeAsChar(this$static._optimum[posMem]) |
|
this$static._optimum[posMem].PosPrev = posMem - 1 |
|
if (this$static._optimum[cur].Prev2) { |
|
this$static._optimum[posMem - 1].Prev1IsChar = 0 |
|
this$static._optimum[posMem - 1].PosPrev = |
|
this$static._optimum[cur].PosPrev2 |
|
this$static._optimum[posMem - 1].BackPrev = |
|
this$static._optimum[cur].BackPrev2 |
|
} |
|
} |
|
posPrev = posMem |
|
backCur = backMem |
|
backMem = this$static._optimum[posPrev].BackPrev |
|
posMem = this$static._optimum[posPrev].PosPrev |
|
this$static._optimum[posPrev].BackPrev = backCur |
|
this$static._optimum[posPrev].PosPrev = cur |
|
cur = posPrev |
|
} while (cur > 0) |
|
this$static.backRes = this$static._optimum[0].BackPrev |
|
this$static._optimumCurrentIndex = this$static._optimum[0].PosPrev |
|
return this$static._optimumCurrentIndex |
|
} |
|
|
|
function $BaseInit(this$static) { |
|
this$static._state = 0 |
|
this$static._previousByte = 0 |
|
for (var i = 0; i < 4; ++i) { |
|
this$static._repDistances[i] = 0 |
|
} |
|
} |
|
|
|
function $CodeOneBlock(this$static, inSize, outSize, finished) { |
|
var baseVal, |
|
complexState, |
|
curByte, |
|
distance, |
|
footerBits, |
|
i, |
|
len, |
|
lenToPosState, |
|
matchByte, |
|
pos, |
|
posReduced, |
|
posSlot, |
|
posState, |
|
progressPosValuePrev, |
|
subCoder |
|
inSize[0] = P0_longLit |
|
outSize[0] = P0_longLit |
|
finished[0] = 1 |
|
if (this$static._inStream) { |
|
this$static._matchFinder._stream = this$static._inStream |
|
$Init_5(this$static._matchFinder) |
|
this$static._needReleaseMFStream = 1 |
|
this$static._inStream = null |
|
} |
|
if (this$static._finished) { |
|
return |
|
} |
|
this$static._finished = 1 |
|
progressPosValuePrev = this$static.nowPos64 |
|
if (eq(this$static.nowPos64, P0_longLit)) { |
|
if (!$GetNumAvailableBytes(this$static._matchFinder)) { |
|
$Flush(this$static, lowBits_0(this$static.nowPos64)) |
|
return |
|
} |
|
$ReadMatchDistances(this$static) |
|
posState = lowBits_0(this$static.nowPos64) & this$static._posStateMask |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isMatch, |
|
(this$static._state << 4) + posState, |
|
0 |
|
) |
|
this$static._state = StateUpdateChar(this$static._state) |
|
curByte = $GetIndexByte( |
|
this$static._matchFinder, |
|
-this$static._additionalOffset |
|
) |
|
$Encode_1( |
|
$GetSubCoder( |
|
this$static._literalEncoder, |
|
lowBits_0(this$static.nowPos64), |
|
this$static._previousByte |
|
), |
|
this$static._rangeEncoder, |
|
curByte |
|
) |
|
this$static._previousByte = curByte |
|
--this$static._additionalOffset |
|
this$static.nowPos64 = add(this$static.nowPos64, P1_longLit) |
|
} |
|
if (!$GetNumAvailableBytes(this$static._matchFinder)) { |
|
$Flush(this$static, lowBits_0(this$static.nowPos64)) |
|
return |
|
} |
|
while (1) { |
|
len = $GetOptimum(this$static, lowBits_0(this$static.nowPos64)) |
|
pos = this$static.backRes |
|
posState = lowBits_0(this$static.nowPos64) & this$static._posStateMask |
|
complexState = (this$static._state << 4) + posState |
|
if (len == 1 && pos == -1) { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isMatch, |
|
complexState, |
|
0 |
|
) |
|
curByte = $GetIndexByte( |
|
this$static._matchFinder, |
|
-this$static._additionalOffset |
|
) |
|
subCoder = $GetSubCoder( |
|
this$static._literalEncoder, |
|
lowBits_0(this$static.nowPos64), |
|
this$static._previousByte |
|
) |
|
if (this$static._state < 7) { |
|
$Encode_1(subCoder, this$static._rangeEncoder, curByte) |
|
} else { |
|
matchByte = $GetIndexByte( |
|
this$static._matchFinder, |
|
-this$static._repDistances[0] - 1 - this$static._additionalOffset |
|
) |
|
$EncodeMatched(subCoder, this$static._rangeEncoder, matchByte, curByte) |
|
} |
|
this$static._previousByte = curByte |
|
this$static._state = StateUpdateChar(this$static._state) |
|
} else { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isMatch, |
|
complexState, |
|
1 |
|
) |
|
if (pos < 4) { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRep, |
|
this$static._state, |
|
1 |
|
) |
|
if (!pos) { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRepG0, |
|
this$static._state, |
|
0 |
|
) |
|
if (len == 1) { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRep0Long, |
|
complexState, |
|
0 |
|
) |
|
} else { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRep0Long, |
|
complexState, |
|
1 |
|
) |
|
} |
|
} else { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRepG0, |
|
this$static._state, |
|
1 |
|
) |
|
if (pos == 1) { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRepG1, |
|
this$static._state, |
|
0 |
|
) |
|
} else { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRepG1, |
|
this$static._state, |
|
1 |
|
) |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRepG2, |
|
this$static._state, |
|
pos - 2 |
|
) |
|
} |
|
} |
|
if (len == 1) { |
|
this$static._state = this$static._state < 7 ? 9 : 11 |
|
} else { |
|
$Encode_0( |
|
this$static._repMatchLenEncoder, |
|
this$static._rangeEncoder, |
|
len - 2, |
|
posState |
|
) |
|
this$static._state = this$static._state < 7 ? 8 : 11 |
|
} |
|
distance = this$static._repDistances[pos] |
|
if (pos != 0) { |
|
for (i = pos; i >= 1; --i) { |
|
this$static._repDistances[i] = this$static._repDistances[i - 1] |
|
} |
|
this$static._repDistances[0] = distance |
|
} |
|
} else { |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRep, |
|
this$static._state, |
|
0 |
|
) |
|
this$static._state = this$static._state < 7 ? 7 : 10 |
|
$Encode_0( |
|
this$static._lenEncoder, |
|
this$static._rangeEncoder, |
|
len - 2, |
|
posState |
|
) |
|
pos -= 4 |
|
posSlot = GetPosSlot(pos) |
|
lenToPosState = GetLenToPosState(len) |
|
$Encode_2( |
|
this$static._posSlotEncoder[lenToPosState], |
|
this$static._rangeEncoder, |
|
posSlot |
|
) |
|
if (posSlot >= 4) { |
|
footerBits = (posSlot >> 1) - 1 |
|
baseVal = (2 | (posSlot & 1)) << footerBits |
|
posReduced = pos - baseVal |
|
if (posSlot < 14) { |
|
ReverseEncode( |
|
this$static._posEncoders, |
|
baseVal - posSlot - 1, |
|
this$static._rangeEncoder, |
|
footerBits, |
|
posReduced |
|
) |
|
} else { |
|
$EncodeDirectBits( |
|
this$static._rangeEncoder, |
|
posReduced >> 4, |
|
footerBits - 4 |
|
) |
|
$ReverseEncode( |
|
this$static._posAlignEncoder, |
|
this$static._rangeEncoder, |
|
posReduced & 15 |
|
) |
|
++this$static._alignPriceCount |
|
} |
|
} |
|
distance = pos |
|
for (i = 3; i >= 1; --i) { |
|
this$static._repDistances[i] = this$static._repDistances[i - 1] |
|
} |
|
this$static._repDistances[0] = distance |
|
++this$static._matchPriceCount |
|
} |
|
this$static._previousByte = $GetIndexByte( |
|
this$static._matchFinder, |
|
len - 1 - this$static._additionalOffset |
|
) |
|
} |
|
this$static._additionalOffset -= len |
|
this$static.nowPos64 = add(this$static.nowPos64, fromInt(len)) |
|
if (!this$static._additionalOffset) { |
|
if (this$static._matchPriceCount >= 128) { |
|
$FillDistancesPrices(this$static) |
|
} |
|
if (this$static._alignPriceCount >= 16) { |
|
$FillAlignPrices(this$static) |
|
} |
|
inSize[0] = this$static.nowPos64 |
|
outSize[0] = $GetProcessedSizeAdd(this$static._rangeEncoder) |
|
if (!$GetNumAvailableBytes(this$static._matchFinder)) { |
|
$Flush(this$static, lowBits_0(this$static.nowPos64)) |
|
return |
|
} |
|
if ( |
|
compare(sub(this$static.nowPos64, progressPosValuePrev), [4096, 0]) >= 0 |
|
) { |
|
this$static._finished = 0 |
|
finished[0] = 0 |
|
return |
|
} |
|
} |
|
} |
|
} |
|
|
|
function $Create_2(this$static) { |
|
var bt, numHashBytes |
|
if (!this$static._matchFinder) { |
|
bt = {} |
|
numHashBytes = 4 |
|
if (!this$static._matchFinderType) { |
|
numHashBytes = 2 |
|
} |
|
$SetType(bt, numHashBytes) |
|
this$static._matchFinder = bt |
|
} |
|
$Create_1( |
|
this$static._literalEncoder, |
|
this$static._numLiteralPosStateBits, |
|
this$static._numLiteralContextBits |
|
) |
|
if ( |
|
this$static._dictionarySize == this$static._dictionarySizePrev && |
|
this$static._numFastBytesPrev == this$static._numFastBytes |
|
) { |
|
return |
|
} |
|
$Create_3( |
|
this$static._matchFinder, |
|
this$static._dictionarySize, |
|
4096, |
|
this$static._numFastBytes, |
|
274 |
|
) |
|
this$static._dictionarySizePrev = this$static._dictionarySize |
|
this$static._numFastBytesPrev = this$static._numFastBytes |
|
} |
|
|
|
function $Encoder(this$static) { |
|
var i |
|
this$static._repDistances = initDim(4) |
|
this$static._optimum = [] |
|
this$static._rangeEncoder = {} |
|
this$static._isMatch = initDim(192) |
|
this$static._isRep = initDim(12) |
|
this$static._isRepG0 = initDim(12) |
|
this$static._isRepG1 = initDim(12) |
|
this$static._isRepG2 = initDim(12) |
|
this$static._isRep0Long = initDim(192) |
|
this$static._posSlotEncoder = [] |
|
this$static._posEncoders = initDim(114) |
|
this$static._posAlignEncoder = $BitTreeEncoder({}, 4) |
|
this$static._lenEncoder = $Encoder$LenPriceTableEncoder({}) |
|
this$static._repMatchLenEncoder = $Encoder$LenPriceTableEncoder({}) |
|
this$static._literalEncoder = {} |
|
this$static._matchDistances = [] |
|
this$static._posSlotPrices = [] |
|
this$static._distancesPrices = [] |
|
this$static._alignPrices = initDim(16) |
|
this$static.reps = initDim(4) |
|
this$static.repLens = initDim(4) |
|
this$static.processedInSize = [P0_longLit] |
|
this$static.processedOutSize = [P0_longLit] |
|
this$static.finished = [0] |
|
this$static.properties = initDim(5) |
|
this$static.tempPrices = initDim(128) |
|
this$static._longestMatchLength = 0 |
|
this$static._matchFinderType = 1 |
|
this$static._numDistancePairs = 0 |
|
this$static._numFastBytesPrev = -1 |
|
this$static.backRes = 0 |
|
for (i = 0; i < 4096; ++i) { |
|
this$static._optimum[i] = {} |
|
} |
|
for (i = 0; i < 4; ++i) { |
|
this$static._posSlotEncoder[i] = $BitTreeEncoder({}, 6) |
|
} |
|
return this$static |
|
} |
|
|
|
function $FillAlignPrices(this$static) { |
|
for (var i = 0; i < 16; ++i) { |
|
this$static._alignPrices[i] = $ReverseGetPrice( |
|
this$static._posAlignEncoder, |
|
i |
|
) |
|
} |
|
this$static._alignPriceCount = 0 |
|
} |
|
|
|
function $FillDistancesPrices(this$static) { |
|
var baseVal, encoder, footerBits, i, lenToPosState, posSlot, st, st2 |
|
for (i = 4; i < 128; ++i) { |
|
posSlot = GetPosSlot(i) |
|
footerBits = (posSlot >> 1) - 1 |
|
baseVal = (2 | (posSlot & 1)) << footerBits |
|
this$static.tempPrices[i] = ReverseGetPrice( |
|
this$static._posEncoders, |
|
baseVal - posSlot - 1, |
|
footerBits, |
|
i - baseVal |
|
) |
|
} |
|
for (lenToPosState = 0; lenToPosState < 4; ++lenToPosState) { |
|
encoder = this$static._posSlotEncoder[lenToPosState] |
|
st = lenToPosState << 6 |
|
for (posSlot = 0; posSlot < this$static._distTableSize; ++posSlot) { |
|
this$static._posSlotPrices[st + posSlot] = $GetPrice_1(encoder, posSlot) |
|
} |
|
for (posSlot = 14; posSlot < this$static._distTableSize; ++posSlot) { |
|
this$static._posSlotPrices[st + posSlot] += ((posSlot >> 1) - 1 - 4) << 6 |
|
} |
|
st2 = lenToPosState * 128 |
|
for (i = 0; i < 4; ++i) { |
|
this$static._distancesPrices[st2 + i] = this$static._posSlotPrices[st + i] |
|
} |
|
for (; i < 128; ++i) { |
|
this$static._distancesPrices[st2 + i] = |
|
this$static._posSlotPrices[st + GetPosSlot(i)] + |
|
this$static.tempPrices[i] |
|
} |
|
} |
|
this$static._matchPriceCount = 0 |
|
} |
|
|
|
function $Flush(this$static, nowPos) { |
|
$ReleaseMFStream(this$static) |
|
$WriteEndMarker(this$static, nowPos & this$static._posStateMask) |
|
for (var i = 0; i < 5; ++i) { |
|
$ShiftLow(this$static._rangeEncoder) |
|
} |
|
} |
|
|
|
function $GetOptimum(this$static, position) { |
|
var cur, |
|
curAnd1Price, |
|
curAndLenCharPrice, |
|
curAndLenPrice, |
|
curBack, |
|
curPrice, |
|
currentByte, |
|
distance, |
|
i, |
|
len, |
|
lenEnd, |
|
lenMain, |
|
lenRes, |
|
lenTest, |
|
lenTest2, |
|
lenTestTemp, |
|
matchByte, |
|
matchPrice, |
|
newLen, |
|
nextIsChar, |
|
nextMatchPrice, |
|
nextOptimum, |
|
nextRepMatchPrice, |
|
normalMatchPrice, |
|
numAvailableBytes, |
|
numAvailableBytesFull, |
|
numDistancePairs, |
|
offs, |
|
offset, |
|
opt, |
|
optimum, |
|
pos, |
|
posPrev, |
|
posState, |
|
posStateNext, |
|
price_4, |
|
repIndex, |
|
repLen, |
|
repMatchPrice, |
|
repMaxIndex, |
|
shortRepPrice, |
|
startLen, |
|
state, |
|
state2, |
|
t, |
|
price, |
|
price_0, |
|
price_1, |
|
price_2, |
|
price_3 |
|
if (this$static._optimumEndIndex != this$static._optimumCurrentIndex) { |
|
lenRes = |
|
this$static._optimum[this$static._optimumCurrentIndex].PosPrev - |
|
this$static._optimumCurrentIndex |
|
this$static.backRes = |
|
this$static._optimum[this$static._optimumCurrentIndex].BackPrev |
|
this$static._optimumCurrentIndex = |
|
this$static._optimum[this$static._optimumCurrentIndex].PosPrev |
|
return lenRes |
|
} |
|
this$static._optimumCurrentIndex = this$static._optimumEndIndex = 0 |
|
if (this$static._longestMatchWasFound) { |
|
lenMain = this$static._longestMatchLength |
|
this$static._longestMatchWasFound = 0 |
|
} else { |
|
lenMain = $ReadMatchDistances(this$static) |
|
} |
|
numDistancePairs = this$static._numDistancePairs |
|
numAvailableBytes = $GetNumAvailableBytes(this$static._matchFinder) + 1 |
|
if (numAvailableBytes < 2) { |
|
this$static.backRes = -1 |
|
return 1 |
|
} |
|
if (numAvailableBytes > 273) { |
|
numAvailableBytes = 273 |
|
} |
|
repMaxIndex = 0 |
|
for (i = 0; i < 4; ++i) { |
|
this$static.reps[i] = this$static._repDistances[i] |
|
this$static.repLens[i] = $GetMatchLen( |
|
this$static._matchFinder, |
|
-1, |
|
this$static.reps[i], |
|
273 |
|
) |
|
if (this$static.repLens[i] > this$static.repLens[repMaxIndex]) { |
|
repMaxIndex = i |
|
} |
|
} |
|
if (this$static.repLens[repMaxIndex] >= this$static._numFastBytes) { |
|
this$static.backRes = repMaxIndex |
|
lenRes = this$static.repLens[repMaxIndex] |
|
$MovePos(this$static, lenRes - 1) |
|
return lenRes |
|
} |
|
if (lenMain >= this$static._numFastBytes) { |
|
this$static.backRes = this$static._matchDistances[numDistancePairs - 1] + 4 |
|
$MovePos(this$static, lenMain - 1) |
|
return lenMain |
|
} |
|
currentByte = $GetIndexByte(this$static._matchFinder, -1) |
|
matchByte = $GetIndexByte( |
|
this$static._matchFinder, |
|
-this$static._repDistances[0] - 1 - 1 |
|
) |
|
if ( |
|
lenMain < 2 && |
|
currentByte != matchByte && |
|
this$static.repLens[repMaxIndex] < 2 |
|
) { |
|
this$static.backRes = -1 |
|
return 1 |
|
} |
|
this$static._optimum[0].State = this$static._state |
|
posState = position & this$static._posStateMask |
|
this$static._optimum[1].Price = |
|
ProbPrices[ |
|
this$static._isMatch[(this$static._state << 4) + posState] >>> 2 |
|
] + |
|
$GetPrice_0( |
|
$GetSubCoder( |
|
this$static._literalEncoder, |
|
position, |
|
this$static._previousByte |
|
), |
|
this$static._state >= 7, |
|
matchByte, |
|
currentByte |
|
) |
|
$MakeAsChar(this$static._optimum[1]) |
|
matchPrice = |
|
ProbPrices[ |
|
(2048 - this$static._isMatch[(this$static._state << 4) + posState]) >>> 2 |
|
] |
|
repMatchPrice = |
|
matchPrice + |
|
ProbPrices[(2048 - this$static._isRep[this$static._state]) >>> 2] |
|
if (matchByte == currentByte) { |
|
shortRepPrice = |
|
repMatchPrice + |
|
$GetRepLen1Price(this$static, this$static._state, posState) |
|
if (shortRepPrice < this$static._optimum[1].Price) { |
|
this$static._optimum[1].Price = shortRepPrice |
|
$MakeAsShortRep(this$static._optimum[1]) |
|
} |
|
} |
|
lenEnd = |
|
lenMain >= this$static.repLens[repMaxIndex] |
|
? lenMain |
|
: this$static.repLens[repMaxIndex] |
|
if (lenEnd < 2) { |
|
this$static.backRes = this$static._optimum[1].BackPrev |
|
return 1 |
|
} |
|
this$static._optimum[1].PosPrev = 0 |
|
this$static._optimum[0].Backs0 = this$static.reps[0] |
|
this$static._optimum[0].Backs1 = this$static.reps[1] |
|
this$static._optimum[0].Backs2 = this$static.reps[2] |
|
this$static._optimum[0].Backs3 = this$static.reps[3] |
|
len = lenEnd |
|
do { |
|
this$static._optimum[len--].Price = 268435455 |
|
} while (len >= 2) |
|
for (i = 0; i < 4; ++i) { |
|
repLen = this$static.repLens[i] |
|
if (repLen < 2) { |
|
continue |
|
} |
|
price_4 = |
|
repMatchPrice + |
|
$GetPureRepPrice(this$static, i, this$static._state, posState) |
|
do { |
|
curAndLenPrice = |
|
price_4 + |
|
$GetPrice(this$static._repMatchLenEncoder, repLen - 2, posState) |
|
optimum = this$static._optimum[repLen] |
|
if (curAndLenPrice < optimum.Price) { |
|
optimum.Price = curAndLenPrice |
|
optimum.PosPrev = 0 |
|
optimum.BackPrev = i |
|
optimum.Prev1IsChar = 0 |
|
} |
|
} while (--repLen >= 2) |
|
} |
|
normalMatchPrice = |
|
matchPrice + ProbPrices[this$static._isRep[this$static._state] >>> 2] |
|
len = this$static.repLens[0] >= 2 ? this$static.repLens[0] + 1 : 2 |
|
if (len <= lenMain) { |
|
offs = 0 |
|
while (len > this$static._matchDistances[offs]) { |
|
offs += 2 |
|
} |
|
for (; ; ++len) { |
|
distance = this$static._matchDistances[offs + 1] |
|
curAndLenPrice = |
|
normalMatchPrice + $GetPosLenPrice(this$static, distance, len, posState) |
|
optimum = this$static._optimum[len] |
|
if (curAndLenPrice < optimum.Price) { |
|
optimum.Price = curAndLenPrice |
|
optimum.PosPrev = 0 |
|
optimum.BackPrev = distance + 4 |
|
optimum.Prev1IsChar = 0 |
|
} |
|
if (len == this$static._matchDistances[offs]) { |
|
offs += 2 |
|
if (offs == numDistancePairs) { |
|
break |
|
} |
|
} |
|
} |
|
} |
|
cur = 0 |
|
while (1) { |
|
++cur |
|
if (cur == lenEnd) { |
|
return $Backward(this$static, cur) |
|
} |
|
newLen = $ReadMatchDistances(this$static) |
|
numDistancePairs = this$static._numDistancePairs |
|
if (newLen >= this$static._numFastBytes) { |
|
this$static._longestMatchLength = newLen |
|
this$static._longestMatchWasFound = 1 |
|
return $Backward(this$static, cur) |
|
} |
|
++position |
|
posPrev = this$static._optimum[cur].PosPrev |
|
if (this$static._optimum[cur].Prev1IsChar) { |
|
--posPrev |
|
if (this$static._optimum[cur].Prev2) { |
|
state = this$static._optimum[this$static._optimum[cur].PosPrev2].State |
|
if (this$static._optimum[cur].BackPrev2 < 4) { |
|
state = state < 7 ? 8 : 11 |
|
} else { |
|
state = state < 7 ? 7 : 10 |
|
} |
|
} else { |
|
state = this$static._optimum[posPrev].State |
|
} |
|
state = StateUpdateChar(state) |
|
} else { |
|
state = this$static._optimum[posPrev].State |
|
} |
|
if (posPrev == cur - 1) { |
|
if (!this$static._optimum[cur].BackPrev) { |
|
state = state < 7 ? 9 : 11 |
|
} else { |
|
state = StateUpdateChar(state) |
|
} |
|
} else { |
|
if ( |
|
this$static._optimum[cur].Prev1IsChar && |
|
this$static._optimum[cur].Prev2 |
|
) { |
|
posPrev = this$static._optimum[cur].PosPrev2 |
|
pos = this$static._optimum[cur].BackPrev2 |
|
state = state < 7 ? 8 : 11 |
|
} else { |
|
pos = this$static._optimum[cur].BackPrev |
|
if (pos < 4) { |
|
state = state < 7 ? 8 : 11 |
|
} else { |
|
state = state < 7 ? 7 : 10 |
|
} |
|
} |
|
opt = this$static._optimum[posPrev] |
|
if (pos < 4) { |
|
if (!pos) { |
|
this$static.reps[0] = opt.Backs0 |
|
this$static.reps[1] = opt.Backs1 |
|
this$static.reps[2] = opt.Backs2 |
|
this$static.reps[3] = opt.Backs3 |
|
} else if (pos == 1) { |
|
this$static.reps[0] = opt.Backs1 |
|
this$static.reps[1] = opt.Backs0 |
|
this$static.reps[2] = opt.Backs2 |
|
this$static.reps[3] = opt.Backs3 |
|
} else if (pos == 2) { |
|
this$static.reps[0] = opt.Backs2 |
|
this$static.reps[1] = opt.Backs0 |
|
this$static.reps[2] = opt.Backs1 |
|
this$static.reps[3] = opt.Backs3 |
|
} else { |
|
this$static.reps[0] = opt.Backs3 |
|
this$static.reps[1] = opt.Backs0 |
|
this$static.reps[2] = opt.Backs1 |
|
this$static.reps[3] = opt.Backs2 |
|
} |
|
} else { |
|
this$static.reps[0] = pos - 4 |
|
this$static.reps[1] = opt.Backs0 |
|
this$static.reps[2] = opt.Backs1 |
|
this$static.reps[3] = opt.Backs2 |
|
} |
|
} |
|
this$static._optimum[cur].State = state |
|
this$static._optimum[cur].Backs0 = this$static.reps[0] |
|
this$static._optimum[cur].Backs1 = this$static.reps[1] |
|
this$static._optimum[cur].Backs2 = this$static.reps[2] |
|
this$static._optimum[cur].Backs3 = this$static.reps[3] |
|
curPrice = this$static._optimum[cur].Price |
|
currentByte = $GetIndexByte(this$static._matchFinder, -1) |
|
matchByte = $GetIndexByte( |
|
this$static._matchFinder, |
|
-this$static.reps[0] - 1 - 1 |
|
) |
|
posState = position & this$static._posStateMask |
|
curAnd1Price = |
|
curPrice + |
|
ProbPrices[this$static._isMatch[(state << 4) + posState] >>> 2] + |
|
$GetPrice_0( |
|
$GetSubCoder( |
|
this$static._literalEncoder, |
|
position, |
|
$GetIndexByte(this$static._matchFinder, -2) |
|
), |
|
state >= 7, |
|
matchByte, |
|
currentByte |
|
) |
|
nextOptimum = this$static._optimum[cur + 1] |
|
nextIsChar = 0 |
|
if (curAnd1Price < nextOptimum.Price) { |
|
nextOptimum.Price = curAnd1Price |
|
nextOptimum.PosPrev = cur |
|
nextOptimum.BackPrev = -1 |
|
nextOptimum.Prev1IsChar = 0 |
|
nextIsChar = 1 |
|
} |
|
matchPrice = |
|
curPrice + |
|
ProbPrices[(2048 - this$static._isMatch[(state << 4) + posState]) >>> 2] |
|
repMatchPrice = |
|
matchPrice + ProbPrices[(2048 - this$static._isRep[state]) >>> 2] |
|
if ( |
|
matchByte == currentByte && |
|
!(nextOptimum.PosPrev < cur && !nextOptimum.BackPrev) |
|
) { |
|
shortRepPrice = |
|
repMatchPrice + |
|
(ProbPrices[this$static._isRepG0[state] >>> 2] + |
|
ProbPrices[this$static._isRep0Long[(state << 4) + posState] >>> 2]) |
|
if (shortRepPrice <= nextOptimum.Price) { |
|
nextOptimum.Price = shortRepPrice |
|
nextOptimum.PosPrev = cur |
|
nextOptimum.BackPrev = 0 |
|
nextOptimum.Prev1IsChar = 0 |
|
nextIsChar = 1 |
|
} |
|
} |
|
numAvailableBytesFull = $GetNumAvailableBytes(this$static._matchFinder) + 1 |
|
numAvailableBytesFull = |
|
4095 - cur < numAvailableBytesFull ? 4095 - cur : numAvailableBytesFull |
|
numAvailableBytes = numAvailableBytesFull |
|
if (numAvailableBytes < 2) { |
|
continue |
|
} |
|
if (numAvailableBytes > this$static._numFastBytes) { |
|
numAvailableBytes = this$static._numFastBytes |
|
} |
|
if (!nextIsChar && matchByte != currentByte) { |
|
t = Math.min(numAvailableBytesFull - 1, this$static._numFastBytes) |
|
lenTest2 = $GetMatchLen( |
|
this$static._matchFinder, |
|
0, |
|
this$static.reps[0], |
|
t |
|
) |
|
if (lenTest2 >= 2) { |
|
state2 = StateUpdateChar(state) |
|
posStateNext = (position + 1) & this$static._posStateMask |
|
nextRepMatchPrice = |
|
curAnd1Price + |
|
ProbPrices[ |
|
(2048 - this$static._isMatch[(state2 << 4) + posStateNext]) >>> 2 |
|
] + |
|
ProbPrices[(2048 - this$static._isRep[state2]) >>> 2] |
|
offset = cur + 1 + lenTest2 |
|
while (lenEnd < offset) { |
|
this$static._optimum[++lenEnd].Price = 268435455 |
|
} |
|
curAndLenPrice = |
|
nextRepMatchPrice + |
|
((price = $GetPrice( |
|
this$static._repMatchLenEncoder, |
|
lenTest2 - 2, |
|
posStateNext |
|
)), |
|
price + $GetPureRepPrice(this$static, 0, state2, posStateNext)) |
|
optimum = this$static._optimum[offset] |
|
if (curAndLenPrice < optimum.Price) { |
|
optimum.Price = curAndLenPrice |
|
optimum.PosPrev = cur + 1 |
|
optimum.BackPrev = 0 |
|
optimum.Prev1IsChar = 1 |
|
optimum.Prev2 = 0 |
|
} |
|
} |
|
} |
|
startLen = 2 |
|
for (repIndex = 0; repIndex < 4; ++repIndex) { |
|
lenTest = $GetMatchLen( |
|
this$static._matchFinder, |
|
-1, |
|
this$static.reps[repIndex], |
|
numAvailableBytes |
|
) |
|
if (lenTest < 2) { |
|
continue |
|
} |
|
lenTestTemp = lenTest |
|
do { |
|
while (lenEnd < cur + lenTest) { |
|
this$static._optimum[++lenEnd].Price = 268435455 |
|
} |
|
curAndLenPrice = |
|
repMatchPrice + |
|
((price_0 = $GetPrice( |
|
this$static._repMatchLenEncoder, |
|
lenTest - 2, |
|
posState |
|
)), |
|
price_0 + $GetPureRepPrice(this$static, repIndex, state, posState)) |
|
optimum = this$static._optimum[cur + lenTest] |
|
if (curAndLenPrice < optimum.Price) { |
|
optimum.Price = curAndLenPrice |
|
optimum.PosPrev = cur |
|
optimum.BackPrev = repIndex |
|
optimum.Prev1IsChar = 0 |
|
} |
|
} while (--lenTest >= 2) |
|
lenTest = lenTestTemp |
|
if (!repIndex) { |
|
startLen = lenTest + 1 |
|
} |
|
if (lenTest < numAvailableBytesFull) { |
|
t = Math.min( |
|
numAvailableBytesFull - 1 - lenTest, |
|
this$static._numFastBytes |
|
) |
|
lenTest2 = $GetMatchLen( |
|
this$static._matchFinder, |
|
lenTest, |
|
this$static.reps[repIndex], |
|
t |
|
) |
|
if (lenTest2 >= 2) { |
|
state2 = state < 7 ? 8 : 11 |
|
posStateNext = (position + lenTest) & this$static._posStateMask |
|
curAndLenCharPrice = |
|
repMatchPrice + |
|
((price_1 = $GetPrice( |
|
this$static._repMatchLenEncoder, |
|
lenTest - 2, |
|
posState |
|
)), |
|
price_1 + |
|
$GetPureRepPrice(this$static, repIndex, state, posState)) + |
|
ProbPrices[ |
|
this$static._isMatch[(state2 << 4) + posStateNext] >>> 2 |
|
] + |
|
$GetPrice_0( |
|
$GetSubCoder( |
|
this$static._literalEncoder, |
|
position + lenTest, |
|
$GetIndexByte(this$static._matchFinder, lenTest - 1 - 1) |
|
), |
|
1, |
|
$GetIndexByte( |
|
this$static._matchFinder, |
|
lenTest - 1 - (this$static.reps[repIndex] + 1) |
|
), |
|
$GetIndexByte(this$static._matchFinder, lenTest - 1) |
|
) |
|
state2 = StateUpdateChar(state2) |
|
posStateNext = (position + lenTest + 1) & this$static._posStateMask |
|
nextMatchPrice = |
|
curAndLenCharPrice + |
|
ProbPrices[ |
|
(2048 - this$static._isMatch[(state2 << 4) + posStateNext]) >>> 2 |
|
] |
|
nextRepMatchPrice = |
|
nextMatchPrice + |
|
ProbPrices[(2048 - this$static._isRep[state2]) >>> 2] |
|
offset = lenTest + 1 + lenTest2 |
|
while (lenEnd < cur + offset) { |
|
this$static._optimum[++lenEnd].Price = 268435455 |
|
} |
|
curAndLenPrice = |
|
nextRepMatchPrice + |
|
((price_2 = $GetPrice( |
|
this$static._repMatchLenEncoder, |
|
lenTest2 - 2, |
|
posStateNext |
|
)), |
|
price_2 + $GetPureRepPrice(this$static, 0, state2, posStateNext)) |
|
optimum = this$static._optimum[cur + offset] |
|
if (curAndLenPrice < optimum.Price) { |
|
optimum.Price = curAndLenPrice |
|
optimum.PosPrev = cur + lenTest + 1 |
|
optimum.BackPrev = 0 |
|
optimum.Prev1IsChar = 1 |
|
optimum.Prev2 = 1 |
|
optimum.PosPrev2 = cur |
|
optimum.BackPrev2 = repIndex |
|
} |
|
} |
|
} |
|
} |
|
if (newLen > numAvailableBytes) { |
|
newLen = numAvailableBytes |
|
for ( |
|
numDistancePairs = 0; |
|
newLen > this$static._matchDistances[numDistancePairs]; |
|
numDistancePairs += 2 |
|
) {} |
|
this$static._matchDistances[numDistancePairs] = newLen |
|
numDistancePairs += 2 |
|
} |
|
if (newLen >= startLen) { |
|
normalMatchPrice = |
|
matchPrice + ProbPrices[this$static._isRep[state] >>> 2] |
|
while (lenEnd < cur + newLen) { |
|
this$static._optimum[++lenEnd].Price = 268435455 |
|
} |
|
offs = 0 |
|
while (startLen > this$static._matchDistances[offs]) { |
|
offs += 2 |
|
} |
|
for (lenTest = startLen; ; ++lenTest) { |
|
curBack = this$static._matchDistances[offs + 1] |
|
curAndLenPrice = |
|
normalMatchPrice + |
|
$GetPosLenPrice(this$static, curBack, lenTest, posState) |
|
optimum = this$static._optimum[cur + lenTest] |
|
if (curAndLenPrice < optimum.Price) { |
|
optimum.Price = curAndLenPrice |
|
optimum.PosPrev = cur |
|
optimum.BackPrev = curBack + 4 |
|
optimum.Prev1IsChar = 0 |
|
} |
|
if (lenTest == this$static._matchDistances[offs]) { |
|
if (lenTest < numAvailableBytesFull) { |
|
t = Math.min( |
|
numAvailableBytesFull - 1 - lenTest, |
|
this$static._numFastBytes |
|
) |
|
lenTest2 = $GetMatchLen( |
|
this$static._matchFinder, |
|
lenTest, |
|
curBack, |
|
t |
|
) |
|
if (lenTest2 >= 2) { |
|
state2 = state < 7 ? 7 : 10 |
|
posStateNext = (position + lenTest) & this$static._posStateMask |
|
curAndLenCharPrice = |
|
curAndLenPrice + |
|
ProbPrices[ |
|
this$static._isMatch[(state2 << 4) + posStateNext] >>> 2 |
|
] + |
|
$GetPrice_0( |
|
$GetSubCoder( |
|
this$static._literalEncoder, |
|
position + lenTest, |
|
$GetIndexByte(this$static._matchFinder, lenTest - 1 - 1) |
|
), |
|
1, |
|
$GetIndexByte( |
|
this$static._matchFinder, |
|
lenTest - (curBack + 1) - 1 |
|
), |
|
$GetIndexByte(this$static._matchFinder, lenTest - 1) |
|
) |
|
state2 = StateUpdateChar(state2) |
|
posStateNext = |
|
(position + lenTest + 1) & this$static._posStateMask |
|
nextMatchPrice = |
|
curAndLenCharPrice + |
|
ProbPrices[ |
|
(2048 - |
|
this$static._isMatch[(state2 << 4) + posStateNext]) >>> |
|
2 |
|
] |
|
nextRepMatchPrice = |
|
nextMatchPrice + |
|
ProbPrices[(2048 - this$static._isRep[state2]) >>> 2] |
|
offset = lenTest + 1 + lenTest2 |
|
while (lenEnd < cur + offset) { |
|
this$static._optimum[++lenEnd].Price = 268435455 |
|
} |
|
curAndLenPrice = |
|
nextRepMatchPrice + |
|
((price_3 = $GetPrice( |
|
this$static._repMatchLenEncoder, |
|
lenTest2 - 2, |
|
posStateNext |
|
)), |
|
price_3 + |
|
$GetPureRepPrice(this$static, 0, state2, posStateNext)) |
|
optimum = this$static._optimum[cur + offset] |
|
if (curAndLenPrice < optimum.Price) { |
|
optimum.Price = curAndLenPrice |
|
optimum.PosPrev = cur + lenTest + 1 |
|
optimum.BackPrev = 0 |
|
optimum.Prev1IsChar = 1 |
|
optimum.Prev2 = 1 |
|
optimum.PosPrev2 = cur |
|
optimum.BackPrev2 = curBack + 4 |
|
} |
|
} |
|
} |
|
offs += 2 |
|
if (offs == numDistancePairs) break |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function $GetPosLenPrice(this$static, pos, len, posState) { |
|
var price, |
|
lenToPosState = GetLenToPosState(len) |
|
if (pos < 128) { |
|
price = this$static._distancesPrices[lenToPosState * 128 + pos] |
|
} else { |
|
price = |
|
this$static._posSlotPrices[(lenToPosState << 6) + GetPosSlot2(pos)] + |
|
this$static._alignPrices[pos & 15] |
|
} |
|
return price + $GetPrice(this$static._lenEncoder, len - 2, posState) |
|
} |
|
|
|
function $GetPureRepPrice(this$static, repIndex, state, posState) { |
|
var price |
|
if (!repIndex) { |
|
price = ProbPrices[this$static._isRepG0[state] >>> 2] |
|
price += |
|
ProbPrices[ |
|
(2048 - this$static._isRep0Long[(state << 4) + posState]) >>> 2 |
|
] |
|
} else { |
|
price = ProbPrices[(2048 - this$static._isRepG0[state]) >>> 2] |
|
if (repIndex == 1) { |
|
price += ProbPrices[this$static._isRepG1[state] >>> 2] |
|
} else { |
|
price += ProbPrices[(2048 - this$static._isRepG1[state]) >>> 2] |
|
price += GetPrice(this$static._isRepG2[state], repIndex - 2) |
|
} |
|
} |
|
return price |
|
} |
|
|
|
function $GetRepLen1Price(this$static, state, posState) { |
|
return ( |
|
ProbPrices[this$static._isRepG0[state] >>> 2] + |
|
ProbPrices[this$static._isRep0Long[(state << 4) + posState] >>> 2] |
|
) |
|
} |
|
|
|
function $Init_4(this$static) { |
|
$BaseInit(this$static) |
|
$Init_9(this$static._rangeEncoder) |
|
InitBitModels(this$static._isMatch) |
|
InitBitModels(this$static._isRep0Long) |
|
InitBitModels(this$static._isRep) |
|
InitBitModels(this$static._isRepG0) |
|
InitBitModels(this$static._isRepG1) |
|
InitBitModels(this$static._isRepG2) |
|
InitBitModels(this$static._posEncoders) |
|
$Init_3(this$static._literalEncoder) |
|
for (var i = 0; i < 4; ++i) { |
|
InitBitModels(this$static._posSlotEncoder[i].Models) |
|
} |
|
$Init_2(this$static._lenEncoder, 1 << this$static._posStateBits) |
|
$Init_2(this$static._repMatchLenEncoder, 1 << this$static._posStateBits) |
|
InitBitModels(this$static._posAlignEncoder.Models) |
|
this$static._longestMatchWasFound = 0 |
|
this$static._optimumEndIndex = 0 |
|
this$static._optimumCurrentIndex = 0 |
|
this$static._additionalOffset = 0 |
|
} |
|
|
|
function $MovePos(this$static, num) { |
|
if (num > 0) { |
|
$Skip(this$static._matchFinder, num) |
|
this$static._additionalOffset += num |
|
} |
|
} |
|
|
|
function $ReadMatchDistances(this$static) { |
|
var lenRes = 0 |
|
this$static._numDistancePairs = $GetMatches( |
|
this$static._matchFinder, |
|
this$static._matchDistances |
|
) |
|
if (this$static._numDistancePairs > 0) { |
|
lenRes = this$static._matchDistances[this$static._numDistancePairs - 2] |
|
if (lenRes == this$static._numFastBytes) |
|
lenRes += $GetMatchLen( |
|
this$static._matchFinder, |
|
lenRes - 1, |
|
this$static._matchDistances[this$static._numDistancePairs - 1], |
|
273 - lenRes |
|
) |
|
} |
|
++this$static._additionalOffset |
|
return lenRes |
|
} |
|
|
|
function $ReleaseMFStream(this$static) { |
|
if (this$static._matchFinder && this$static._needReleaseMFStream) { |
|
this$static._matchFinder._stream = null |
|
this$static._needReleaseMFStream = 0 |
|
} |
|
} |
|
|
|
function $ReleaseStreams(this$static) { |
|
$ReleaseMFStream(this$static) |
|
this$static._rangeEncoder.Stream = null |
|
} |
|
|
|
function $SetDictionarySize_0(this$static, dictionarySize) { |
|
this$static._dictionarySize = dictionarySize |
|
for (var dicLogSize = 0; dictionarySize > 1 << dicLogSize; ++dicLogSize) {} |
|
this$static._distTableSize = dicLogSize * 2 |
|
} |
|
|
|
function $SetMatchFinder(this$static, matchFinderIndex) { |
|
var matchFinderIndexPrev = this$static._matchFinderType |
|
this$static._matchFinderType = matchFinderIndex |
|
if ( |
|
this$static._matchFinder && |
|
matchFinderIndexPrev != this$static._matchFinderType |
|
) { |
|
this$static._dictionarySizePrev = -1 |
|
this$static._matchFinder = null |
|
} |
|
} |
|
|
|
function $WriteCoderProperties(this$static, outStream) { |
|
this$static.properties[0] = |
|
(((this$static._posStateBits * 5 + this$static._numLiteralPosStateBits) * |
|
9 + |
|
this$static._numLiteralContextBits) << |
|
24) >> |
|
24 |
|
for (var i = 0; i < 4; ++i) { |
|
this$static.properties[1 + i] = |
|
((this$static._dictionarySize >> (8 * i)) << 24) >> 24 |
|
} |
|
$write_0(outStream, this$static.properties, 0, 5) |
|
} |
|
|
|
function $WriteEndMarker(this$static, posState) { |
|
if (!this$static._writeEndMark) { |
|
return |
|
} |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isMatch, |
|
(this$static._state << 4) + posState, |
|
1 |
|
) |
|
$Encode_3( |
|
this$static._rangeEncoder, |
|
this$static._isRep, |
|
this$static._state, |
|
0 |
|
) |
|
this$static._state = this$static._state < 7 ? 7 : 10 |
|
$Encode_0(this$static._lenEncoder, this$static._rangeEncoder, 0, posState) |
|
var lenToPosState = GetLenToPosState(2) |
|
$Encode_2( |
|
this$static._posSlotEncoder[lenToPosState], |
|
this$static._rangeEncoder, |
|
63 |
|
) |
|
$EncodeDirectBits(this$static._rangeEncoder, 67108863, 26) |
|
$ReverseEncode(this$static._posAlignEncoder, this$static._rangeEncoder, 15) |
|
} |
|
|
|
function GetPosSlot(pos) { |
|
if (pos < 2048) { |
|
return g_FastPos[pos] |
|
} |
|
if (pos < 2097152) { |
|
return g_FastPos[pos >> 10] + 20 |
|
} |
|
return g_FastPos[pos >> 20] + 40 |
|
} |
|
|
|
function GetPosSlot2(pos) { |
|
if (pos < 131072) { |
|
return g_FastPos[pos >> 6] + 12 |
|
} |
|
if (pos < 134217728) { |
|
return g_FastPos[pos >> 16] + 32 |
|
} |
|
return g_FastPos[pos >> 26] + 52 |
|
} |
|
|
|
function $Encode(this$static, rangeEncoder, symbol, posState) { |
|
if (symbol < 8) { |
|
$Encode_3(rangeEncoder, this$static._choice, 0, 0) |
|
$Encode_2(this$static._lowCoder[posState], rangeEncoder, symbol) |
|
} else { |
|
symbol -= 8 |
|
$Encode_3(rangeEncoder, this$static._choice, 0, 1) |
|
if (symbol < 8) { |
|
$Encode_3(rangeEncoder, this$static._choice, 1, 0) |
|
$Encode_2(this$static._midCoder[posState], rangeEncoder, symbol) |
|
} else { |
|
$Encode_3(rangeEncoder, this$static._choice, 1, 1) |
|
$Encode_2(this$static._highCoder, rangeEncoder, symbol - 8) |
|
} |
|
} |
|
} |
|
|
|
function $Encoder$LenEncoder(this$static) { |
|
this$static._choice = initDim(2) |
|
this$static._lowCoder = initDim(16) |
|
this$static._midCoder = initDim(16) |
|
this$static._highCoder = $BitTreeEncoder({}, 8) |
|
for (var posState = 0; posState < 16; ++posState) { |
|
this$static._lowCoder[posState] = $BitTreeEncoder({}, 3) |
|
this$static._midCoder[posState] = $BitTreeEncoder({}, 3) |
|
} |
|
return this$static |
|
} |
|
|
|
function $Init_2(this$static, numPosStates) { |
|
InitBitModels(this$static._choice) |
|
for (var posState = 0; posState < numPosStates; ++posState) { |
|
InitBitModels(this$static._lowCoder[posState].Models) |
|
InitBitModels(this$static._midCoder[posState].Models) |
|
} |
|
InitBitModels(this$static._highCoder.Models) |
|
} |
|
|
|
function $SetPrices(this$static, posState, numSymbols, prices, st) { |
|
var a0, a1, b0, b1, i |
|
a0 = ProbPrices[this$static._choice[0] >>> 2] |
|
a1 = ProbPrices[(2048 - this$static._choice[0]) >>> 2] |
|
b0 = a1 + ProbPrices[this$static._choice[1] >>> 2] |
|
b1 = a1 + ProbPrices[(2048 - this$static._choice[1]) >>> 2] |
|
i = 0 |
|
for (i = 0; i < 8; ++i) { |
|
if (i >= numSymbols) return |
|
prices[st + i] = a0 + $GetPrice_1(this$static._lowCoder[posState], i) |
|
} |
|
for (; i < 16; ++i) { |
|
if (i >= numSymbols) return |
|
prices[st + i] = b0 + $GetPrice_1(this$static._midCoder[posState], i - 8) |
|
} |
|
for (; i < numSymbols; ++i) { |
|
prices[st + i] = b1 + $GetPrice_1(this$static._highCoder, i - 8 - 8) |
|
} |
|
} |
|
|
|
function $Encode_0(this$static, rangeEncoder, symbol, posState) { |
|
$Encode(this$static, rangeEncoder, symbol, posState) |
|
if (--this$static._counters[posState] == 0) { |
|
$SetPrices( |
|
this$static, |
|
posState, |
|
this$static._tableSize, |
|
this$static._prices, |
|
posState * 272 |
|
) |
|
this$static._counters[posState] = this$static._tableSize |
|
} |
|
} |
|
|
|
function $Encoder$LenPriceTableEncoder(this$static) { |
|
$Encoder$LenEncoder(this$static) |
|
this$static._prices = [] |
|
this$static._counters = [] |
|
return this$static |
|
} |
|
|
|
function $GetPrice(this$static, symbol, posState) { |
|
return this$static._prices[posState * 272 + symbol] |
|
} |
|
|
|
function $UpdateTables(this$static, numPosStates) { |
|
for (var posState = 0; posState < numPosStates; ++posState) { |
|
$SetPrices( |
|
this$static, |
|
posState, |
|
this$static._tableSize, |
|
this$static._prices, |
|
posState * 272 |
|
) |
|
this$static._counters[posState] = this$static._tableSize |
|
} |
|
} |
|
|
|
function $Create_1(this$static, numPosBits, numPrevBits) { |
|
var i, numStates |
|
if ( |
|
this$static.m_Coders != null && |
|
this$static.m_NumPrevBits == numPrevBits && |
|
this$static.m_NumPosBits == numPosBits |
|
) { |
|
return |
|
} |
|
this$static.m_NumPosBits = numPosBits |
|
this$static.m_PosMask = (1 << numPosBits) - 1 |
|
this$static.m_NumPrevBits = numPrevBits |
|
numStates = 1 << (this$static.m_NumPrevBits + this$static.m_NumPosBits) |
|
this$static.m_Coders = initDim(numStates) |
|
for (i = 0; i < numStates; ++i) { |
|
this$static.m_Coders[i] = $Encoder$LiteralEncoder$Encoder2({}) |
|
} |
|
} |
|
|
|
function $GetSubCoder(this$static, pos, prevByte) { |
|
return this$static.m_Coders[ |
|
((pos & this$static.m_PosMask) << this$static.m_NumPrevBits) + |
|
((prevByte & 255) >>> (8 - this$static.m_NumPrevBits)) |
|
] |
|
} |
|
|
|
function $Init_3(this$static) { |
|
var i, |
|
numStates = 1 << (this$static.m_NumPrevBits + this$static.m_NumPosBits) |
|
for (i = 0; i < numStates; ++i) { |
|
InitBitModels(this$static.m_Coders[i].m_Encoders) |
|
} |
|
} |
|
|
|
function $Encode_1(this$static, rangeEncoder, symbol) { |
|
var bit, |
|
i, |
|
context = 1 |
|
for (i = 7; i >= 0; --i) { |
|
bit = (symbol >> i) & 1 |
|
$Encode_3(rangeEncoder, this$static.m_Encoders, context, bit) |
|
context = (context << 1) | bit |
|
} |
|
} |
|
|
|
function $EncodeMatched(this$static, rangeEncoder, matchByte, symbol) { |
|
var bit, |
|
i, |
|
matchBit, |
|
state, |
|
same = 1, |
|
context = 1 |
|
for (i = 7; i >= 0; --i) { |
|
bit = (symbol >> i) & 1 |
|
state = context |
|
if (same) { |
|
matchBit = (matchByte >> i) & 1 |
|
state += (1 + matchBit) << 8 |
|
same = matchBit == bit |
|
} |
|
$Encode_3(rangeEncoder, this$static.m_Encoders, state, bit) |
|
context = (context << 1) | bit |
|
} |
|
} |
|
|
|
function $Encoder$LiteralEncoder$Encoder2(this$static) { |
|
this$static.m_Encoders = initDim(768) |
|
return this$static |
|
} |
|
|
|
function $GetPrice_0(this$static, matchMode, matchByte, symbol) { |
|
var bit, |
|
context = 1, |
|
i = 7, |
|
matchBit, |
|
price = 0 |
|
if (matchMode) { |
|
for (; i >= 0; --i) { |
|
matchBit = (matchByte >> i) & 1 |
|
bit = (symbol >> i) & 1 |
|
price += GetPrice( |
|
this$static.m_Encoders[((1 + matchBit) << 8) + context], |
|
bit |
|
) |
|
context = (context << 1) | bit |
|
if (matchBit != bit) { |
|
--i |
|
break |
|
} |
|
} |
|
} |
|
for (; i >= 0; --i) { |
|
bit = (symbol >> i) & 1 |
|
price += GetPrice(this$static.m_Encoders[context], bit) |
|
context = (context << 1) | bit |
|
} |
|
return price |
|
} |
|
|
|
function $MakeAsChar(this$static) { |
|
this$static.BackPrev = -1 |
|
this$static.Prev1IsChar = 0 |
|
} |
|
|
|
function $MakeAsShortRep(this$static) { |
|
this$static.BackPrev = 0 |
|
this$static.Prev1IsChar = 0 |
|
} |
|
function $BitTreeDecoder(this$static, numBitLevels) { |
|
this$static.NumBitLevels = numBitLevels |
|
this$static.Models = initDim(1 << numBitLevels) |
|
return this$static |
|
} |
|
|
|
function $Decode_0(this$static, rangeDecoder) { |
|
var bitIndex, |
|
m = 1 |
|
for (bitIndex = this$static.NumBitLevels; bitIndex != 0; --bitIndex) { |
|
m = (m << 1) + $DecodeBit(rangeDecoder, this$static.Models, m) |
|
} |
|
return m - (1 << this$static.NumBitLevels) |
|
} |
|
|
|
function $ReverseDecode(this$static, rangeDecoder) { |
|
var bit, |
|
bitIndex, |
|
m = 1, |
|
symbol = 0 |
|
for (bitIndex = 0; bitIndex < this$static.NumBitLevels; ++bitIndex) { |
|
bit = $DecodeBit(rangeDecoder, this$static.Models, m) |
|
m <<= 1 |
|
m += bit |
|
symbol |= bit << bitIndex |
|
} |
|
return symbol |
|
} |
|
|
|
function ReverseDecode(Models, startIndex, rangeDecoder, NumBitLevels) { |
|
var bit, |
|
bitIndex, |
|
m = 1, |
|
symbol = 0 |
|
for (bitIndex = 0; bitIndex < NumBitLevels; ++bitIndex) { |
|
bit = $DecodeBit(rangeDecoder, Models, startIndex + m) |
|
m <<= 1 |
|
m += bit |
|
symbol |= bit << bitIndex |
|
} |
|
return symbol |
|
} |
|
function $BitTreeEncoder(this$static, numBitLevels) { |
|
this$static.NumBitLevels = numBitLevels |
|
this$static.Models = initDim(1 << numBitLevels) |
|
return this$static |
|
} |
|
|
|
function $Encode_2(this$static, rangeEncoder, symbol) { |
|
var bit, |
|
bitIndex, |
|
m = 1 |
|
for (bitIndex = this$static.NumBitLevels; bitIndex != 0; ) { |
|
--bitIndex |
|
bit = (symbol >>> bitIndex) & 1 |
|
$Encode_3(rangeEncoder, this$static.Models, m, bit) |
|
m = (m << 1) | bit |
|
} |
|
} |
|
|
|
function $GetPrice_1(this$static, symbol) { |
|
var bit, |
|
bitIndex, |
|
m = 1, |
|
price = 0 |
|
for (bitIndex = this$static.NumBitLevels; bitIndex != 0; ) { |
|
--bitIndex |
|
bit = (symbol >>> bitIndex) & 1 |
|
price += GetPrice(this$static.Models[m], bit) |
|
m = (m << 1) + bit |
|
} |
|
return price |
|
} |
|
|
|
function $ReverseEncode(this$static, rangeEncoder, symbol) { |
|
var bit, |
|
i, |
|
m = 1 |
|
for (i = 0; i < this$static.NumBitLevels; ++i) { |
|
bit = symbol & 1 |
|
$Encode_3(rangeEncoder, this$static.Models, m, bit) |
|
m = (m << 1) | bit |
|
symbol >>= 1 |
|
} |
|
} |
|
|
|
function $ReverseGetPrice(this$static, symbol) { |
|
var bit, |
|
i, |
|
m = 1, |
|
price = 0 |
|
for (i = this$static.NumBitLevels; i != 0; --i) { |
|
bit = symbol & 1 |
|
symbol >>>= 1 |
|
price += GetPrice(this$static.Models[m], bit) |
|
m = (m << 1) | bit |
|
} |
|
return price |
|
} |
|
|
|
function ReverseEncode(Models, startIndex, rangeEncoder, NumBitLevels, symbol) { |
|
var bit, |
|
i, |
|
m = 1 |
|
for (i = 0; i < NumBitLevels; ++i) { |
|
bit = symbol & 1 |
|
$Encode_3(rangeEncoder, Models, startIndex + m, bit) |
|
m = (m << 1) | bit |
|
symbol >>= 1 |
|
} |
|
} |
|
|
|
function ReverseGetPrice(Models, startIndex, NumBitLevels, symbol) { |
|
var bit, |
|
i, |
|
m = 1, |
|
price = 0 |
|
for (i = NumBitLevels; i != 0; --i) { |
|
bit = symbol & 1 |
|
symbol >>>= 1 |
|
price += ProbPrices[(((Models[startIndex + m] - bit) ^ -bit) & 2047) >>> 2] |
|
m = (m << 1) | bit |
|
} |
|
return price |
|
} |
|
function $DecodeBit(this$static, probs, index) { |
|
var newBound, |
|
prob = probs[index] |
|
newBound = (this$static.Range >>> 11) * prob |
|
if ((this$static.Code ^ -2147483648) < (newBound ^ -2147483648)) { |
|
this$static.Range = newBound |
|
probs[index] = ((prob + ((2048 - prob) >>> 5)) << 16) >> 16 |
|
if (!(this$static.Range & -16777216)) { |
|
this$static.Code = (this$static.Code << 8) | $read(this$static.Stream) |
|
this$static.Range <<= 8 |
|
} |
|
return 0 |
|
} else { |
|
this$static.Range -= newBound |
|
this$static.Code -= newBound |
|
probs[index] = ((prob - (prob >>> 5)) << 16) >> 16 |
|
if (!(this$static.Range & -16777216)) { |
|
this$static.Code = (this$static.Code << 8) | $read(this$static.Stream) |
|
this$static.Range <<= 8 |
|
} |
|
return 1 |
|
} |
|
} |
|
|
|
function $DecodeDirectBits(this$static, numTotalBits) { |
|
var i, |
|
t, |
|
result = 0 |
|
for (i = numTotalBits; i != 0; --i) { |
|
this$static.Range >>>= 1 |
|
t = (this$static.Code - this$static.Range) >>> 31 |
|
this$static.Code -= this$static.Range & (t - 1) |
|
result = (result << 1) | (1 - t) |
|
if (!(this$static.Range & -16777216)) { |
|
this$static.Code = (this$static.Code << 8) | $read(this$static.Stream) |
|
this$static.Range <<= 8 |
|
} |
|
} |
|
return result |
|
} |
|
|
|
function $Init_8(this$static) { |
|
this$static.Code = 0 |
|
this$static.Range = -1 |
|
for (var i = 0; i < 5; ++i) { |
|
this$static.Code = (this$static.Code << 8) | $read(this$static.Stream) |
|
} |
|
} |
|
function InitBitModels(probs) { |
|
for (var i = probs.length - 1; i >= 0; --i) { |
|
probs[i] = 1024 |
|
} |
|
} |
|
var ProbPrices = (function() { |
|
var end, |
|
i, |
|
j, |
|
start, |
|
ProbPrices = [] |
|
for (i = 8; i >= 0; --i) { |
|
start = 1 << (9 - i - 1) |
|
end = 1 << (9 - i) |
|
for (j = start; j < end; ++j) { |
|
ProbPrices[j] = (i << 6) + (((end - j) << 6) >>> (9 - i - 1)) |
|
} |
|
} |
|
return ProbPrices |
|
})() |
|
|
|
function $Encode_3(this$static, probs, index, symbol) { |
|
var newBound, |
|
prob = probs[index] |
|
newBound = (this$static.Range >>> 11) * prob |
|
if (!symbol) { |
|
this$static.Range = newBound |
|
probs[index] = ((prob + ((2048 - prob) >>> 5)) << 16) >> 16 |
|
} else { |
|
this$static.Low = add( |
|
this$static.Low, |
|
and(fromInt(newBound), [4294967295, 0]) |
|
) |
|
this$static.Range -= newBound |
|
probs[index] = ((prob - (prob >>> 5)) << 16) >> 16 |
|
} |
|
if (!(this$static.Range & -16777216)) { |
|
this$static.Range <<= 8 |
|
$ShiftLow(this$static) |
|
} |
|
} |
|
|
|
function $EncodeDirectBits(this$static, v, numTotalBits) { |
|
for (var i = numTotalBits - 1; i >= 0; --i) { |
|
this$static.Range >>>= 1 |
|
if (((v >>> i) & 1) == 1) { |
|
this$static.Low = add(this$static.Low, fromInt(this$static.Range)) |
|
} |
|
if (!(this$static.Range & -16777216)) { |
|
this$static.Range <<= 8 |
|
$ShiftLow(this$static) |
|
} |
|
} |
|
} |
|
|
|
function $GetProcessedSizeAdd(this$static) { |
|
return add(add(fromInt(this$static._cacheSize), this$static._position), [ |
|
4, |
|
0 |
|
]) |
|
} |
|
|
|
function $Init_9(this$static) { |
|
this$static._position = P0_longLit |
|
this$static.Low = P0_longLit |
|
this$static.Range = -1 |
|
this$static._cacheSize = 1 |
|
this$static._cache = 0 |
|
} |
|
|
|
function $ShiftLow(this$static) { |
|
var temp, |
|
LowHi = lowBits_0(shru(this$static.Low, 32)) |
|
if (LowHi != 0 || compare(this$static.Low, [4278190080, 0]) < 0) { |
|
this$static._position = add( |
|
this$static._position, |
|
fromInt(this$static._cacheSize) |
|
) |
|
temp = this$static._cache |
|
do { |
|
$write(this$static.Stream, temp + LowHi) |
|
temp = 255 |
|
} while (--this$static._cacheSize != 0) |
|
this$static._cache = lowBits_0(this$static.Low) >>> 24 |
|
} |
|
++this$static._cacheSize |
|
this$static.Low = shl(and(this$static.Low, [16777215, 0]), 8) |
|
} |
|
|
|
function GetPrice(Prob, symbol) { |
|
return ProbPrices[(((Prob - symbol) ^ -symbol) & 2047) >>> 2] |
|
} |
|
function decode(utf) { |
|
var i = 0, |
|
j = 0, |
|
x, |
|
y, |
|
z, |
|
l = utf.length, |
|
buf = [], |
|
charCodes = [] |
|
for (; i < l; ++i, ++j) { |
|
x = utf[i] & 255 |
|
if (!(x & 128)) { |
|
if (!x) { |
|
// It appears that this is binary data, so it cannot be converted to a string, so just send it back. |
|
return utf |
|
} |
|
charCodes[j] = x |
|
} else if ((x & 224) == 192) { |
|
if (i + 1 >= l) { |
|
// It appears that this is binary data, so it cannot be converted to a string, so just send it back. |
|
return utf |
|
} |
|
y = utf[++i] & 255 |
|
if ((y & 192) != 128) { |
|
// It appears that this is binary data, so it cannot be converted to a string, so just send it back. |
|
return utf |
|
} |
|
charCodes[j] = ((x & 31) << 6) | (y & 63) |
|
} else if ((x & 240) == 224) { |
|
if (i + 2 >= l) { |
|
// It appears that this is binary data, so it cannot be converted to a string, so just send it back. |
|
return utf |
|
} |
|
y = utf[++i] & 255 |
|
if ((y & 192) != 128) { |
|
// It appears that this is binary data, so it cannot be converted to a string, so just send it back. |
|
return utf |
|
} |
|
z = utf[++i] & 255 |
|
if ((z & 192) != 128) { |
|
// It appears that this is binary data, so it cannot be converted to a string, so just send it back. |
|
return utf |
|
} |
|
charCodes[j] = ((x & 15) << 12) | ((y & 63) << 6) | (z & 63) |
|
} else { |
|
// It appears that this is binary data, so it cannot be converted to a string, so just send it back. |
|
return utf |
|
} |
|
if (j == 16383) { |
|
buf.push(String.fromCharCode.apply(String, charCodes)) |
|
j = -1 |
|
} |
|
} |
|
if (j > 0) { |
|
charCodes.length = j |
|
buf.push(String.fromCharCode.apply(String, charCodes)) |
|
} |
|
return buf.join('') |
|
} |
|
function encode(s) { |
|
var ch, |
|
chars = [], |
|
data, |
|
elen = 0, |
|
i, |
|
l = s.length |
|
// Be able to handle binary arrays and buffers. |
|
if (typeof s == 'object') { |
|
return s |
|
} else { |
|
$getChars(s, 0, l, chars, 0) |
|
} |
|
// Add extra spaces in the array to break up the unicode symbols. |
|
for (i = 0; i < l; ++i) { |
|
ch = chars[i] |
|
if (ch >= 1 && ch <= 127) { |
|
++elen |
|
} else if (!ch || (ch >= 128 && ch <= 2047)) { |
|
elen += 2 |
|
} else { |
|
elen += 3 |
|
} |
|
} |
|
data = [] |
|
elen = 0 |
|
for (i = 0; i < l; ++i) { |
|
ch = chars[i] |
|
if (ch >= 1 && ch <= 127) { |
|
data[elen++] = (ch << 24) >> 24 |
|
} else if (!ch || (ch >= 128 && ch <= 2047)) { |
|
data[elen++] = ((192 | ((ch >> 6) & 31)) << 24) >> 24 |
|
data[elen++] = ((128 | (ch & 63)) << 24) >> 24 |
|
} else { |
|
data[elen++] = ((224 | ((ch >> 12) & 15)) << 24) >> 24 |
|
data[elen++] = ((128 | ((ch >> 6) & 63)) << 24) >> 24 |
|
data[elen++] = ((128 | (ch & 63)) << 24) >> 24 |
|
} |
|
} |
|
return data |
|
} |
|
// s is dictionarySize |
|
// f is fb |
|
// m is matchFinder |
|
// NOTE: Because some values are always the same, they have been removed. |
|
// lc is always 3 |
|
// lp is always 0 |
|
// pb is always 2 |
|
const modes = [ |
|
{ s: 16, f: 64, m: 0 }, |
|
{ s: 20, f: 64, m: 0 }, |
|
{ s: 19, f: 64, m: 1 }, |
|
{ s: 20, f: 64, m: 1 }, |
|
{ s: 21, f: 128, m: 1 }, |
|
{ s: 22, f: 128, m: 1 }, |
|
{ s: 23, f: 128, m: 1 }, |
|
{ s: 24, f: 255, m: 1 }, |
|
{ s: 25, f: 255, m: 1 } |
|
] |
|
|
|
function get_mode_obj(mode) { |
|
return modes[mode - 1] || modes[6] |
|
} |
|
|
|
/** |
|
* Compress a string with the LZMA algorithm |
|
* |
|
* @param {string} value The string to be compressed |
|
* @param {object} options |
|
* @param {1|2|3|4|5|6|7|8|9} options.mode Which mode to use (1 through 9, defaults to 7) |
|
* @param {boolean} options.enableEndMark Whether to write an end mark |
|
* @returns {string} |
|
*/ |
|
export function compress(value, { mode = 7, enableEndMark = true } = {}) { |
|
var this$static = {} |
|
|
|
this$static.c = $LZMAByteArrayCompressor( |
|
{}, |
|
encode(value), |
|
get_mode_obj(mode), |
|
enableEndMark |
|
) |
|
while ($processChunk(this$static.c.chunker)); |
|
return $toByteArray(this$static.c.output) |
|
} |
|
|
|
/** |
|
* Compress a string with the LZMA algorithm to URL-safe characters |
|
* |
|
* @param {string} value The string to be compressed |
|
* @param {object} options |
|
* @param {1|2|3|4|5|6|7|8|9} options.mode Which mode to use (1 through 9, defaults to 7) |
|
* @param {boolean} options.enableEndMark Whether to write an end mark |
|
* @returns {string} |
|
*/ |
|
export function compressUrlSafe( |
|
string, |
|
{ mode = 7, enableEndMark = true } = {} |
|
) { |
|
const compressedString = compress(string, { mode, enableEndMark }) |
|
const compressedBytes = new Uint8Array(compressedString) |
|
|
|
return base64.encodeFromArrayUrlSafe(compressedBytes) |
|
} |
|
|
|
/** |
|
* Decompress a string compressed with the LZMA algorithm |
|
* |
|
* @param {number[]|Int8Array} bytes The int8 array created by the compress() function |
|
* @returns {string} |
|
*/ |
|
export function decompress(bytes) { |
|
var this$static = {} |
|
|
|
this$static.d = $LZMAByteArrayDecompressor({}, bytes) |
|
while ($processChunk(this$static.d.chunker)); |
|
return decode($toByteArray(this$static.d.output)) |
|
} |
|
|
|
/** |
|
* Decompress a string compressed with the URL-safe compress function |
|
* |
|
* @param {string} string The URL-safe string generated by the compressUrlSafe() function |
|
* @returns {string} |
|
*/ |
|
export function decompressUrlSafe(string) { |
|
return decompress(new Int8Array(base64.decodeToArrayUrlSafe(string))) |
|
} |
Hey dude, I've came to same results using other method. Just for sharing, soon it will be avaliable on github.
I though that no one had this idea before so started doing it myself.
All base conversions were implemented by myself based on a mongodb shortID code that I've came across in the past and forked to fit my needs.
Intead of using LZMA I've searched for a JavaScript Gzip implementation, and after most of the hard job were already done I've searched for compressing data into URLs and found your gist.
This project is a part of this one
Then when I finished my code, I tested your data for benchmarking and curiously they reached the same result with your data
My testing results:
This test can be acessed here