import { assert , readString } from '../../util' ; import ArrayBufferSlice from '../../ArrayBufferSlice' ; export function decompressSW ( srcBuffer ) { const srcView = srcBuffer . createDataView ( ) ; assert ( readString ( srcBuffer , 0x00 , 0x04 ) === 'Yaz0' ) ; let uncompressedSize = srcView . getUint32 ( 0x04 , false ) ; const dstBuffer = new Uint8Array ( uncompressedSize ) ; let srcOffs = 0x10 ; let dstOffs = 0x00 ; while ( true ) { const commandByte = srcView . getUint8 ( srcOffs ++ ) ; let i = 8 ; while ( i -- ) { if ( commandByte & ( 1 << i ) ) { uncompressedSize -- ; dstBuffer [ dstOffs ++ ] = srcView . getUint8 ( srcOffs ++ ) ; } else { const tmp = srcView . getUint16 ( srcOffs , false ) ; srcOffs += 2 ; const windowOffset = ( tmp & 0x0FFF ) + 1 ; let windowLength = ( tmp >> 12 ) + 2 ; if ( windowLength === 2 ) { windowLength += srcView . getUint8 ( srcOffs ++ ) + 0x10 ; } assert ( windowLength >= 3 && windowLength <= 0x111 ) ; let copyOffs = dstOffs - windowOffset ; uncompressedSize -= windowLength ; while ( windowLength -- ) dstBuffer [ dstOffs ++ ] = dstBuffer [ copyOffs ++ ] ; } if ( uncompressedSize <= 0 ) return new ArrayBufferSlice ( dstBuffer . buffer ) ; } } } export class Yaz0DecompressorWASM { constructor ( private yaz0dec ) { } public decompress ( srcBuffer ) { const buf = this . yaz0dec ( srcBuffer . createTypedArray ( Uint8Array ) ) ; return new ArrayBufferSlice ( buf . buffer , buf . byteOffset , buf . byteLength ) ; } } export function decompressSync ( d , srcBuffer ) { return d . decompress ( srcBuffer ) ; } let _decompressor = null ; export async function getWASM ( ) { if ( _decompressor === null ) { const { yaz0dec } = await import ( '../../../rust/pkg/index' ) ; _decompressor = new Yaz0DecompressorWASM ( yaz0dec ) ; } return _decompressor ; } export async function decompress ( srcBuffer ) { return decompressSync ( await getWASM ( ) , srcBuffer ) ; }