brotli-lib 0.0.2 → 0.0.4
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 +19 -17
- package/dist/decode/engine.d.ts.map +1 -1
- package/dist/decode.cjs +172 -77
- package/dist/decode.js +172 -77
- package/dist/encode/backward-references.d.ts +0 -1
- package/dist/encode/backward-references.d.ts.map +1 -1
- package/dist/encode/enc-constants.d.ts.map +1 -1
- package/dist/encode/metablock.d.ts +1 -0
- package/dist/encode/metablock.d.ts.map +1 -1
- package/dist/encode.cjs +3175 -97
- package/dist/encode.js +3175 -97
- package/dist/index.cjs +3346 -173
- package/dist/index.js +3346 -173
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,38 +58,40 @@ class BrotliEncoder {
|
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
FONT mode uses distance coding parameters optimized for transformed font data. It doesn't improve compression on raw TTF/OTF files - the gains come from WOFF2's font-specific transforms (glyf, loca, hmtx) applied before brotli compression
|
|
62
|
+
|
|
61
63
|
## Performance
|
|
62
64
|
|
|
63
65
|
### Decode
|
|
64
66
|
|
|
65
|
-
| | brotli-lib | brotli.js | Google
|
|
67
|
+
| | brotli-lib | brotli.js | Google decode.ts |
|
|
66
68
|
|--|------------|-----------|---------------|
|
|
67
|
-
| Speed (vs Google) | 1.
|
|
69
|
+
| Speed (vs Google) | 1.05-1.1x | 0.5-0.6x | 1x |
|
|
68
70
|
| Custom dictionary | yes | no | yes |
|
|
69
71
|
| Compressed static dict | yes | yes | no |
|
|
70
72
|
|
|
71
73
|
Decode times (Apple M2 Max, Node 22):
|
|
72
74
|
|
|
73
|
-
| File | brotli-lib | brotli.js | Google
|
|
75
|
+
| File | brotli-lib | brotli.js | Google decode.ts |
|
|
74
76
|
|------|------------|-----------|---------------|
|
|
75
|
-
| enc-ttf (305 KB) |
|
|
76
|
-
| enc-otf (253 KB) |
|
|
77
|
-
| enc-var-ttf (788 KB) |
|
|
78
|
-
| noto-tc (7 MB) |
|
|
77
|
+
| enc-ttf (305 KB) | 2.5 ms | 4.5 ms | 2.8 ms |
|
|
78
|
+
| enc-otf (253 KB) | 2.5 ms | 4.3 ms | 2.7 ms |
|
|
79
|
+
| enc-var-ttf (788 KB) | 6.8 ms | 11.8 ms | 7.1 ms |
|
|
80
|
+
| noto-tc (7 MB) | 55 ms | 90 ms | 57 ms |
|
|
79
81
|
|
|
80
|
-
1.7x faster than brotli.js,
|
|
82
|
+
1.7x faster than brotli.js, 5-10% faster than Google's JS decoder
|
|
81
83
|
|
|
82
84
|
### Encode
|
|
83
85
|
|
|
84
86
|
Encoder vs Node.js native `zlib.brotliCompressSync` (quality 11):
|
|
85
87
|
|
|
86
|
-
| Input | brotli-lib | node:zlib |
|
|
87
|
-
|
|
88
|
-
| 13 B | 0.
|
|
89
|
-
| 4.5 KB | 0.
|
|
90
|
-
| 45 KB | 3.
|
|
88
|
+
| Input | brotli-lib | node:zlib | vs native |
|
|
89
|
+
|-------|-----------|-----------|-----------|
|
|
90
|
+
| 13 B | 0.001 ms | 0.16 ms | 160x faster |
|
|
91
|
+
| 4.5 KB | 0.27 ms | 0.33 ms | 1.2x faster |
|
|
92
|
+
| 45 KB | 3.0 ms | 1.4 ms | 2x slower |
|
|
91
93
|
|
|
92
|
-
Much faster for tiny inputs (no native binding overhead), faster for medium, 2x slower for large
|
|
94
|
+
Much faster for tiny inputs (no native binding overhead), faster for medium, ~2x slower for large
|
|
93
95
|
|
|
94
96
|
Run `npm run bench` to reproduce
|
|
95
97
|
|
|
@@ -97,11 +99,11 @@ Run `npm run bench` to reproduce
|
|
|
97
99
|
|
|
98
100
|
| Import | Export size (gzip) |
|
|
99
101
|
|--------|--------------------|
|
|
102
|
+
| `brotli-lib/encode` | 25 KB |
|
|
100
103
|
| `brotli-lib/decode` | 66 KB |
|
|
101
|
-
| `brotli-lib
|
|
102
|
-
| `brotli-lib` | 82 KB |
|
|
104
|
+
| `brotli-lib` | 90 KB |
|
|
103
105
|
|
|
104
|
-
The 122 KB static dictionary is compressed to 52 KB and bootstrapped at runtime (à la Devon Govett's brotli.js)
|
|
106
|
+
The 122 KB static dictionary is compressed to 52 KB and bootstrapped at runtime (à la Devon Govett's brotli.js).
|
|
105
107
|
|
|
106
108
|
## License
|
|
107
109
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/decode/engine.ts"],"names":[],"mappings":"AASA,UAAU,mBAAmB;IAC3B,gBAAgB,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/decode/engine.ts"],"names":[],"mappings":"AASA,UAAU,mBAAmB;IAC3B,gBAAgB,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAiHD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAMlD;AAGD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAMlD;AAurDD,cAAM,KAAK;IACT,UAAU,EAAE,UAAU,CAAqB;IAC3C,YAAY,yBAAoB;IAChC,UAAU,yBAAoB;IAC9B,cAAc,yBAAoB;IAClC,aAAa,yBAAoB;IACjC,MAAM,EAAE,UAAU,CAAqB;IACvC,UAAU,yBAAoB;IAC9B,YAAY,2BAAsB;IAClC,WAAW,0BAAqB;IAChC,SAAS,0BAAqB;IAC9B,KAAK,0BAAqB;IAC1B,UAAU,0BAAqB;IAC/B,gBAAgB,0BAAqB;IACrC,gBAAgB,0BAAqB;IACrC,iBAAiB,0BAAqB;IACtC,UAAU,0BAAqB;IAC/B,aAAa,SAAK;IAClB,YAAY,SAAK;IACjB,gBAAgB,SAAK;IACrB,aAAa,SAAK;IAClB,SAAS,SAAK;IACd,UAAU,SAAK;IACf,SAAS,SAAK;IACd,kBAAkB,SAAK;IACvB,eAAe,SAAK;IACpB,QAAQ,SAAK;IACb,cAAc,SAAK;IACnB,UAAU,SAAK;IACf,kBAAkB,SAAK;IACvB,oBAAoB,SAAK;IACzB,kBAAkB,SAAK;IACvB,oBAAoB,SAAK;IACzB,mBAAmB,SAAK;IACxB,qBAAqB,SAAK;IAC1B,GAAG,SAAK;IACR,WAAW,SAAK;IAChB,SAAS,SAAK;IACd,qBAAqB,SAAK;IAC1B,cAAc,SAAK;IACnB,cAAc,SAAK;IACnB,CAAC,SAAK;IACN,YAAY,SAAK;IACjB,eAAe,SAAK;IACpB,mBAAmB,SAAK;IACxB,oBAAoB,SAAK;IACzB,oBAAoB,SAAK;IACzB,YAAY,SAAK;IACjB,sBAAsB,SAAK;IAC3B,mBAAmB,SAAK;IACxB,QAAQ,SAAK;IACb,UAAU,SAAK;IACf,mBAAmB,SAAK;IACxB,iBAAiB,SAAK;IACtB,cAAc,SAAK;IACnB,iBAAiB,SAAK;IACtB,YAAY,SAAK;IACjB,YAAY,SAAK;IACjB,UAAU,SAAK;IACf,sBAAsB,SAAK;IAC3B,oBAAoB,SAAK;IACzB,OAAO,SAAK;IACZ,aAAa,SAAK;IAClB,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,SAAS,SAAK;IACd,UAAU,SAAK;IACf,UAAU,SAAK;IACf,UAAU,SAAK;IACf,QAAQ,QAAgB;IACxB,cAAc,0BAAqB;IACnC,WAAW,SAAK;IAChB,UAAU,yBAAoB;IAC9B,KAAK,cAAqC;;CAS3C;AAmDD,cAAM,WAAW;IACf,IAAI,EAAE,UAAU,GAAG,SAAS,CAAqB;IACjD,MAAM,SAAK;gBACE,IAAI,EAAE,UAAU,GAAG,SAAS;CAG1C;AAuCD;;GAEG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,UAAU,CA2D5E"}
|
package/dist/decode.cjs
CHANGED
|
@@ -478,6 +478,15 @@ const COPY_LENGTH_N_BITS = Int16Array.from([
|
|
|
478
478
|
const CMD_LOOKUP = new Int16Array(2816);
|
|
479
479
|
unpackCommandLookupTable(CMD_LOOKUP);
|
|
480
480
|
const IS_LITTLE_ENDIAN = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
|
|
481
|
+
const _scratchCount = new Int32Array(16);
|
|
482
|
+
const _scratchOffset = new Int32Array(16);
|
|
483
|
+
const _scratchSorted = new Int32Array(1080);
|
|
484
|
+
const _scratchHCLTable = new Int32Array(33);
|
|
485
|
+
const _scratchCLCL = new Int32Array(18);
|
|
486
|
+
const _scratchCodeLengths = new Int32Array(1080);
|
|
487
|
+
const _scratchSymbols = new Int32Array(4);
|
|
488
|
+
const _scratchMtf = new Int32Array(256);
|
|
489
|
+
const _scratchCtxMapTable = new Int32Array(1081);
|
|
481
490
|
function log2floor(i) {
|
|
482
491
|
let result = -1;
|
|
483
492
|
let step = 16;
|
|
@@ -667,16 +676,12 @@ function readBlockLength(tableGroup, tableIdx, s) {
|
|
|
667
676
|
return BLOCK_LENGTH_OFFSET[code] + (n <= 16 ? readFewBits(s, n) : readManyBits(s, n));
|
|
668
677
|
}
|
|
669
678
|
function moveToFront(v, index) {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
while (i > 0) {
|
|
673
|
-
v[i] = v[i - 1];
|
|
674
|
-
i--;
|
|
675
|
-
}
|
|
679
|
+
const value = v[index];
|
|
680
|
+
v.copyWithin(1, 0, index);
|
|
676
681
|
v[0] = value;
|
|
677
682
|
}
|
|
678
683
|
function inverseMoveToFrontTransform(v, vLen) {
|
|
679
|
-
const mtf =
|
|
684
|
+
const mtf = _scratchMtf;
|
|
680
685
|
for (let i = 0; i < 256; ++i) mtf[i] = i;
|
|
681
686
|
for (let i = 0; i < vLen; ++i) {
|
|
682
687
|
const index = v[i] & 255;
|
|
@@ -690,8 +695,8 @@ function readHuffmanCodeLengths(codeLengthCodeLengths, numSymbols, codeLengths,
|
|
|
690
695
|
let repeat = 0;
|
|
691
696
|
let repeatCodeLen = 0;
|
|
692
697
|
let space = 32768;
|
|
693
|
-
const table =
|
|
694
|
-
buildHuffmanTable(table,
|
|
698
|
+
const table = _scratchHCLTable;
|
|
699
|
+
buildHuffmanTable(table, 32, 5, codeLengthCodeLengths, 18);
|
|
695
700
|
while (symbol < numSymbols && space > 0) {
|
|
696
701
|
if (s.halfOffset > 2030) {
|
|
697
702
|
const result = readMoreInput(s);
|
|
@@ -731,7 +736,8 @@ function readHuffmanCodeLengths(codeLengthCodeLengths, numSymbols, codeLengths,
|
|
|
731
736
|
repeat += readFewBits(s, extraBits) + 3;
|
|
732
737
|
const repeatDelta = repeat - oldRepeat;
|
|
733
738
|
if (symbol + repeatDelta > numSymbols) return makeError(s, -2);
|
|
734
|
-
|
|
739
|
+
codeLengths.fill(repeatCodeLen, symbol, symbol + repeatDelta);
|
|
740
|
+
symbol += repeatDelta;
|
|
735
741
|
if (repeatCodeLen !== 0) space -= repeatDelta << 15 - repeatCodeLen;
|
|
736
742
|
}
|
|
737
743
|
}
|
|
@@ -744,8 +750,9 @@ function checkDupes(s, symbols, length) {
|
|
|
744
750
|
return 0;
|
|
745
751
|
}
|
|
746
752
|
function readSimpleHuffmanCode(alphabetSizeMax, alphabetSizeLimit, tableGroup, tableIdx, s) {
|
|
747
|
-
const codeLengths =
|
|
748
|
-
|
|
753
|
+
const codeLengths = _scratchCodeLengths;
|
|
754
|
+
codeLengths.fill(0, 0, alphabetSizeLimit);
|
|
755
|
+
const symbols = _scratchSymbols;
|
|
749
756
|
const maxBits = 1 + log2floor(alphabetSizeMax - 1);
|
|
750
757
|
const numSymbols = readFewBits(s, 2) + 1;
|
|
751
758
|
for (let i = 0; i < numSymbols; ++i) {
|
|
@@ -791,8 +798,10 @@ function readSimpleHuffmanCode(alphabetSizeMax, alphabetSizeLimit, tableGroup, t
|
|
|
791
798
|
return buildHuffmanTable(tableGroup, tableIdx, 8, codeLengths, alphabetSizeLimit);
|
|
792
799
|
}
|
|
793
800
|
function readComplexHuffmanCode(alphabetSizeLimit, skip, tableGroup, tableIdx, s) {
|
|
794
|
-
const codeLengths =
|
|
795
|
-
|
|
801
|
+
const codeLengths = _scratchCodeLengths;
|
|
802
|
+
codeLengths.fill(0, 0, alphabetSizeLimit);
|
|
803
|
+
const codeLengthCodeLengths = _scratchCLCL;
|
|
804
|
+
codeLengthCodeLengths.fill(0);
|
|
796
805
|
let space = 32;
|
|
797
806
|
let numCodes = 0;
|
|
798
807
|
for (let i = skip; i < 18; ++i) {
|
|
@@ -849,8 +858,8 @@ function decodeContextMap(contextMapSize, contextMap, s) {
|
|
|
849
858
|
if (useRleForZeros !== 0) maxRunLengthPrefix = readFewBits(s, 4) + 1;
|
|
850
859
|
const alphabetSize = numTrees + maxRunLengthPrefix;
|
|
851
860
|
const tableSize = MAX_HUFFMAN_TABLE_SIZE[alphabetSize + 31 >> 5];
|
|
852
|
-
const table =
|
|
853
|
-
const tableIdx =
|
|
861
|
+
const table = _scratchCtxMapTable;
|
|
862
|
+
const tableIdx = tableSize;
|
|
854
863
|
result = readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
|
|
855
864
|
if (result < 0) return result;
|
|
856
865
|
let i = 0;
|
|
@@ -873,12 +882,9 @@ function decodeContextMap(contextMapSize, contextMap, s) {
|
|
|
873
882
|
s.bitOffset -= 16;
|
|
874
883
|
}
|
|
875
884
|
let reps = (1 << code) + readFewBits(s, code);
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
i++;
|
|
880
|
-
reps--;
|
|
881
|
-
}
|
|
885
|
+
if (i + reps > contextMapSize) return makeError(s, -3);
|
|
886
|
+
contextMap.fill(0, i, i + reps);
|
|
887
|
+
i += reps;
|
|
882
888
|
} else {
|
|
883
889
|
contextMap[i] = code - maxRunLengthPrefix;
|
|
884
890
|
i++;
|
|
@@ -1296,55 +1302,136 @@ function decompress(s) {
|
|
|
1296
1302
|
s.runningState = 7;
|
|
1297
1303
|
continue;
|
|
1298
1304
|
case 7:
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
s.literalBlockLength
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1305
|
+
{
|
|
1306
|
+
let _bo = s.bitOffset;
|
|
1307
|
+
let _ac = s.accumulator32;
|
|
1308
|
+
let _ho = s.halfOffset;
|
|
1309
|
+
let _pos = s.pos;
|
|
1310
|
+
let _j = s.j;
|
|
1311
|
+
let _lbl = s.literalBlockLength;
|
|
1312
|
+
const _sb = s.shortBuffer;
|
|
1313
|
+
const _ltg = s.literalTreeGroup;
|
|
1314
|
+
const _il = s.insertLength;
|
|
1315
|
+
if (s.trivialLiteralContext !== 0) {
|
|
1316
|
+
let _lti = s.literalTreeIdx;
|
|
1317
|
+
while (_j < _il) {
|
|
1318
|
+
if (_ho > 2030) {
|
|
1319
|
+
s.halfOffset = _ho;
|
|
1320
|
+
result = readMoreInput(s);
|
|
1321
|
+
if (result < 0) return result;
|
|
1322
|
+
_ho = s.halfOffset;
|
|
1323
|
+
}
|
|
1324
|
+
if (_lbl === 0) {
|
|
1325
|
+
s.bitOffset = _bo;
|
|
1326
|
+
s.accumulator32 = _ac;
|
|
1327
|
+
s.halfOffset = _ho;
|
|
1328
|
+
decodeLiteralBlockSwitch(s);
|
|
1329
|
+
_bo = s.bitOffset;
|
|
1330
|
+
_ac = s.accumulator32;
|
|
1331
|
+
_ho = s.halfOffset;
|
|
1332
|
+
_lbl = s.literalBlockLength;
|
|
1333
|
+
_lti = s.literalTreeIdx;
|
|
1334
|
+
}
|
|
1335
|
+
_lbl--;
|
|
1336
|
+
if (_bo >= 16) {
|
|
1337
|
+
_ac = _sb[_ho++] << 16 | _ac >>> 16;
|
|
1338
|
+
_bo -= 16;
|
|
1339
|
+
}
|
|
1340
|
+
let _rsOff = _ltg[_lti];
|
|
1341
|
+
const _rsV = _ac >>> _bo;
|
|
1342
|
+
_rsOff += _rsV & 255;
|
|
1343
|
+
const _rsE0 = _ltg[_rsOff];
|
|
1344
|
+
const _rsBits = _rsE0 >> 16;
|
|
1345
|
+
if (_rsBits <= 8) {
|
|
1346
|
+
_bo += _rsBits;
|
|
1347
|
+
ringBuffer[_pos] = _rsE0 & 65535;
|
|
1348
|
+
} else {
|
|
1349
|
+
_rsOff += _rsE0 & 65535;
|
|
1350
|
+
_rsOff += (_rsV & (1 << _rsBits) - 1) >>> 8;
|
|
1351
|
+
const _rsE1 = _ltg[_rsOff];
|
|
1352
|
+
_bo += (_rsE1 >> 16) + 8;
|
|
1353
|
+
ringBuffer[_pos] = _rsE1 & 65535;
|
|
1354
|
+
}
|
|
1355
|
+
_pos++;
|
|
1356
|
+
_j++;
|
|
1357
|
+
if (_pos >= fence) {
|
|
1358
|
+
s.nextRunningState = 7;
|
|
1359
|
+
s.runningState = 12;
|
|
1360
|
+
break;
|
|
1361
|
+
}
|
|
1335
1362
|
}
|
|
1336
|
-
|
|
1337
|
-
ringBuffer[
|
|
1338
|
-
|
|
1339
|
-
s.
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1363
|
+
} else {
|
|
1364
|
+
let prevByte1 = ringBuffer[_pos - 1 & ringBufferMask];
|
|
1365
|
+
let prevByte2 = ringBuffer[_pos - 2 & ringBufferMask];
|
|
1366
|
+
let _cms = s.contextMapSlice;
|
|
1367
|
+
let _clo1 = s.contextLookupOffset1;
|
|
1368
|
+
let _clo2 = s.contextLookupOffset2;
|
|
1369
|
+
const _cm = s.contextMap;
|
|
1370
|
+
while (_j < _il) {
|
|
1371
|
+
if (_ho > 2030) {
|
|
1372
|
+
s.halfOffset = _ho;
|
|
1373
|
+
result = readMoreInput(s);
|
|
1374
|
+
if (result < 0) return result;
|
|
1375
|
+
_ho = s.halfOffset;
|
|
1376
|
+
}
|
|
1377
|
+
if (_lbl === 0) {
|
|
1378
|
+
s.bitOffset = _bo;
|
|
1379
|
+
s.accumulator32 = _ac;
|
|
1380
|
+
s.halfOffset = _ho;
|
|
1381
|
+
s.contextMapSlice = _cms;
|
|
1382
|
+
decodeLiteralBlockSwitch(s);
|
|
1383
|
+
_bo = s.bitOffset;
|
|
1384
|
+
_ac = s.accumulator32;
|
|
1385
|
+
_ho = s.halfOffset;
|
|
1386
|
+
_lbl = s.literalBlockLength;
|
|
1387
|
+
_cms = s.contextMapSlice;
|
|
1388
|
+
_clo1 = s.contextLookupOffset1;
|
|
1389
|
+
_clo2 = s.contextLookupOffset2;
|
|
1390
|
+
}
|
|
1391
|
+
const literalContext = LOOKUP[_clo1 + prevByte1] | LOOKUP[_clo2 + prevByte2];
|
|
1392
|
+
const literalTreeIdx = _cm[_cms + literalContext] & 255;
|
|
1393
|
+
_lbl--;
|
|
1394
|
+
prevByte2 = prevByte1;
|
|
1395
|
+
if (_bo >= 16) {
|
|
1396
|
+
_ac = _sb[_ho++] << 16 | _ac >>> 16;
|
|
1397
|
+
_bo -= 16;
|
|
1398
|
+
}
|
|
1399
|
+
{
|
|
1400
|
+
let _rsOff = _ltg[literalTreeIdx];
|
|
1401
|
+
const _rsV = _ac >>> _bo;
|
|
1402
|
+
_rsOff += _rsV & 255;
|
|
1403
|
+
const _rsE0 = _ltg[_rsOff];
|
|
1404
|
+
const _rsBits = _rsE0 >> 16;
|
|
1405
|
+
if (_rsBits <= 8) {
|
|
1406
|
+
_bo += _rsBits;
|
|
1407
|
+
prevByte1 = _rsE0 & 65535;
|
|
1408
|
+
} else {
|
|
1409
|
+
_rsOff += _rsE0 & 65535;
|
|
1410
|
+
_rsOff += (_rsV & (1 << _rsBits) - 1) >>> 8;
|
|
1411
|
+
const _rsE1 = _ltg[_rsOff];
|
|
1412
|
+
_bo += (_rsE1 >> 16) + 8;
|
|
1413
|
+
prevByte1 = _rsE1 & 65535;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
ringBuffer[_pos] = prevByte1;
|
|
1417
|
+
_pos++;
|
|
1418
|
+
_j++;
|
|
1419
|
+
if (_pos >= fence) {
|
|
1420
|
+
s.nextRunningState = 7;
|
|
1421
|
+
s.runningState = 12;
|
|
1422
|
+
break;
|
|
1423
|
+
}
|
|
1344
1424
|
}
|
|
1425
|
+
s.contextMapSlice = _cms;
|
|
1345
1426
|
}
|
|
1427
|
+
s.bitOffset = _bo;
|
|
1428
|
+
s.accumulator32 = _ac;
|
|
1429
|
+
s.halfOffset = _ho;
|
|
1430
|
+
s.pos = _pos;
|
|
1431
|
+
s.j = _j;
|
|
1432
|
+
s.literalBlockLength = _lbl;
|
|
1433
|
+
if (s.runningState !== 7) continue;
|
|
1346
1434
|
}
|
|
1347
|
-
if (s.runningState !== 7) continue;
|
|
1348
1435
|
s.metaBlockLength -= s.insertLength;
|
|
1349
1436
|
if (s.metaBlockLength <= 0) {
|
|
1350
1437
|
s.runningState = 4;
|
|
@@ -1404,7 +1491,8 @@ function decompress(s) {
|
|
|
1404
1491
|
const srcEnd = src + copyLength;
|
|
1405
1492
|
const dstEnd = dst + copyLength;
|
|
1406
1493
|
if (srcEnd < ringBufferMask && dstEnd < ringBufferMask) {
|
|
1407
|
-
if (s.distance ===
|
|
1494
|
+
if (s.distance === 1) ringBuffer.fill(ringBuffer[src], dst, dstEnd);
|
|
1495
|
+
else if (s.distance === 4 && copyLength >= 8) {
|
|
1408
1496
|
ringBuffer[dst] = ringBuffer[src];
|
|
1409
1497
|
ringBuffer[dst + 1] = ringBuffer[src + 1];
|
|
1410
1498
|
ringBuffer[dst + 2] = ringBuffer[src + 2];
|
|
@@ -1642,9 +1730,11 @@ function nextTableBitSize(count, len, rootBits) {
|
|
|
1642
1730
|
}
|
|
1643
1731
|
function buildHuffmanTable(tableGroup, tableIdx, rootBits, codeLengths, codeLengthsSize) {
|
|
1644
1732
|
const tableOffset = tableGroup[tableIdx];
|
|
1645
|
-
const sorted =
|
|
1646
|
-
const count =
|
|
1647
|
-
const offset =
|
|
1733
|
+
const sorted = _scratchSorted;
|
|
1734
|
+
const count = _scratchCount;
|
|
1735
|
+
const offset = _scratchOffset;
|
|
1736
|
+
count.fill(0);
|
|
1737
|
+
offset.fill(0);
|
|
1648
1738
|
for (let sym = 0; sym < codeLengthsSize; ++sym) count[codeLengths[sym]]++;
|
|
1649
1739
|
offset[1] = 0;
|
|
1650
1740
|
for (let len = 1; len < 15; ++len) offset[len + 1] = offset[len] + count[len];
|
|
@@ -1653,7 +1743,7 @@ function buildHuffmanTable(tableGroup, tableIdx, rootBits, codeLengths, codeLeng
|
|
|
1653
1743
|
let tableSize = 1 << tableBits;
|
|
1654
1744
|
let totalSize = tableSize;
|
|
1655
1745
|
if (offset[15] === 1) {
|
|
1656
|
-
|
|
1746
|
+
tableGroup.fill(sorted[0], tableOffset, tableOffset + totalSize);
|
|
1657
1747
|
return totalSize;
|
|
1658
1748
|
}
|
|
1659
1749
|
let key = 0;
|
|
@@ -2037,17 +2127,21 @@ function brotliDecode$1(bytes, options) {
|
|
|
2037
2127
|
return result;
|
|
2038
2128
|
}
|
|
2039
2129
|
let totalOutput = 0;
|
|
2130
|
+
let chunkSize = 16384;
|
|
2040
2131
|
const chunks = [];
|
|
2132
|
+
const chunkSizes = [];
|
|
2041
2133
|
while (true) {
|
|
2042
|
-
const chunk = new Uint8Array(
|
|
2134
|
+
const chunk = new Uint8Array(chunkSize);
|
|
2043
2135
|
chunks.push(chunk);
|
|
2136
|
+
chunkSizes.push(chunkSize);
|
|
2044
2137
|
s.output = chunk;
|
|
2045
2138
|
s.outputOffset = 0;
|
|
2046
|
-
s.outputLength =
|
|
2139
|
+
s.outputLength = chunkSize;
|
|
2047
2140
|
s.outputUsed = 0;
|
|
2048
2141
|
decompress(s);
|
|
2049
2142
|
totalOutput += s.outputUsed;
|
|
2050
|
-
if (s.outputUsed <
|
|
2143
|
+
if (s.outputUsed < chunkSize) break;
|
|
2144
|
+
if (chunkSize < 4194304) chunkSize *= 2;
|
|
2051
2145
|
}
|
|
2052
2146
|
close(s);
|
|
2053
2147
|
closeInput(s);
|
|
@@ -2055,8 +2149,9 @@ function brotliDecode$1(bytes, options) {
|
|
|
2055
2149
|
let offset = 0;
|
|
2056
2150
|
for (let i = 0; i < chunks.length; ++i) {
|
|
2057
2151
|
const chunk = chunks[i];
|
|
2058
|
-
const
|
|
2059
|
-
|
|
2152
|
+
const sz = chunkSizes[i];
|
|
2153
|
+
const len = Math.min(totalOutput, offset + sz) - offset;
|
|
2154
|
+
if (len < sz) result.set(chunk.subarray(0, len), offset);
|
|
2060
2155
|
else result.set(chunk, offset);
|
|
2061
2156
|
offset += len;
|
|
2062
2157
|
}
|