minimal-webrtc/camera/static/js/prefixCompressor.js

48 lines
1.5 KiB
JavaScript

async function loadLZMAPrefixCompressor(prefixFilename) {
class PrefixCompressor {
constructor(prefix, compress, decompress, bytesToIgnore) {
this.prefix = prefix;
this.prefixCompressed = compress(prefix);
this.bytesToIgnore = bytesToIgnore;
this.baseCompress = compress;
this.baseDecompress = decompress;
}
compress(str) {
const c = this.baseCompress(this.prefix + str);
for (var i = this.bytesToIgnore;
i < this.prefixCompressed.length
&& this.prefixCompressed[i] == c[i];
i++) { }
const omittedBytes = this.prefixCompressed.length - i;
const res = c.subarray(i - 1);
res[0] = omittedBytes;
return res;
}
decompress(arr) {
const omittedBytes = arr[0];
const prefixBytes = this.prefixCompressed.length-omittedBytes;
const c = new Uint8Array(prefixBytes + arr.length-1);
c.set(this.prefixCompressed.subarray(0, prefixBytes));
c.set(arr.subarray(1), prefixBytes);
const d = this.baseDecompress(c);
return d.substring(this.prefix.length);
}
}
async function loadDictionary() {
const response = await fetch(prefixFilename);
return await response.text();
}
const prefix = await loadDictionary();
return new PrefixCompressor(prefix, str => {
const res = new Uint8Array(LZMA.compress(str, 9));
// Clear uncompressed size as it will be invalid.
for (var i = 5; i < 13; i++) res[i] = 255;
return res;
}, arr => {
return LZMA.decompress(arr).toString();
}, 12);
}