Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/module/zstd/lib/common/huf.h
48774 views
1
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only
2
/* ******************************************************************
3
* huff0 huffman codec,
4
* part of Finite State Entropy library
5
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
6
*
7
* You can contact the author at :
8
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
9
*
10
* This source code is licensed under both the BSD-style license (found in the
11
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
12
* in the COPYING file in the root directory of this source tree).
13
* You may select, at your option, one of the above-listed licenses.
14
****************************************************************** */
15
16
#if defined (__cplusplus)
17
extern "C" {
18
#endif
19
20
#ifndef HUF_H_298734234
21
#define HUF_H_298734234
22
23
/* *** Dependencies *** */
24
#include <stddef.h> /* size_t */
25
26
27
/* *** library symbols visibility *** */
28
/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual,
29
* HUF symbols remain "private" (internal symbols for library only).
30
* Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */
31
#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)
32
# define HUF_PUBLIC_API __attribute__ ((visibility ("default")))
33
#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */
34
# define HUF_PUBLIC_API __declspec(dllexport)
35
#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)
36
# define HUF_PUBLIC_API __declspec(dllimport) /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */
37
#else
38
# define HUF_PUBLIC_API
39
#endif
40
41
42
/* ========================== */
43
/* *** simple functions *** */
44
/* ========================== */
45
46
/** HUF_compress() :
47
* Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'.
48
* 'dst' buffer must be already allocated.
49
* Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize).
50
* `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB.
51
* @return : size of compressed data (<= `dstCapacity`).
52
* Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
53
* if HUF_isError(return), compression failed (more details using HUF_getErrorName())
54
*/
55
HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity,
56
const void* src, size_t srcSize);
57
58
/** HUF_decompress() :
59
* Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
60
* into already allocated buffer 'dst', of minimum size 'dstSize'.
61
* `originalSize` : **must** be the ***exact*** size of original (uncompressed) data.
62
* Note : in contrast with FSE, HUF_decompress can regenerate
63
* RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
64
* because it knows size to regenerate (originalSize).
65
* @return : size of regenerated data (== originalSize),
66
* or an error code, which can be tested using HUF_isError()
67
*/
68
HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize,
69
const void* cSrc, size_t cSrcSize);
70
71
72
/* *** Tool functions *** */
73
#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */
74
HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
75
76
/* Error Management */
77
HUF_PUBLIC_API unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */
78
HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */
79
80
81
/* *** Advanced function *** */
82
83
/** HUF_compress2() :
84
* Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`.
85
* `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX .
86
* `tableLog` must be `<= HUF_TABLELOG_MAX` . */
87
HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity,
88
const void* src, size_t srcSize,
89
unsigned maxSymbolValue, unsigned tableLog);
90
91
/** HUF_compress4X_wksp() :
92
* Same as HUF_compress2(), but uses externally allocated `workSpace`.
93
* `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */
94
#define HUF_WORKSPACE_SIZE ((6 << 10) + 256)
95
#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
96
HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
97
const void* src, size_t srcSize,
98
unsigned maxSymbolValue, unsigned tableLog,
99
void* workSpace, size_t wkspSize);
100
101
#endif /* HUF_H_298734234 */
102
103
/* ******************************************************************
104
* WARNING !!
105
* The following section contains advanced and experimental definitions
106
* which shall never be used in the context of a dynamic library,
107
* because they are not guaranteed to remain stable in the future.
108
* Only consider them in association with static linking.
109
* *****************************************************************/
110
#if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY)
111
#define HUF_H_HUF_STATIC_LINKING_ONLY
112
113
/* *** Dependencies *** */
114
#include "mem.h" /* U32 */
115
116
117
/* *** Constants *** */
118
#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
119
#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */
120
#define HUF_SYMBOLVALUE_MAX 255
121
122
#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
123
#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
124
# error "HUF_TABLELOG_MAX is too large !"
125
#endif
126
127
128
/* ****************************************
129
* Static allocation
130
******************************************/
131
/* HUF buffer bounds */
132
#define HUF_CTABLEBOUND 129
133
#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */
134
#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
135
136
/* static allocation of HUF's Compression Table */
137
#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */
138
#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32))
139
#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
140
U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \
141
void* name##hv = &(name##hb); \
142
HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */
143
144
/* static allocation of HUF's DTable */
145
typedef U32 HUF_DTable;
146
#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog)))
147
#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \
148
HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }
149
#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
150
HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
151
152
153
/* ****************************************
154
* Advanced decompression functions
155
******************************************/
156
size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
157
#ifndef HUF_FORCE_DECOMPRESS_X1
158
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
159
#endif
160
161
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */
162
size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
163
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */
164
size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
165
size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */
166
#ifndef HUF_FORCE_DECOMPRESS_X1
167
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
168
size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */
169
#endif
170
171
172
/* ****************************************
173
* HUF detailed API
174
* ****************************************/
175
176
/*! HUF_compress() does the following:
177
* 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h")
178
* 2. (optional) refine tableLog using HUF_optimalTableLog()
179
* 3. build Huffman table from count using HUF_buildCTable()
180
* 4. save Huffman table to memory buffer using HUF_writeCTable()
181
* 5. encode the data stream using HUF_compress4X_usingCTable()
182
*
183
* The following API allows targeting specific sub-functions for advanced tasks.
184
* For example, it's possible to compress several blocks using the same 'CTable',
185
* or to save and regenerate 'CTable' using external methods.
186
*/
187
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
188
typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
189
size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */
190
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
191
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
192
size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
193
int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
194
195
typedef enum {
196
HUF_repeat_none, /**< Cannot use the previous table */
197
HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */
198
HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */
199
} HUF_repeat;
200
/** HUF_compress4X_repeat() :
201
* Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
202
* If it uses hufTable it does not modify hufTable or repeat.
203
* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
204
* If preferRepeat then the old table will always be used if valid. */
205
size_t HUF_compress4X_repeat(void* dst, size_t dstSize,
206
const void* src, size_t srcSize,
207
unsigned maxSymbolValue, unsigned tableLog,
208
void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
209
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2);
210
211
/** HUF_buildCTable_wksp() :
212
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
213
* `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE.
214
*/
215
#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1)
216
#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned))
217
size_t HUF_buildCTable_wksp (HUF_CElt* tree,
218
const unsigned* count, U32 maxSymbolValue, U32 maxNbBits,
219
void* workSpace, size_t wkspSize);
220
221
/*! HUF_readStats() :
222
* Read compact Huffman tree, saved by HUF_writeCTable().
223
* `huffWeight` is destination buffer.
224
* @return : size read from `src` , or an error Code .
225
* Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */
226
size_t HUF_readStats(BYTE* huffWeight, size_t hwSize,
227
U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
228
const void* src, size_t srcSize);
229
230
/** HUF_readCTable() :
231
* Loading a CTable saved with HUF_writeCTable() */
232
size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights);
233
234
/** HUF_getNbBits() :
235
* Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX
236
* Note 1 : is not inlined, as HUF_CElt definition is private
237
* Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */
238
U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue);
239
240
/*
241
* HUF_decompress() does the following:
242
* 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics
243
* 2. build Huffman table from save, using HUF_readDTableX?()
244
* 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable()
245
*/
246
247
/** HUF_selectDecoder() :
248
* Tells which decoder is likely to decode faster,
249
* based on a set of pre-computed metrics.
250
* @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .
251
* Assumption : 0 < dstSize <= 128 KB */
252
U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
253
254
/**
255
* The minimum workspace size for the `workSpace` used in
256
* HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp().
257
*
258
* The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when
259
* HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15.
260
* Buffer overflow errors may potentially occur if code modifications result in
261
* a required workspace size greater than that specified in the following
262
* macro.
263
*/
264
#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10)
265
#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32))
266
267
#ifndef HUF_FORCE_DECOMPRESS_X2
268
size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize);
269
size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize);
270
#endif
271
#ifndef HUF_FORCE_DECOMPRESS_X1
272
size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);
273
size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize);
274
#endif
275
276
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
277
#ifndef HUF_FORCE_DECOMPRESS_X2
278
size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
279
#endif
280
#ifndef HUF_FORCE_DECOMPRESS_X1
281
size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
282
#endif
283
284
285
/* ====================== */
286
/* single stream variants */
287
/* ====================== */
288
289
size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
290
size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
291
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
292
/** HUF_compress1X_repeat() :
293
* Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
294
* If it uses hufTable it does not modify hufTable or repeat.
295
* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
296
* If preferRepeat then the old table will always be used if valid. */
297
size_t HUF_compress1X_repeat(void* dst, size_t dstSize,
298
const void* src, size_t srcSize,
299
unsigned maxSymbolValue, unsigned tableLog,
300
void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
301
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2);
302
303
size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
304
#ifndef HUF_FORCE_DECOMPRESS_X1
305
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
306
#endif
307
308
size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
309
size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);
310
#ifndef HUF_FORCE_DECOMPRESS_X2
311
size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
312
size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */
313
#endif
314
#ifndef HUF_FORCE_DECOMPRESS_X1
315
size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
316
size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */
317
#endif
318
319
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */
320
#ifndef HUF_FORCE_DECOMPRESS_X2
321
size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
322
#endif
323
#ifndef HUF_FORCE_DECOMPRESS_X1
324
size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
325
#endif
326
327
/* BMI2 variants.
328
* If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.
329
*/
330
size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
331
#ifndef HUF_FORCE_DECOMPRESS_X2
332
size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
333
#endif
334
size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
335
size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
336
337
#endif /* HUF_STATIC_LINKING_ONLY */
338
339
#if defined (__cplusplus)
340
}
341
#endif
342
343