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
package/lib/index.d.ts
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Copyright Filip Seman
|
|
4
4
|
* SPDX-License-Identifier: MIT
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { type CompressionMode } from "./lzma.js";
|
|
7
7
|
export { LZMA } from "./lzma.js";
|
|
8
|
+
export { CRC32_TABLE } from "./utils.js";
|
|
8
9
|
/**
|
|
9
10
|
* Compresses data using LZMA algorithm
|
|
10
11
|
*
|
|
@@ -12,7 +13,7 @@ export { LZMA } from "./lzma.js";
|
|
|
12
13
|
* @param mode Compression mode (1-9), defaults to 5
|
|
13
14
|
* @returns Compressed data as a byte array
|
|
14
15
|
*/
|
|
15
|
-
export declare function compress(data: Uint8Array | ArrayBuffer, mode?:
|
|
16
|
+
export declare function compress(data: Uint8Array | ArrayBuffer, mode?: CompressionMode): Uint8Array;
|
|
16
17
|
/**
|
|
17
18
|
* Compresses data using LZMA algorithm
|
|
18
19
|
*
|
|
@@ -20,7 +21,7 @@ export declare function compress(data: Uint8Array | ArrayBuffer, mode?: keyof LZ
|
|
|
20
21
|
* @param mode Compression mode (1-9), defaults to 5
|
|
21
22
|
* @returns Compressed data as byte array
|
|
22
23
|
*/
|
|
23
|
-
export declare function compressString(data: string, mode?:
|
|
24
|
+
export declare function compressString(data: string, mode?: CompressionMode): Uint8Array;
|
|
24
25
|
/**
|
|
25
26
|
* Decompresses LZMA compressed data
|
|
26
27
|
*
|
package/lib/index.js
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Copyright Filip Seman
|
|
4
4
|
* SPDX-License-Identifier: MIT
|
|
5
5
|
*/
|
|
6
|
-
import { LZMA } from "./lzma.js";
|
|
6
|
+
import { LZMA, } from "./lzma.js";
|
|
7
7
|
export { LZMA } from "./lzma.js";
|
|
8
|
+
export { CRC32_TABLE } from "./utils.js";
|
|
8
9
|
/**
|
|
9
10
|
* Compresses data using LZMA algorithm
|
|
10
11
|
*
|
|
@@ -13,8 +14,12 @@ export { LZMA } from "./lzma.js";
|
|
|
13
14
|
* @returns Compressed data as a byte array
|
|
14
15
|
*/
|
|
15
16
|
export function compress(data, mode = 5) {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
// Convert ArrayBuffer to Uint8Array if needed
|
|
18
|
+
const input = data instanceof ArrayBuffer
|
|
19
|
+
? new Uint8Array(data)
|
|
20
|
+
: data;
|
|
21
|
+
const result = new LZMA().compress(input, mode);
|
|
22
|
+
return new Uint8Array(result);
|
|
18
23
|
}
|
|
19
24
|
/**
|
|
20
25
|
* Compresses data using LZMA algorithm
|
|
@@ -24,8 +29,8 @@ export function compress(data, mode = 5) {
|
|
|
24
29
|
* @returns Compressed data as byte array
|
|
25
30
|
*/
|
|
26
31
|
export function compressString(data, mode = 5) {
|
|
27
|
-
const
|
|
28
|
-
return new Uint8Array(
|
|
32
|
+
const compressedData = new LZMA().compressString(data, mode);
|
|
33
|
+
return new Uint8Array(compressedData);
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* Decompresses LZMA compressed data
|
|
@@ -34,8 +39,11 @@ export function compressString(data, mode = 5) {
|
|
|
34
39
|
* @returns Decompressed data
|
|
35
40
|
*/
|
|
36
41
|
export function decompress(data) {
|
|
37
|
-
const
|
|
38
|
-
|
|
42
|
+
const input = data instanceof ArrayBuffer
|
|
43
|
+
? new Uint8Array(data)
|
|
44
|
+
: data;
|
|
45
|
+
const decompressedData = new LZMA().decompress(input);
|
|
46
|
+
return new Uint8Array(decompressedData);
|
|
39
47
|
}
|
|
40
48
|
/**
|
|
41
49
|
* Decompresses LZMA compressed data
|
|
@@ -44,6 +52,5 @@ export function decompress(data) {
|
|
|
44
52
|
* @returns Decompressed data as string
|
|
45
53
|
*/
|
|
46
54
|
export function decompressString(data) {
|
|
47
|
-
|
|
48
|
-
return lzma.decompressString(data);
|
|
55
|
+
return new LZMA().decompressString(data);
|
|
49
56
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type BitTree } from "./utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Range encoder interface for LenEncoder to communicate with
|
|
4
|
+
*/
|
|
5
|
+
export interface RangeEncoder {
|
|
6
|
+
encodeBit(probs: number[], index: number, symbol: number): void;
|
|
7
|
+
encodeBitTree(encoder: BitTree, symbol: number): void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Length encoder class for LZMA compression
|
|
11
|
+
* Handles encoding of match lengths with price optimization
|
|
12
|
+
*/
|
|
13
|
+
export declare class LenEncoder {
|
|
14
|
+
private choice;
|
|
15
|
+
private lowCoder;
|
|
16
|
+
private midCoder;
|
|
17
|
+
private highCoder;
|
|
18
|
+
private tableSize;
|
|
19
|
+
private prices;
|
|
20
|
+
private counters;
|
|
21
|
+
constructor();
|
|
22
|
+
/**
|
|
23
|
+
* Initialize the encoder with specified number of position states
|
|
24
|
+
*/
|
|
25
|
+
init(numPosStates: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Encode a length value using the provided range encoder
|
|
28
|
+
*/
|
|
29
|
+
encode(symbol: number, posState: number, rangeEncoder: RangeEncoder): void;
|
|
30
|
+
/**
|
|
31
|
+
* Encode with price table update
|
|
32
|
+
*/
|
|
33
|
+
encodeWithUpdate(symbol: number, posState: number, rangeEncoder: RangeEncoder): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get price for encoding a symbol at the given position state
|
|
36
|
+
*/
|
|
37
|
+
getPrice(symbol: number, posState: number): number;
|
|
38
|
+
/**
|
|
39
|
+
* Initialize as a price table encoder
|
|
40
|
+
*/
|
|
41
|
+
initPriceTable(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Set table size for price optimization
|
|
44
|
+
*/
|
|
45
|
+
setTableSize(size: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Set table size and update internal counters
|
|
48
|
+
*/
|
|
49
|
+
setTableSizeAndInitCounters(size: number, numPosStates: number): void;
|
|
50
|
+
/**
|
|
51
|
+
* Get table size
|
|
52
|
+
*/
|
|
53
|
+
getTableSize(): number;
|
|
54
|
+
/**
|
|
55
|
+
* Update price tables for all position states
|
|
56
|
+
*/
|
|
57
|
+
updateTables(numPosStates: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Calculate price for bit tree encoder
|
|
60
|
+
*/
|
|
61
|
+
private getBitTreePrice;
|
|
62
|
+
/**
|
|
63
|
+
* Get price for a single bit
|
|
64
|
+
*/
|
|
65
|
+
private getBitPrice;
|
|
66
|
+
/**
|
|
67
|
+
* Set prices for all symbols in a position state range
|
|
68
|
+
*/
|
|
69
|
+
private setPrices;
|
|
70
|
+
}
|
package/lib/len-coder.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { createBitTree, getBitPrice, initArray, initBitModels, } from "./utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Length encoder class for LZMA compression
|
|
4
|
+
* Handles encoding of match lengths with price optimization
|
|
5
|
+
*/
|
|
6
|
+
export class LenEncoder {
|
|
7
|
+
// Choice probability arrays for length range selection
|
|
8
|
+
choice = initArray(2);
|
|
9
|
+
// Low range coders (for lengths 2-9)
|
|
10
|
+
lowCoder = [];
|
|
11
|
+
// Mid range coders (for lengths 10-17)
|
|
12
|
+
midCoder = [];
|
|
13
|
+
// High range coder (for lengths 18+)
|
|
14
|
+
highCoder = createBitTree(8);
|
|
15
|
+
// Price optimization properties
|
|
16
|
+
tableSize = 0;
|
|
17
|
+
prices = [];
|
|
18
|
+
counters = [];
|
|
19
|
+
constructor() {
|
|
20
|
+
// Initialize low and mid coders for all position states (up to 16)
|
|
21
|
+
for (let posState = 0; posState < 16; ++posState) {
|
|
22
|
+
this.lowCoder[posState] = createBitTree(3);
|
|
23
|
+
this.midCoder[posState] = createBitTree(3);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Initialize the encoder with specified number of position states
|
|
28
|
+
*/
|
|
29
|
+
init(numPosStates) {
|
|
30
|
+
// Initialize choice probability models
|
|
31
|
+
initBitModels(this.choice);
|
|
32
|
+
// Initialize low and mid coders for each position state
|
|
33
|
+
for (let posState = 0; posState < numPosStates; ++posState) {
|
|
34
|
+
initBitModels(this.lowCoder[posState].models);
|
|
35
|
+
initBitModels(this.midCoder[posState].models);
|
|
36
|
+
}
|
|
37
|
+
// Initialize high coder
|
|
38
|
+
initBitModels(this.highCoder.models);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Encode a length value using the provided range encoder
|
|
42
|
+
*/
|
|
43
|
+
encode(symbol, posState, rangeEncoder) {
|
|
44
|
+
if (symbol < 8) {
|
|
45
|
+
// Length 2-9: use low coder
|
|
46
|
+
rangeEncoder.encodeBit(this.choice, 0, 0);
|
|
47
|
+
rangeEncoder.encodeBitTree(this.lowCoder[posState], symbol);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
symbol -= 8;
|
|
51
|
+
rangeEncoder.encodeBit(this.choice, 0, 1);
|
|
52
|
+
if (symbol < 8) {
|
|
53
|
+
// Length 10-17: use mid coder
|
|
54
|
+
rangeEncoder.encodeBit(this.choice, 1, 0);
|
|
55
|
+
rangeEncoder.encodeBitTree(this.midCoder[posState], symbol);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Length 18+: use high coder
|
|
59
|
+
rangeEncoder.encodeBit(this.choice, 1, 1);
|
|
60
|
+
rangeEncoder.encodeBitTree(this.highCoder, symbol - 8);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Encode with price table update
|
|
66
|
+
*/
|
|
67
|
+
encodeWithUpdate(symbol, posState, rangeEncoder) {
|
|
68
|
+
this.encode(symbol, posState, rangeEncoder);
|
|
69
|
+
if (this.counters && (this.counters[posState] -= 1) == 0) {
|
|
70
|
+
// Reset counter and update prices if needed
|
|
71
|
+
this.counters[posState] = this.tableSize;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get price for encoding a symbol at the given position state
|
|
76
|
+
*/
|
|
77
|
+
getPrice(symbol, posState) {
|
|
78
|
+
return this.prices[posState * 0x110 + symbol];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Initialize as a price table encoder
|
|
82
|
+
*/
|
|
83
|
+
initPriceTable() {
|
|
84
|
+
this.prices = [];
|
|
85
|
+
this.counters = [];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Set table size for price optimization
|
|
89
|
+
*/
|
|
90
|
+
setTableSize(size) {
|
|
91
|
+
this.tableSize = size;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Set table size and update internal counters
|
|
95
|
+
*/
|
|
96
|
+
setTableSizeAndInitCounters(size, numPosStates) {
|
|
97
|
+
this.tableSize = size;
|
|
98
|
+
if (this.counters) {
|
|
99
|
+
for (let posState = 0; posState < numPosStates; ++posState) {
|
|
100
|
+
this.counters[posState] = size;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get table size
|
|
106
|
+
*/
|
|
107
|
+
getTableSize() {
|
|
108
|
+
return this.tableSize;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Update price tables for all position states
|
|
112
|
+
*/
|
|
113
|
+
updateTables(numPosStates) {
|
|
114
|
+
if (!this.prices || !this.counters) {
|
|
115
|
+
this.initPriceTable();
|
|
116
|
+
}
|
|
117
|
+
for (let posState = 0; posState < numPosStates; ++posState) {
|
|
118
|
+
this.setPrices(posState, this.tableSize, this.prices, 0);
|
|
119
|
+
if (this.counters) {
|
|
120
|
+
this.counters[posState] = this.tableSize;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Private methods for internal state management
|
|
125
|
+
/**
|
|
126
|
+
* Calculate price for bit tree encoder
|
|
127
|
+
*/
|
|
128
|
+
getBitTreePrice(encoder, symbol) {
|
|
129
|
+
let bit, bitIndex, m = 1, price = 0;
|
|
130
|
+
for (bitIndex = encoder.numBitLevels; bitIndex != 0;) {
|
|
131
|
+
bitIndex -= 1;
|
|
132
|
+
bit = symbol >>> bitIndex & 1;
|
|
133
|
+
price += this.getBitPrice(encoder.models[m], bit);
|
|
134
|
+
m = (m << 1) + bit;
|
|
135
|
+
}
|
|
136
|
+
return price;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get price for a single bit
|
|
140
|
+
*/
|
|
141
|
+
getBitPrice(prob, symbol) {
|
|
142
|
+
return getBitPrice(prob, symbol);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Set prices for all symbols in a position state range
|
|
146
|
+
*/
|
|
147
|
+
setPrices(posState, numSymbols, prices, priceIndex) {
|
|
148
|
+
const a0 = this.getBitPrice(this.choice[0], 0);
|
|
149
|
+
const a1 = this.getBitPrice(this.choice[0], 1);
|
|
150
|
+
const b0 = a1 + this.getBitPrice(this.choice[1], 0);
|
|
151
|
+
const b1 = a1 + this.getBitPrice(this.choice[1], 1);
|
|
152
|
+
let i = 0;
|
|
153
|
+
const st = priceIndex + posState * 0x110;
|
|
154
|
+
// Set prices for low range (lengths 2-9)
|
|
155
|
+
for (i = 0; i < 8; ++i) {
|
|
156
|
+
if (i >= numSymbols)
|
|
157
|
+
return;
|
|
158
|
+
prices[st + i] = a0 + this.getBitTreePrice(this.lowCoder[posState], i);
|
|
159
|
+
}
|
|
160
|
+
// Set prices for mid range (lengths 10-17)
|
|
161
|
+
for (; i < 16; ++i) {
|
|
162
|
+
if (i >= numSymbols)
|
|
163
|
+
return;
|
|
164
|
+
prices[st + i] = b0 + this.getBitTreePrice(this.midCoder[posState], i - 8);
|
|
165
|
+
}
|
|
166
|
+
// Set prices for high range (lengths 18+)
|
|
167
|
+
for (; i < numSymbols; ++i) {
|
|
168
|
+
prices[st + i] = b1 + this.getBitTreePrice(this.highCoder, i - 8 - 8);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type BasicRangeDecoder, type BasicRangeEncoder } from "./utils.js";
|
|
2
|
+
export declare class LitSubCoder {
|
|
3
|
+
private coders;
|
|
4
|
+
constructor();
|
|
5
|
+
/**
|
|
6
|
+
* Decode normal literal symbol
|
|
7
|
+
*/
|
|
8
|
+
decodeNormal(rd: BasicRangeDecoder): number;
|
|
9
|
+
/**
|
|
10
|
+
* Decode literal symbol with match byte context
|
|
11
|
+
*/
|
|
12
|
+
decodeWithMatchByte(rd: BasicRangeDecoder, matchByte: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* Encode literal symbol
|
|
15
|
+
*/
|
|
16
|
+
encode(re: BasicRangeEncoder, symbol: number): void;
|
|
17
|
+
/**
|
|
18
|
+
* Encode literal symbol with match byte context
|
|
19
|
+
*/
|
|
20
|
+
encodeMatched(re: BasicRangeEncoder, matchByte: number, symbol: number): void;
|
|
21
|
+
/**
|
|
22
|
+
* Get price for encoding literal symbol
|
|
23
|
+
*/
|
|
24
|
+
getPrice(matchMode: boolean, matchByte: number, symbol: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* Reset coder to initial state
|
|
27
|
+
*/
|
|
28
|
+
reset(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get decoders array (for compatibility with LiteralDecoderEncoder2)
|
|
31
|
+
*/
|
|
32
|
+
get decoders(): number[];
|
|
33
|
+
}
|
|
34
|
+
export declare class LitCoder {
|
|
35
|
+
private _coders;
|
|
36
|
+
private _numPrevBits;
|
|
37
|
+
private _posMask;
|
|
38
|
+
constructor(numPosBits: number, numPrevBits: number);
|
|
39
|
+
/**
|
|
40
|
+
* Get sub-coder for position and previous byte
|
|
41
|
+
*/
|
|
42
|
+
getSubCoder(pos: number, prevByte: number): LitSubCoder;
|
|
43
|
+
/**
|
|
44
|
+
* Reset all sub-coders
|
|
45
|
+
*/
|
|
46
|
+
reset(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Get number of previous bits (for compatibility)
|
|
49
|
+
*/
|
|
50
|
+
get numPrevBits(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Get number of position bits (for compatibility)
|
|
53
|
+
*/
|
|
54
|
+
get numPosBits(): number;
|
|
55
|
+
/**
|
|
56
|
+
* Get position mask (for compatibility)
|
|
57
|
+
*/
|
|
58
|
+
get posMask(): number;
|
|
59
|
+
/**
|
|
60
|
+
* Get coders array (for compatibility)
|
|
61
|
+
*/
|
|
62
|
+
get coders(): LitSubCoder[];
|
|
63
|
+
}
|
package/lib/lit-coder.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { getBitPrice, initArray, } from "./utils.js";
|
|
2
|
+
export class LitSubCoder {
|
|
3
|
+
coders;
|
|
4
|
+
constructor() {
|
|
5
|
+
this.coders = initArray(0x300, 0x400);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Decode normal literal symbol
|
|
9
|
+
*/
|
|
10
|
+
decodeNormal(rd) {
|
|
11
|
+
let symbol = 1;
|
|
12
|
+
while (symbol < 0x100) {
|
|
13
|
+
const i = rd.decodeBit(this.coders, symbol);
|
|
14
|
+
symbol = (symbol << 1) | i;
|
|
15
|
+
}
|
|
16
|
+
return symbol & 0xFF;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Decode literal symbol with match byte context
|
|
20
|
+
*/
|
|
21
|
+
decodeWithMatchByte(rd, matchByte) {
|
|
22
|
+
let uMatchByte = matchByte;
|
|
23
|
+
let symbol = 1;
|
|
24
|
+
while (symbol < 0x100) {
|
|
25
|
+
const matchBit = (uMatchByte >> 7) & 1;
|
|
26
|
+
uMatchByte <<= 1;
|
|
27
|
+
const bit = rd.decodeBit(this.coders, ((1 + matchBit) << 8) + symbol);
|
|
28
|
+
symbol = (symbol << 1) | bit;
|
|
29
|
+
if (matchBit !== bit) {
|
|
30
|
+
while (symbol < 0x100) {
|
|
31
|
+
const i = rd.decodeBit(this.coders, symbol);
|
|
32
|
+
symbol = (symbol << 1) | i;
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return symbol & 0xFF;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Encode literal symbol
|
|
41
|
+
*/
|
|
42
|
+
encode(re, symbol) {
|
|
43
|
+
let context = 1;
|
|
44
|
+
for (let i = 7; i >= 0; i--) {
|
|
45
|
+
const bit = (symbol >> i) & 1;
|
|
46
|
+
re.encodeBit(this.coders, context, bit);
|
|
47
|
+
context = (context << 1) | bit;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Encode literal symbol with match byte context
|
|
52
|
+
*/
|
|
53
|
+
encodeMatched(re, matchByte, symbol) {
|
|
54
|
+
let uMatchByte = matchByte;
|
|
55
|
+
let context = 1;
|
|
56
|
+
let same = true;
|
|
57
|
+
for (let i = 7; i >= 0; i--) {
|
|
58
|
+
const bit = (symbol >> i) & 1;
|
|
59
|
+
let state = context;
|
|
60
|
+
if (same) {
|
|
61
|
+
const matchBit = (uMatchByte >> i) & 1;
|
|
62
|
+
state += (1 + matchBit) << 8;
|
|
63
|
+
same = matchBit === bit;
|
|
64
|
+
}
|
|
65
|
+
re.encodeBit(this.coders, state, bit);
|
|
66
|
+
context = (context << 1) | bit;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get price for encoding literal symbol
|
|
71
|
+
*/
|
|
72
|
+
getPrice(matchMode, matchByte, symbol) {
|
|
73
|
+
let uMatchByte = matchByte;
|
|
74
|
+
let price = 0;
|
|
75
|
+
let context = 1;
|
|
76
|
+
let i = 7;
|
|
77
|
+
if (matchMode) {
|
|
78
|
+
while (i >= 0) {
|
|
79
|
+
const matchBit = (uMatchByte >> i) & 1;
|
|
80
|
+
const bit = (symbol >> i) & 1;
|
|
81
|
+
price += getBitPrice(this.coders[(1 + matchBit) << 8 + context], bit);
|
|
82
|
+
context = (context << 1) | bit;
|
|
83
|
+
if (matchBit !== bit) {
|
|
84
|
+
i--;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
i--;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
while (i >= 0) {
|
|
91
|
+
const bit = (symbol >> i) & 1;
|
|
92
|
+
price += getBitPrice(this.coders[context], bit);
|
|
93
|
+
context = (context << 1) | bit;
|
|
94
|
+
i--;
|
|
95
|
+
}
|
|
96
|
+
return price;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Reset coder to initial state
|
|
100
|
+
*/
|
|
101
|
+
reset() {
|
|
102
|
+
this.coders.fill(1024);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get decoders array (for compatibility with LiteralDecoderEncoder2)
|
|
106
|
+
*/
|
|
107
|
+
get decoders() {
|
|
108
|
+
return this.coders;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export class LitCoder {
|
|
112
|
+
_coders;
|
|
113
|
+
_numPrevBits;
|
|
114
|
+
_posMask;
|
|
115
|
+
constructor(numPosBits, numPrevBits) {
|
|
116
|
+
const numStates = 1 << (numPrevBits + numPosBits);
|
|
117
|
+
this._coders = [];
|
|
118
|
+
this._numPrevBits = numPrevBits;
|
|
119
|
+
this._posMask = (1 << numPosBits) - 1;
|
|
120
|
+
for (let i = 0; i < numStates; i++) {
|
|
121
|
+
this._coders[i] = new LitSubCoder();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get sub-coder for position and previous byte
|
|
126
|
+
*/
|
|
127
|
+
getSubCoder(pos, prevByte) {
|
|
128
|
+
return this._coders[((pos & this._posMask) << this._numPrevBits)
|
|
129
|
+
+ (prevByte >> (8 - this._numPrevBits))];
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Reset all sub-coders
|
|
133
|
+
*/
|
|
134
|
+
reset() {
|
|
135
|
+
this._coders.forEach((coder) => coder.reset());
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get number of previous bits (for compatibility)
|
|
139
|
+
*/
|
|
140
|
+
get numPrevBits() {
|
|
141
|
+
return this._numPrevBits;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get number of position bits (for compatibility)
|
|
145
|
+
*/
|
|
146
|
+
get numPosBits() {
|
|
147
|
+
// Calculate from posMask
|
|
148
|
+
return Math.log2(this._posMask + 1);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get position mask (for compatibility)
|
|
152
|
+
*/
|
|
153
|
+
get posMask() {
|
|
154
|
+
return this._posMask;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get coders array (for compatibility)
|
|
158
|
+
*/
|
|
159
|
+
get coders() {
|
|
160
|
+
return this._coders;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { MatchFinder } from "./encoder.js";
|
|
2
|
+
/**
|
|
3
|
+
* LzInWindow - Input Window helper for LZMA encoding
|
|
4
|
+
*
|
|
5
|
+
* This class manages the input window operations for LZMA encoding,
|
|
6
|
+
* including buffer management, position tracking, and input stream reading.
|
|
7
|
+
*/
|
|
8
|
+
export declare class LzInWindow {
|
|
9
|
+
private matchFinder;
|
|
10
|
+
constructor(matchFinder: MatchFinder);
|
|
11
|
+
/**
|
|
12
|
+
* Get a byte at the specified index relative to current position
|
|
13
|
+
*/
|
|
14
|
+
getIndexByte(index: number): number;
|
|
15
|
+
/**
|
|
16
|
+
* Calculate match length between current position and a previous position
|
|
17
|
+
*/
|
|
18
|
+
getMatchLen(index: number, distance: number, limit: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Get number of available bytes in the input window
|
|
21
|
+
*/
|
|
22
|
+
getNumAvailableBytes(): number;
|
|
23
|
+
/**
|
|
24
|
+
* Move buffer block when reaching buffer boundaries
|
|
25
|
+
*/
|
|
26
|
+
moveBlock(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Move position by one and handle buffer management
|
|
29
|
+
*/
|
|
30
|
+
movePos(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Read a block of data from the input stream
|
|
33
|
+
*/
|
|
34
|
+
readBlock(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Reduce all position offsets by the specified value
|
|
37
|
+
*/
|
|
38
|
+
reduceOffsets(subValue: number): void;
|
|
39
|
+
/**
|
|
40
|
+
* Read data from the input stream into the buffer
|
|
41
|
+
*/
|
|
42
|
+
private readFromStream;
|
|
43
|
+
}
|