1
// Copyright 2019+ Klaus Post. All rights reserved.
2
// License information can be found in the LICENSE file.
3
// Based on work by Yann Collet, released under BSD License.
14
// fsePredef are the predefined fse tables as defined here:
15
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#default-distributions
16
// These values are already transformed.
17
fsePredef [3]fseDecoder
19
// fsePredefEnc are the predefined encoder based on fse tables as defined here:
20
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#default-distributions
21
// These values are already transformed.
22
fsePredefEnc [3]fseEncoder
24
// symbolTableX contain the transformations needed for each type as defined in
25
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#the-codes-for-literals-lengths-match-lengths-and-offsets
26
symbolTableX [3][]baseOffset
28
// maxTableSymbol is the biggest supported symbol for each table type
29
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#the-codes-for-literals-lengths-match-lengths-and-offsets
30
maxTableSymbol = [3]uint8{tableLiteralLengths: maxLiteralLengthSymbol, tableOffsets: maxOffsetLengthSymbol, tableMatchLengths: maxMatchLengthSymbol}
32
// bitTables is the bits table for each table.
33
bitTables = [3][]byte{tableLiteralLengths: llBitsTable[:], tableOffsets: nil, tableMatchLengths: mlBitsTable[:]}
39
// indexes for fsePredef and symbolTableX
40
tableLiteralLengths tableIndex = 0
41
tableOffsets tableIndex = 1
42
tableMatchLengths tableIndex = 2
44
maxLiteralLengthSymbol = 35
45
maxOffsetLengthSymbol = 30
46
maxMatchLengthSymbol = 52
49
// baseOffset is used for calculating transformations.
50
type baseOffset struct {
55
// fillBase will precalculate base offsets with the given bit distributions.
56
func fillBase(dst []baseOffset, base uint32, bits ...uint8) {
57
if len(bits) != len(dst) {
58
panic(fmt.Sprintf("len(dst) (%d) != len(bits) (%d)", len(dst), len(bits)))
60
for i, bit := range bits {
61
if base > math.MaxInt32 {
62
panic("invalid decoding table, base overflows int32")
75
func initPredefined() {
77
// Literals length codes
78
tmp := make([]baseOffset, 36)
79
for i := range tmp[:16] {
85
fillBase(tmp[16:], 16, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
86
symbolTableX[tableLiteralLengths] = tmp
89
tmp = make([]baseOffset, 53)
90
for i := range tmp[:32] {
92
// The transformation adds the 3 length.
93
baseLine: uint32(i) + 3,
97
fillBase(tmp[32:], 35, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
98
symbolTableX[tableMatchLengths] = tmp
101
tmp = make([]baseOffset, maxOffsetBits+1)
106
fillBase(tmp[2:], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30)
107
symbolTableX[tableOffsets] = tmp
109
// Fill predefined tables and transform them.
110
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#default-distributions
111
for i := range fsePredef[:] {
113
switch tableIndex(i) {
114
case tableLiteralLengths:
115
// https://github.com/facebook/zstd/blob/ededcfca57366461021c922720878c81a5854a0a/lib/decompress/zstd_decompress_block.c#L243
117
copy(f.norm[:], []int16{4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
118
2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
122
// https://github.com/facebook/zstd/blob/ededcfca57366461021c922720878c81a5854a0a/lib/decompress/zstd_decompress_block.c#L281
124
copy(f.norm[:], []int16{
125
1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
126
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1})
128
case tableMatchLengths:
129
//https://github.com/facebook/zstd/blob/ededcfca57366461021c922720878c81a5854a0a/lib/decompress/zstd_decompress_block.c#L304
131
copy(f.norm[:], []int16{
132
1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
133
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
134
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1,
138
if err := f.buildDtable(); err != nil {
139
panic(fmt.Errorf("building table %v: %v", tableIndex(i), err))
141
if err := f.transform(symbolTableX[i]); err != nil {
142
panic(fmt.Errorf("building table %v: %v", tableIndex(i), err))
146
// Create encoder as well
147
enc := &fsePredefEnc[i]
148
copy(enc.norm[:], f.norm[:])
149
enc.symbolLen = f.symbolLen
150
enc.actualTableLog = f.actualTableLog
151
if err := enc.buildCTable(); err != nil {
152
panic(fmt.Errorf("building encoding table %v: %v", tableIndex(i), err))
154
enc.setBits(bitTables[i])
155
enc.preDefined = true