ocean-subgraph/src/lzma/range-decoder.ts

96 lines
2.1 KiB
TypeScript

import { LZMA } from "./lzma";
/**
* LZMA Decoder
* @author Nidin Vinayakan
*/
export class RangeDecoder {
static kTopValue: u32 = 1 << 24
public inStream: Uint8Array
public corrupted: boolean
public in_pos: i32
private range: u32 = 0
private code: u32 = 0
constructor() {
this.in_pos = 13
}
@inline
public isFinishedOK(): boolean {
return this.code == 0
}
@inline
public init(): void {
this.corrupted = false
if (this.inStream[this.in_pos++] != 0) {
this.corrupted = true
}
this.range = 0xffffffff
this.code = 0
for (var i: i32 = 0; i < 4; i++) {
this.code = (this.code << 8) | this.inStream[this.in_pos++]
}
if (this.code == this.range) {
this.corrupted = true
}
}
@inline
public normalize():void {
if (this.range < RangeDecoder.kTopValue) {
this.range <<= 8
this.code = (this.code << 8) | this.inStream[this.in_pos++]
}
}
@inline
public decodeDirectBits(numBits: i32): i32 {
var res:u32 = 0
do {
this.range >>>= 1
this.code -= this.range
let t:u32 = 0 - (this.code >>> 31)
this.code += this.range & t
if (this.code == this.range) {
this.corrupted = true
}
this.normalize()
res <<= 1
res += t + 1
} while (--numBits)
return res
}
@inline
decodeBit(prob: Uint16Array, index: i32):u16 {
var v:u16 = prob.__unchecked_get(index);
var bound:u32 = (this.range >> LZMA.kNumBitModelTotalBits) * v;
var symbol:u16 = 0;
if (this.code < bound)
{
v += ((1 << LZMA.kNumBitModelTotalBits) - v) >> LZMA.kNumMoveBits;
this.range = bound;
symbol = 0;
}
else
{
v -= v >> LZMA.kNumMoveBits;
this.code -= bound;
this.range -= bound;
symbol = 1;
}
prob.__unchecked_set(index, v)
this.normalize();
return symbol;
}
}