UNPKG

molstar

Version:

A comprehensive macromolecular library.

404 lines 15.2 kB
"use strict"; /** * Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * * ported from https://github.com/photopea/UZIP.js/blob/master/UZIP.js * MIT License, Copyright (c) 2018 Photopea */ Object.defineProperty(exports, "__esModule", { value: true }); exports._deflateRaw = void 0; var tslib_1 = require("tslib"); var huffman_1 = require("./huffman"); var util_1 = require("./util"); function DeflateContext(data, out, opos, lvl) { var lits = util_1.U.lits, strt = util_1.U.strt, prev = util_1.U.prev; return { data: data, out: out, opt: Opts[lvl], i: 0, pos: opos << 3, cvrd: 0, dlen: data.length, li: 0, lc: 0, bs: 0, ebits: 0, c: 0, nc: 0, lits: lits, strt: strt, prev: prev }; } function deflateChunk(ctx, count) { var data = ctx.data, dlen = ctx.dlen, out = ctx.out, opt = ctx.opt; var i = ctx.i, pos = ctx.pos, cvrd = ctx.cvrd, li = ctx.li, lc = ctx.lc, bs = ctx.bs, ebits = ctx.ebits, c = ctx.c, nc = ctx.nc; var lits = util_1.U.lits, strt = util_1.U.strt, prev = util_1.U.prev; var end = Math.min(i + count, dlen); for (; i < end; i++) { c = nc; if (i + 1 < dlen - 2) { nc = _hash(data, i + 1); var ii = ((i + 1) & 0x7fff); prev[ii] = strt[nc]; strt[nc] = ii; } if (cvrd <= i) { if ((li > 14000 || lc > 26697) && (dlen - i) > 100) { if (cvrd < i) { lits[li] = i - cvrd; li += 2; cvrd = i; } pos = _writeBlock(((i === dlen - 1) || (cvrd === dlen)) ? 1 : 0, lits, li, ebits, data, bs, i - bs, out, pos); li = lc = ebits = 0; bs = i; } var mch = 0; if (i < dlen - 2) { mch = _bestMatch(data, i, prev, c, Math.min(opt[2], dlen - i), opt[3]); } if (mch !== 0) { var len = mch >>> 16, dst = mch & 0xffff; var lgi = _goodIndex(len, util_1.U.of0); util_1.U.lhst[257 + lgi]++; var dgi = _goodIndex(dst, util_1.U.df0); util_1.U.dhst[dgi]++; ebits += util_1.U.exb[lgi] + util_1.U.dxb[dgi]; lits[li] = (len << 23) | (i - cvrd); lits[li + 1] = (dst << 16) | (lgi << 8) | dgi; li += 2; cvrd = i + len; } else { util_1.U.lhst[data[i]]++; } lc++; } } ctx.i = i; ctx.pos = pos; ctx.cvrd = cvrd; ctx.li = li; ctx.lc = lc; ctx.bs = bs; ctx.ebits = ebits; ctx.c = c; ctx.nc = nc; } /** * - good_length: reduce lazy search above this match length; * - max_lazy: do not perform lazy search above this match length; * - nice_length: quit search above this match length; */ var Opts = [ /* good lazy nice chain */ /* 0 */ [0, 0, 0, 0, 0], /* 1 */ [4, 4, 8, 4, 0], /* 2 */ [4, 5, 16, 8, 0], /* 3 */ [4, 6, 16, 16, 0], /* 4 */ [4, 10, 16, 32, 0], /* 5 */ [8, 16, 32, 32, 0], /* 6 */ [8, 16, 128, 128, 0], /* 7 */ [8, 32, 128, 256, 0], /* 8 */ [32, 128, 258, 1024, 1], /* 9 */ [32, 258, 258, 4096, 1] /* max compression */ ]; function _deflateRaw(runtime, data, out, opos, lvl) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var ctx, dlen, i_1, pos_1, len, li, cvrd, pos, i, lits, bs, ebits; return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: ctx = DeflateContext(data, out, opos, lvl); dlen = ctx.dlen; if (lvl === 0) { i_1 = ctx.i, pos_1 = ctx.pos; while (i_1 < dlen) { len = Math.min(0xffff, dlen - i_1); _putsE(out, pos_1, (i_1 + len === dlen ? 1 : 0)); pos_1 = _copyExact(data, i_1, len, out, pos_1 + 8); i_1 += len; } return [2 /*return*/, pos_1 >>> 3]; } if (dlen > 2) { ctx.nc = _hash(data, 0); ctx.strt[ctx.nc] = 0; } _a.label = 1; case 1: if (!(ctx.i < dlen)) return [3 /*break*/, 4]; if (!runtime.shouldUpdate) return [3 /*break*/, 3]; return [4 /*yield*/, runtime.update({ message: 'Deflating...', current: ctx.i, max: dlen })]; case 2: _a.sent(); _a.label = 3; case 3: deflateChunk(ctx, 1024 * 1024); return [3 /*break*/, 1]; case 4: li = ctx.li, cvrd = ctx.cvrd, pos = ctx.pos; i = ctx.i, lits = ctx.lits, bs = ctx.bs, ebits = ctx.ebits; if (bs !== i || data.length === 0) { if (cvrd < i) { lits[li] = i - cvrd; li += 2; cvrd = i; } pos = _writeBlock(1, lits, li, ebits, data, bs, i - bs, out, pos); } while ((pos & 7) !== 0) pos++; return [2 /*return*/, pos >>> 3]; } }); }); } exports._deflateRaw = _deflateRaw; function _bestMatch(data, i, prev, c, nice, chain) { var ci = (i & 0x7fff), pi = prev[ci]; // console.log("----", i); var dif = ((ci - pi + (1 << 15)) & 0x7fff); if (pi === ci || c !== _hash(data, i - dif)) return 0; var tl = 0, td = 0; // top length, top distance var dlim = Math.min(0x7fff, i); while (dif <= dlim && --chain !== 0 && pi !== ci /* && c==UZIP.F._hash(data,i-dif)*/) { if (tl === 0 || (data[i + tl] === data[i + tl - dif])) { var cl = _howLong(data, i, dif); if (cl > tl) { tl = cl; td = dif; if (tl >= nice) break; //* if (dif + 2 < cl) cl = dif + 2; var maxd = 0; // pi does not point to the start of the word for (var j = 0; j < cl - 2; j++) { var ei = (i - dif + j + (1 << 15)) & 0x7fff; var li = prev[ei]; var curd = (ei - li + (1 << 15)) & 0x7fff; if (curd > maxd) { maxd = curd; pi = ei; } } } } ci = pi; pi = prev[ci]; dif += ((ci - pi + (1 << 15)) & 0x7fff); } return (tl << 16) | td; } function _howLong(data, i, dif) { if (data[i] !== data[i - dif] || data[i + 1] !== data[i + 1 - dif] || data[i + 2] !== data[i + 2 - dif]) return 0; var oi = i, l = Math.min(data.length, i + 258); i += 3; // while(i+4<l && data[i]==data[i-dif] && data[i+1]==data[i+1-dif] && data[i+2]==data[i+2-dif] && data[i+3]==data[i+3-dif]) i+=4; while (i < l && data[i] === data[i - dif]) i++; return i - oi; } function _hash(data, i) { return (((data[i] << 8) | data[i + 1]) + (data[i + 2] << 4)) & 0xffff; // var hash_shift = 0, hash_mask = 255; // var h = data[i+1] % 251; // h = (((h << 8) + data[i+2]) % 251); // h = (((h << 8) + data[i+2]) % 251); // h = ((h<<hash_shift) ^ (c) ) & hash_mask; // return h | (data[i]<<8); // return (data[i] | (data[i+1]<<8)); } function _writeBlock(BFINAL, lits, li, ebits, data, o0, l0, out, pos) { util_1.U.lhst[256]++; var _a = getTrees(), ML = _a[0], MD = _a[1], MH = _a[2], numl = _a[3], numd = _a[4], numh = _a[5], lset = _a[6], dset = _a[7]; var cstSize = (((pos + 3) & 7) === 0 ? 0 : 8 - ((pos + 3) & 7)) + 32 + (l0 << 3); var fxdSize = ebits + contSize(util_1.U.fltree, util_1.U.lhst) + contSize(util_1.U.fdtree, util_1.U.dhst); var dynSize = ebits + contSize(util_1.U.ltree, util_1.U.lhst) + contSize(util_1.U.dtree, util_1.U.dhst); dynSize += 14 + 3 * numh + contSize(util_1.U.itree, util_1.U.ihst) + (util_1.U.ihst[16] * 2 + util_1.U.ihst[17] * 3 + util_1.U.ihst[18] * 7); for (var j = 0; j < 286; j++) util_1.U.lhst[j] = 0; for (var j = 0; j < 30; j++) util_1.U.dhst[j] = 0; for (var j = 0; j < 19; j++) util_1.U.ihst[j] = 0; var BTYPE = (cstSize < fxdSize && cstSize < dynSize) ? 0 : (fxdSize < dynSize ? 1 : 2); _putsF(out, pos, BFINAL); _putsF(out, pos + 1, BTYPE); pos += 3; // let opos = pos; if (BTYPE === 0) { while ((pos & 7) !== 0) pos++; pos = _copyExact(data, o0, l0, out, pos); } else { var ltree = void 0, dtree = void 0; if (BTYPE === 1) { ltree = util_1.U.fltree; dtree = util_1.U.fdtree; } else if (BTYPE === 2) { (0, util_1.makeCodes)(util_1.U.ltree, ML); (0, util_1.revCodes)(util_1.U.ltree, ML); (0, util_1.makeCodes)(util_1.U.dtree, MD); (0, util_1.revCodes)(util_1.U.dtree, MD); (0, util_1.makeCodes)(util_1.U.itree, MH); (0, util_1.revCodes)(util_1.U.itree, MH); ltree = util_1.U.ltree; dtree = util_1.U.dtree; _putsE(out, pos, numl - 257); pos += 5; // 286 _putsE(out, pos, numd - 1); pos += 5; // 30 _putsE(out, pos, numh - 4); pos += 4; // 19 for (var i = 0; i < numh; i++) _putsE(out, pos + i * 3, util_1.U.itree[(util_1.U.ordr[i] << 1) + 1]); pos += 3 * numh; pos = _codeTiny(lset, util_1.U.itree, out, pos); pos = _codeTiny(dset, util_1.U.itree, out, pos); } else { throw new Error("unknown BTYPE " + BTYPE); } var off = o0; for (var si = 0; si < li; si += 2) { var qb = lits[si], len = (qb >>> 23), end = off + (qb & ((1 << 23) - 1)); while (off < end) pos = _writeLit(data[off++], ltree, out, pos); if (len !== 0) { var qc = lits[si + 1], dst = (qc >> 16), lgi = (qc >> 8) & 255, dgi = (qc & 255); pos = _writeLit(257 + lgi, ltree, out, pos); _putsE(out, pos, len - util_1.U.of0[lgi]); pos += util_1.U.exb[lgi]; pos = _writeLit(dgi, dtree, out, pos); _putsF(out, pos, dst - util_1.U.df0[dgi]); pos += util_1.U.dxb[dgi]; off += len; } } pos = _writeLit(256, ltree, out, pos); } // console.log(pos-opos, fxdSize, dynSize, cstSize); return pos; } function _copyExact(data, off, len, out, pos) { var p8 = (pos >>> 3); out[p8] = (len); out[p8 + 1] = (len >>> 8); out[p8 + 2] = 255 - out[p8]; out[p8 + 3] = 255 - out[p8 + 1]; p8 += 4; out.set(new Uint8Array(data.buffer, off, len), p8); // for(var i=0; i<len; i++) out[p8+i]=data[off+i]; return pos + ((len + 4) << 3); } /* Interesting facts: - decompressed block can have bytes, which do not occur in a Huffman tree (copied from the previous block by reference) */ function getTrees() { var ML = (0, huffman_1._hufTree)(util_1.U.lhst, util_1.U.ltree, 15); var MD = (0, huffman_1._hufTree)(util_1.U.dhst, util_1.U.dtree, 15); var lset = []; var numl = _lenCodes(util_1.U.ltree, lset); var dset = []; var numd = _lenCodes(util_1.U.dtree, dset); for (var i = 0; i < lset.length; i += 2) util_1.U.ihst[lset[i]]++; for (var i = 0; i < dset.length; i += 2) util_1.U.ihst[dset[i]]++; var MH = (0, huffman_1._hufTree)(util_1.U.ihst, util_1.U.itree, 7); var numh = 19; while (numh > 4 && util_1.U.itree[(util_1.U.ordr[numh - 1] << 1) + 1] === 0) numh--; return [ML, MD, MH, numl, numd, numh, lset, dset]; } function contSize(tree, hst) { var s = 0; for (var i = 0; i < hst.length; i++) s += hst[i] * tree[(i << 1) + 1]; return s; } function _codeTiny(set, tree, out, pos) { for (var i = 0; i < set.length; i += 2) { var l = set[i], rst = set[i + 1]; // console.log(l, pos, tree[(l<<1)+1]); pos = _writeLit(l, tree, out, pos); var rsl = l === 16 ? 2 : (l === 17 ? 3 : 7); if (l > 15) { _putsE(out, pos, rst); pos += rsl; } } return pos; } function _lenCodes(tree, set) { var len = tree.length; while (len !== 2 && tree[len - 1] === 0) len -= 2; // when no distances, keep one code with length 0 for (var i = 0; i < len; i += 2) { var l = tree[i + 1], nxt = (i + 3 < len ? tree[i + 3] : -1), nnxt = (i + 5 < len ? tree[i + 5] : -1), prv = (i === 0 ? -1 : tree[i - 1]); if (l === 0 && nxt === l && nnxt === l) { var lz = i + 5; while (lz + 2 < len && tree[lz + 2] === l) lz += 2; var zc = Math.min((lz + 1 - i) >>> 1, 138); if (zc < 11) set.push(17, zc - 3); else set.push(18, zc - 11); i += zc * 2 - 2; } else if (l === prv && nxt === l && nnxt === l) { var lz = i + 5; while (lz + 2 < len && tree[lz + 2] === l) lz += 2; var zc = Math.min((lz + 1 - i) >>> 1, 6); set.push(16, zc - 3); i += zc * 2 - 2; } else { set.push(l, 0); } } return len >>> 1; } function _goodIndex(v, arr) { var i = 0; if (arr[i | 16] <= v) i |= 16; if (arr[i | 8] <= v) i |= 8; if (arr[i | 4] <= v) i |= 4; if (arr[i | 2] <= v) i |= 2; if (arr[i | 1] <= v) i |= 1; return i; } function _writeLit(ch, ltree, out, pos) { _putsF(out, pos, ltree[ch << 1]); return pos + ltree[(ch << 1) + 1]; } function _putsE(dt, pos, val) { val = val << (pos & 7); var o = (pos >>> 3); dt[o] |= val; dt[o + 1] |= (val >>> 8); } function _putsF(dt, pos, val) { val = val << (pos & 7); var o = (pos >>> 3); dt[o] |= val; dt[o + 1] |= (val >>> 8); dt[o + 2] |= (val >>> 16); } //# sourceMappingURL=deflate.js.map