UNPKG

@gmod/cram

Version:

read CRAM files with pure Javascript

60 lines 2.18 kB
import CramCodec from "./_base.js"; import { CramBufferOverrunError, CramUnimplementedError } from "../../errors.js"; export default class GammaCodec extends CramCodec { constructor(parameters, dataType) { super(parameters, dataType); if (this.dataType !== 'int') { throw new CramUnimplementedError(`${this.dataType} decoding not yet implemented by GAMMA codec`); } } decode(_slice, coreDataBlock, _blocksByContentId, cursors) { return decodeGammaInline(coreDataBlock.content, cursors.coreBlock, this.parameters.offset); } } /** * Optimized gamma decoder with inlined bit reading. * Avoids function call overhead by inlining the getBits logic. */ function decodeGammaInline(data, cursor, offset) { let { bytePosition, bitPosition } = cursor; let length = 1; // Count leading zeros (each 0 bit increases length). A truncated core block // reads as zeros forever, so guard against running off the end. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition while (true) { if (bytePosition >= data.length) { throw new CramBufferOverrunError('read beyond end of core block; file seems truncated'); } const bit = (data[bytePosition] >> bitPosition) & 1; bitPosition -= 1; if (bitPosition < 0) { bytePosition += 1; bitPosition = 7; } if (bit === 1) { break; } length += 1; } // Now read (length - 1) more bits for the value let readBits = 0; const bitsToRead = length - 1; if (bitsToRead > 0) { // Optimized multi-bit read for (let i = 0; i < bitsToRead; i++) { readBits <<= 1; readBits |= (data[bytePosition] >> bitPosition) & 1; bitPosition -= 1; if (bitPosition < 0) { bytePosition += 1; bitPosition = 7; } } } // Update cursor cursor.bytePosition = bytePosition; cursor.bitPosition = bitPosition; const value = readBits | (1 << (length - 1)); return value - offset; } //# sourceMappingURL=gamma.js.map