UNPKG

@gmod/bgzf-filehandle

Version:

read from a compressed bgzip file (with .gzi) as if it were uncompressed

105 lines 3.91 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.unzip = unzip; exports.unzipChunkSlice = unzipChunkSlice; const pako_1 = __importDefault(require("pako")); const util_ts_1 = require("./util.js"); //@ts-ignore const { Z_SYNC_FLUSH, Inflate } = pako_1.default; // browserify-zlib, which is the zlib shim used by default in webpacked code, // does not properly uncompress bgzf chunks that contain more than one bgzf // block, so export an unzip function that uses pako directly if we are running // in a browser. async function unzip(inputData) { try { let strm; let pos = 0; let inflator; const blocks = []; do { const remainingInput = inputData.subarray(pos); inflator = new Inflate(); ({ strm } = inflator); inflator.push(remainingInput, Z_SYNC_FLUSH); if (inflator.err) { throw new Error(inflator.msg); } pos += strm.next_in; blocks.push(inflator.result); } while (strm.avail_in); return (0, util_ts_1.concatUint8Array)(blocks); } catch (e) { // return a slightly more informative error message if (/incorrect header check/.exec(`${e}`)) { throw new Error('problem decompressing block: incorrect gzip header check'); } throw e; } } // keeps track of the position of compressed blocks in terms of file offsets, // and a decompressed equivalent // // also slices (0,minv.dataPosition) and (maxv.dataPosition,end) off async function unzipChunkSlice(inputData, chunk) { try { let strm; const { minv, maxv } = chunk; let cpos = minv.blockPosition; let dpos = minv.dataPosition; const chunks = []; const cpositions = []; const dpositions = []; let i = 0; do { const remainingInput = inputData.subarray(cpos - minv.blockPosition); const inflator = new Inflate(); ({ strm } = inflator); inflator.push(remainingInput, Z_SYNC_FLUSH); if (inflator.err) { throw new Error(inflator.msg); } const buffer = inflator.result; chunks.push(buffer); let len = buffer.length; cpositions.push(cpos); dpositions.push(dpos); if (chunks.length === 1 && minv.dataPosition) { // this is the first chunk, trim it chunks[0] = chunks[0].subarray(minv.dataPosition); len = chunks[0].length; } const origCpos = cpos; cpos += strm.next_in; dpos += len; if (origCpos >= maxv.blockPosition) { // this is the last chunk, trim it and stop decompressing. note if it is // the same block is minv it subtracts that already trimmed part of the // slice length chunks[i] = chunks[i].subarray(0, maxv.blockPosition === minv.blockPosition ? maxv.dataPosition - minv.dataPosition + 1 : maxv.dataPosition + 1); cpositions.push(cpos); dpositions.push(dpos); break; } i++; } while (strm.avail_in); return { buffer: (0, util_ts_1.concatUint8Array)(chunks), cpositions, dpositions, }; } catch (e) { // return a slightly more informative error message if (/incorrect header check/.exec(`${e}`)) { throw new Error('problem decompressing block: incorrect gzip header check'); } throw e; } } //# sourceMappingURL=unzip.js.map