zstd-ruby 1.4.1.0 → 1.5.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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/ruby.yml +35 -0
- data/README.md +2 -2
- data/ext/zstdruby/libzstd/BUCK +5 -7
- data/ext/zstdruby/libzstd/Makefile +304 -113
- data/ext/zstdruby/libzstd/README.md +83 -20
- data/ext/zstdruby/libzstd/common/bitstream.h +59 -51
- data/ext/zstdruby/libzstd/common/compiler.h +150 -8
- data/ext/zstdruby/libzstd/common/cpu.h +1 -3
- data/ext/zstdruby/libzstd/common/debug.c +11 -31
- data/ext/zstdruby/libzstd/common/debug.h +22 -49
- data/ext/zstdruby/libzstd/common/entropy_common.c +201 -75
- data/ext/zstdruby/libzstd/common/error_private.c +3 -1
- data/ext/zstdruby/libzstd/common/error_private.h +8 -4
- data/ext/zstdruby/libzstd/common/fse.h +50 -42
- data/ext/zstdruby/libzstd/common/fse_decompress.c +149 -55
- data/ext/zstdruby/libzstd/common/huf.h +43 -39
- data/ext/zstdruby/libzstd/common/mem.h +69 -25
- data/ext/zstdruby/libzstd/common/pool.c +30 -20
- data/ext/zstdruby/libzstd/common/pool.h +3 -3
- data/ext/zstdruby/libzstd/common/threading.c +51 -4
- data/ext/zstdruby/libzstd/common/threading.h +36 -4
- data/ext/zstdruby/libzstd/common/xxhash.c +40 -92
- data/ext/zstdruby/libzstd/common/xxhash.h +12 -32
- data/ext/zstdruby/libzstd/common/zstd_common.c +10 -10
- data/ext/zstdruby/libzstd/common/zstd_deps.h +111 -0
- data/ext/zstdruby/libzstd/common/zstd_internal.h +230 -111
- data/ext/zstdruby/libzstd/common/zstd_trace.h +154 -0
- data/ext/zstdruby/libzstd/compress/fse_compress.c +47 -63
- data/ext/zstdruby/libzstd/compress/hist.c +41 -63
- data/ext/zstdruby/libzstd/compress/hist.h +13 -33
- data/ext/zstdruby/libzstd/compress/huf_compress.c +332 -193
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +3614 -1696
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +546 -86
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +158 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +29 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +441 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +54 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +572 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +32 -0
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +662 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +43 -41
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +85 -80
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +1184 -111
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +59 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +333 -208
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +15 -3
- data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +103 -0
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +228 -129
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +151 -440
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +32 -114
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +395 -276
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +20 -16
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +3 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +630 -231
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +606 -380
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +8 -5
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +39 -9
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +9 -8
- data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +2 -2
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
- data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +55 -46
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +20 -9
- data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +43 -31
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +53 -30
- data/ext/zstdruby/libzstd/dll/example/Makefile +2 -1
- data/ext/zstdruby/libzstd/dll/example/README.md +16 -22
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +4 -4
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +24 -14
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +17 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +17 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +25 -11
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +43 -32
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +2 -2
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +27 -19
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +32 -20
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
- data/ext/zstdruby/libzstd/libzstd.pc.in +2 -1
- data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +201 -31
- data/ext/zstdruby/libzstd/zstd.h +740 -153
- data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +3 -1
- data/lib/zstd-ruby/version.rb +1 -1
- data/zstd-ruby.gemspec +1 -1
- metadata +21 -10
- data/.travis.yml +0 -14
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -19,113 +19,57 @@
|
|
|
19
19
|
/* Note : This is an internal API.
|
|
20
20
|
* These APIs used to be exposed with ZSTDLIB_API,
|
|
21
21
|
* because it used to be the only way to invoke MT compression.
|
|
22
|
-
* Now,
|
|
23
|
-
* instead.
|
|
24
|
-
*
|
|
25
|
-
* If you depend on these APIs and can't switch, then define
|
|
26
|
-
* ZSTD_LEGACY_MULTITHREADED_API when making the dynamic library.
|
|
27
|
-
* However, we may completely remove these functions in a future
|
|
28
|
-
* release, so please switch soon.
|
|
22
|
+
* Now, you must use ZSTD_compress2 and ZSTD_compressStream2() instead.
|
|
29
23
|
*
|
|
30
24
|
* This API requires ZSTD_MULTITHREAD to be defined during compilation,
|
|
31
25
|
* otherwise ZSTDMT_createCCtx*() will fail.
|
|
32
26
|
*/
|
|
33
27
|
|
|
34
|
-
#ifdef ZSTD_LEGACY_MULTITHREADED_API
|
|
35
|
-
# define ZSTDMT_API ZSTDLIB_API
|
|
36
|
-
#else
|
|
37
|
-
# define ZSTDMT_API
|
|
38
|
-
#endif
|
|
39
|
-
|
|
40
28
|
/* === Dependencies === */
|
|
41
|
-
#include
|
|
29
|
+
#include "../common/zstd_deps.h" /* size_t */
|
|
42
30
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
|
|
43
|
-
#include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */
|
|
31
|
+
#include "../zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */
|
|
44
32
|
|
|
45
33
|
|
|
46
34
|
/* === Constants === */
|
|
47
|
-
#ifndef ZSTDMT_NBWORKERS_MAX
|
|
48
|
-
# define ZSTDMT_NBWORKERS_MAX
|
|
35
|
+
#ifndef ZSTDMT_NBWORKERS_MAX /* a different value can be selected at compile time */
|
|
36
|
+
# define ZSTDMT_NBWORKERS_MAX ((sizeof(void*)==4) /*32-bit*/ ? 64 : 256)
|
|
49
37
|
#endif
|
|
50
|
-
#ifndef ZSTDMT_JOBSIZE_MIN
|
|
51
|
-
# define ZSTDMT_JOBSIZE_MIN (
|
|
38
|
+
#ifndef ZSTDMT_JOBSIZE_MIN /* a different value can be selected at compile time */
|
|
39
|
+
# define ZSTDMT_JOBSIZE_MIN (512 KB)
|
|
52
40
|
#endif
|
|
53
41
|
#define ZSTDMT_JOBLOG_MAX (MEM_32bits() ? 29 : 30)
|
|
54
42
|
#define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB))
|
|
55
43
|
|
|
56
44
|
|
|
45
|
+
/* ========================================================
|
|
46
|
+
* === Private interface, for use by ZSTD_compress.c ===
|
|
47
|
+
* === Not exposed in libzstd. Never invoke directly ===
|
|
48
|
+
* ======================================================== */
|
|
49
|
+
|
|
57
50
|
/* === Memory management === */
|
|
58
51
|
typedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx;
|
|
59
52
|
/* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
ZSTDMT_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
|
|
65
|
-
|
|
66
|
-
ZSTDMT_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/* === Simple one-pass compression function === */
|
|
70
|
-
|
|
71
|
-
ZSTDMT_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
|
|
72
|
-
void* dst, size_t dstCapacity,
|
|
73
|
-
const void* src, size_t srcSize,
|
|
74
|
-
int compressionLevel);
|
|
75
|
-
|
|
53
|
+
ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers,
|
|
54
|
+
ZSTD_customMem cMem,
|
|
55
|
+
ZSTD_threadPool *pool);
|
|
56
|
+
size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
|
|
76
57
|
|
|
58
|
+
size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
|
|
77
59
|
|
|
78
60
|
/* === Streaming functions === */
|
|
79
61
|
|
|
80
|
-
|
|
81
|
-
ZSTDMT_API size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize); /**< if srcSize is not known at reset time, use ZSTD_CONTENTSIZE_UNKNOWN. Note: for compatibility with older programs, 0 means the same as ZSTD_CONTENTSIZE_UNKNOWN, but it will change in the future to mean "empty" */
|
|
82
|
-
|
|
83
|
-
ZSTDMT_API size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx);
|
|
84
|
-
ZSTDMT_API size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
|
|
85
|
-
|
|
86
|
-
ZSTDMT_API size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */
|
|
87
|
-
ZSTDMT_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
/* === Advanced functions and parameters === */
|
|
91
|
-
|
|
92
|
-
ZSTDMT_API size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
|
|
93
|
-
void* dst, size_t dstCapacity,
|
|
94
|
-
const void* src, size_t srcSize,
|
|
95
|
-
const ZSTD_CDict* cdict,
|
|
96
|
-
ZSTD_parameters params,
|
|
97
|
-
int overlapLog);
|
|
98
|
-
|
|
99
|
-
ZSTDMT_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
|
|
100
|
-
const void* dict, size_t dictSize, /* dict can be released after init, a local copy is preserved within zcs */
|
|
101
|
-
ZSTD_parameters params,
|
|
102
|
-
unsigned long long pledgedSrcSize); /* pledgedSrcSize is optional and can be zero == unknown */
|
|
103
|
-
|
|
104
|
-
ZSTDMT_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
|
|
105
|
-
const ZSTD_CDict* cdict,
|
|
106
|
-
ZSTD_frameParameters fparams,
|
|
107
|
-
unsigned long long pledgedSrcSize); /* note : zero means empty */
|
|
108
|
-
|
|
109
|
-
/* ZSTDMT_parameter :
|
|
110
|
-
* List of parameters that can be set using ZSTDMT_setMTCtxParameter() */
|
|
111
|
-
typedef enum {
|
|
112
|
-
ZSTDMT_p_jobSize, /* Each job is compressed in parallel. By default, this value is dynamically determined depending on compression parameters. Can be set explicitly here. */
|
|
113
|
-
ZSTDMT_p_overlapLog, /* Each job may reload a part of previous job to enhance compression ratio; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window. This is a "sticky" parameter : its value will be re-used on next compression job */
|
|
114
|
-
ZSTDMT_p_rsyncable /* Enables rsyncable mode. */
|
|
115
|
-
} ZSTDMT_parameter;
|
|
116
|
-
|
|
117
|
-
/* ZSTDMT_setMTCtxParameter() :
|
|
118
|
-
* allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter.
|
|
119
|
-
* The function must be called typically after ZSTD_createCCtx() but __before ZSTDMT_init*() !__
|
|
120
|
-
* Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions.
|
|
121
|
-
* @return : 0, or an error code (which can be tested using ZSTD_isError()) */
|
|
122
|
-
ZSTDMT_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value);
|
|
123
|
-
|
|
124
|
-
/* ZSTDMT_getMTCtxParameter() :
|
|
125
|
-
* Query the ZSTDMT_CCtx for a parameter value.
|
|
126
|
-
* @return : 0, or an error code (which can be tested using ZSTD_isError()) */
|
|
127
|
-
ZSTDMT_API size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value);
|
|
62
|
+
size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx);
|
|
128
63
|
|
|
64
|
+
/*! ZSTDMT_initCStream_internal() :
|
|
65
|
+
* Private use only. Init streaming operation.
|
|
66
|
+
* expects params to be valid.
|
|
67
|
+
* must receive dict, or cdict, or none, but not both.
|
|
68
|
+
* @return : 0, or an error code */
|
|
69
|
+
size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
|
|
70
|
+
const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,
|
|
71
|
+
const ZSTD_CDict* cdict,
|
|
72
|
+
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
|
|
129
73
|
|
|
130
74
|
/*! ZSTDMT_compressStream_generic() :
|
|
131
75
|
* Combines ZSTDMT_compressStream() with optional ZSTDMT_flushStream() or ZSTDMT_endStream()
|
|
@@ -134,16 +78,10 @@ ZSTDMT_API size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter
|
|
|
134
78
|
* 0 if fully flushed
|
|
135
79
|
* or an error code
|
|
136
80
|
* note : needs to be init using any ZSTD_initCStream*() variant */
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
/* ========================================================
|
|
144
|
-
* === Private interface, for use by ZSTD_compress.c ===
|
|
145
|
-
* === Not exposed in libzstd. Never invoke directly ===
|
|
146
|
-
* ======================================================== */
|
|
81
|
+
size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
82
|
+
ZSTD_outBuffer* output,
|
|
83
|
+
ZSTD_inBuffer* input,
|
|
84
|
+
ZSTD_EndDirective endOp);
|
|
147
85
|
|
|
148
86
|
/*! ZSTDMT_toFlushNow()
|
|
149
87
|
* Tell how many bytes are ready to be flushed immediately.
|
|
@@ -153,15 +91,6 @@ ZSTDMT_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
153
91
|
* therefore flushing is limited by speed of oldest job. */
|
|
154
92
|
size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx);
|
|
155
93
|
|
|
156
|
-
/*! ZSTDMT_CCtxParam_setMTCtxParameter()
|
|
157
|
-
* like ZSTDMT_setMTCtxParameter(), but into a ZSTD_CCtx_Params */
|
|
158
|
-
size_t ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, int value);
|
|
159
|
-
|
|
160
|
-
/*! ZSTDMT_CCtxParam_setNbWorkers()
|
|
161
|
-
* Set nbWorkers, and clamp it.
|
|
162
|
-
* Also reset jobSize and overlapLog */
|
|
163
|
-
size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers);
|
|
164
|
-
|
|
165
94
|
/*! ZSTDMT_updateCParams_whileCompressing() :
|
|
166
95
|
* Updates only a selected set of compression parameters, to remain compatible with current frame.
|
|
167
96
|
* New parameters will be applied to next compression job. */
|
|
@@ -174,17 +103,6 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p
|
|
|
174
103
|
ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx);
|
|
175
104
|
|
|
176
105
|
|
|
177
|
-
/*! ZSTDMT_initCStream_internal() :
|
|
178
|
-
* Private use only. Init streaming operation.
|
|
179
|
-
* expects params to be valid.
|
|
180
|
-
* must receive dict, or cdict, or none, but not both.
|
|
181
|
-
* @return : 0, or an error code */
|
|
182
|
-
size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
|
|
183
|
-
const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,
|
|
184
|
-
const ZSTD_CDict* cdict,
|
|
185
|
-
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
|
|
186
|
-
|
|
187
|
-
|
|
188
106
|
#if defined (__cplusplus)
|
|
189
107
|
}
|
|
190
108
|
#endif
|
|
@@ -1,47 +1,27 @@
|
|
|
1
1
|
/* ******************************************************************
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
notice, this list of conditions and the following disclaimer.
|
|
14
|
-
* Redistributions in binary form must reproduce the above
|
|
15
|
-
copyright notice, this list of conditions and the following disclaimer
|
|
16
|
-
in the documentation and/or other materials provided with the
|
|
17
|
-
distribution.
|
|
18
|
-
|
|
19
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
20
|
-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
21
|
-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
22
|
-
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
23
|
-
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
24
|
-
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
25
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
26
|
-
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
27
|
-
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
-
|
|
31
|
-
You can contact the author at :
|
|
32
|
-
- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
2
|
+
* huff0 huffman decoder,
|
|
3
|
+
* part of Finite State Entropy library
|
|
4
|
+
* Copyright (c) Yann Collet, Facebook, Inc.
|
|
5
|
+
*
|
|
6
|
+
* You can contact the author at :
|
|
7
|
+
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under both the BSD-style license (found in the
|
|
10
|
+
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
11
|
+
* in the COPYING file in the root directory of this source tree).
|
|
12
|
+
* You may select, at your option, one of the above-listed licenses.
|
|
33
13
|
****************************************************************** */
|
|
34
14
|
|
|
35
15
|
/* **************************************************************
|
|
36
16
|
* Dependencies
|
|
37
17
|
****************************************************************/
|
|
38
|
-
#include
|
|
39
|
-
#include "compiler.h"
|
|
40
|
-
#include "bitstream.h" /* BIT_* */
|
|
41
|
-
#include "fse.h" /* to compress headers */
|
|
18
|
+
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
|
|
19
|
+
#include "../common/compiler.h"
|
|
20
|
+
#include "../common/bitstream.h" /* BIT_* */
|
|
21
|
+
#include "../common/fse.h" /* to compress headers */
|
|
42
22
|
#define HUF_STATIC_LINKING_ONLY
|
|
43
|
-
#include "huf.h"
|
|
44
|
-
#include "error_private.h"
|
|
23
|
+
#include "../common/huf.h"
|
|
24
|
+
#include "../common/error_private.h"
|
|
45
25
|
|
|
46
26
|
/* **************************************************************
|
|
47
27
|
* Macros
|
|
@@ -61,7 +41,6 @@
|
|
|
61
41
|
* Error Management
|
|
62
42
|
****************************************************************/
|
|
63
43
|
#define HUF_isError ERR_isError
|
|
64
|
-
#define CHECK_F(f) { size_t const err_ = (f); if (HUF_isError(err_)) return err_; }
|
|
65
44
|
|
|
66
45
|
|
|
67
46
|
/* **************************************************************
|
|
@@ -124,7 +103,7 @@ typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved;
|
|
|
124
103
|
static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
|
|
125
104
|
{
|
|
126
105
|
DTableDesc dtd;
|
|
127
|
-
|
|
106
|
+
ZSTD_memcpy(&dtd, table, sizeof(dtd));
|
|
128
107
|
return dtd;
|
|
129
108
|
}
|
|
130
109
|
|
|
@@ -136,29 +115,51 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
|
|
|
136
115
|
/*-***************************/
|
|
137
116
|
typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decoding */
|
|
138
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at
|
|
120
|
+
* a time.
|
|
121
|
+
*/
|
|
122
|
+
static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
|
|
123
|
+
U64 D4;
|
|
124
|
+
if (MEM_isLittleEndian()) {
|
|
125
|
+
D4 = symbol + (nbBits << 8);
|
|
126
|
+
} else {
|
|
127
|
+
D4 = (symbol << 8) + nbBits;
|
|
128
|
+
}
|
|
129
|
+
D4 *= 0x0001000100010001ULL;
|
|
130
|
+
return D4;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
typedef struct {
|
|
134
|
+
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
|
|
135
|
+
U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1];
|
|
136
|
+
U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
|
|
137
|
+
BYTE symbols[HUF_SYMBOLVALUE_MAX + 1];
|
|
138
|
+
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
|
139
|
+
} HUF_ReadDTableX1_Workspace;
|
|
140
|
+
|
|
141
|
+
|
|
139
142
|
size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize)
|
|
143
|
+
{
|
|
144
|
+
return HUF_readDTableX1_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2)
|
|
140
148
|
{
|
|
141
149
|
U32 tableLog = 0;
|
|
142
150
|
U32 nbSymbols = 0;
|
|
143
151
|
size_t iSize;
|
|
144
152
|
void* const dtPtr = DTable + 1;
|
|
145
153
|
HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;
|
|
154
|
+
HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace;
|
|
146
155
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
size_t spaceUsed32 = 0;
|
|
150
|
-
|
|
151
|
-
rankVal = (U32 *)workSpace + spaceUsed32;
|
|
152
|
-
spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1;
|
|
153
|
-
huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32);
|
|
154
|
-
spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
|
|
155
|
-
|
|
156
|
-
if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
|
|
156
|
+
DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp));
|
|
157
|
+
if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge);
|
|
157
158
|
|
|
158
159
|
DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
|
|
159
|
-
/*
|
|
160
|
+
/* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
|
|
160
161
|
|
|
161
|
-
iSize =
|
|
162
|
+
iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), bmi2);
|
|
162
163
|
if (HUF_isError(iSize)) return iSize;
|
|
163
164
|
|
|
164
165
|
/* Table header */
|
|
@@ -166,40 +167,117 @@ size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize
|
|
|
166
167
|
if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
|
|
167
168
|
dtd.tableType = 0;
|
|
168
169
|
dtd.tableLog = (BYTE)tableLog;
|
|
169
|
-
|
|
170
|
+
ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
|
|
170
171
|
}
|
|
171
172
|
|
|
172
|
-
/*
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
173
|
+
/* Compute symbols and rankStart given rankVal:
|
|
174
|
+
*
|
|
175
|
+
* rankVal already contains the number of values of each weight.
|
|
176
|
+
*
|
|
177
|
+
* symbols contains the symbols ordered by weight. First are the rankVal[0]
|
|
178
|
+
* weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on.
|
|
179
|
+
* symbols[0] is filled (but unused) to avoid a branch.
|
|
180
|
+
*
|
|
181
|
+
* rankStart contains the offset where each rank belongs in the DTable.
|
|
182
|
+
* rankStart[0] is not filled because there are no entries in the table for
|
|
183
|
+
* weight 0.
|
|
184
|
+
*/
|
|
185
|
+
{
|
|
186
|
+
int n;
|
|
187
|
+
int nextRankStart = 0;
|
|
188
|
+
int const unroll = 4;
|
|
189
|
+
int const nLimit = (int)nbSymbols - unroll + 1;
|
|
190
|
+
for (n=0; n<(int)tableLog+1; n++) {
|
|
191
|
+
U32 const curr = nextRankStart;
|
|
192
|
+
nextRankStart += wksp->rankVal[n];
|
|
193
|
+
wksp->rankStart[n] = curr;
|
|
194
|
+
}
|
|
195
|
+
for (n=0; n < nLimit; n += unroll) {
|
|
196
|
+
int u;
|
|
197
|
+
for (u=0; u < unroll; ++u) {
|
|
198
|
+
size_t const w = wksp->huffWeight[n+u];
|
|
199
|
+
wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
for (; n < (int)nbSymbols; ++n) {
|
|
203
|
+
size_t const w = wksp->huffWeight[n];
|
|
204
|
+
wksp->symbols[wksp->rankStart[w]++] = (BYTE)n;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
192
207
|
|
|
208
|
+
/* fill DTable
|
|
209
|
+
* We fill all entries of each weight in order.
|
|
210
|
+
* That way length is a constant for each iteration of the outter loop.
|
|
211
|
+
* We can switch based on the length to a different inner loop which is
|
|
212
|
+
* optimized for that particular case.
|
|
213
|
+
*/
|
|
214
|
+
{
|
|
215
|
+
U32 w;
|
|
216
|
+
int symbol=wksp->rankVal[0];
|
|
217
|
+
int rankStart=0;
|
|
218
|
+
for (w=1; w<tableLog+1; ++w) {
|
|
219
|
+
int const symbolCount = wksp->rankVal[w];
|
|
220
|
+
int const length = (1 << w) >> 1;
|
|
221
|
+
int uStart = rankStart;
|
|
222
|
+
BYTE const nbBits = (BYTE)(tableLog + 1 - w);
|
|
223
|
+
int s;
|
|
224
|
+
int u;
|
|
225
|
+
switch (length) {
|
|
226
|
+
case 1:
|
|
227
|
+
for (s=0; s<symbolCount; ++s) {
|
|
228
|
+
HUF_DEltX1 D;
|
|
229
|
+
D.byte = wksp->symbols[symbol + s];
|
|
230
|
+
D.nbBits = nbBits;
|
|
231
|
+
dt[uStart] = D;
|
|
232
|
+
uStart += 1;
|
|
233
|
+
}
|
|
234
|
+
break;
|
|
235
|
+
case 2:
|
|
236
|
+
for (s=0; s<symbolCount; ++s) {
|
|
237
|
+
HUF_DEltX1 D;
|
|
238
|
+
D.byte = wksp->symbols[symbol + s];
|
|
239
|
+
D.nbBits = nbBits;
|
|
240
|
+
dt[uStart+0] = D;
|
|
241
|
+
dt[uStart+1] = D;
|
|
242
|
+
uStart += 2;
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
case 4:
|
|
246
|
+
for (s=0; s<symbolCount; ++s) {
|
|
247
|
+
U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
|
|
248
|
+
MEM_write64(dt + uStart, D4);
|
|
249
|
+
uStart += 4;
|
|
250
|
+
}
|
|
251
|
+
break;
|
|
252
|
+
case 8:
|
|
253
|
+
for (s=0; s<symbolCount; ++s) {
|
|
254
|
+
U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
|
|
255
|
+
MEM_write64(dt + uStart, D4);
|
|
256
|
+
MEM_write64(dt + uStart + 4, D4);
|
|
257
|
+
uStart += 8;
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
default:
|
|
261
|
+
for (s=0; s<symbolCount; ++s) {
|
|
262
|
+
U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
|
|
263
|
+
for (u=0; u < length; u += 16) {
|
|
264
|
+
MEM_write64(dt + uStart + u + 0, D4);
|
|
265
|
+
MEM_write64(dt + uStart + u + 4, D4);
|
|
266
|
+
MEM_write64(dt + uStart + u + 8, D4);
|
|
267
|
+
MEM_write64(dt + uStart + u + 12, D4);
|
|
268
|
+
}
|
|
269
|
+
assert(u == length);
|
|
270
|
+
uStart += length;
|
|
271
|
+
}
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
symbol += symbolCount;
|
|
275
|
+
rankStart += symbolCount * length;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
193
278
|
return iSize;
|
|
194
279
|
}
|
|
195
280
|
|
|
196
|
-
size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize)
|
|
197
|
-
{
|
|
198
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
199
|
-
return HUF_readDTableX1_wksp(DTable, src, srcSize,
|
|
200
|
-
workSpace, sizeof(workSpace));
|
|
201
|
-
}
|
|
202
|
-
|
|
203
281
|
FORCE_INLINE_TEMPLATE BYTE
|
|
204
282
|
HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)
|
|
205
283
|
{
|
|
@@ -280,6 +358,7 @@ HUF_decompress4X1_usingDTable_internal_body(
|
|
|
280
358
|
{ const BYTE* const istart = (const BYTE*) cSrc;
|
|
281
359
|
BYTE* const ostart = (BYTE*) dst;
|
|
282
360
|
BYTE* const oend = ostart + dstSize;
|
|
361
|
+
BYTE* const olimit = oend - 3;
|
|
283
362
|
const void* const dtPtr = DTable + 1;
|
|
284
363
|
const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
|
|
285
364
|
|
|
@@ -304,9 +383,9 @@ HUF_decompress4X1_usingDTable_internal_body(
|
|
|
304
383
|
BYTE* op2 = opStart2;
|
|
305
384
|
BYTE* op3 = opStart3;
|
|
306
385
|
BYTE* op4 = opStart4;
|
|
307
|
-
U32 endSignal = BIT_DStream_unfinished;
|
|
308
386
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
|
309
387
|
U32 const dtLog = dtd.tableLog;
|
|
388
|
+
U32 endSignal = 1;
|
|
310
389
|
|
|
311
390
|
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
|
312
391
|
CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
|
|
@@ -315,8 +394,7 @@ HUF_decompress4X1_usingDTable_internal_body(
|
|
|
315
394
|
CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
|
|
316
395
|
|
|
317
396
|
/* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
|
|
318
|
-
|
|
319
|
-
while ( (endSignal==BIT_DStream_unfinished) && (op4<(oend-3)) ) {
|
|
397
|
+
for ( ; (endSignal) & (op4 < olimit) ; ) {
|
|
320
398
|
HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
|
|
321
399
|
HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
|
|
322
400
|
HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
|
|
@@ -333,10 +411,10 @@ HUF_decompress4X1_usingDTable_internal_body(
|
|
|
333
411
|
HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
|
|
334
412
|
HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
|
|
335
413
|
HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
414
|
+
endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
|
|
415
|
+
endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
|
|
416
|
+
endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
|
|
417
|
+
endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
|
|
340
418
|
}
|
|
341
419
|
|
|
342
420
|
/* check corruption */
|
|
@@ -398,20 +476,6 @@ size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
|
|
|
398
476
|
}
|
|
399
477
|
|
|
400
478
|
|
|
401
|
-
size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
|
|
402
|
-
const void* cSrc, size_t cSrcSize)
|
|
403
|
-
{
|
|
404
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
405
|
-
return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
|
|
406
|
-
workSpace, sizeof(workSpace));
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
410
|
-
{
|
|
411
|
-
HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
|
|
412
|
-
return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
479
|
size_t HUF_decompress4X1_usingDTable(
|
|
416
480
|
void* dst, size_t dstSize,
|
|
417
481
|
const void* cSrc, size_t cSrcSize,
|
|
@@ -428,8 +492,7 @@ static size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size
|
|
|
428
492
|
{
|
|
429
493
|
const BYTE* ip = (const BYTE*) cSrc;
|
|
430
494
|
|
|
431
|
-
size_t const hSize =
|
|
432
|
-
workSpace, wkspSize);
|
|
495
|
+
size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
|
|
433
496
|
if (HUF_isError(hSize)) return hSize;
|
|
434
497
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
435
498
|
ip += hSize; cSrcSize -= hSize;
|
|
@@ -445,18 +508,6 @@ size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
|
445
508
|
}
|
|
446
509
|
|
|
447
510
|
|
|
448
|
-
size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
449
|
-
{
|
|
450
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
451
|
-
return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
452
|
-
workSpace, sizeof(workSpace));
|
|
453
|
-
}
|
|
454
|
-
size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
455
|
-
{
|
|
456
|
-
HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
|
|
457
|
-
return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
511
|
#endif /* HUF_FORCE_DECOMPRESS_X2 */
|
|
461
512
|
|
|
462
513
|
|
|
@@ -477,13 +528,15 @@ typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];
|
|
|
477
528
|
static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed,
|
|
478
529
|
const U32* rankValOrigin, const int minWeight,
|
|
479
530
|
const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
|
|
480
|
-
U32 nbBitsBaseline, U16 baseSeq)
|
|
531
|
+
U32 nbBitsBaseline, U16 baseSeq, U32* wksp, size_t wkspSize)
|
|
481
532
|
{
|
|
482
533
|
HUF_DEltX2 DElt;
|
|
483
|
-
U32 rankVal
|
|
534
|
+
U32* rankVal = wksp;
|
|
484
535
|
|
|
536
|
+
assert(wkspSize >= HUF_TABLELOG_MAX + 1);
|
|
537
|
+
(void)wkspSize;
|
|
485
538
|
/* get pre-calculated rankVal */
|
|
486
|
-
|
|
539
|
+
ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
|
|
487
540
|
|
|
488
541
|
/* fill skipped values */
|
|
489
542
|
if (minWeight>1) {
|
|
@@ -518,14 +571,18 @@ static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 co
|
|
|
518
571
|
static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
|
|
519
572
|
const sortedSymbol_t* sortedList, const U32 sortedListSize,
|
|
520
573
|
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
|
|
521
|
-
const U32 nbBitsBaseline)
|
|
574
|
+
const U32 nbBitsBaseline, U32* wksp, size_t wkspSize)
|
|
522
575
|
{
|
|
523
|
-
U32 rankVal
|
|
576
|
+
U32* rankVal = wksp;
|
|
524
577
|
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
|
|
525
578
|
const U32 minBits = nbBitsBaseline - maxWeight;
|
|
526
579
|
U32 s;
|
|
527
580
|
|
|
528
|
-
|
|
581
|
+
assert(wkspSize >= HUF_TABLELOG_MAX + 1);
|
|
582
|
+
wksp += HUF_TABLELOG_MAX + 1;
|
|
583
|
+
wkspSize -= HUF_TABLELOG_MAX + 1;
|
|
584
|
+
|
|
585
|
+
ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
|
|
529
586
|
|
|
530
587
|
/* fill DTable */
|
|
531
588
|
for (s=0; s<sortedListSize; s++) {
|
|
@@ -543,7 +600,7 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
|
|
|
543
600
|
HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits,
|
|
544
601
|
rankValOrigin[nbBits], minWeight,
|
|
545
602
|
sortedList+sortedRank, sortedListSize-sortedRank,
|
|
546
|
-
nbBitsBaseline, symbol);
|
|
603
|
+
nbBitsBaseline, symbol, wksp, wkspSize);
|
|
547
604
|
} else {
|
|
548
605
|
HUF_DEltX2 DElt;
|
|
549
606
|
MEM_writeLE16(&(DElt.sequence), symbol);
|
|
@@ -557,6 +614,15 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
|
|
|
557
614
|
}
|
|
558
615
|
}
|
|
559
616
|
|
|
617
|
+
typedef struct {
|
|
618
|
+
rankValCol_t rankVal[HUF_TABLELOG_MAX];
|
|
619
|
+
U32 rankStats[HUF_TABLELOG_MAX + 1];
|
|
620
|
+
U32 rankStart0[HUF_TABLELOG_MAX + 2];
|
|
621
|
+
sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
|
|
622
|
+
BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
|
|
623
|
+
U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
|
|
624
|
+
} HUF_ReadDTableX2_Workspace;
|
|
625
|
+
|
|
560
626
|
size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
|
|
561
627
|
const void* src, size_t srcSize,
|
|
562
628
|
void* workSpace, size_t wkspSize)
|
|
@@ -569,48 +635,33 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
|
|
|
569
635
|
HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
|
|
570
636
|
U32 *rankStart;
|
|
571
637
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32);
|
|
580
|
-
spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2;
|
|
581
|
-
rankStats = (U32 *)workSpace + spaceUsed32;
|
|
582
|
-
spaceUsed32 += HUF_TABLELOG_MAX + 1;
|
|
583
|
-
rankStart0 = (U32 *)workSpace + spaceUsed32;
|
|
584
|
-
spaceUsed32 += HUF_TABLELOG_MAX + 2;
|
|
585
|
-
sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t);
|
|
586
|
-
spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2;
|
|
587
|
-
weightList = (BYTE *)((U32 *)workSpace + spaceUsed32);
|
|
588
|
-
spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
|
|
589
|
-
|
|
590
|
-
if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
|
|
591
|
-
|
|
592
|
-
rankStart = rankStart0 + 1;
|
|
593
|
-
memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));
|
|
638
|
+
HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace;
|
|
639
|
+
|
|
640
|
+
if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC);
|
|
641
|
+
|
|
642
|
+
rankStart = wksp->rankStart0 + 1;
|
|
643
|
+
ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats));
|
|
644
|
+
ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0));
|
|
594
645
|
|
|
595
646
|
DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
|
|
596
647
|
if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
|
|
597
|
-
/*
|
|
648
|
+
/* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
|
|
598
649
|
|
|
599
|
-
iSize =
|
|
650
|
+
iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), /* bmi2 */ 0);
|
|
600
651
|
if (HUF_isError(iSize)) return iSize;
|
|
601
652
|
|
|
602
653
|
/* check result */
|
|
603
654
|
if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
|
|
604
655
|
|
|
605
656
|
/* find maxWeight */
|
|
606
|
-
for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
|
657
|
+
for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
|
607
658
|
|
|
608
659
|
/* Get start index of each weight */
|
|
609
660
|
{ U32 w, nextRankStart = 0;
|
|
610
661
|
for (w=1; w<maxW+1; w++) {
|
|
611
|
-
U32
|
|
612
|
-
nextRankStart += rankStats[w];
|
|
613
|
-
rankStart[w] =
|
|
662
|
+
U32 curr = nextRankStart;
|
|
663
|
+
nextRankStart += wksp->rankStats[w];
|
|
664
|
+
rankStart[w] = curr;
|
|
614
665
|
}
|
|
615
666
|
rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
|
|
616
667
|
sizeOfSort = nextRankStart;
|
|
@@ -619,57 +670,51 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
|
|
|
619
670
|
/* sort symbols by weight */
|
|
620
671
|
{ U32 s;
|
|
621
672
|
for (s=0; s<nbSymbols; s++) {
|
|
622
|
-
U32 const w = weightList[s];
|
|
673
|
+
U32 const w = wksp->weightList[s];
|
|
623
674
|
U32 const r = rankStart[w]++;
|
|
624
|
-
sortedSymbol[r].symbol = (BYTE)s;
|
|
625
|
-
sortedSymbol[r].weight = (BYTE)w;
|
|
675
|
+
wksp->sortedSymbol[r].symbol = (BYTE)s;
|
|
676
|
+
wksp->sortedSymbol[r].weight = (BYTE)w;
|
|
626
677
|
}
|
|
627
678
|
rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
|
|
628
679
|
}
|
|
629
680
|
|
|
630
681
|
/* Build rankVal */
|
|
631
|
-
{ U32* const rankVal0 = rankVal[0];
|
|
682
|
+
{ U32* const rankVal0 = wksp->rankVal[0];
|
|
632
683
|
{ int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */
|
|
633
684
|
U32 nextRankVal = 0;
|
|
634
685
|
U32 w;
|
|
635
686
|
for (w=1; w<maxW+1; w++) {
|
|
636
|
-
U32
|
|
637
|
-
nextRankVal += rankStats[w] << (w+rescale);
|
|
638
|
-
rankVal0[w] =
|
|
687
|
+
U32 curr = nextRankVal;
|
|
688
|
+
nextRankVal += wksp->rankStats[w] << (w+rescale);
|
|
689
|
+
rankVal0[w] = curr;
|
|
639
690
|
} }
|
|
640
691
|
{ U32 const minBits = tableLog+1 - maxW;
|
|
641
692
|
U32 consumed;
|
|
642
693
|
for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
|
|
643
|
-
U32* const rankValPtr = rankVal[consumed];
|
|
694
|
+
U32* const rankValPtr = wksp->rankVal[consumed];
|
|
644
695
|
U32 w;
|
|
645
696
|
for (w = 1; w < maxW+1; w++) {
|
|
646
697
|
rankValPtr[w] = rankVal0[w] >> consumed;
|
|
647
698
|
} } } }
|
|
648
699
|
|
|
649
700
|
HUF_fillDTableX2(dt, maxTableLog,
|
|
650
|
-
sortedSymbol, sizeOfSort,
|
|
651
|
-
rankStart0, rankVal, maxW,
|
|
652
|
-
tableLog+1
|
|
701
|
+
wksp->sortedSymbol, sizeOfSort,
|
|
702
|
+
wksp->rankStart0, wksp->rankVal, maxW,
|
|
703
|
+
tableLog+1,
|
|
704
|
+
wksp->calleeWksp, sizeof(wksp->calleeWksp) / sizeof(U32));
|
|
653
705
|
|
|
654
706
|
dtd.tableLog = (BYTE)maxTableLog;
|
|
655
707
|
dtd.tableType = 1;
|
|
656
|
-
|
|
708
|
+
ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
|
|
657
709
|
return iSize;
|
|
658
710
|
}
|
|
659
711
|
|
|
660
|
-
size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)
|
|
661
|
-
{
|
|
662
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
663
|
-
return HUF_readDTableX2_wksp(DTable, src, srcSize,
|
|
664
|
-
workSpace, sizeof(workSpace));
|
|
665
|
-
}
|
|
666
|
-
|
|
667
712
|
|
|
668
713
|
FORCE_INLINE_TEMPLATE U32
|
|
669
714
|
HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
|
|
670
715
|
{
|
|
671
716
|
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
|
672
|
-
|
|
717
|
+
ZSTD_memcpy(op, dt+val, 2);
|
|
673
718
|
BIT_skipBits(DStream, dt[val].nbBits);
|
|
674
719
|
return dt[val].length;
|
|
675
720
|
}
|
|
@@ -678,7 +723,7 @@ FORCE_INLINE_TEMPLATE U32
|
|
|
678
723
|
HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
|
|
679
724
|
{
|
|
680
725
|
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
|
681
|
-
|
|
726
|
+
ZSTD_memcpy(op, dt+val, 1);
|
|
682
727
|
if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
|
|
683
728
|
else {
|
|
684
729
|
if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
|
|
@@ -755,7 +800,6 @@ HUF_decompress1X2_usingDTable_internal_body(
|
|
|
755
800
|
return dstSize;
|
|
756
801
|
}
|
|
757
802
|
|
|
758
|
-
|
|
759
803
|
FORCE_INLINE_TEMPLATE size_t
|
|
760
804
|
HUF_decompress4X2_usingDTable_internal_body(
|
|
761
805
|
void* dst, size_t dstSize,
|
|
@@ -767,6 +811,7 @@ HUF_decompress4X2_usingDTable_internal_body(
|
|
|
767
811
|
{ const BYTE* const istart = (const BYTE*) cSrc;
|
|
768
812
|
BYTE* const ostart = (BYTE*) dst;
|
|
769
813
|
BYTE* const oend = ostart + dstSize;
|
|
814
|
+
BYTE* const olimit = oend - (sizeof(size_t)-1);
|
|
770
815
|
const void* const dtPtr = DTable+1;
|
|
771
816
|
const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
|
|
772
817
|
|
|
@@ -791,7 +836,7 @@ HUF_decompress4X2_usingDTable_internal_body(
|
|
|
791
836
|
BYTE* op2 = opStart2;
|
|
792
837
|
BYTE* op3 = opStart3;
|
|
793
838
|
BYTE* op4 = opStart4;
|
|
794
|
-
U32 endSignal;
|
|
839
|
+
U32 endSignal = 1;
|
|
795
840
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
|
796
841
|
U32 const dtLog = dtd.tableLog;
|
|
797
842
|
|
|
@@ -802,8 +847,29 @@ HUF_decompress4X2_usingDTable_internal_body(
|
|
|
802
847
|
CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
|
|
803
848
|
|
|
804
849
|
/* 16-32 symbols per loop (4-8 symbols per stream) */
|
|
805
|
-
|
|
806
|
-
|
|
850
|
+
for ( ; (endSignal) & (op4 < olimit); ) {
|
|
851
|
+
#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
|
|
852
|
+
HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
|
|
853
|
+
HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
|
|
854
|
+
HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
|
|
855
|
+
HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
|
|
856
|
+
HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
|
|
857
|
+
HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
|
|
858
|
+
HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
|
|
859
|
+
HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
|
|
860
|
+
endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
|
|
861
|
+
endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
|
|
862
|
+
HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
|
|
863
|
+
HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
|
|
864
|
+
HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
|
|
865
|
+
HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
|
|
866
|
+
HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
|
|
867
|
+
HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
|
|
868
|
+
HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
|
|
869
|
+
HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
|
|
870
|
+
endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
|
|
871
|
+
endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
|
|
872
|
+
#else
|
|
807
873
|
HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
|
|
808
874
|
HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
|
|
809
875
|
HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
|
|
@@ -820,8 +886,12 @@ HUF_decompress4X2_usingDTable_internal_body(
|
|
|
820
886
|
HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
|
|
821
887
|
HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
|
|
822
888
|
HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
|
|
823
|
-
|
|
824
|
-
|
|
889
|
+
endSignal = (U32)LIKELY(
|
|
890
|
+
(BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
|
|
891
|
+
& (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
|
|
892
|
+
& (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
|
|
893
|
+
& (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished));
|
|
894
|
+
#endif
|
|
825
895
|
}
|
|
826
896
|
|
|
827
897
|
/* check corruption */
|
|
@@ -874,20 +944,6 @@ size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
|
|
|
874
944
|
}
|
|
875
945
|
|
|
876
946
|
|
|
877
|
-
size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
|
|
878
|
-
const void* cSrc, size_t cSrcSize)
|
|
879
|
-
{
|
|
880
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
881
|
-
return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
|
|
882
|
-
workSpace, sizeof(workSpace));
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
886
|
-
{
|
|
887
|
-
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
|
|
888
|
-
return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
|
889
|
-
}
|
|
890
|
-
|
|
891
947
|
size_t HUF_decompress4X2_usingDTable(
|
|
892
948
|
void* dst, size_t dstSize,
|
|
893
949
|
const void* cSrc, size_t cSrcSize,
|
|
@@ -921,20 +977,6 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
|
921
977
|
}
|
|
922
978
|
|
|
923
979
|
|
|
924
|
-
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
925
|
-
const void* cSrc, size_t cSrcSize)
|
|
926
|
-
{
|
|
927
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
928
|
-
return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
929
|
-
workSpace, sizeof(workSpace));
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
933
|
-
{
|
|
934
|
-
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
|
|
935
|
-
return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
980
|
#endif /* HUF_FORCE_DECOMPRESS_X1 */
|
|
939
981
|
|
|
940
982
|
|
|
@@ -1035,67 +1077,6 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
|
|
|
1035
1077
|
}
|
|
1036
1078
|
|
|
1037
1079
|
|
|
1038
|
-
typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
|
1039
|
-
|
|
1040
|
-
size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1041
|
-
{
|
|
1042
|
-
#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
|
|
1043
|
-
static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 };
|
|
1044
|
-
#endif
|
|
1045
|
-
|
|
1046
|
-
/* validation checks */
|
|
1047
|
-
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
|
1048
|
-
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
|
1049
|
-
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
|
1050
|
-
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
|
1051
|
-
|
|
1052
|
-
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
|
1053
|
-
#if defined(HUF_FORCE_DECOMPRESS_X1)
|
|
1054
|
-
(void)algoNb;
|
|
1055
|
-
assert(algoNb == 0);
|
|
1056
|
-
return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize);
|
|
1057
|
-
#elif defined(HUF_FORCE_DECOMPRESS_X2)
|
|
1058
|
-
(void)algoNb;
|
|
1059
|
-
assert(algoNb == 1);
|
|
1060
|
-
return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize);
|
|
1061
|
-
#else
|
|
1062
|
-
return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
|
|
1063
|
-
#endif
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1068
|
-
{
|
|
1069
|
-
/* validation checks */
|
|
1070
|
-
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
|
1071
|
-
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
|
1072
|
-
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
|
1073
|
-
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
|
1074
|
-
|
|
1075
|
-
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
|
1076
|
-
#if defined(HUF_FORCE_DECOMPRESS_X1)
|
|
1077
|
-
(void)algoNb;
|
|
1078
|
-
assert(algoNb == 0);
|
|
1079
|
-
return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
|
|
1080
|
-
#elif defined(HUF_FORCE_DECOMPRESS_X2)
|
|
1081
|
-
(void)algoNb;
|
|
1082
|
-
assert(algoNb == 1);
|
|
1083
|
-
return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
|
|
1084
|
-
#else
|
|
1085
|
-
return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
|
|
1086
|
-
HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
|
|
1087
|
-
#endif
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1092
|
-
{
|
|
1093
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1094
|
-
return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
1095
|
-
workSpace, sizeof(workSpace));
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
1080
|
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst,
|
|
1100
1081
|
size_t dstSize, const void* cSrc,
|
|
1101
1082
|
size_t cSrcSize, void* workSpace,
|
|
@@ -1129,8 +1110,8 @@ size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
|
1129
1110
|
/* validation checks */
|
|
1130
1111
|
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
|
1131
1112
|
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
|
1132
|
-
if (cSrcSize == dstSize) {
|
|
1133
|
-
if (cSrcSize == 1) {
|
|
1113
|
+
if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
|
1114
|
+
if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
|
1134
1115
|
|
|
1135
1116
|
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
|
1136
1117
|
#if defined(HUF_FORCE_DECOMPRESS_X1)
|
|
@@ -1152,14 +1133,6 @@ size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
|
1152
1133
|
}
|
|
1153
1134
|
}
|
|
1154
1135
|
|
|
1155
|
-
size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
1156
|
-
const void* cSrc, size_t cSrcSize)
|
|
1157
|
-
{
|
|
1158
|
-
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1159
|
-
return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
1160
|
-
workSpace, sizeof(workSpace));
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
1136
|
|
|
1164
1137
|
size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)
|
|
1165
1138
|
{
|
|
@@ -1183,7 +1156,7 @@ size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstS
|
|
|
1183
1156
|
{
|
|
1184
1157
|
const BYTE* ip = (const BYTE*) cSrc;
|
|
1185
1158
|
|
|
1186
|
-
size_t const hSize =
|
|
1159
|
+
size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
|
|
1187
1160
|
if (HUF_isError(hSize)) return hSize;
|
|
1188
1161
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
1189
1162
|
ip += hSize; cSrcSize -= hSize;
|
|
@@ -1230,3 +1203,149 @@ size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t ds
|
|
|
1230
1203
|
#endif
|
|
1231
1204
|
}
|
|
1232
1205
|
}
|
|
1206
|
+
|
|
1207
|
+
#ifndef ZSTD_NO_UNUSED_FUNCTIONS
|
|
1208
|
+
#ifndef HUF_FORCE_DECOMPRESS_X2
|
|
1209
|
+
size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize)
|
|
1210
|
+
{
|
|
1211
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1212
|
+
return HUF_readDTableX1_wksp(DTable, src, srcSize,
|
|
1213
|
+
workSpace, sizeof(workSpace));
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
|
|
1217
|
+
const void* cSrc, size_t cSrcSize)
|
|
1218
|
+
{
|
|
1219
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1220
|
+
return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
|
|
1221
|
+
workSpace, sizeof(workSpace));
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1225
|
+
{
|
|
1226
|
+
HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
|
|
1227
|
+
return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
|
|
1228
|
+
}
|
|
1229
|
+
#endif
|
|
1230
|
+
|
|
1231
|
+
#ifndef HUF_FORCE_DECOMPRESS_X1
|
|
1232
|
+
size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)
|
|
1233
|
+
{
|
|
1234
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1235
|
+
return HUF_readDTableX2_wksp(DTable, src, srcSize,
|
|
1236
|
+
workSpace, sizeof(workSpace));
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
|
|
1240
|
+
const void* cSrc, size_t cSrcSize)
|
|
1241
|
+
{
|
|
1242
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1243
|
+
return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
|
|
1244
|
+
workSpace, sizeof(workSpace));
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1248
|
+
{
|
|
1249
|
+
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
|
|
1250
|
+
return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
|
1251
|
+
}
|
|
1252
|
+
#endif
|
|
1253
|
+
|
|
1254
|
+
#ifndef HUF_FORCE_DECOMPRESS_X2
|
|
1255
|
+
size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1256
|
+
{
|
|
1257
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1258
|
+
return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
1259
|
+
workSpace, sizeof(workSpace));
|
|
1260
|
+
}
|
|
1261
|
+
size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1262
|
+
{
|
|
1263
|
+
HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
|
|
1264
|
+
return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
|
1265
|
+
}
|
|
1266
|
+
#endif
|
|
1267
|
+
|
|
1268
|
+
#ifndef HUF_FORCE_DECOMPRESS_X1
|
|
1269
|
+
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
1270
|
+
const void* cSrc, size_t cSrcSize)
|
|
1271
|
+
{
|
|
1272
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1273
|
+
return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
1274
|
+
workSpace, sizeof(workSpace));
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1278
|
+
{
|
|
1279
|
+
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
|
|
1280
|
+
return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
|
1281
|
+
}
|
|
1282
|
+
#endif
|
|
1283
|
+
|
|
1284
|
+
typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
|
1285
|
+
|
|
1286
|
+
size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1287
|
+
{
|
|
1288
|
+
#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
|
|
1289
|
+
static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 };
|
|
1290
|
+
#endif
|
|
1291
|
+
|
|
1292
|
+
/* validation checks */
|
|
1293
|
+
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
|
1294
|
+
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
|
1295
|
+
if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
|
1296
|
+
if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
|
1297
|
+
|
|
1298
|
+
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
|
1299
|
+
#if defined(HUF_FORCE_DECOMPRESS_X1)
|
|
1300
|
+
(void)algoNb;
|
|
1301
|
+
assert(algoNb == 0);
|
|
1302
|
+
return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize);
|
|
1303
|
+
#elif defined(HUF_FORCE_DECOMPRESS_X2)
|
|
1304
|
+
(void)algoNb;
|
|
1305
|
+
assert(algoNb == 1);
|
|
1306
|
+
return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize);
|
|
1307
|
+
#else
|
|
1308
|
+
return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
|
|
1309
|
+
#endif
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1314
|
+
{
|
|
1315
|
+
/* validation checks */
|
|
1316
|
+
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
|
1317
|
+
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
|
1318
|
+
if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
|
1319
|
+
if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
|
1320
|
+
|
|
1321
|
+
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
|
1322
|
+
#if defined(HUF_FORCE_DECOMPRESS_X1)
|
|
1323
|
+
(void)algoNb;
|
|
1324
|
+
assert(algoNb == 0);
|
|
1325
|
+
return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
|
|
1326
|
+
#elif defined(HUF_FORCE_DECOMPRESS_X2)
|
|
1327
|
+
(void)algoNb;
|
|
1328
|
+
assert(algoNb == 1);
|
|
1329
|
+
return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
|
|
1330
|
+
#else
|
|
1331
|
+
return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
|
|
1332
|
+
HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
|
|
1333
|
+
#endif
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
1338
|
+
{
|
|
1339
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1340
|
+
return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
1341
|
+
workSpace, sizeof(workSpace));
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
|
|
1345
|
+
const void* cSrc, size_t cSrcSize)
|
|
1346
|
+
{
|
|
1347
|
+
U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
|
|
1348
|
+
return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
|
|
1349
|
+
workSpace, sizeof(workSpace));
|
|
1350
|
+
}
|
|
1351
|
+
#endif
|