var MiniLZ4 = (function() {
var exports = {};
exports.uncompress = function (input, output, sIdx, eIdx) {
sIdx = sIdx || 0
eIdx = eIdx || (input.length - sIdx)
for (var i = sIdx, n = eIdx, j = 0; i < n;) {
var token = input[i++]
var literals_length = (token >> 4)
if (literals_length > 0) {
var l = literals_length + 240
while (l === 255) {
l = input[i++]
literals_length += l
}
var end = i + literals_length
while (i < end) output[j++] = input[i++]
if (i === n) return j
}
var offset = input[i++] | (input[i++] << 8)
if (offset === 0) return j
if (offset > j) return -(i-2)
var match_length = (token & 0xf)
var l = match_length + 240
while (l === 255) {
l = input[i++]
match_length += l
}
var pos = j - offset
var end = j + match_length + 4
while (j < end) output[j++] = output[pos++]
}
return j
}
var
maxInputSize = 0x7E000000
, minMatch = 4
, hashLog = 16
, hashShift = (minMatch * 8) - hashLog
, hashSize = 1 << hashLog
, copyLength = 8
, lastLiterals = 5
, mfLimit = copyLength + minMatch
, skipStrength = 6
, mlBits = 4
, mlMask = (1 << mlBits) - 1
, runBits = 8 - mlBits
, runMask = (1 << runBits) - 1
, hasher = 2654435761
assert(hashShift === 16);
var hashTable = new Int16Array(1<<16);
var empty = new Int16Array(hashTable.length);
exports.compressBound = function (isize) {
return isize > maxInputSize
? 0
: (isize + (isize/255) + 16) | 0
}
exports.compress = function (src, dst, sIdx, eIdx) {
hashTable.set(empty);
return compressBlock(src, dst, 0, sIdx || 0, eIdx || dst.length)
}
function compressBlock (src, dst, pos, sIdx, eIdx) {
var dpos = sIdx
var dlen = eIdx - sIdx
var anchor = 0
if (src.length >= maxInputSize) throw new Error("input too large")
if (src.length > mfLimit) {
var n = exports.compressBound(src.length)
if ( dlen < n ) throw Error("output too small: " + dlen + " < " + n)
var
step = 1
, findMatchAttempts = (1 << skipStrength) + 3
, srcLength = src.length - mfLimit
while (pos + minMatch < srcLength) {
var sequenceLowBits = src[pos+1]<<8 | src[pos]
var sequenceHighBits = src[pos+3]<<8 | src[pos+2]
var hash = Math.imul(sequenceLowBits | (sequenceHighBits << 16), hasher) >>> hashShift;
var ref = hashTable[hash] - 1
hashTable[hash] = pos + 1
if ( ref < 0 ||
((pos - ref) >>> 16) > 0 ||
(
((src[ref+3]<<8 | src[ref+2]) != sequenceHighBits) ||
((src[ref+1]<<8 | src[ref]) != sequenceLowBits )
)
) {
step = findMatchAttempts++ >> skipStrength
pos += step
continue
}
findMatchAttempts = (1 << skipStrength) + 3
var literals_length = pos - anchor
var offset = pos - ref
pos += minMatch
ref += minMatch
var match_length = pos
while (pos < srcLength && src[pos] == src[ref]) {
pos++
ref++
}
match_length = pos - match_length
var token = match_length < mlMask ? match_length : mlMask
if (literals_length >= runMask) {
dst[dpos++] = (runMask << mlBits) + token
for (var len = literals_length - runMask; len > 254; len -= 255) {
dst[dpos++] = 255
}
dst[dpos++] = len
} else {
dst[dpos++] = (literals_length << mlBits) + token
}
for (var i = 0; i < literals_length; i++) {
dst[dpos++] = src[anchor+i]
}
dst[dpos++] = offset
dst[dpos++] = (offset >> 8)
if (match_length >= mlMask) {
match_length -= mlMask
while (match_length >= 255) {
match_length -= 255
dst[dpos++] = 255
}
dst[dpos++] = match_length
}
anchor = pos
}
}
if (anchor == 0) return 0
literals_length = src.length - anchor
if (literals_length >= runMask) {
dst[dpos++] = (runMask << mlBits)
for (var ln = literals_length - runMask; ln > 254; ln -= 255) {
dst[dpos++] = 255
}
dst[dpos++] = ln
} else {
dst[dpos++] = (literals_length << mlBits)
}
pos = anchor
while (pos < src.length) {
dst[dpos++] = src[pos++]
}
return dpos
}
exports.CHUNK_SIZE = 2048;
exports.compressPackage = function(data, verify) {
if (verify) {
var temp = new Uint8Array(exports.CHUNK_SIZE);
}
assert(data instanceof ArrayBuffer);
data = new Uint8Array(data);
console.log('compressing package of size ' + data.length);
var compressedChunks = [];
var successes = [];
var offset = 0;
var total = 0;
while (offset < data.length) {
var chunk = data.subarray(offset, offset + exports.CHUNK_SIZE);
offset += exports.CHUNK_SIZE;
var bound = exports.compressBound(chunk.length);
var compressed = new Uint8Array(bound);
var compressedSize = exports.compress(chunk, compressed);
if (compressedSize > 0) {
assert(compressedSize <= bound);
compressed = compressed.subarray(0, compressedSize);
compressedChunks.push(compressed);
total += compressedSize;
successes.push(1);
if (verify) {
var back = exports.uncompress(compressed, temp);
assert(back === chunk.length, [back, chunk.length]);
for (var i = 0; i < chunk.length; i++) {
assert(chunk[i] === temp[i]);
}
}
} else {
assert(compressedSize === 0);
compressedChunks.push(chunk);
total += chunk.length;
successes.push(0);
}
}
data = null;
var compressedData = {
'data': new Uint8Array(total + exports.CHUNK_SIZE*2),
'cachedOffset': total,
'cachedIndexes': [-1, -1],
'cachedChunks': [null, null],
'offsets': [],
'sizes': [],
'successes': successes,
};
offset = 0;
for (var i = 0; i < compressedChunks.length; i++) {
compressedData['data'].set(compressedChunks[i], offset);
compressedData['offsets'][i] = offset;
compressedData['sizes'][i] = compressedChunks[i].length
offset += compressedChunks[i].length;
}
console.log('compressed package into ' + [compressedData['data'].length]);
assert(offset === total);
return compressedData;
};
assert(exports.CHUNK_SIZE < (1 << 15));
return exports;
})();
if (typeof module != 'undefined') {
module.exports = MiniLZ4;
}