@patrickdk77/archive-defuse 0.1.2 → 0.1.3
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 +1 -1
- package/dist/lzma1/NOTICE +32 -18
- package/dist/lzma1/crc32.d.ts +2 -1
- package/dist/lzma1/crc32.js +3 -2
- package/dist/lzma1/hash234.d.ts +3 -1
- package/dist/lzma1/hash234.js +9 -4
- package/dist/lzma1/hc4.d.ts +3 -2
- package/dist/lzma1/hc4.js +6 -4
- package/dist/lzma1/header.js +1 -1
- package/dist/lzma1/lz-decoder.d.ts +14 -14
- package/dist/lzma1/lz-decoder.js +15 -33
- package/dist/lzma1/lz-encoder.d.ts +3 -2
- package/dist/lzma1/lz-encoder.js +6 -4
- package/dist/lzma1/lzma-coder.d.ts +51 -27
- package/dist/lzma1/lzma-coder.js +114 -48
- package/dist/lzma1/lzma-decoder.d.ts +41 -19
- package/dist/lzma1/lzma-decoder.js +159 -437
- package/dist/lzma1/lzma-encoder-fast.d.ts +2 -1
- package/dist/lzma1/lzma-encoder-fast.js +3 -2
- package/dist/lzma1/lzma-encoder.d.ts +68 -40
- package/dist/lzma1/lzma-encoder.js +289 -232
- package/dist/lzma1/lzma2-decoder.d.ts +17 -2
- package/dist/lzma1/lzma2-decoder.js +71 -15
- package/dist/lzma1/range-coder.d.ts +4 -0
- package/dist/lzma1/range-coder.js +5 -1
- package/dist/lzma1/range-decoder.d.ts +22 -22
- package/dist/lzma1/range-decoder.js +74 -32
- package/dist/lzma1/range-encoder.d.ts +26 -28
- package/dist/lzma1/range-encoder.js +98 -150
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Copied from lzma1 (Apache-2.0, Copyright Filip Seman) and changed for
|
|
2
|
+
// Copied from lzma1 0.6.1 (Apache-2.0, Copyright Filip Seman) and changed for archive-defuse. NOTICE in this folder lists the changes.
|
|
3
3
|
/**
|
|
4
4
|
* LZMA encoder base: codes the symbols chosen by a subclass and keeps the
|
|
5
5
|
* price tables the subclasses use to choose between symbols.
|
|
@@ -8,60 +8,73 @@
|
|
|
8
8
|
* - `LzmaEncoderFast` uses simple heuristics (levels 1-3).
|
|
9
9
|
* - `LzmaEncoderNormal` searches for the cheapest symbol sequence (levels 4-9).
|
|
10
10
|
*
|
|
11
|
-
* Ported from XZ for Java (0BSD)
|
|
11
|
+
* Ported from XZ for Java (0BSD), `src/org/tukaani/xz/lzma/LZMAEncoder.java`,
|
|
12
|
+
* by Lasse Collin and Igor Pavlov. The LZMA2 entry points and chunk limits
|
|
13
|
+
* are not ported; this library produces only LZMA1 (".lzma") streams. The
|
|
14
|
+
* inner coder classes take their outer encoder (or the range encoder) as
|
|
15
|
+
* an explicit parameter where Java captures it implicitly.
|
|
12
16
|
*/
|
|
13
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.LengthEncoder = exports.LzmaEncoder = void 0;
|
|
18
|
+
exports.LengthEncoder = exports.LiteralEncoder = exports.LzmaEncoder = void 0;
|
|
15
19
|
exports.getDistSlot = getDistSlot;
|
|
16
20
|
const lzma_coder_1 = require("./lzma-coder");
|
|
17
21
|
const range_coder_1 = require("./range-coder");
|
|
18
22
|
const range_encoder_1 = require("./range-encoder");
|
|
19
23
|
const DIST_PRICE_UPDATE_INTERVAL = lzma_coder_1.FULL_DISTANCES;
|
|
20
24
|
const ALIGN_PRICE_UPDATE_INTERVAL = lzma_coder_1.ALIGN_SIZE;
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Gets an integer [0, 63] matching the highest two bits of an integer.
|
|
27
|
+
* This is like bit scan reverse (BSR) on x86 except that this also
|
|
28
|
+
* cares about the second highest bit.
|
|
29
|
+
*/
|
|
23
30
|
function getDistSlot(dist) {
|
|
24
31
|
if (dist <= lzma_coder_1.DIST_MODEL_START && dist >= 0) {
|
|
25
32
|
return dist;
|
|
26
33
|
}
|
|
34
|
+
// 31 - Integer.numberOfLeadingZeros(dist)
|
|
27
35
|
const i = 31 - Math.clz32(dist);
|
|
28
36
|
return (i << 1) + ((dist >>> (i - 1)) & 1);
|
|
29
37
|
}
|
|
30
38
|
class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
31
39
|
rc;
|
|
32
40
|
lz;
|
|
33
|
-
|
|
41
|
+
literalEncoder;
|
|
34
42
|
matchLenEncoder;
|
|
35
43
|
repLenEncoder;
|
|
44
|
+
niceLen;
|
|
36
45
|
distPriceCount = 0;
|
|
37
46
|
alignPriceCount = 0;
|
|
38
|
-
/** Whether a distance
|
|
47
|
+
/** Whether a distance was encoded since the last reset. */
|
|
39
48
|
distModelsUsed = false;
|
|
49
|
+
/** Whether align bits were encoded since the last reset. */
|
|
40
50
|
alignModelUsed = false;
|
|
41
51
|
distSlotPricesSize;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
fullDistPrices = new Uint32Array(lzma_coder_1.DIST_STATES * lzma_coder_1.FULL_DISTANCES);
|
|
46
|
-
alignPrices = new Uint32Array(lzma_coder_1.ALIGN_SIZE);
|
|
52
|
+
distSlotPrices;
|
|
53
|
+
fullDistPrices = newPriceArray(lzma_coder_1.DIST_STATES, lzma_coder_1.FULL_DISTANCES);
|
|
54
|
+
alignPrices = new Int32Array(lzma_coder_1.ALIGN_SIZE);
|
|
47
55
|
/**
|
|
48
56
|
* Symbol chosen by `getNextSymbol()`:
|
|
49
57
|
* -1 = literal, 0-3 = rep match, 4+ = match with distance `back - REPS`.
|
|
50
58
|
*/
|
|
51
59
|
back = 0;
|
|
52
|
-
/** Bytes the match finder is ahead of the encoder. */
|
|
60
|
+
/** Bytes the match finder is ahead of the encoder. Package-private in Java. */
|
|
53
61
|
readAhead = -1;
|
|
54
62
|
constructor(rc, lz, config) {
|
|
55
63
|
super(config.lc, config.lp, config.pb);
|
|
56
64
|
this.rc = rc;
|
|
57
65
|
this.lz = lz;
|
|
58
66
|
this.niceLen = config.niceLen;
|
|
67
|
+
this.literalEncoder = new LiteralEncoder(this, config.lc, config.lp);
|
|
59
68
|
this.matchLenEncoder = new LengthEncoder(this.probs, lzma_coder_1.MATCH_LEN, config.pb, config.niceLen);
|
|
60
69
|
this.repLenEncoder = new LengthEncoder(this.probs, lzma_coder_1.REP_LEN, config.pb, config.niceLen);
|
|
61
70
|
this.distSlotPricesSize = getDistSlot(config.dictSize - 1) + 1;
|
|
71
|
+
this.distSlotPrices = newPriceArray(lzma_coder_1.DIST_STATES, this.distSlotPricesSize);
|
|
62
72
|
this.reset();
|
|
63
73
|
}
|
|
64
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Prepares for a new, independent input written to `rc` (contract
|
|
76
|
+
* adaptation: lets a pooled encoder be reused by a later call).
|
|
77
|
+
*/
|
|
65
78
|
restart(rc) {
|
|
66
79
|
this.rc = rc;
|
|
67
80
|
this.lz.reset();
|
|
@@ -77,7 +90,7 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
77
90
|
this.alignModelUsed = false;
|
|
78
91
|
this.readAhead = -1;
|
|
79
92
|
}
|
|
80
|
-
/**
|
|
93
|
+
/** Compress for LZMA1. */
|
|
81
94
|
encode() {
|
|
82
95
|
if (!this.lz.isStarted() && !this.encodeInit()) {
|
|
83
96
|
return;
|
|
@@ -86,21 +99,26 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
86
99
|
// Each call encodes one symbol.
|
|
87
100
|
}
|
|
88
101
|
}
|
|
89
|
-
/** Encodes the end marker: a match with distance 0xFFFFFFFF. */
|
|
90
102
|
encodeEndMarker() {
|
|
103
|
+
// End of stream marker is encoded as a match with the maximum
|
|
104
|
+
// possible distance. The length is ignored by the decoder,
|
|
105
|
+
// but the minimum length has been used by the LZMA SDK.
|
|
106
|
+
//
|
|
107
|
+
// Distance is a 32-bit unsigned integer in LZMA.
|
|
108
|
+
// As an int32, UINT32_MAX becomes -1.
|
|
91
109
|
const posState = (this.lz.getPos() - this.readAhead) & this.posMask;
|
|
92
|
-
this.rc.encodeBit(this.probs, lzma_coder_1.IS_MATCH + (this.state << 4) + posState, 1);
|
|
93
|
-
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP + this.state, 0);
|
|
110
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_MATCH + (this.state.get() << 4) + posState, 1);
|
|
111
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP + this.state.get(), 0);
|
|
94
112
|
this.encodeMatch(-1, lzma_coder_1.MATCH_LEN_MIN, posState);
|
|
95
113
|
}
|
|
96
|
-
/** The first symbol is always a literal with no previous byte. */
|
|
97
114
|
encodeInit() {
|
|
98
115
|
if (!this.lz.hasEnoughData(0)) {
|
|
99
116
|
return false;
|
|
100
117
|
}
|
|
118
|
+
// The first symbol must be a literal.
|
|
101
119
|
this.skip(1);
|
|
102
|
-
this.rc.encodeBit(this.probs, lzma_coder_1.IS_MATCH + (this.state << 4), 0);
|
|
103
|
-
this.
|
|
120
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_MATCH + (this.state.get() << 4), 0);
|
|
121
|
+
this.literalEncoder.encodeInit(this.rc);
|
|
104
122
|
--this.readAhead;
|
|
105
123
|
return true;
|
|
106
124
|
}
|
|
@@ -109,105 +127,86 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
109
127
|
return false;
|
|
110
128
|
}
|
|
111
129
|
const len = this.getNextSymbol();
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const back = this.back;
|
|
118
|
-
if (back === -1) {
|
|
119
|
-
rc.encodeBit(probs, lzma_coder_1.IS_MATCH + (this.state << 4) + posState, 0);
|
|
120
|
-
this.encodeLiteral(this.literalOffset(lz.getByte(1 + this.readAhead), pos));
|
|
130
|
+
const posState = (this.lz.getPos() - this.readAhead) & this.posMask;
|
|
131
|
+
if (this.back === -1) {
|
|
132
|
+
// Literal i.e. eight-bit byte
|
|
133
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_MATCH + (this.state.get() << 4) + posState, 0);
|
|
134
|
+
this.literalEncoder.encode(this.rc);
|
|
121
135
|
}
|
|
122
136
|
else {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
// Some type of match
|
|
138
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_MATCH + (this.state.get() << 4) + posState, 1);
|
|
139
|
+
if (this.back < lzma_coder_1.REPS) {
|
|
140
|
+
// Repeated match i.e. the same distance
|
|
141
|
+
// has been used earlier.
|
|
142
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP + this.state.get(), 1);
|
|
143
|
+
this.encodeRepMatch(this.back, len, posState);
|
|
127
144
|
}
|
|
128
145
|
else {
|
|
129
|
-
|
|
130
|
-
this.
|
|
146
|
+
// Normal match
|
|
147
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP + this.state.get(), 0);
|
|
148
|
+
this.encodeMatch(this.back - lzma_coder_1.REPS, len, posState);
|
|
131
149
|
}
|
|
132
150
|
}
|
|
133
151
|
this.readAhead -= len;
|
|
134
152
|
return true;
|
|
135
153
|
}
|
|
136
|
-
encodeLiteral(offset) {
|
|
137
|
-
const symbol = this.lz.getByte(this.readAhead);
|
|
138
|
-
if ((0, lzma_coder_1.isLiteralState)(this.state)) {
|
|
139
|
-
this.rc.encodeLiteral(this.probs, offset, symbol);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
const matchByte = this.lz.getByte(this.reps[0] + 1 + this.readAhead);
|
|
143
|
-
this.rc.encodeMatchedLiteral(this.probs, offset, symbol, matchByte);
|
|
144
|
-
}
|
|
145
|
-
this.state = (0, lzma_coder_1.stateAfterLiteral)(this.state);
|
|
146
|
-
}
|
|
147
154
|
encodeMatch(dist, len, posState) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const reps = this.reps;
|
|
151
|
-
this.state = (0, lzma_coder_1.stateAfterMatch)(this.state);
|
|
152
|
-
this.matchLenEncoder.encode(rc, len, posState);
|
|
155
|
+
this.state.updateMatch();
|
|
156
|
+
this.matchLenEncoder.encode(this.rc, len, posState);
|
|
153
157
|
const distSlot = getDistSlot(dist);
|
|
154
|
-
rc.encodeBitTree(probs, lzma_coder_1.
|
|
158
|
+
this.rc.encodeBitTree(this.probs, lzma_coder_1.DIST_SLOT_OFFSET + ((0, lzma_coder_1.getDistState)(len) << lzma_coder_1.DIST_SLOT_BITS), lzma_coder_1.DIST_SLOT_BITS, distSlot);
|
|
155
159
|
this.distModelsUsed = true;
|
|
156
160
|
if (distSlot >= lzma_coder_1.DIST_MODEL_START) {
|
|
157
161
|
const footerBits = (distSlot >>> 1) - 1;
|
|
158
162
|
const base = (2 | (distSlot & 1)) << footerBits;
|
|
159
163
|
const distReduced = dist - base;
|
|
160
164
|
if (distSlot < lzma_coder_1.DIST_MODEL_END) {
|
|
161
|
-
rc.encodeReverseBitTree(probs, (0, lzma_coder_1.distSpecialOffset)(distSlot, base), footerBits, distReduced);
|
|
165
|
+
this.rc.encodeReverseBitTree(this.probs, (0, lzma_coder_1.distSpecialOffset)(distSlot, base), footerBits, distReduced);
|
|
162
166
|
}
|
|
163
167
|
else {
|
|
164
|
-
rc.encodeDirectBits(distReduced >>> lzma_coder_1.ALIGN_BITS, footerBits - lzma_coder_1.ALIGN_BITS);
|
|
165
|
-
rc.encodeReverseBitTree(probs, lzma_coder_1.DIST_ALIGN, lzma_coder_1.ALIGN_BITS, distReduced & lzma_coder_1.ALIGN_MASK);
|
|
168
|
+
this.rc.encodeDirectBits(distReduced >>> lzma_coder_1.ALIGN_BITS, footerBits - lzma_coder_1.ALIGN_BITS);
|
|
169
|
+
this.rc.encodeReverseBitTree(this.probs, lzma_coder_1.DIST_ALIGN, lzma_coder_1.ALIGN_BITS, distReduced & lzma_coder_1.ALIGN_MASK);
|
|
166
170
|
this.alignModelUsed = true;
|
|
167
171
|
--this.alignPriceCount;
|
|
168
172
|
}
|
|
169
173
|
}
|
|
170
|
-
reps[3] = reps[2];
|
|
171
|
-
reps[2] = reps[1];
|
|
172
|
-
reps[1] = reps[0];
|
|
173
|
-
reps[0] = dist;
|
|
174
|
+
this.reps[3] = this.reps[2];
|
|
175
|
+
this.reps[2] = this.reps[1];
|
|
176
|
+
this.reps[1] = this.reps[0];
|
|
177
|
+
this.reps[0] = dist;
|
|
174
178
|
--this.distPriceCount;
|
|
175
179
|
}
|
|
176
180
|
encodeRepMatch(rep, len, posState) {
|
|
177
|
-
const rc = this.rc;
|
|
178
|
-
const probs = this.probs;
|
|
179
|
-
const reps = this.reps;
|
|
180
|
-
const state = this.state;
|
|
181
181
|
if (rep === 0) {
|
|
182
|
-
rc.encodeBit(probs, lzma_coder_1.IS_REP0 + state, 0);
|
|
183
|
-
rc.encodeBit(probs, lzma_coder_1.IS_REP0_LONG + (state << 4) + posState, len === 1 ? 0 : 1);
|
|
182
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP0 + this.state.get(), 0);
|
|
183
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP0_LONG + (this.state.get() << 4) + posState, len === 1 ? 0 : 1);
|
|
184
184
|
}
|
|
185
185
|
else {
|
|
186
|
-
const dist = reps[rep];
|
|
187
|
-
rc.encodeBit(probs, lzma_coder_1.IS_REP0 + state, 1);
|
|
186
|
+
const dist = this.reps[rep];
|
|
187
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP0 + this.state.get(), 1);
|
|
188
188
|
if (rep === 1) {
|
|
189
|
-
rc.encodeBit(probs, lzma_coder_1.IS_REP1 + state, 0);
|
|
189
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP1 + this.state.get(), 0);
|
|
190
190
|
}
|
|
191
191
|
else {
|
|
192
|
-
rc.encodeBit(probs, lzma_coder_1.IS_REP1 + state, 1);
|
|
193
|
-
rc.encodeBit(probs, lzma_coder_1.IS_REP2 + state, rep - 2);
|
|
192
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP1 + this.state.get(), 1);
|
|
193
|
+
this.rc.encodeBit(this.probs, lzma_coder_1.IS_REP2 + this.state.get(), rep - 2);
|
|
194
194
|
if (rep === 3) {
|
|
195
|
-
reps[3] = reps[2];
|
|
195
|
+
this.reps[3] = this.reps[2];
|
|
196
196
|
}
|
|
197
|
-
reps[2] = reps[1];
|
|
197
|
+
this.reps[2] = this.reps[1];
|
|
198
198
|
}
|
|
199
|
-
reps[1] = reps[0];
|
|
200
|
-
reps[0] = dist;
|
|
199
|
+
this.reps[1] = this.reps[0];
|
|
200
|
+
this.reps[0] = dist;
|
|
201
201
|
}
|
|
202
202
|
if (len === 1) {
|
|
203
|
-
this.state
|
|
203
|
+
this.state.updateShortRep();
|
|
204
204
|
}
|
|
205
205
|
else {
|
|
206
|
-
this.repLenEncoder.encode(rc, len, posState);
|
|
207
|
-
this.state
|
|
206
|
+
this.repLenEncoder.encode(this.rc, len, posState);
|
|
207
|
+
this.state.updateLongRep();
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
-
// -- Match finder access --
|
|
211
210
|
getMatches() {
|
|
212
211
|
++this.readAhead;
|
|
213
212
|
return this.lz.getMatches();
|
|
@@ -216,13 +215,6 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
216
215
|
this.readAhead += len;
|
|
217
216
|
this.lz.skip(len);
|
|
218
217
|
}
|
|
219
|
-
// -- Prices --
|
|
220
|
-
getLiteralPrice(curByte, matchByte, prevByte, pos, state) {
|
|
221
|
-
const probs = this.probs;
|
|
222
|
-
const offset = this.literalOffset(prevByte, pos);
|
|
223
|
-
const price = (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_MATCH + (state << 4) + (pos & this.posMask)], 0);
|
|
224
|
-
return price + ((0, lzma_coder_1.isLiteralState)(state) ? getLiteralNormalPrice(probs, offset, curByte) : getLiteralMatchedPrice(probs, offset, curByte, matchByte));
|
|
225
|
-
}
|
|
226
218
|
getAnyMatchPrice(state, posState) {
|
|
227
219
|
return (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_MATCH + (state << 4) + posState], 1);
|
|
228
220
|
}
|
|
@@ -233,22 +225,20 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
233
225
|
return anyMatchPrice + (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP + state], 1);
|
|
234
226
|
}
|
|
235
227
|
getShortRepPrice(anyRepPrice, state, posState) {
|
|
236
|
-
|
|
237
|
-
return anyRepPrice + (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP0 + state], 0) + (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP0_LONG + (state << 4) + posState], 0);
|
|
228
|
+
return anyRepPrice + (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP0 + state], 0) + (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP0_LONG + (state << 4) + posState], 0);
|
|
238
229
|
}
|
|
239
230
|
getLongRepPrice(anyRepPrice, rep, state, posState) {
|
|
240
|
-
const probs = this.probs;
|
|
241
231
|
let price = anyRepPrice;
|
|
242
232
|
if (rep === 0) {
|
|
243
|
-
price += (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP0 + state], 0) + (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP0_LONG + (state << 4) + posState], 1);
|
|
233
|
+
price += (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP0 + state], 0) + (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP0_LONG + (state << 4) + posState], 1);
|
|
244
234
|
}
|
|
245
235
|
else {
|
|
246
|
-
price += (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP0 + state], 1);
|
|
236
|
+
price += (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP0 + state], 1);
|
|
247
237
|
if (rep === 1) {
|
|
248
|
-
price += (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP1 + state], 0);
|
|
238
|
+
price += (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP1 + state], 0);
|
|
249
239
|
}
|
|
250
240
|
else {
|
|
251
|
-
price += (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP1 + state], 1) + (0, range_encoder_1.getBitPrice)(probs[lzma_coder_1.IS_REP2 + state], rep - 2);
|
|
241
|
+
price += (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP1 + state], 1) + (0, range_encoder_1.getBitPrice)(this.probs[lzma_coder_1.IS_REP2 + state], rep - 2);
|
|
252
242
|
}
|
|
253
243
|
}
|
|
254
244
|
return price;
|
|
@@ -259,27 +249,17 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
259
249
|
const longRepPrice = this.getLongRepPrice(anyRepPrice, rep, state, posState);
|
|
260
250
|
return longRepPrice + this.repLenEncoder.getPrice(len, posState);
|
|
261
251
|
}
|
|
262
|
-
getMatchAndLenPrice(normalMatchPrice, dist, len, posState) {
|
|
263
|
-
return normalMatchPrice + this.matchLenEncoder.getPrice(len, posState) + this.getDistPrice((0, lzma_coder_1.getDistState)(len), dist);
|
|
264
|
-
}
|
|
265
|
-
/** Price of coding `dist` in distance state `distState`. */
|
|
266
252
|
getDistPrice(distState, dist) {
|
|
267
253
|
if (dist < lzma_coder_1.FULL_DISTANCES) {
|
|
268
|
-
return this.fullDistPrices[distState
|
|
254
|
+
return this.fullDistPrices[distState][dist];
|
|
269
255
|
}
|
|
270
|
-
// distSlotPrices includes
|
|
271
|
-
|
|
256
|
+
// Note that distSlotPrices includes also
|
|
257
|
+
// the price of direct bits.
|
|
258
|
+
const distSlot = getDistSlot(dist);
|
|
259
|
+
return this.distSlotPrices[distState][distSlot] + this.alignPrices[dist & lzma_coder_1.ALIGN_MASK];
|
|
272
260
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (this.distPriceCount <= 0) {
|
|
276
|
-
this.updateDistPrices();
|
|
277
|
-
}
|
|
278
|
-
if (this.alignPriceCount <= 0) {
|
|
279
|
-
this.updateAlignPrices();
|
|
280
|
-
}
|
|
281
|
-
this.matchLenEncoder.updatePrices();
|
|
282
|
-
this.repLenEncoder.updatePrices();
|
|
261
|
+
getMatchAndLenPrice(normalMatchPrice, dist, len, posState) {
|
|
262
|
+
return normalMatchPrice + this.matchLenEncoder.getPrice(len, posState) + this.getDistPrice((0, lzma_coder_1.getDistState)(len), dist);
|
|
283
263
|
}
|
|
284
264
|
updateDistPrices() {
|
|
285
265
|
this.distPriceCount = DIST_PRICE_UPDATE_INTERVAL;
|
|
@@ -289,8 +269,10 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
289
269
|
else {
|
|
290
270
|
// The models still have their initial probabilities.
|
|
291
271
|
const initial = getInitialPrices();
|
|
292
|
-
|
|
293
|
-
|
|
272
|
+
for (let distState = 0; distState < lzma_coder_1.DIST_STATES; ++distState) {
|
|
273
|
+
this.distSlotPrices[distState].set(initial.distSlotPrices[distState].subarray(0, this.distSlotPricesSize));
|
|
274
|
+
this.fullDistPrices[distState].set(initial.fullDistPrices[distState]);
|
|
275
|
+
}
|
|
294
276
|
}
|
|
295
277
|
}
|
|
296
278
|
updateAlignPrices() {
|
|
@@ -299,40 +281,49 @@ class LzmaEncoder extends lzma_coder_1.LzmaCoder {
|
|
|
299
281
|
computeAlignPrices(this.probs, this.alignPrices);
|
|
300
282
|
}
|
|
301
283
|
else {
|
|
302
|
-
this.alignPrices.set(getInitialPrices().
|
|
284
|
+
this.alignPrices.set(getInitialPrices().alignPrices);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Updates the lookup tables used for calculating match distance
|
|
289
|
+
* and length prices. The updating is skipped for performance reasons
|
|
290
|
+
* if the tables haven't changed much since the previous update.
|
|
291
|
+
*/
|
|
292
|
+
updatePrices() {
|
|
293
|
+
if (this.distPriceCount <= 0) {
|
|
294
|
+
this.updateDistPrices();
|
|
303
295
|
}
|
|
296
|
+
if (this.alignPriceCount <= 0) {
|
|
297
|
+
this.updateAlignPrices();
|
|
298
|
+
}
|
|
299
|
+
this.matchLenEncoder.updatePrices();
|
|
300
|
+
this.repLenEncoder.updatePrices();
|
|
304
301
|
}
|
|
305
302
|
}
|
|
306
303
|
exports.LzmaEncoder = LzmaEncoder;
|
|
307
|
-
|
|
308
|
-
* Prices of the distance slots `[distState << 6 | slot]` (including the
|
|
309
|
-
* direct bits) and of the distances below `FULL_DISTANCES`
|
|
310
|
-
* `[distState * FULL_DISTANCES + dist]`.
|
|
311
|
-
*/
|
|
312
|
-
function computeDistPrices(probs, slotCount, slotPrices, fullPrices) {
|
|
304
|
+
function computeDistPrices(probs, distSlotPricesSize, distSlotPrices, fullDistPrices) {
|
|
313
305
|
for (let distState = 0; distState < lzma_coder_1.DIST_STATES; ++distState) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
for (let distSlot = 0; distSlot < slotCount; ++distSlot) {
|
|
317
|
-
slotPrices[slots + distSlot] = (0, range_encoder_1.getBitTreePrice)(probs, tree, lzma_coder_1.DIST_SLOT_BITS, distSlot);
|
|
306
|
+
for (let distSlot = 0; distSlot < distSlotPricesSize; ++distSlot) {
|
|
307
|
+
distSlotPrices[distState][distSlot] = (0, range_encoder_1.getBitTreePrice)(probs, lzma_coder_1.DIST_SLOT_OFFSET + (distState << lzma_coder_1.DIST_SLOT_BITS), lzma_coder_1.DIST_SLOT_BITS, distSlot);
|
|
318
308
|
}
|
|
319
|
-
for (let distSlot = lzma_coder_1.DIST_MODEL_END; distSlot <
|
|
309
|
+
for (let distSlot = lzma_coder_1.DIST_MODEL_END; distSlot < distSlotPricesSize; ++distSlot) {
|
|
320
310
|
const count = (distSlot >>> 1) - 1 - lzma_coder_1.ALIGN_BITS;
|
|
321
|
-
|
|
311
|
+
distSlotPrices[distState][distSlot] += (0, range_encoder_1.getDirectBitsPrice)(count);
|
|
322
312
|
}
|
|
323
313
|
for (let dist = 0; dist < lzma_coder_1.DIST_MODEL_START; ++dist) {
|
|
324
|
-
|
|
314
|
+
fullDistPrices[distState][dist] = distSlotPrices[distState][dist];
|
|
325
315
|
}
|
|
326
316
|
}
|
|
327
317
|
let dist = lzma_coder_1.DIST_MODEL_START;
|
|
328
318
|
for (let distSlot = lzma_coder_1.DIST_MODEL_START; distSlot < lzma_coder_1.DIST_MODEL_END; ++distSlot) {
|
|
329
319
|
const footerBits = (distSlot >>> 1) - 1;
|
|
330
320
|
const base = (2 | (distSlot & 1)) << footerBits;
|
|
331
|
-
const
|
|
332
|
-
for (let i = 0; i <
|
|
333
|
-
const
|
|
321
|
+
const limit = 1 << footerBits;
|
|
322
|
+
for (let i = 0; i < limit; ++i) {
|
|
323
|
+
const distReduced = dist - base;
|
|
324
|
+
const price = (0, range_encoder_1.getReverseBitTreePrice)(probs, (0, lzma_coder_1.distSpecialOffset)(distSlot, base), footerBits, distReduced);
|
|
334
325
|
for (let distState = 0; distState < lzma_coder_1.DIST_STATES; ++distState) {
|
|
335
|
-
|
|
326
|
+
fullDistPrices[distState][dist] = distSlotPrices[distState][distSlot] + price;
|
|
336
327
|
}
|
|
337
328
|
++dist;
|
|
338
329
|
}
|
|
@@ -343,155 +334,221 @@ function computeAlignPrices(probs, alignPrices) {
|
|
|
343
334
|
alignPrices[i] = (0, range_encoder_1.getReverseBitTreePrice)(probs, lzma_coder_1.DIST_ALIGN, lzma_coder_1.ALIGN_BITS, i);
|
|
344
335
|
}
|
|
345
336
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
337
|
+
function newPriceArray(count, size) {
|
|
338
|
+
return Array.from({ length: count }, () => new Int32Array(size));
|
|
339
|
+
}
|
|
340
|
+
class LiteralEncoder extends lzma_coder_1.LiteralCoder {
|
|
341
|
+
encoder;
|
|
342
|
+
subencoders;
|
|
343
|
+
constructor(encoder, lc, lp) {
|
|
344
|
+
super(lc, lp);
|
|
345
|
+
this.encoder = encoder;
|
|
346
|
+
this.subencoders = Array.from({ length: 1 << (lc + lp) }, (_, i) => new LiteralSubencoder(encoder, lzma_coder_1.LITERAL + 0x300 * i));
|
|
347
|
+
}
|
|
348
|
+
encodeInit(rc) {
|
|
349
|
+
// When encoding the first byte of the stream, there is
|
|
350
|
+
// no previous byte in the dictionary so the encode function
|
|
351
|
+
// wouldn't work.
|
|
352
|
+
this.subencoders[0].encode(rc);
|
|
353
|
+
}
|
|
354
|
+
encode(rc) {
|
|
355
|
+
const encoder = this.encoder;
|
|
356
|
+
const i = this.getSubcoderIndex(encoder.lz.getByte(1 + encoder.readAhead), encoder.lz.getPos() - encoder.readAhead);
|
|
357
|
+
this.subencoders[i].encode(rc);
|
|
358
|
+
}
|
|
359
|
+
getPrice(curByte, matchByte, prevByte, pos, state) {
|
|
360
|
+
const encoder = this.encoder;
|
|
361
|
+
let price = (0, range_encoder_1.getBitPrice)(encoder.probs[lzma_coder_1.IS_MATCH + (state << 4) + (pos & encoder.posMask)], 0);
|
|
362
|
+
const i = this.getSubcoderIndex(prevByte, pos);
|
|
363
|
+
price += (0, lzma_coder_1.isLiteralState)(state) ? this.subencoders[i].getNormalPrice(curByte) : this.subencoders[i].getMatchedPrice(curByte, matchByte);
|
|
364
|
+
return price;
|
|
357
365
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
366
|
+
}
|
|
367
|
+
exports.LiteralEncoder = LiteralEncoder;
|
|
368
|
+
class LiteralSubencoder extends lzma_coder_1.LiteralSubcoder {
|
|
369
|
+
encoder;
|
|
370
|
+
constructor(encoder, literalOffset) {
|
|
371
|
+
super(encoder.probs, literalOffset);
|
|
372
|
+
this.encoder = encoder;
|
|
373
|
+
}
|
|
374
|
+
encode(rc) {
|
|
375
|
+
const encoder = this.encoder;
|
|
376
|
+
const probs = this.probs;
|
|
377
|
+
let symbol = encoder.lz.getByte(encoder.readAhead) | 0x100;
|
|
378
|
+
if (encoder.state.isLiteral()) {
|
|
379
|
+
let subencoderIndex;
|
|
380
|
+
let bit;
|
|
381
|
+
do {
|
|
382
|
+
subencoderIndex = symbol >>> 8;
|
|
383
|
+
bit = (symbol >>> 7) & 1;
|
|
384
|
+
rc.encodeBit(probs, this.literalOffset + subencoderIndex, bit);
|
|
385
|
+
symbol <<= 1;
|
|
386
|
+
} while (symbol < 0x10000);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
let matchByte = encoder.lz.getByte(encoder.reps[0] + 1 + encoder.readAhead);
|
|
390
|
+
let offset = 0x100;
|
|
391
|
+
let subencoderIndex;
|
|
392
|
+
let matchBit;
|
|
393
|
+
let bit;
|
|
394
|
+
do {
|
|
395
|
+
matchByte <<= 1;
|
|
396
|
+
matchBit = matchByte & offset;
|
|
397
|
+
subencoderIndex = offset + matchBit + (symbol >>> 8);
|
|
398
|
+
bit = (symbol >>> 7) & 1;
|
|
399
|
+
rc.encodeBit(probs, this.literalOffset + subencoderIndex, bit);
|
|
400
|
+
symbol <<= 1;
|
|
401
|
+
offset &= ~(matchByte ^ symbol);
|
|
402
|
+
} while (symbol < 0x10000);
|
|
403
|
+
}
|
|
404
|
+
encoder.state.updateLiteral();
|
|
363
405
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
406
|
+
getNormalPrice(symbolIn) {
|
|
407
|
+
let symbol = symbolIn;
|
|
408
|
+
const probs = this.probs;
|
|
409
|
+
let price = 0;
|
|
410
|
+
let subencoderIndex;
|
|
411
|
+
let bit;
|
|
412
|
+
symbol |= 0x100;
|
|
413
|
+
do {
|
|
414
|
+
subencoderIndex = symbol >>> 8;
|
|
415
|
+
bit = (symbol >>> 7) & 1;
|
|
416
|
+
price += (0, range_encoder_1.getBitPrice)(probs[this.literalOffset + subencoderIndex], bit);
|
|
417
|
+
symbol <<= 1;
|
|
418
|
+
} while (symbol < 0x100 << 8);
|
|
419
|
+
return price;
|
|
367
420
|
}
|
|
368
|
-
|
|
369
|
-
let
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
421
|
+
getMatchedPrice(symbolIn, matchByteIn) {
|
|
422
|
+
let symbol = symbolIn;
|
|
423
|
+
let matchByte = matchByteIn;
|
|
424
|
+
const probs = this.probs;
|
|
425
|
+
let price = 0;
|
|
426
|
+
let offset = 0x100;
|
|
427
|
+
let subencoderIndex;
|
|
428
|
+
let matchBit;
|
|
429
|
+
let bit;
|
|
430
|
+
symbol |= 0x100;
|
|
431
|
+
do {
|
|
432
|
+
matchByte <<= 1;
|
|
433
|
+
matchBit = matchByte & offset;
|
|
434
|
+
subencoderIndex = offset + matchBit + (symbol >>> 8);
|
|
435
|
+
bit = (symbol >>> 7) & 1;
|
|
436
|
+
price += (0, range_encoder_1.getBitPrice)(probs[this.literalOffset + subencoderIndex], bit);
|
|
437
|
+
symbol <<= 1;
|
|
438
|
+
offset &= ~(matchByte ^ symbol);
|
|
439
|
+
} while (symbol < 0x100 << 8);
|
|
440
|
+
return price;
|
|
387
441
|
}
|
|
388
|
-
return initialPrices;
|
|
389
|
-
}
|
|
390
|
-
function getLiteralNormalPrice(probs, offset, symbolIn) {
|
|
391
|
-
let symbol = symbolIn;
|
|
392
|
-
let price = 0;
|
|
393
|
-
symbol |= 0x100;
|
|
394
|
-
do {
|
|
395
|
-
price += (0, range_encoder_1.getBitPrice)(probs[offset + (symbol >>> 8)], (symbol >>> 7) & 1);
|
|
396
|
-
symbol <<= 1;
|
|
397
|
-
} while (symbol < 0x10000);
|
|
398
|
-
return price;
|
|
399
442
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
matchByte <<= 1;
|
|
408
|
-
const matchBit = matchByte & matchOffset;
|
|
409
|
-
price += (0, range_encoder_1.getBitPrice)(probs[offset + matchOffset + matchBit + (symbol >>> 8)], (symbol >>> 7) & 1);
|
|
410
|
-
symbol <<= 1;
|
|
411
|
-
matchOffset &= ~(matchByte ^ symbol);
|
|
412
|
-
} while (symbol < 0x10000);
|
|
413
|
-
return price;
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Length encoder with cached prices. Prices of each position state are
|
|
417
|
-
* recalculated after every `LEN_PRICE_UPDATE_INTERVAL` encoded lengths.
|
|
418
|
-
*/
|
|
419
|
-
class LengthEncoder {
|
|
420
|
-
probs;
|
|
421
|
-
/** Offset of this length coder in `probs`. */
|
|
422
|
-
coder;
|
|
443
|
+
class LengthEncoder extends lzma_coder_1.LengthCoder {
|
|
444
|
+
/**
|
|
445
|
+
* The prices are updated after at least
|
|
446
|
+
* `PRICE_UPDATE_INTERVAL` many lengths
|
|
447
|
+
* have been encoded with the same posState.
|
|
448
|
+
*/
|
|
449
|
+
static PRICE_UPDATE_INTERVAL = 32;
|
|
423
450
|
counters;
|
|
451
|
+
prices;
|
|
424
452
|
/** Whether a length was encoded since the last reset. */
|
|
425
453
|
used = false;
|
|
426
|
-
/** Prices per position state, `[posState * lenSymbols + len - MATCH_LEN_MIN]`. */
|
|
427
|
-
prices;
|
|
428
|
-
lenSymbols;
|
|
429
454
|
constructor(probs, coder, pb, niceLen) {
|
|
430
|
-
|
|
431
|
-
this.coder = coder;
|
|
455
|
+
super(probs, coder);
|
|
432
456
|
const posStates = 1 << pb;
|
|
433
457
|
this.counters = new Int32Array(posStates);
|
|
434
|
-
// Always allocate at least LOW_SYMBOLS + MID_SYMBOLS
|
|
435
|
-
// updatePrices
|
|
436
|
-
|
|
437
|
-
|
|
458
|
+
// Always allocate at least LOW_SYMBOLS + MID_SYMBOLS because
|
|
459
|
+
// it makes updatePrices slightly simpler. The prices aren't
|
|
460
|
+
// usually needed anyway if niceLen < 18.
|
|
461
|
+
const lenSymbols = Math.max(niceLen - lzma_coder_1.MATCH_LEN_MIN + 1, lzma_coder_1.LOW_SYMBOLS + lzma_coder_1.MID_SYMBOLS);
|
|
462
|
+
this.prices = newPriceArray(posStates, lenSymbols);
|
|
438
463
|
}
|
|
439
464
|
reset() {
|
|
440
|
-
//
|
|
465
|
+
// Reset counters to zero to force price update before
|
|
466
|
+
// the prices are needed.
|
|
441
467
|
this.counters.fill(0);
|
|
442
468
|
this.used = false;
|
|
443
469
|
}
|
|
444
470
|
encode(rc, lenIn, posState) {
|
|
445
471
|
let len = lenIn;
|
|
446
|
-
const probs = this.probs;
|
|
447
|
-
const coder = this.coder;
|
|
448
472
|
len -= lzma_coder_1.MATCH_LEN_MIN;
|
|
449
473
|
if (len < lzma_coder_1.LOW_SYMBOLS) {
|
|
450
|
-
rc.encodeBit(probs, coder + lzma_coder_1.LEN_CHOICE, 0);
|
|
451
|
-
rc.encodeBitTree(probs, coder + lzma_coder_1.LEN_LOW + posState * lzma_coder_1.LOW_SYMBOLS, 3, len);
|
|
474
|
+
rc.encodeBit(this.probs, this.coder + lzma_coder_1.LEN_CHOICE, 0);
|
|
475
|
+
rc.encodeBitTree(this.probs, this.coder + lzma_coder_1.LEN_LOW + posState * lzma_coder_1.LOW_SYMBOLS, 3, len);
|
|
452
476
|
}
|
|
453
477
|
else {
|
|
454
|
-
rc.encodeBit(probs, coder + lzma_coder_1.LEN_CHOICE, 1);
|
|
478
|
+
rc.encodeBit(this.probs, this.coder + lzma_coder_1.LEN_CHOICE, 1);
|
|
455
479
|
len -= lzma_coder_1.LOW_SYMBOLS;
|
|
456
480
|
if (len < lzma_coder_1.MID_SYMBOLS) {
|
|
457
|
-
rc.encodeBit(probs, coder + lzma_coder_1.LEN_CHOICE2, 0);
|
|
458
|
-
rc.encodeBitTree(probs, coder + lzma_coder_1.LEN_MID + posState * lzma_coder_1.MID_SYMBOLS, 3, len);
|
|
481
|
+
rc.encodeBit(this.probs, this.coder + lzma_coder_1.LEN_CHOICE2, 0);
|
|
482
|
+
rc.encodeBitTree(this.probs, this.coder + lzma_coder_1.LEN_MID + posState * lzma_coder_1.MID_SYMBOLS, 3, len);
|
|
459
483
|
}
|
|
460
484
|
else {
|
|
461
|
-
rc.encodeBit(probs, coder + lzma_coder_1.LEN_CHOICE2, 1);
|
|
462
|
-
rc.encodeBitTree(probs, coder + lzma_coder_1.LEN_HIGH, 8, len - lzma_coder_1.MID_SYMBOLS);
|
|
485
|
+
rc.encodeBit(this.probs, this.coder + lzma_coder_1.LEN_CHOICE2, 1);
|
|
486
|
+
rc.encodeBitTree(this.probs, this.coder + lzma_coder_1.LEN_HIGH, 8, len - lzma_coder_1.MID_SYMBOLS);
|
|
463
487
|
}
|
|
464
488
|
}
|
|
465
489
|
--this.counters[posState];
|
|
466
490
|
this.used = true;
|
|
467
491
|
}
|
|
468
492
|
getPrice(len, posState) {
|
|
469
|
-
return this.prices[posState
|
|
493
|
+
return this.prices[posState][len - lzma_coder_1.MATCH_LEN_MIN];
|
|
470
494
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
return posState * this.lenSymbols - lzma_coder_1.MATCH_LEN_MIN;
|
|
495
|
+
getPriceRow(posState) {
|
|
496
|
+
return this.prices[posState];
|
|
474
497
|
}
|
|
475
498
|
updatePrices() {
|
|
476
499
|
for (let posState = 0; posState < this.counters.length; ++posState) {
|
|
477
500
|
if (this.counters[posState] <= 0) {
|
|
478
|
-
this.counters[posState] =
|
|
501
|
+
this.counters[posState] = LengthEncoder.PRICE_UPDATE_INTERVAL;
|
|
479
502
|
this.updatePosStatePrices(posState);
|
|
480
503
|
}
|
|
481
504
|
}
|
|
482
505
|
}
|
|
483
506
|
updatePosStatePrices(posState) {
|
|
484
|
-
const start = posState * this.lenSymbols;
|
|
485
507
|
if (this.used) {
|
|
486
|
-
computeLengthPrices(this.probs, this.coder, posState, this.prices
|
|
508
|
+
computeLengthPrices(this.probs, this.coder, posState, this.prices[posState]);
|
|
487
509
|
}
|
|
488
510
|
else {
|
|
489
511
|
// The model still has its initial probabilities.
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
this.prices[start + i] = initial[i];
|
|
493
|
-
}
|
|
512
|
+
const prices = this.prices[posState];
|
|
513
|
+
prices.set(getInitialPrices().lengthPrices.subarray(0, prices.length));
|
|
494
514
|
}
|
|
495
515
|
}
|
|
496
516
|
}
|
|
497
517
|
exports.LengthEncoder = LengthEncoder;
|
|
518
|
+
function computeLengthPrices(probs, coder, posState, prices) {
|
|
519
|
+
let choice0Price = (0, range_encoder_1.getBitPrice)(probs[coder + lzma_coder_1.LEN_CHOICE], 0);
|
|
520
|
+
let i = 0;
|
|
521
|
+
for (; i < lzma_coder_1.LOW_SYMBOLS; ++i) {
|
|
522
|
+
prices[i] = choice0Price + (0, range_encoder_1.getBitTreePrice)(probs, coder + lzma_coder_1.LEN_LOW + posState * lzma_coder_1.LOW_SYMBOLS, 3, i);
|
|
523
|
+
}
|
|
524
|
+
choice0Price = (0, range_encoder_1.getBitPrice)(probs[coder + lzma_coder_1.LEN_CHOICE], 1);
|
|
525
|
+
let choice1Price = (0, range_encoder_1.getBitPrice)(probs[coder + lzma_coder_1.LEN_CHOICE2], 0);
|
|
526
|
+
for (; i < lzma_coder_1.LOW_SYMBOLS + lzma_coder_1.MID_SYMBOLS; ++i) {
|
|
527
|
+
prices[i] = choice0Price + choice1Price + (0, range_encoder_1.getBitTreePrice)(probs, coder + lzma_coder_1.LEN_MID + posState * lzma_coder_1.MID_SYMBOLS, 3, i - lzma_coder_1.LOW_SYMBOLS);
|
|
528
|
+
}
|
|
529
|
+
choice1Price = (0, range_encoder_1.getBitPrice)(probs[coder + lzma_coder_1.LEN_CHOICE2], 1);
|
|
530
|
+
for (; i < prices.length; ++i) {
|
|
531
|
+
prices[i] = choice0Price + choice1Price + (0, range_encoder_1.getBitTreePrice)(probs, coder + lzma_coder_1.LEN_HIGH, 8, i - lzma_coder_1.LOW_SYMBOLS - lzma_coder_1.MID_SYMBOLS);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
let initialPrices;
|
|
535
|
+
/**
|
|
536
|
+
* Price tables for models that still have their initial probabilities.
|
|
537
|
+
* They are the same for every encoder, so they are computed once, by the
|
|
538
|
+
* same functions the encoders use, on an array of initial probabilities.
|
|
539
|
+
*/
|
|
540
|
+
function getInitialPrices() {
|
|
541
|
+
if (initialPrices === undefined) {
|
|
542
|
+
const probs = new Uint16Array(lzma_coder_1.LITERAL);
|
|
543
|
+
(0, range_coder_1.initProbs)(probs);
|
|
544
|
+
const distSlotPrices = newPriceArray(lzma_coder_1.DIST_STATES, lzma_coder_1.DIST_SLOTS);
|
|
545
|
+
const fullDistPrices = newPriceArray(lzma_coder_1.DIST_STATES, lzma_coder_1.FULL_DISTANCES);
|
|
546
|
+
computeDistPrices(probs, lzma_coder_1.DIST_SLOTS, distSlotPrices, fullDistPrices);
|
|
547
|
+
const alignPrices = new Int32Array(lzma_coder_1.ALIGN_SIZE);
|
|
548
|
+
computeAlignPrices(probs, alignPrices);
|
|
549
|
+
const lengthPrices = new Int32Array(lzma_coder_1.MATCH_LEN_MAX - lzma_coder_1.MATCH_LEN_MIN + 1);
|
|
550
|
+
computeLengthPrices(probs, lzma_coder_1.MATCH_LEN, 0, lengthPrices);
|
|
551
|
+
initialPrices = { distSlotPrices, fullDistPrices, alignPrices, lengthPrices };
|
|
552
|
+
}
|
|
553
|
+
return initialPrices;
|
|
554
|
+
}
|