lzma1 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/lib/chunker.d.ts +46 -0
- package/lib/chunker.js +68 -0
- package/lib/decoder.d.ts +80 -0
- package/lib/decoder.js +469 -0
- package/lib/encoder.d.ts +266 -0
- package/lib/encoder.js +822 -0
- package/lib/index.d.ts +4 -3
- package/lib/index.js +16 -9
- package/lib/len-coder.d.ts +70 -0
- package/lib/len-coder.js +171 -0
- package/lib/lit-coder.d.ts +63 -0
- package/lib/lit-coder.js +162 -0
- package/lib/lz-in-window.d.ts +43 -0
- package/lib/lz-in-window.js +132 -0
- package/lib/lz-window.d.ts +35 -0
- package/lib/lz-window.js +89 -0
- package/lib/lzma.d.ts +97 -56
- package/lib/lzma.js +244 -1485
- package/lib/match-finder-config.d.ts +34 -0
- package/lib/match-finder-config.js +63 -0
- package/lib/range-bit-tree-coder.d.ts +34 -0
- package/lib/range-bit-tree-coder.js +95 -0
- package/lib/range-decoder.d.ts +34 -0
- package/lib/range-decoder.js +98 -0
- package/lib/range-encoder.d.ts +46 -0
- package/lib/range-encoder.js +129 -0
- package/lib/streams.d.ts +32 -0
- package/lib/streams.js +1 -0
- package/lib/utils.d.ts +127 -0
- package/lib/utils.js +300 -0
- package/package.json +3 -3
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { MatchFinder } from "./encoder.js";
|
|
2
|
+
/**
|
|
3
|
+
* Match finder configuration helpers
|
|
4
|
+
* Pure functions extracted from LZMA class for better modularity
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Compute window reservation size for match finder buffer allocation
|
|
8
|
+
*/
|
|
9
|
+
export declare function computeWindowReservSize(dictionarySize: number, keepBefore: number, numFastBytes: number, keepAfter: number): number;
|
|
10
|
+
/**
|
|
11
|
+
* Ensure cyclic buffer is properly sized and allocated
|
|
12
|
+
*/
|
|
13
|
+
export declare function ensureCyclicBuffer(matchFinder: MatchFinder, dictionarySize: number): void;
|
|
14
|
+
interface HashSizeConfig {
|
|
15
|
+
hashMask: number;
|
|
16
|
+
hashSizeSum: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compute hash size for match finder hash table
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeHashSize(dictionarySize: number, hashArrayEnabled: boolean): HashSizeConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Set cut value for match finder based on fast bytes setting
|
|
24
|
+
*/
|
|
25
|
+
export declare function setCutValue(numFastBytes: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Set maximum match length for match finder
|
|
28
|
+
*/
|
|
29
|
+
export declare function setMatchMaxLen(numFastBytes: number): number;
|
|
30
|
+
/**
|
|
31
|
+
* Check if dictionary size is below threshold requiring special handling
|
|
32
|
+
*/
|
|
33
|
+
export declare function isDictionarySizeBelowThreshold(dictionarySize: number): boolean;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { DICTIONARY_SIZE_THRESHOLD, initArray, } from "./utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Match finder configuration helpers
|
|
4
|
+
* Pure functions extracted from LZMA class for better modularity
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Compute window reservation size for match finder buffer allocation
|
|
8
|
+
*/
|
|
9
|
+
export function computeWindowReservSize(dictionarySize, keepBefore, numFastBytes, keepAfter) {
|
|
10
|
+
return ~~((dictionarySize + keepBefore + numFastBytes + keepAfter) / 2) + 0x100;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Ensure cyclic buffer is properly sized and allocated
|
|
14
|
+
*/
|
|
15
|
+
export function ensureCyclicBuffer(matchFinder, dictionarySize) {
|
|
16
|
+
const cyclicBufferSize = dictionarySize + 1;
|
|
17
|
+
if (matchFinder._cyclicBufferSize !== cyclicBufferSize) {
|
|
18
|
+
const doubledCyclicBufferSize = (matchFinder._cyclicBufferSize = cyclicBufferSize) * 2;
|
|
19
|
+
matchFinder._son = initArray(doubledCyclicBufferSize);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Compute hash size for match finder hash table
|
|
24
|
+
*/
|
|
25
|
+
export function computeHashSize(dictionarySize, hashArrayEnabled) {
|
|
26
|
+
let hs = 0x10000;
|
|
27
|
+
let hashMask = 0;
|
|
28
|
+
if (hashArrayEnabled) {
|
|
29
|
+
hs = dictionarySize - 1;
|
|
30
|
+
hs |= hs >> 1;
|
|
31
|
+
hs |= hs >> 2;
|
|
32
|
+
hs |= hs >> 4;
|
|
33
|
+
hs |= hs >> 0x08;
|
|
34
|
+
hs >>= 1;
|
|
35
|
+
hs |= 0xFFFF;
|
|
36
|
+
if (hs > 0x1000000) {
|
|
37
|
+
hs >>= 1;
|
|
38
|
+
}
|
|
39
|
+
hashMask = hs;
|
|
40
|
+
hs += 1;
|
|
41
|
+
// Add kFixHashSize (assumed to be available on matchFinder)
|
|
42
|
+
// This will be passed in from the calling context
|
|
43
|
+
}
|
|
44
|
+
return { hashMask, hashSizeSum: hs };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Set cut value for match finder based on fast bytes setting
|
|
48
|
+
*/
|
|
49
|
+
export function setCutValue(numFastBytes) {
|
|
50
|
+
return 0x10 + (numFastBytes >> 1);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Set maximum match length for match finder
|
|
54
|
+
*/
|
|
55
|
+
export function setMatchMaxLen(numFastBytes) {
|
|
56
|
+
return numFastBytes;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if dictionary size is below threshold requiring special handling
|
|
60
|
+
*/
|
|
61
|
+
export function isDictionarySizeBelowThreshold(dictionarySize) {
|
|
62
|
+
return dictionarySize < DICTIONARY_SIZE_THRESHOLD;
|
|
63
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type BasicRangeDecoder, type BasicRangeEncoder } from "./utils.js";
|
|
2
|
+
export declare class RangeBitTreeCoder {
|
|
3
|
+
private models;
|
|
4
|
+
private numBitLevels;
|
|
5
|
+
constructor(numBitLevels: number);
|
|
6
|
+
/**
|
|
7
|
+
* Decode symbol using range decoder
|
|
8
|
+
*/
|
|
9
|
+
decode(rd: BasicRangeDecoder): number;
|
|
10
|
+
/**
|
|
11
|
+
* Reverse decode symbol using range decoder
|
|
12
|
+
*/
|
|
13
|
+
reverseDecode(rd: BasicRangeDecoder): number;
|
|
14
|
+
/**
|
|
15
|
+
* Encode symbol using range encoder
|
|
16
|
+
*/
|
|
17
|
+
encode(re: BasicRangeEncoder, symbol: number): void;
|
|
18
|
+
/**
|
|
19
|
+
* Reverse encode symbol using range encoder
|
|
20
|
+
*/
|
|
21
|
+
reverseEncode(re: BasicRangeEncoder, symbol: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Get price for encoding symbol
|
|
24
|
+
*/
|
|
25
|
+
getPrice(symbol: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Get price for reverse encoding symbol
|
|
28
|
+
*/
|
|
29
|
+
reverseGetPrice(symbol: number): number;
|
|
30
|
+
/**
|
|
31
|
+
* Reset models to initial state
|
|
32
|
+
*/
|
|
33
|
+
reset(): void;
|
|
34
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { getBitPrice, initArray, } from "./utils.js";
|
|
2
|
+
export class RangeBitTreeCoder {
|
|
3
|
+
models;
|
|
4
|
+
numBitLevels;
|
|
5
|
+
constructor(numBitLevels) {
|
|
6
|
+
this.numBitLevels = numBitLevels;
|
|
7
|
+
this.models = initArray(1 << numBitLevels, 1024); // Initialize with default probability
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Decode symbol using range decoder
|
|
11
|
+
*/
|
|
12
|
+
decode(rd) {
|
|
13
|
+
let res = 1;
|
|
14
|
+
for (let bitIndex = this.numBitLevels; bitIndex !== 0; bitIndex--) {
|
|
15
|
+
const bit = rd.decodeBit(this.models, res);
|
|
16
|
+
res = (res << 1) + bit;
|
|
17
|
+
}
|
|
18
|
+
res -= 1 << this.numBitLevels;
|
|
19
|
+
return res;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Reverse decode symbol using range decoder
|
|
23
|
+
*/
|
|
24
|
+
reverseDecode(rd) {
|
|
25
|
+
let index = 1;
|
|
26
|
+
let res = 0;
|
|
27
|
+
for (let bitIndex = 0; bitIndex < this.numBitLevels; bitIndex++) {
|
|
28
|
+
const bit = rd.decodeBit(this.models, index);
|
|
29
|
+
index <<= 1;
|
|
30
|
+
index += bit;
|
|
31
|
+
res |= bit << bitIndex;
|
|
32
|
+
}
|
|
33
|
+
return res;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Encode symbol using range encoder
|
|
37
|
+
*/
|
|
38
|
+
encode(re, symbol) {
|
|
39
|
+
let m = 1;
|
|
40
|
+
for (let bitIndex = this.numBitLevels; bitIndex !== 0;) {
|
|
41
|
+
bitIndex--;
|
|
42
|
+
const bit = (symbol >> bitIndex) & 1;
|
|
43
|
+
re.encodeBit(this.models, m, bit);
|
|
44
|
+
m = (m << 1) | bit;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Reverse encode symbol using range encoder
|
|
49
|
+
*/
|
|
50
|
+
reverseEncode(re, symbol) {
|
|
51
|
+
let m = 1;
|
|
52
|
+
for (let i = 0; i < this.numBitLevels; i++) {
|
|
53
|
+
const bit = symbol & 1;
|
|
54
|
+
re.encodeBit(this.models, m, bit);
|
|
55
|
+
m = (m << 1) | bit;
|
|
56
|
+
symbol >>= 1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get price for encoding symbol
|
|
61
|
+
*/
|
|
62
|
+
getPrice(symbol) {
|
|
63
|
+
let res = 0;
|
|
64
|
+
let m = 1;
|
|
65
|
+
for (let bitIndex = this.numBitLevels; bitIndex !== 0;) {
|
|
66
|
+
bitIndex--;
|
|
67
|
+
const bit = (symbol >> bitIndex) & 1;
|
|
68
|
+
res += getBitPrice(this.models[m], bit);
|
|
69
|
+
m = (m << 1) + bit;
|
|
70
|
+
}
|
|
71
|
+
return res;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get price for reverse encoding symbol
|
|
75
|
+
*/
|
|
76
|
+
reverseGetPrice(symbol) {
|
|
77
|
+
let res = 0;
|
|
78
|
+
let m = 1;
|
|
79
|
+
for (let i = this.numBitLevels; i !== 0; i--) {
|
|
80
|
+
const bit = symbol & 1;
|
|
81
|
+
symbol >>= 1;
|
|
82
|
+
res += getBitPrice(this.models[m], bit);
|
|
83
|
+
m = (m << 1) | bit;
|
|
84
|
+
}
|
|
85
|
+
return res;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Reset models to initial state
|
|
89
|
+
*/
|
|
90
|
+
reset() {
|
|
91
|
+
for (let i = 0; i < this.models.length; i++) {
|
|
92
|
+
this.models[i] = 1024; // Default probability
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { BaseStream } from "./streams.js";
|
|
2
|
+
export declare class RangeDecoder {
|
|
3
|
+
stream: BaseStream | null;
|
|
4
|
+
code: number;
|
|
5
|
+
rrange: number;
|
|
6
|
+
/**
|
|
7
|
+
* Set input stream for decoding
|
|
8
|
+
*/
|
|
9
|
+
setStream(stream: BaseStream | null): void;
|
|
10
|
+
/**
|
|
11
|
+
* Initialize range decoder
|
|
12
|
+
*/
|
|
13
|
+
init(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Decode a single bit using probability model
|
|
16
|
+
*/
|
|
17
|
+
decodeBit(probs: number[], index: number): 0 | 1;
|
|
18
|
+
/**
|
|
19
|
+
* Decode direct bits (without probability model)
|
|
20
|
+
*/
|
|
21
|
+
decodeDirectBits(numTotalBits: number): number;
|
|
22
|
+
/**
|
|
23
|
+
* Get current code value (for compatibility)
|
|
24
|
+
*/
|
|
25
|
+
get currentCode(): number;
|
|
26
|
+
/**
|
|
27
|
+
* Get current range value (for compatibility)
|
|
28
|
+
*/
|
|
29
|
+
get currentRange(): number;
|
|
30
|
+
/**
|
|
31
|
+
* Read a single byte from the input stream
|
|
32
|
+
*/
|
|
33
|
+
private readFromStream;
|
|
34
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export class RangeDecoder {
|
|
2
|
+
stream = null;
|
|
3
|
+
code = 0;
|
|
4
|
+
rrange = 0;
|
|
5
|
+
/**
|
|
6
|
+
* Set input stream for decoding
|
|
7
|
+
*/
|
|
8
|
+
setStream(stream) {
|
|
9
|
+
this.stream = stream;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Initialize range decoder
|
|
13
|
+
*/
|
|
14
|
+
init() {
|
|
15
|
+
this.code = 0;
|
|
16
|
+
this.rrange = -1;
|
|
17
|
+
for (let i = 0; i < 5; ++i) {
|
|
18
|
+
this.code = this.code << 8 | this.readFromStream();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Decode a single bit using probability model
|
|
23
|
+
*/
|
|
24
|
+
decodeBit(probs, index) {
|
|
25
|
+
let newBound, prob = probs[index];
|
|
26
|
+
newBound = (this.rrange >>> 11) * prob;
|
|
27
|
+
if ((this.code ^ -0x80000000) < (newBound ^ -0x80000000)) {
|
|
28
|
+
this.rrange = newBound;
|
|
29
|
+
probs[index] = prob + (2048 - prob >>> 5) << 16 >> 16;
|
|
30
|
+
if (!(this.rrange & -0x1000000)) {
|
|
31
|
+
this.code = this.code << 8 | this.readFromStream();
|
|
32
|
+
this.rrange <<= 8;
|
|
33
|
+
}
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
this.rrange -= newBound;
|
|
38
|
+
this.code -= newBound;
|
|
39
|
+
probs[index] = prob - (prob >>> 5) << 16 >> 16;
|
|
40
|
+
if (!(this.rrange & -0x1000000)) {
|
|
41
|
+
this.code = this.code << 8 | this.readFromStream();
|
|
42
|
+
this.rrange <<= 8;
|
|
43
|
+
}
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Decode direct bits (without probability model)
|
|
49
|
+
*/
|
|
50
|
+
decodeDirectBits(numTotalBits) {
|
|
51
|
+
let result = 0;
|
|
52
|
+
for (let i = numTotalBits; i != 0; i -= 1) {
|
|
53
|
+
this.rrange >>>= 1;
|
|
54
|
+
let t = (this.code - this.rrange) >>> 31;
|
|
55
|
+
this.code -= this.rrange & (t - 1);
|
|
56
|
+
result = result << 1 | 1 - t;
|
|
57
|
+
if (!(this.rrange & -0x1000000)) {
|
|
58
|
+
this.code = this.code << 8 | this.readFromStream();
|
|
59
|
+
this.rrange <<= 8;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get current code value (for compatibility)
|
|
66
|
+
*/
|
|
67
|
+
get currentCode() {
|
|
68
|
+
return this.code;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get current range value (for compatibility)
|
|
72
|
+
*/
|
|
73
|
+
get currentRange() {
|
|
74
|
+
return this.rrange;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Read a single byte from the input stream
|
|
78
|
+
*/
|
|
79
|
+
readFromStream() {
|
|
80
|
+
if (!this.stream) {
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
if (this.stream.pos >= this.stream.count) {
|
|
84
|
+
return -1;
|
|
85
|
+
}
|
|
86
|
+
let value;
|
|
87
|
+
if (this.stream.buf instanceof ArrayBuffer) {
|
|
88
|
+
value = new Uint8Array(this.stream.buf)[this.stream.pos++];
|
|
89
|
+
}
|
|
90
|
+
else if (this.stream.buf instanceof Uint8Array) {
|
|
91
|
+
value = this.stream.buf[this.stream.pos++];
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
value = this.stream.buf[this.stream.pos++];
|
|
95
|
+
}
|
|
96
|
+
return value & 0xFF;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BufferWithCount } from "./streams.js";
|
|
2
|
+
export declare class RangeEncoder {
|
|
3
|
+
private stream;
|
|
4
|
+
private low;
|
|
5
|
+
private rrange;
|
|
6
|
+
private cache;
|
|
7
|
+
private cacheSize;
|
|
8
|
+
private position;
|
|
9
|
+
constructor();
|
|
10
|
+
/**
|
|
11
|
+
* Set output stream for encoding
|
|
12
|
+
*/
|
|
13
|
+
setStream(stream: BufferWithCount | null): void;
|
|
14
|
+
/**
|
|
15
|
+
* Initialize range encoder
|
|
16
|
+
*/
|
|
17
|
+
init(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Encode a single bit using probability model
|
|
20
|
+
*/
|
|
21
|
+
encodeBit(probs: number[], index: number, bit: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Encode direct bits (without probability model)
|
|
24
|
+
*/
|
|
25
|
+
encodeDirectBits(value: number, numTotalBits: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Encode bit tree symbol
|
|
28
|
+
*/
|
|
29
|
+
encodeBitTree(numBitLevels: number, models: number[], symbol: number, startIndex?: number): void;
|
|
30
|
+
/**
|
|
31
|
+
* Reverse encode bits
|
|
32
|
+
*/
|
|
33
|
+
reverseEncodeBits(numBitLevels: number, models: number[], symbol: number, startIndex: number): void;
|
|
34
|
+
/**
|
|
35
|
+
* Finish encoding and flush remaining data
|
|
36
|
+
*/
|
|
37
|
+
finish(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Shift low value and write to stream
|
|
40
|
+
*/
|
|
41
|
+
private shiftLow;
|
|
42
|
+
/**
|
|
43
|
+
* Write byte to output stream
|
|
44
|
+
*/
|
|
45
|
+
private writeToStream;
|
|
46
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { add64, fromInt64, lowBits64, } from "./utils.js";
|
|
2
|
+
export class RangeEncoder {
|
|
3
|
+
stream = null;
|
|
4
|
+
low = [0, 0];
|
|
5
|
+
rrange = 0;
|
|
6
|
+
cache = 0;
|
|
7
|
+
cacheSize = 0;
|
|
8
|
+
position = [0, 0];
|
|
9
|
+
constructor() {
|
|
10
|
+
// Initialize with default values
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Set output stream for encoding
|
|
14
|
+
*/
|
|
15
|
+
setStream(stream) {
|
|
16
|
+
this.stream = stream;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Initialize range encoder
|
|
20
|
+
*/
|
|
21
|
+
init() {
|
|
22
|
+
this.position = [0, 0];
|
|
23
|
+
this.low = [0, 0];
|
|
24
|
+
this.rrange = -1;
|
|
25
|
+
this.cacheSize = 1;
|
|
26
|
+
this.cache = 0;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Encode a single bit using probability model
|
|
30
|
+
*/
|
|
31
|
+
encodeBit(probs, index, bit) {
|
|
32
|
+
const prob = probs[index];
|
|
33
|
+
const newBound = (this.rrange >>> 11) * prob;
|
|
34
|
+
if (bit === 0) {
|
|
35
|
+
this.rrange = newBound;
|
|
36
|
+
probs[index] = prob + ((2048 - prob) >>> 5) << 16 >> 16;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.low = add64(this.low, fromInt64(newBound));
|
|
40
|
+
this.rrange -= newBound;
|
|
41
|
+
probs[index] = prob - (prob >>> 5) << 16 >> 16;
|
|
42
|
+
}
|
|
43
|
+
if (!(this.rrange & -0x1000000)) {
|
|
44
|
+
this.rrange <<= 8;
|
|
45
|
+
this.shiftLow();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Encode direct bits (without probability model)
|
|
50
|
+
*/
|
|
51
|
+
encodeDirectBits(value, numTotalBits) {
|
|
52
|
+
for (let i = numTotalBits - 1; i >= 0; i--) {
|
|
53
|
+
this.rrange >>>= 1;
|
|
54
|
+
if (((value >>> i) & 1) === 1) {
|
|
55
|
+
this.low = add64(this.low, fromInt64(this.rrange));
|
|
56
|
+
}
|
|
57
|
+
if (!(this.rrange & -0x1000000)) {
|
|
58
|
+
this.rrange <<= 8;
|
|
59
|
+
this.shiftLow();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Encode bit tree symbol
|
|
65
|
+
*/
|
|
66
|
+
encodeBitTree(numBitLevels, models, symbol, startIndex = 1) {
|
|
67
|
+
let m = 1;
|
|
68
|
+
for (let bitIndex = numBitLevels; bitIndex !== 0; bitIndex--) {
|
|
69
|
+
const bit = (symbol >>> (bitIndex - 1)) & 1;
|
|
70
|
+
this.encodeBit(models, startIndex + m - 1, bit);
|
|
71
|
+
m = (m << 1) | bit;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reverse encode bits
|
|
76
|
+
*/
|
|
77
|
+
reverseEncodeBits(numBitLevels, models, symbol, startIndex) {
|
|
78
|
+
let m = 1;
|
|
79
|
+
for (let i = 0; i < numBitLevels; i++) {
|
|
80
|
+
const bit = symbol & 1;
|
|
81
|
+
this.encodeBit(models, startIndex + m, bit);
|
|
82
|
+
m = (m << 1) | bit;
|
|
83
|
+
symbol >>>= 1;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Finish encoding and flush remaining data
|
|
88
|
+
*/
|
|
89
|
+
finish() {
|
|
90
|
+
for (let i = 0; i < 5; i++) {
|
|
91
|
+
this.shiftLow();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Shift low value and write to stream
|
|
96
|
+
*/
|
|
97
|
+
shiftLow() {
|
|
98
|
+
const lowHi = lowBits64([this.low[1], 0]);
|
|
99
|
+
if (lowHi !== 0 || this.low[0] < 0xFF000000) {
|
|
100
|
+
this.position = add64(this.position, fromInt64(this.cacheSize));
|
|
101
|
+
let temp = this.cache;
|
|
102
|
+
do {
|
|
103
|
+
this.writeToStream(temp + lowHi);
|
|
104
|
+
temp = 255;
|
|
105
|
+
} while (--this.cacheSize !== 0);
|
|
106
|
+
this.cache = (this.low[0] >>> 24) & 0xFF;
|
|
107
|
+
}
|
|
108
|
+
this.cacheSize++;
|
|
109
|
+
this.low = [(this.low[0] & 0xFFFFFF) << 8, this.low[1]];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Write byte to output stream
|
|
113
|
+
*/
|
|
114
|
+
writeToStream(value) {
|
|
115
|
+
if (!this.stream) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Ensure buffer has enough capacity
|
|
119
|
+
if (this.stream.count >= this.stream.buf.length) {
|
|
120
|
+
const newSize = Math.max(this.stream.buf.length * 2, this.stream.count + 1);
|
|
121
|
+
const newBuf = new Array(newSize);
|
|
122
|
+
for (let i = 0; i < this.stream.count; i++) {
|
|
123
|
+
newBuf[i] = this.stream.buf[i];
|
|
124
|
+
}
|
|
125
|
+
this.stream.buf = newBuf;
|
|
126
|
+
}
|
|
127
|
+
this.stream.buf[this.stream.count++] = value & 0xFF;
|
|
128
|
+
}
|
|
129
|
+
}
|
package/lib/streams.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RelativeIndexable is a generic interface for array-like structures
|
|
3
|
+
* that can be indexed with a number
|
|
4
|
+
*/
|
|
5
|
+
export type RelativeIndexable<T> = {
|
|
6
|
+
[key: number]: T;
|
|
7
|
+
length: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Base stream interface for input/output operations
|
|
11
|
+
*/
|
|
12
|
+
export interface BaseStream {
|
|
13
|
+
buf: RelativeIndexable<number> | Uint8Array | ArrayBuffer | number[];
|
|
14
|
+
pos: number;
|
|
15
|
+
count: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Represents a buffer with a count of used elements
|
|
19
|
+
*/
|
|
20
|
+
export interface BufferWithCount {
|
|
21
|
+
buf: number[];
|
|
22
|
+
count: number;
|
|
23
|
+
write(buf: number[]): void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Writer interface for output operations
|
|
27
|
+
*/
|
|
28
|
+
export interface Writer {
|
|
29
|
+
buf?: number[];
|
|
30
|
+
count?: number;
|
|
31
|
+
write(buf: number[]): void;
|
|
32
|
+
}
|
package/lib/streams.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export interface BitTree {
|
|
2
|
+
numBitLevels: number;
|
|
3
|
+
models: number[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Literal decoder/encoder for optimization
|
|
7
|
+
*/
|
|
8
|
+
export interface LiteralDecoderEncoder2 {
|
|
9
|
+
decoders: number[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Basic range encoder interface for bit operations
|
|
13
|
+
*/
|
|
14
|
+
export interface BasicRangeEncoder {
|
|
15
|
+
encodeBit(probs: number[], index: number, bit: number): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Basic range decoder interface for bit operations
|
|
19
|
+
*/
|
|
20
|
+
export interface BasicRangeDecoder {
|
|
21
|
+
decodeBit(probs: number[], index: number): number;
|
|
22
|
+
}
|
|
23
|
+
export declare const INFINITY_PRICE = 268435455;
|
|
24
|
+
export declare const _MAX_UINT32 = 4294967295;
|
|
25
|
+
export declare const DICTIONARY_SIZE_THRESHOLD = 1073741823;
|
|
26
|
+
export declare const kTopValue: number;
|
|
27
|
+
export declare const kNumBitModelTotalBits = 11;
|
|
28
|
+
export declare const kBitModelTotal: number;
|
|
29
|
+
export declare const kNumMoveBits = 5;
|
|
30
|
+
export declare const kNumMoveReducingBits = 2;
|
|
31
|
+
export declare const kNumBitPriceShiftBits = 6;
|
|
32
|
+
export declare const MATCH_DECODERS_SIZE = 192;
|
|
33
|
+
export declare const REP_DECODERS_SIZE = 12;
|
|
34
|
+
export declare const POS_DECODERS_SIZE = 114;
|
|
35
|
+
export declare const LITERAL_DECODER_SIZE = 768;
|
|
36
|
+
export declare const DEFAULT_WINDOW_SIZE = 4096;
|
|
37
|
+
export declare const CHOICE_ARRAY_SIZE = 2;
|
|
38
|
+
export declare const N1_LONG_LIT: [number, number];
|
|
39
|
+
export declare const MIN_VALUE: [number, number];
|
|
40
|
+
export declare const P0_LONG_LIT: [number, number];
|
|
41
|
+
export declare const P1_LONG_LIT: [number, number];
|
|
42
|
+
export declare const ZERO_64: [number, number];
|
|
43
|
+
/**
|
|
44
|
+
* CRC32 lookup table for hash calculations
|
|
45
|
+
* dprint-ignore
|
|
46
|
+
*/
|
|
47
|
+
export declare const CRC32_TABLE: number[];
|
|
48
|
+
/**
|
|
49
|
+
* Pre-computed static instances for common use
|
|
50
|
+
*/
|
|
51
|
+
export declare const PROB_PRICES: number[];
|
|
52
|
+
export declare const G_FAST_POS: number[];
|
|
53
|
+
/**
|
|
54
|
+
* Initialize array with specified length and default value
|
|
55
|
+
* This is MUCH faster than "new Array(len)" in newer versions of v8
|
|
56
|
+
* (starting with Node.js 0.11.15, which uses v8 3.28.73).
|
|
57
|
+
*/
|
|
58
|
+
export declare function initArray(len: number, value?: number): number[];
|
|
59
|
+
/**
|
|
60
|
+
* Copy array data with bounds checking and overlap handling
|
|
61
|
+
*/
|
|
62
|
+
export declare function arraycopy(src: number[], srcOfs: number, dest: number[], destOfs: number, len: number): void;
|
|
63
|
+
/**
|
|
64
|
+
* Get bit price using pre-computed probability prices
|
|
65
|
+
*/
|
|
66
|
+
export declare function getBitPrice(probability: number, bit: number): number;
|
|
67
|
+
/**
|
|
68
|
+
* Create a 64-bit number from low and high parts
|
|
69
|
+
*/
|
|
70
|
+
export declare function create64(valueLow: number, valueHigh: number): [number, number];
|
|
71
|
+
/**
|
|
72
|
+
* Add two 64-bit numbers
|
|
73
|
+
*/
|
|
74
|
+
export declare function add64(a: [number, number], b: [number, number]): [number, number];
|
|
75
|
+
/**
|
|
76
|
+
* Subtract two 64-bit numbers
|
|
77
|
+
*/
|
|
78
|
+
export declare function sub64(a: [number, number], b: [number, number]): [number, number];
|
|
79
|
+
/**
|
|
80
|
+
* Compare two 64-bit numbers
|
|
81
|
+
*/
|
|
82
|
+
export declare function compare64(a: [number, number], b: [number, number]): 0 | 1 | -1;
|
|
83
|
+
/**
|
|
84
|
+
* Extract low bits from 64-bit number
|
|
85
|
+
*/
|
|
86
|
+
export declare function lowBits64(a: [number, number]): number;
|
|
87
|
+
/**
|
|
88
|
+
* Create 64-bit number from integer
|
|
89
|
+
*/
|
|
90
|
+
export declare function fromInt64(value: number): [number, number];
|
|
91
|
+
/**
|
|
92
|
+
* Right shift 64-bit number
|
|
93
|
+
*/
|
|
94
|
+
export declare function shr64(a: [number, number], n: number): [number, number];
|
|
95
|
+
/**
|
|
96
|
+
* Bit model operations
|
|
97
|
+
*/
|
|
98
|
+
/**
|
|
99
|
+
* Initialize bit models with default probability
|
|
100
|
+
*/
|
|
101
|
+
export declare function initBitModels(probs: number[]): void;
|
|
102
|
+
/**
|
|
103
|
+
* Position and state operations
|
|
104
|
+
*/
|
|
105
|
+
/**
|
|
106
|
+
* Get length to position state mapping
|
|
107
|
+
*/
|
|
108
|
+
export declare function getLenToPosState(len: number): number;
|
|
109
|
+
/**
|
|
110
|
+
* Update state after character encoding/decoding
|
|
111
|
+
*/
|
|
112
|
+
export declare function stateUpdateChar(index: number): number;
|
|
113
|
+
/**
|
|
114
|
+
* Bit tree operations
|
|
115
|
+
*/
|
|
116
|
+
/**
|
|
117
|
+
* Create a bit tree with specified number of bit levels
|
|
118
|
+
*/
|
|
119
|
+
export declare function createBitTree(numBitLevels: number): BitTree;
|
|
120
|
+
/**
|
|
121
|
+
* Create probability prices lookup table
|
|
122
|
+
*/
|
|
123
|
+
export declare function createProbPrices(): number[];
|
|
124
|
+
/**
|
|
125
|
+
* Create fast position lookup table
|
|
126
|
+
*/
|
|
127
|
+
export declare function createFastPos(): number[];
|