zstdify 1.0.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/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/bitstream/bitReader.d.ts +26 -0
- package/dist/bitstream/bitReader.js +86 -0
- package/dist/bitstream/bitReader.js.map +1 -0
- package/dist/bitstream/bitReader.test.d.ts +1 -0
- package/dist/bitstream/bitReader.test.js +47 -0
- package/dist/bitstream/bitReader.test.js.map +1 -0
- package/dist/bitstream/bitReaderReverse.d.ts +23 -0
- package/dist/bitstream/bitReaderReverse.js +84 -0
- package/dist/bitstream/bitReaderReverse.js.map +1 -0
- package/dist/bitstream/bitReaderReverse.test.d.ts +1 -0
- package/dist/bitstream/bitReaderReverse.test.js +49 -0
- package/dist/bitstream/bitReaderReverse.test.js.map +1 -0
- package/dist/bitstream/bitWriter.d.ts +15 -0
- package/dist/bitstream/bitWriter.js +47 -0
- package/dist/bitstream/bitWriter.js.map +1 -0
- package/dist/bitstream/index.d.ts +4 -0
- package/dist/bitstream/index.js +5 -0
- package/dist/bitstream/index.js.map +1 -0
- package/dist/bitstream/littleEndian.d.ts +7 -0
- package/dist/bitstream/littleEndian.js +45 -0
- package/dist/bitstream/littleEndian.js.map +1 -0
- package/dist/bitstream/littleEndian.test.d.ts +1 -0
- package/dist/bitstream/littleEndian.test.js +21 -0
- package/dist/bitstream/littleEndian.test.js.map +1 -0
- package/dist/bitstream/varint.d.ts +9 -0
- package/dist/bitstream/varint.js +40 -0
- package/dist/bitstream/varint.js.map +1 -0
- package/dist/bitstream/varint.test.d.ts +1 -0
- package/dist/bitstream/varint.test.js +25 -0
- package/dist/bitstream/varint.test.js.map +1 -0
- package/dist/compress.d.ts +9 -0
- package/dist/compress.js +74 -0
- package/dist/compress.js.map +1 -0
- package/dist/decode/block.d.ts +11 -0
- package/dist/decode/block.js +28 -0
- package/dist/decode/block.js.map +1 -0
- package/dist/decode/block.test.d.ts +1 -0
- package/dist/decode/block.test.js +26 -0
- package/dist/decode/block.test.js.map +1 -0
- package/dist/decode/decompressFrame.d.ts +9 -0
- package/dist/decode/decompressFrame.js +147 -0
- package/dist/decode/decompressFrame.js.map +1 -0
- package/dist/decode/literals.corruption.test.d.ts +1 -0
- package/dist/decode/literals.corruption.test.js +26 -0
- package/dist/decode/literals.corruption.test.js.map +1 -0
- package/dist/decode/literals.d.ts +49 -0
- package/dist/decode/literals.js +300 -0
- package/dist/decode/literals.js.map +1 -0
- package/dist/decode/literals.test.d.ts +1 -0
- package/dist/decode/literals.test.js +52 -0
- package/dist/decode/literals.test.js.map +1 -0
- package/dist/decode/reconstruct.d.ts +13 -0
- package/dist/decode/reconstruct.js +80 -0
- package/dist/decode/reconstruct.js.map +1 -0
- package/dist/decode/reconstruct.test.d.ts +1 -0
- package/dist/decode/reconstruct.test.js +42 -0
- package/dist/decode/reconstruct.test.js.map +1 -0
- package/dist/decode/sequences.corruption.test.d.ts +1 -0
- package/dist/decode/sequences.corruption.test.js +32 -0
- package/dist/decode/sequences.corruption.test.js.map +1 -0
- package/dist/decode/sequences.d.ts +21 -0
- package/dist/decode/sequences.js +222 -0
- package/dist/decode/sequences.js.map +1 -0
- package/dist/decode/sequences.level1.test.d.ts +1 -0
- package/dist/decode/sequences.level1.test.js +35 -0
- package/dist/decode/sequences.level1.test.js.map +1 -0
- package/dist/decompress.d.ts +11 -0
- package/dist/decompress.js +59 -0
- package/dist/decompress.js.map +1 -0
- package/dist/dictionary/decoderDictionary.d.ts +15 -0
- package/dist/dictionary/decoderDictionary.js +116 -0
- package/dist/dictionary/decoderDictionary.js.map +1 -0
- package/dist/dictionary/decoderDictionary.test.d.ts +1 -0
- package/dist/dictionary/decoderDictionary.test.js +87 -0
- package/dist/dictionary/decoderDictionary.test.js.map +1 -0
- package/dist/encode/blockWriter.d.ts +5 -0
- package/dist/encode/blockWriter.js +27 -0
- package/dist/encode/blockWriter.js.map +1 -0
- package/dist/encode/blockWriter.test.d.ts +1 -0
- package/dist/encode/blockWriter.test.js +31 -0
- package/dist/encode/blockWriter.test.js.map +1 -0
- package/dist/encode/compressedBlock.d.ts +3 -0
- package/dist/encode/compressedBlock.js +449 -0
- package/dist/encode/compressedBlock.js.map +1 -0
- package/dist/encode/compressedBlock.test.d.ts +1 -0
- package/dist/encode/compressedBlock.test.js +63 -0
- package/dist/encode/compressedBlock.test.js.map +1 -0
- package/dist/encode/frameWriter.d.ts +4 -0
- package/dist/encode/frameWriter.js +34 -0
- package/dist/encode/frameWriter.js.map +1 -0
- package/dist/encode/frameWriter.test.d.ts +1 -0
- package/dist/encode/frameWriter.test.js +38 -0
- package/dist/encode/frameWriter.test.js.map +1 -0
- package/dist/encode/greedySequences.d.ts +7 -0
- package/dist/encode/greedySequences.js +82 -0
- package/dist/encode/greedySequences.js.map +1 -0
- package/dist/encode/greedySequences.test.d.ts +1 -0
- package/dist/encode/greedySequences.test.js +33 -0
- package/dist/encode/greedySequences.test.js.map +1 -0
- package/dist/entropy/fse.d.ts +33 -0
- package/dist/entropy/fse.js +217 -0
- package/dist/entropy/fse.js.map +1 -0
- package/dist/entropy/fse.test.d.ts +1 -0
- package/dist/entropy/fse.test.js +41 -0
- package/dist/entropy/fse.test.js.map +1 -0
- package/dist/entropy/huffman.d.ts +24 -0
- package/dist/entropy/huffman.js +70 -0
- package/dist/entropy/huffman.js.map +1 -0
- package/dist/entropy/huffman.test.d.ts +1 -0
- package/dist/entropy/huffman.test.js +22 -0
- package/dist/entropy/huffman.test.js.map +1 -0
- package/dist/entropy/index.d.ts +6 -0
- package/dist/entropy/index.js +5 -0
- package/dist/entropy/index.js.map +1 -0
- package/dist/entropy/predefined.d.ts +10 -0
- package/dist/entropy/predefined.js +18 -0
- package/dist/entropy/predefined.js.map +1 -0
- package/dist/entropy/weights.d.ts +20 -0
- package/dist/entropy/weights.js +108 -0
- package/dist/entropy/weights.js.map +1 -0
- package/dist/entropy/weights.test.d.ts +1 -0
- package/dist/entropy/weights.test.js +38 -0
- package/dist/entropy/weights.test.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/errors.test.d.ts +1 -0
- package/dist/errors.test.js +16 -0
- package/dist/errors.test.js.map +1 -0
- package/dist/frame/checksum.d.ts +17 -0
- package/dist/frame/checksum.js +94 -0
- package/dist/frame/checksum.js.map +1 -0
- package/dist/frame/checksum.test.d.ts +1 -0
- package/dist/frame/checksum.test.js +28 -0
- package/dist/frame/checksum.test.js.map +1 -0
- package/dist/frame/frameHeader.d.ts +26 -0
- package/dist/frame/frameHeader.js +127 -0
- package/dist/frame/frameHeader.js.map +1 -0
- package/dist/frame/frameHeader.test.d.ts +1 -0
- package/dist/frame/frameHeader.test.js +83 -0
- package/dist/frame/frameHeader.test.js.map +1 -0
- package/dist/frame/index.d.ts +4 -0
- package/dist/frame/index.js +4 -0
- package/dist/frame/index.js.map +1 -0
- package/dist/frame/skippable.d.ts +12 -0
- package/dist/frame/skippable.js +27 -0
- package/dist/frame/skippable.js.map +1 -0
- package/dist/frame/skippable.test.d.ts +1 -0
- package/dist/frame/skippable.test.js +35 -0
- package/dist/frame/skippable.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"littleEndian.test.js","sourceRoot":"","sources":["../../src/bitstream/littleEndian.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEpE,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC;IAC7B,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QACpD,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAAA,CACzC,CAAC,CAAC;IAEH,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAAA,CAC7C,CAAC,CAAC;IAEH,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAAA,CACtD,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAAA,CAC5C,CAAC,CAAC;AAAA,CACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable-length integer (varint) decode/encode per zstd format.
|
|
3
|
+
* 1-9 bytes, little-endian, 7 bits per byte, high bit = continue.
|
|
4
|
+
*/
|
|
5
|
+
export declare function decodeVarint(data: Uint8Array, offset: number): {
|
|
6
|
+
value: number;
|
|
7
|
+
bytesRead: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function encodeVarint(value: number): Uint8Array;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable-length integer (varint) decode/encode per zstd format.
|
|
3
|
+
* 1-9 bytes, little-endian, 7 bits per byte, high bit = continue.
|
|
4
|
+
*/
|
|
5
|
+
export function decodeVarint(data, offset) {
|
|
6
|
+
let value = 0;
|
|
7
|
+
let shift = 0;
|
|
8
|
+
let pos = offset;
|
|
9
|
+
for (let i = 0; i < 9; i++) {
|
|
10
|
+
if (pos >= data.length) {
|
|
11
|
+
throw new RangeError('decodeVarint: truncated input');
|
|
12
|
+
}
|
|
13
|
+
const byte = data[pos];
|
|
14
|
+
if (byte === undefined)
|
|
15
|
+
throw new RangeError('decodeVarint: truncated input');
|
|
16
|
+
pos++;
|
|
17
|
+
value |= (byte & 0x7f) << shift;
|
|
18
|
+
if ((byte & 0x80) === 0) {
|
|
19
|
+
return { value, bytesRead: pos - offset };
|
|
20
|
+
}
|
|
21
|
+
shift += 7;
|
|
22
|
+
if (shift >= 56) {
|
|
23
|
+
throw new RangeError('decodeVarint: value too large');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
throw new RangeError('decodeVarint: exceeds 9 bytes');
|
|
27
|
+
}
|
|
28
|
+
export function encodeVarint(value) {
|
|
29
|
+
const bytes = [];
|
|
30
|
+
let v = value >>> 0;
|
|
31
|
+
do {
|
|
32
|
+
let byte = v & 0x7f;
|
|
33
|
+
v >>>= 7;
|
|
34
|
+
if (v !== 0)
|
|
35
|
+
byte |= 0x80;
|
|
36
|
+
bytes.push(byte);
|
|
37
|
+
} while (v !== 0);
|
|
38
|
+
return new Uint8Array(bytes);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=varint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"varint.js","sourceRoot":"","sources":["../../src/bitstream/varint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,YAAY,CAAC,IAAgB,EAAE,MAAc,EAAwC;IACnG,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,MAAM,CAAC;IAEjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;QAC9E,GAAG,EAAE,CAAC;QACN,KAAK,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,GAAG,MAAM,EAAE,CAAC;QAC5C,CAAC;QACD,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;AAAA,CACvD;AAED,MAAM,UAAU,YAAY,CAAC,KAAa,EAAc;IACtD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC;IAEpB,GAAG,CAAC;QACF,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC;QACpB,CAAC,MAAM,CAAC,CAAC;QACT,IAAI,CAAC,KAAK,CAAC;YAAE,IAAI,IAAI,IAAI,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;IAElB,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;AAAA,CAC9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { decodeVarint, encodeVarint } from './varint.js';
|
|
3
|
+
describe('varint', () => {
|
|
4
|
+
it('encodes and decodes small values', () => {
|
|
5
|
+
for (const v of [0, 1, 127, 128, 255, 256, 16383]) {
|
|
6
|
+
const encoded = encodeVarint(v);
|
|
7
|
+
const { value, bytesRead } = decodeVarint(encoded, 0);
|
|
8
|
+
expect(value).toBe(v);
|
|
9
|
+
expect(bytesRead).toBe(encoded.length);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
it('decodes single-byte varint', () => {
|
|
13
|
+
const data = new Uint8Array([0x7f]); // 127, no continuation
|
|
14
|
+
const { value, bytesRead } = decodeVarint(data, 0);
|
|
15
|
+
expect(value).toBe(127);
|
|
16
|
+
expect(bytesRead).toBe(1);
|
|
17
|
+
});
|
|
18
|
+
it('decodes two-byte varint', () => {
|
|
19
|
+
const data = new Uint8Array([0x80, 0x01]); // 128 = 0x80 | 0x01<<7
|
|
20
|
+
const { value, bytesRead } = decodeVarint(data, 0);
|
|
21
|
+
expect(value).toBe(128);
|
|
22
|
+
expect(bytesRead).toBe(2);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=varint.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"varint.test.js","sourceRoot":"","sources":["../../src/bitstream/varint.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEzD,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC;IACvB,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;IAAA,CACF,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,uBAAuB;QAC5D,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CAC3B,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,uBAAuB;QAClE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CAC3B,CAAC,CAAC;AAAA,CACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compress input data using zstd.
|
|
3
|
+
* Level 0: raw blocks only (no compression, fast).
|
|
4
|
+
*/
|
|
5
|
+
export type CompressOptions = {
|
|
6
|
+
level?: number;
|
|
7
|
+
checksum?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function compress(input: Uint8Array, options?: CompressOptions): Uint8Array;
|
package/dist/compress.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compress input data using zstd.
|
|
3
|
+
* Level 0: raw blocks only (no compression, fast).
|
|
4
|
+
*/
|
|
5
|
+
import { writeRawBlock, writeRLEBlock } from './encode/blockWriter.js';
|
|
6
|
+
import { buildCompressedBlockPayload, writeCompressedBlock } from './encode/compressedBlock.js';
|
|
7
|
+
import { writeFrameHeader } from './encode/frameWriter.js';
|
|
8
|
+
import { buildGreedySequences } from './encode/greedySequences.js';
|
|
9
|
+
import { computeContentChecksum32 } from './frame/checksum.js';
|
|
10
|
+
const BLOCK_MAX = 128 * 1024;
|
|
11
|
+
export function compress(input, options) {
|
|
12
|
+
const level = options?.level ?? 0;
|
|
13
|
+
const hasChecksum = options?.checksum ?? false;
|
|
14
|
+
const chunks = [];
|
|
15
|
+
chunks.push(writeFrameHeader(input.length, hasChecksum));
|
|
16
|
+
let offset = 0;
|
|
17
|
+
const blockCount = input.length === 0 ? 1 : Math.ceil(input.length / BLOCK_MAX);
|
|
18
|
+
let blockIndex = 0;
|
|
19
|
+
while (offset < input.length || blockIndex < blockCount) {
|
|
20
|
+
const size = Math.min(BLOCK_MAX, input.length - offset);
|
|
21
|
+
const last = blockIndex === blockCount - 1;
|
|
22
|
+
const block = input.subarray(offset, offset + size);
|
|
23
|
+
if (level > 0 && size > 0) {
|
|
24
|
+
if (level > 1) {
|
|
25
|
+
const plan = buildGreedySequences(block);
|
|
26
|
+
if (plan.sequences.length > 0) {
|
|
27
|
+
const payload = buildCompressedBlockPayload(plan.literals, plan.sequences);
|
|
28
|
+
if (payload) {
|
|
29
|
+
const compressed = writeCompressedBlock(payload, last);
|
|
30
|
+
const raw = writeRawBlock(input, offset, size, last);
|
|
31
|
+
if (compressed.length < raw.length) {
|
|
32
|
+
chunks.push(compressed);
|
|
33
|
+
offset += size;
|
|
34
|
+
blockIndex++;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const first = input[offset] ?? 0;
|
|
41
|
+
let isRLE = true;
|
|
42
|
+
for (let i = offset + 1; i < offset + size; i++) {
|
|
43
|
+
if ((input[i] ?? 0) !== first) {
|
|
44
|
+
isRLE = false;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (isRLE) {
|
|
49
|
+
chunks.push(writeRLEBlock(first, size, last));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
chunks.push(writeRawBlock(input, offset, size, last));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
chunks.push(writeRawBlock(input, offset, size, last));
|
|
57
|
+
}
|
|
58
|
+
offset += size;
|
|
59
|
+
blockIndex++;
|
|
60
|
+
}
|
|
61
|
+
if (hasChecksum) {
|
|
62
|
+
const checksum = computeContentChecksum32(input);
|
|
63
|
+
chunks.push(new Uint8Array([checksum & 0xff, (checksum >>> 8) & 0xff, (checksum >>> 16) & 0xff, (checksum >>> 24) & 0xff]));
|
|
64
|
+
}
|
|
65
|
+
const total = chunks.reduce((s, c) => s + c.length, 0);
|
|
66
|
+
const result = new Uint8Array(total);
|
|
67
|
+
let pos = 0;
|
|
68
|
+
for (const chunk of chunks) {
|
|
69
|
+
result.set(chunk, pos);
|
|
70
|
+
pos += chunk.length;
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=compress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block header parsing and block type dispatch.
|
|
3
|
+
*/
|
|
4
|
+
export declare const BLOCK_HEADER_SIZE = 3;
|
|
5
|
+
export type BlockType = 0 | 1 | 2 | 3;
|
|
6
|
+
export interface BlockHeader {
|
|
7
|
+
lastBlock: boolean;
|
|
8
|
+
blockType: BlockType;
|
|
9
|
+
blockSize: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseBlockHeader(data: Uint8Array, offset: number): BlockHeader;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block header parsing and block type dispatch.
|
|
3
|
+
*/
|
|
4
|
+
import { ZstdError } from '../errors.js';
|
|
5
|
+
export const BLOCK_HEADER_SIZE = 3;
|
|
6
|
+
function readU24LE(data, offset) {
|
|
7
|
+
if (offset + 3 > data.length) {
|
|
8
|
+
throw new RangeError(`readU24LE: offset ${offset} + 3 exceeds length ${data.length}`);
|
|
9
|
+
}
|
|
10
|
+
const a = data[offset] ?? 0;
|
|
11
|
+
const b = data[offset + 1] ?? 0;
|
|
12
|
+
const c = data[offset + 2] ?? 0;
|
|
13
|
+
return a | (b << 8) | (c << 16);
|
|
14
|
+
}
|
|
15
|
+
export function parseBlockHeader(data, offset) {
|
|
16
|
+
if (offset + BLOCK_HEADER_SIZE > data.length) {
|
|
17
|
+
throw new ZstdError('Block header truncated', 'corruption_detected');
|
|
18
|
+
}
|
|
19
|
+
const w = readU24LE(data, offset);
|
|
20
|
+
const lastBlock = (w & 1) === 1;
|
|
21
|
+
const blockType = ((w >> 1) & 3);
|
|
22
|
+
const blockSize = w >> 3;
|
|
23
|
+
if (blockType === 3) {
|
|
24
|
+
throw new ZstdError('Reserved block type', 'corruption_detected');
|
|
25
|
+
}
|
|
26
|
+
return { lastBlock, blockType, blockSize };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=block.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/decode/block.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAUnC,SAAS,SAAS,CAAC,IAAgB,EAAE,MAAc,EAAU;IAC3D,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,IAAI,UAAU,CAAC,qBAAqB,MAAM,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,CACjC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAgB,EAAE,MAAc,EAAe;IAC9E,IAAI,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7C,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,qBAAqB,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAc,CAAC;IAC9C,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,CAAC;IAEzB,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,SAAS,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAAA,CAC5C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { parseBlockHeader } from './block.js';
|
|
3
|
+
describe('block', () => {
|
|
4
|
+
it('parses raw block header (last=1, type=0, size=5)', () => {
|
|
5
|
+
// last=1, type=0, size=5 -> (5<<3)|0<<1|1 = 41
|
|
6
|
+
const data = new Uint8Array([0x29, 0x00, 0x00]);
|
|
7
|
+
const block = parseBlockHeader(data, 0);
|
|
8
|
+
expect(block.lastBlock).toBe(true);
|
|
9
|
+
expect(block.blockType).toBe(0);
|
|
10
|
+
expect(block.blockSize).toBe(5);
|
|
11
|
+
});
|
|
12
|
+
it('throws on reserved block type 3', () => {
|
|
13
|
+
// last=0, type=3, size=0
|
|
14
|
+
const data = new Uint8Array([0x06, 0x00, 0x00]);
|
|
15
|
+
expect(() => parseBlockHeader(data, 0)).toThrow(/Reserved block type|corruption/i);
|
|
16
|
+
});
|
|
17
|
+
it('throws when block header is truncated', () => {
|
|
18
|
+
const data = new Uint8Array([0x28, 0xb5]);
|
|
19
|
+
expect(() => parseBlockHeader(data, 0)).toThrow(/Block header truncated|corruption/i);
|
|
20
|
+
});
|
|
21
|
+
it('throws when offset + 3 exceeds data length', () => {
|
|
22
|
+
const data = new Uint8Array([0x29, 0x00]);
|
|
23
|
+
expect(() => parseBlockHeader(data, 0)).toThrow(/truncated|corruption/i);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=block.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block.test.js","sourceRoot":"","sources":["../../src/decode/block.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;IACtB,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE,CAAC;QAC3D,+CAA+C;QAC/C,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAA,CACjC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC;QAC1C,yBAAyB;QACzB,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;IAAA,CACpF,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;IAAA,CACvF,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAAA,CAC1E,CAAC,CAAC;AAAA,CACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decompress a single zstd frame.
|
|
3
|
+
*/
|
|
4
|
+
import type { DecoderDictionaryContext } from '../dictionary/decoderDictionary.js';
|
|
5
|
+
import type { FrameHeader } from '../frame/frameHeader.js';
|
|
6
|
+
export declare function decompressFrame(data: Uint8Array, offset: number, header: FrameHeader, dictionary?: DecoderDictionaryContext | null, maxSize?: number): {
|
|
7
|
+
output: Uint8Array;
|
|
8
|
+
bytesConsumed: number;
|
|
9
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decompress a single zstd frame.
|
|
3
|
+
*/
|
|
4
|
+
import { readU32LE } from '../bitstream/littleEndian.js';
|
|
5
|
+
import { ZstdError } from '../errors.js';
|
|
6
|
+
import { validateContentChecksum } from '../frame/checksum.js';
|
|
7
|
+
import { parseBlockHeader } from './block.js';
|
|
8
|
+
import { decodeCompressedLiterals, decodeRawLiterals, decodeRLELiterals, decodeTreelessLiterals, parseLiteralsSectionHeader, } from './literals.js';
|
|
9
|
+
import { executeSequences } from './reconstruct.js';
|
|
10
|
+
import { decodeSequences } from './sequences.js';
|
|
11
|
+
export function decompressFrame(data, offset, header, dictionary, maxSize) {
|
|
12
|
+
let pos = offset + 4 + header.headerSize;
|
|
13
|
+
const chunks = [];
|
|
14
|
+
let totalSize = 0;
|
|
15
|
+
const repOffsets = dictionary?.repOffsets
|
|
16
|
+
? [dictionary.repOffsets[0], dictionary.repOffsets[1], dictionary.repOffsets[2]]
|
|
17
|
+
: [1, 4, 8];
|
|
18
|
+
let history = new Uint8Array(0);
|
|
19
|
+
if (dictionary?.historyPrefix && dictionary.historyPrefix.length > 0) {
|
|
20
|
+
history = dictionary.historyPrefix.slice();
|
|
21
|
+
}
|
|
22
|
+
let prevHuffmanTable = dictionary?.huffmanTable ?? null;
|
|
23
|
+
let prevSeqTables = dictionary?.sequenceTables ?? null;
|
|
24
|
+
while (true) {
|
|
25
|
+
if (pos + 3 > data.length) {
|
|
26
|
+
throw new ZstdError('Block header truncated', 'corruption_detected');
|
|
27
|
+
}
|
|
28
|
+
const block = parseBlockHeader(data, pos);
|
|
29
|
+
pos += 3;
|
|
30
|
+
if (block.blockType === 0) {
|
|
31
|
+
const literals = decodeRawLiterals(data, pos, block.blockSize);
|
|
32
|
+
chunks.push(literals);
|
|
33
|
+
totalSize += literals.length;
|
|
34
|
+
history = appendToHistory(history, literals, header.windowSize);
|
|
35
|
+
pos += block.blockSize;
|
|
36
|
+
}
|
|
37
|
+
else if (block.blockType === 1) {
|
|
38
|
+
const literals = decodeRLELiterals(data, pos, block.blockSize);
|
|
39
|
+
chunks.push(literals);
|
|
40
|
+
totalSize += literals.length;
|
|
41
|
+
history = appendToHistory(history, literals, header.windowSize);
|
|
42
|
+
pos += 1;
|
|
43
|
+
}
|
|
44
|
+
else if (block.blockType === 2) {
|
|
45
|
+
const blockContent = data.subarray(pos, pos + block.blockSize);
|
|
46
|
+
const { header: litHeader, dataOffset: litDataOffset } = parseLiteralsSectionHeader(blockContent, 0);
|
|
47
|
+
let literals;
|
|
48
|
+
let litBytesConsumed;
|
|
49
|
+
if (litHeader.blockType === 0) {
|
|
50
|
+
literals = decodeRawLiterals(blockContent, litDataOffset, litHeader.regeneratedSize);
|
|
51
|
+
litBytesConsumed = litHeader.headerSize + litHeader.regeneratedSize;
|
|
52
|
+
}
|
|
53
|
+
else if (litHeader.blockType === 1) {
|
|
54
|
+
literals = decodeRLELiterals(blockContent, litDataOffset, litHeader.regeneratedSize);
|
|
55
|
+
litBytesConsumed = litHeader.headerSize + 1;
|
|
56
|
+
}
|
|
57
|
+
else if (litHeader.blockType === 2) {
|
|
58
|
+
const comp = decodeCompressedLiterals(blockContent, litDataOffset, litHeader.compressedSize, litHeader.regeneratedSize, litHeader.numStreams);
|
|
59
|
+
literals = comp.literals;
|
|
60
|
+
prevHuffmanTable = comp.huffmanTable;
|
|
61
|
+
litBytesConsumed = litHeader.headerSize + comp.bytesRead;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (!prevHuffmanTable) {
|
|
65
|
+
throw new ZstdError('Treeless literals without previous Huffman table', 'corruption_detected');
|
|
66
|
+
}
|
|
67
|
+
const comp = decodeTreelessLiterals(blockContent, litDataOffset, litHeader.compressedSize, litHeader.regeneratedSize, litHeader.numStreams, prevHuffmanTable);
|
|
68
|
+
literals = comp.literals;
|
|
69
|
+
litBytesConsumed = litHeader.headerSize + comp.bytesRead;
|
|
70
|
+
}
|
|
71
|
+
const seqSectionSize = block.blockSize - litBytesConsumed;
|
|
72
|
+
let output;
|
|
73
|
+
if (seqSectionSize <= 0) {
|
|
74
|
+
output = literals;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const seqResult = decodeSequences(blockContent, litBytesConsumed, seqSectionSize, prevSeqTables);
|
|
78
|
+
prevSeqTables = seqResult.tables;
|
|
79
|
+
if (seqResult.sequences.length === 0) {
|
|
80
|
+
output = literals;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
output = executeSequences(literals, seqResult.sequences, header.windowSize, repOffsets, history);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
chunks.push(output);
|
|
87
|
+
totalSize += output.length;
|
|
88
|
+
history = appendToHistory(history, output, header.windowSize);
|
|
89
|
+
pos += block.blockSize;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
throw new ZstdError('Unsupported block type', 'corruption_detected');
|
|
93
|
+
}
|
|
94
|
+
if (maxSize !== undefined && totalSize > maxSize) {
|
|
95
|
+
throw new ZstdError('Decompressed size exceeds maxSize', 'parameter_unsupported');
|
|
96
|
+
}
|
|
97
|
+
if (block.lastBlock)
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
const output = concatenateChunks(chunks);
|
|
101
|
+
if (header.contentSize !== null && output.length !== header.contentSize) {
|
|
102
|
+
throw new ZstdError('Frame content size mismatch', 'corruption_detected');
|
|
103
|
+
}
|
|
104
|
+
if (header.hasContentChecksum) {
|
|
105
|
+
if (pos + 4 > data.length) {
|
|
106
|
+
throw new ZstdError('Content checksum truncated', 'corruption_detected');
|
|
107
|
+
}
|
|
108
|
+
const storedChecksum = readU32LE(data, pos);
|
|
109
|
+
if (!validateContentChecksum(output, storedChecksum)) {
|
|
110
|
+
throw new ZstdError('Content checksum mismatch', 'corruption_detected');
|
|
111
|
+
}
|
|
112
|
+
pos += 4;
|
|
113
|
+
return { output, bytesConsumed: pos - offset };
|
|
114
|
+
}
|
|
115
|
+
return { output, bytesConsumed: pos - offset };
|
|
116
|
+
}
|
|
117
|
+
function appendToHistory(history, chunk, windowSize) {
|
|
118
|
+
if (windowSize <= 0 || chunk.length === 0) {
|
|
119
|
+
return history;
|
|
120
|
+
}
|
|
121
|
+
const maxHistory = Math.max(1, windowSize);
|
|
122
|
+
if (chunk.length >= maxHistory) {
|
|
123
|
+
return new Uint8Array(chunk.subarray(chunk.length - maxHistory));
|
|
124
|
+
}
|
|
125
|
+
const keepFromHistory = Math.min(history.length, maxHistory - chunk.length);
|
|
126
|
+
const next = new Uint8Array(keepFromHistory + chunk.length);
|
|
127
|
+
if (keepFromHistory > 0) {
|
|
128
|
+
next.set(history.subarray(history.length - keepFromHistory), 0);
|
|
129
|
+
}
|
|
130
|
+
next.set(chunk, keepFromHistory);
|
|
131
|
+
return next;
|
|
132
|
+
}
|
|
133
|
+
function concatenateChunks(chunks) {
|
|
134
|
+
if (chunks.length === 0)
|
|
135
|
+
return new Uint8Array(0);
|
|
136
|
+
if (chunks.length === 1)
|
|
137
|
+
return chunks[0];
|
|
138
|
+
const total = chunks.reduce((s, c) => s + c.length, 0);
|
|
139
|
+
const result = new Uint8Array(total);
|
|
140
|
+
let pos = 0;
|
|
141
|
+
for (const chunk of chunks) {
|
|
142
|
+
result.set(chunk, pos);
|
|
143
|
+
pos += chunk.length;
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=decompressFrame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decompressFrame.js","sourceRoot":"","sources":["../../src/decode/decompressFrame.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { decodeCompressedLiterals, decodeRawLiterals, decodeRLELiterals, decodeTreelessLiterals, parseLiteralsSectionHeader, } from './literals.js';
|
|
3
|
+
describe('literals corruption handling', () => {
|
|
4
|
+
it('rejects truncated literals section header', () => {
|
|
5
|
+
const data = new Uint8Array([0x24]); // compressed literals sizeFormat=1 requires 3-byte header
|
|
6
|
+
expect(() => parseLiteralsSectionHeader(data, 0)).toThrowError(/header truncated/i);
|
|
7
|
+
});
|
|
8
|
+
it('rejects raw literals overrun', () => {
|
|
9
|
+
const data = new Uint8Array([0x61, 0x62]);
|
|
10
|
+
expect(() => decodeRawLiterals(data, 0, 3)).toThrowError(/Raw literals truncated/i);
|
|
11
|
+
});
|
|
12
|
+
it('rejects rle literals when source byte is missing', () => {
|
|
13
|
+
const data = new Uint8Array([]);
|
|
14
|
+
expect(() => decodeRLELiterals(data, 0, 10)).toThrowError(/RLE literals truncated/i);
|
|
15
|
+
});
|
|
16
|
+
it('rejects invalid compressed literals size', () => {
|
|
17
|
+
const data = new Uint8Array([0x80]); // direct weights header with 1 weight; no stream payload
|
|
18
|
+
expect(() => decodeCompressedLiterals(data, 0, 1, 16, 1)).toThrowError(/truncated|Invalid literals compressed size/i);
|
|
19
|
+
});
|
|
20
|
+
it('rejects treeless 4-stream with compressedSize < 10', () => {
|
|
21
|
+
const table = decodeCompressedLiterals(new Uint8Array([129, 0x10, 0x02]), 0, 3, 1, 1).huffmanTable;
|
|
22
|
+
const data = new Uint8Array(9);
|
|
23
|
+
expect(() => decodeTreelessLiterals(data, 0, 9, 100, 4, table)).toThrowError(/4-stream mode requires at least 10 bytes/i);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=literals.corruption.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"literals.corruption.test.js","sourceRoot":"","sources":["../../src/decode/literals.corruption.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AAEvB,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE,CAAC;IAC7C,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,0DAA0D;QAC/F,MAAM,CAAC,GAAG,EAAE,CAAC,0BAA0B,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;IAAA,CACrF,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAC;IAAA,CACrF,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAC;IAAA,CACtF,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,yDAAyD;QAC9F,MAAM,CAAC,GAAG,EAAE,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CACpE,6CAA6C,CAC9C,CAAC;IAAA,CACH,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;QACnG,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY,CAC1E,2CAA2C,CAC5C,CAAC;IAAA,CACH,CAAC,CAAC;AAAA,CACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode literals section: Raw, RLE, Compressed, Treeless.
|
|
3
|
+
*/
|
|
4
|
+
import { buildHuffmanDecodeTable } from '../entropy/huffman.js';
|
|
5
|
+
export type LiteralsBlockType = 0 | 1 | 2 | 3;
|
|
6
|
+
export interface LiteralsSectionHeader {
|
|
7
|
+
blockType: LiteralsBlockType;
|
|
8
|
+
regeneratedSize: number;
|
|
9
|
+
compressedSize?: number;
|
|
10
|
+
numStreams: 1 | 4;
|
|
11
|
+
headerSize: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parse Literals_Section_Header from compressed block.
|
|
15
|
+
* Returns header info and the byte offset after the header.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseLiteralsSectionHeader(data: Uint8Array, offset: number): {
|
|
18
|
+
header: LiteralsSectionHeader;
|
|
19
|
+
dataOffset: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Decode raw literals block - direct copy.
|
|
23
|
+
*/
|
|
24
|
+
export declare function decodeRawLiterals(data: Uint8Array, offset: number, size: number): Uint8Array;
|
|
25
|
+
/**
|
|
26
|
+
* Decode RLE literals block - single byte repeated.
|
|
27
|
+
*/
|
|
28
|
+
export declare function decodeRLELiterals(data: Uint8Array, offset: number, size: number): Uint8Array;
|
|
29
|
+
/**
|
|
30
|
+
* Decode compressed literals (Huffman). Requires Huffman table from tree description.
|
|
31
|
+
*/
|
|
32
|
+
export declare function decodeCompressedLiterals(data: Uint8Array, offset: number, compressedSize: number, regeneratedSize: number, numStreams: 1 | 4): {
|
|
33
|
+
literals: Uint8Array;
|
|
34
|
+
huffmanTable: {
|
|
35
|
+
table: ReturnType<typeof buildHuffmanDecodeTable>;
|
|
36
|
+
maxNumBits: number;
|
|
37
|
+
};
|
|
38
|
+
bytesRead: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Decode treeless literals (reuse previous Huffman table).
|
|
42
|
+
*/
|
|
43
|
+
export declare function decodeTreelessLiterals(data: Uint8Array, offset: number, compressedSize: number, regeneratedSize: number, numStreams: 1 | 4, huffmanTable: {
|
|
44
|
+
table: ReturnType<typeof buildHuffmanDecodeTable>;
|
|
45
|
+
maxNumBits: number;
|
|
46
|
+
}): {
|
|
47
|
+
literals: Uint8Array;
|
|
48
|
+
bytesRead: number;
|
|
49
|
+
};
|