zstd-ruby 1.3.1.1 → 1.3.2.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/README.md +1 -1
- data/ext/zstdruby/libzstd/.gitignore +1 -0
- data/ext/zstdruby/libzstd/Makefile +40 -26
- data/ext/zstdruby/libzstd/README.md +68 -45
- data/ext/zstdruby/libzstd/common/bitstream.h +35 -23
- data/ext/zstdruby/libzstd/common/compiler.h +1 -0
- data/ext/zstdruby/libzstd/common/error_private.c +4 -2
- data/ext/zstdruby/libzstd/common/error_private.h +4 -4
- data/ext/zstdruby/libzstd/common/fse.h +1 -1
- data/ext/zstdruby/libzstd/common/huf.h +1 -1
- data/ext/zstdruby/libzstd/common/mem.h +1 -0
- data/ext/zstdruby/libzstd/common/pool.c +61 -46
- data/ext/zstdruby/libzstd/common/pool.h +4 -0
- data/ext/zstdruby/libzstd/common/threading.c +11 -15
- data/ext/zstdruby/libzstd/common/threading.h +52 -32
- data/ext/zstdruby/libzstd/common/zstd_common.c +2 -2
- data/ext/zstdruby/libzstd/common/zstd_errors.h +3 -1
- data/ext/zstdruby/libzstd/common/zstd_internal.h +95 -21
- data/ext/zstdruby/libzstd/compress/fse_compress.c +3 -1
- data/ext/zstdruby/libzstd/compress/huf_compress.c +4 -3
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +922 -2102
- data/ext/zstdruby/libzstd/compress/zstd_compress.h +307 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +308 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +28 -0
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +242 -0
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +30 -0
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +749 -0
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +38 -0
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +707 -0
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +67 -0
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +957 -0
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +14 -922
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +210 -133
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +20 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +373 -196
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +1 -0
- data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +1 -0
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -0
- data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -0
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +33 -22
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +8 -5
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +1 -0
- data/ext/zstdruby/libzstd/dll/example/Makefile +5 -5
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -0
- data/ext/zstdruby/libzstd/zstd.h +366 -118
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +11 -1
@@ -5,6 +5,7 @@
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
6
6
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
7
7
|
* in the COPYING file in the root directory of this source tree).
|
8
|
+
* You may select, at your option, one of the above-listed licenses.
|
8
9
|
*/
|
9
10
|
|
10
11
|
#ifndef ZSTDMT_COMPRESS_H
|
@@ -80,19 +81,19 @@ ZSTDLIB_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
|
|
80
81
|
ZSTD_frameParameters fparams,
|
81
82
|
unsigned long long pledgedSrcSize); /* note : zero means empty */
|
82
83
|
|
83
|
-
/*
|
84
|
+
/* ZSTDMT_parameter :
|
84
85
|
* List of parameters that can be set using ZSTDMT_setMTCtxParameter() */
|
85
86
|
typedef enum {
|
86
87
|
ZSTDMT_p_sectionSize, /* size of input "section". Each section is compressed in parallel. 0 means default, which is dynamically determined within compression functions */
|
87
88
|
ZSTDMT_p_overlapSectionLog /* Log of overlapped section; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window */
|
88
|
-
}
|
89
|
+
} ZSTDMT_parameter;
|
89
90
|
|
90
91
|
/* ZSTDMT_setMTCtxParameter() :
|
91
92
|
* allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter.
|
92
93
|
* The function must be called typically after ZSTD_createCCtx().
|
93
94
|
* Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions.
|
94
95
|
* @return : 0, or an error code (which can be tested using ZSTD_isError()) */
|
95
|
-
ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx,
|
96
|
+
ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, unsigned value);
|
96
97
|
|
97
98
|
|
98
99
|
/*! ZSTDMT_compressStream_generic() :
|
@@ -107,6 +108,22 @@ ZSTDLIB_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
107
108
|
ZSTD_EndDirective endOp);
|
108
109
|
|
109
110
|
|
111
|
+
/* === Private definitions; never ever use directly === */
|
112
|
+
|
113
|
+
size_t ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, unsigned value);
|
114
|
+
|
115
|
+
size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThreads);
|
116
|
+
|
117
|
+
/*! ZSTDMT_initCStream_internal() :
|
118
|
+
* Private use only. Init streaming operation.
|
119
|
+
* expects params to be valid.
|
120
|
+
* must receive dict, or cdict, or none, but not both.
|
121
|
+
* @return : 0, or an error code */
|
122
|
+
size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
|
123
|
+
const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
|
124
|
+
const ZSTD_CDict* cdict,
|
125
|
+
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
|
126
|
+
|
110
127
|
|
111
128
|
#if defined (__cplusplus)
|
112
129
|
}
|
@@ -5,6 +5,7 @@
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
6
6
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
7
7
|
* in the COPYING file in the root directory of this source tree).
|
8
|
+
* You may select, at your option, one of the above-listed licenses.
|
8
9
|
*/
|
9
10
|
|
10
11
|
|
@@ -34,7 +35,7 @@
|
|
34
35
|
* Frames requiring more memory will be rejected.
|
35
36
|
*/
|
36
37
|
#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
|
37
|
-
# define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 <<
|
38
|
+
# define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_DEFAULTMAX) + 1)
|
38
39
|
#endif
|
39
40
|
|
40
41
|
|
@@ -101,13 +102,15 @@ struct ZSTD_DCtx_s
|
|
101
102
|
const void* dictEnd; /* end of previous segment */
|
102
103
|
size_t expected;
|
103
104
|
ZSTD_frameHeader fParams;
|
104
|
-
|
105
|
+
U64 decodedSize;
|
106
|
+
blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */
|
105
107
|
ZSTD_dStage stage;
|
106
108
|
U32 litEntropy;
|
107
109
|
U32 fseEntropy;
|
108
110
|
XXH64_state_t xxhState;
|
109
111
|
size_t headerSize;
|
110
112
|
U32 dictID;
|
113
|
+
ZSTD_format_e format;
|
111
114
|
const BYTE* litPtr;
|
112
115
|
ZSTD_customMem customMem;
|
113
116
|
size_t litSize;
|
@@ -126,7 +129,6 @@ struct ZSTD_DCtx_s
|
|
126
129
|
size_t outBuffSize;
|
127
130
|
size_t outStart;
|
128
131
|
size_t outEnd;
|
129
|
-
size_t blockSize;
|
130
132
|
size_t lhSize;
|
131
133
|
void* legacyContext;
|
132
134
|
U32 previousLegacyVersion;
|
@@ -148,39 +150,44 @@ size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)
|
|
148
150
|
|
149
151
|
size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
|
150
152
|
|
151
|
-
|
153
|
+
|
154
|
+
static size_t ZSTD_startingInputLength(ZSTD_format_e format)
|
152
155
|
{
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
dctx->litEntropy = dctx->fseEntropy = 0;
|
161
|
-
dctx->dictID = 0;
|
162
|
-
MEM_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
|
163
|
-
memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
|
164
|
-
dctx->LLTptr = dctx->entropy.LLTable;
|
165
|
-
dctx->MLTptr = dctx->entropy.MLTable;
|
166
|
-
dctx->OFTptr = dctx->entropy.OFTable;
|
167
|
-
dctx->HUFptr = dctx->entropy.hufTable;
|
168
|
-
return 0;
|
156
|
+
size_t const startingInputLength = (format==ZSTD_f_zstd1_magicless) ?
|
157
|
+
ZSTD_frameHeaderSize_prefix - ZSTD_frameIdSize :
|
158
|
+
ZSTD_frameHeaderSize_prefix;
|
159
|
+
ZSTD_STATIC_ASSERT(ZSTD_FRAMEHEADERSIZE_PREFIX >= ZSTD_FRAMEIDSIZE);
|
160
|
+
/* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */
|
161
|
+
assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) );
|
162
|
+
return startingInputLength;
|
169
163
|
}
|
170
164
|
|
171
165
|
static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
|
172
166
|
{
|
173
|
-
|
174
|
-
dctx->staticSize
|
167
|
+
dctx->format = ZSTD_f_zstd1; /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */
|
168
|
+
dctx->staticSize = 0;
|
175
169
|
dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
|
176
|
-
dctx->ddict
|
177
|
-
dctx->ddictLocal
|
178
|
-
dctx->inBuff
|
179
|
-
dctx->inBuffSize
|
180
|
-
dctx->outBuffSize= 0;
|
170
|
+
dctx->ddict = NULL;
|
171
|
+
dctx->ddictLocal = NULL;
|
172
|
+
dctx->inBuff = NULL;
|
173
|
+
dctx->inBuffSize = 0;
|
174
|
+
dctx->outBuffSize = 0;
|
181
175
|
dctx->streamStage = zdss_init;
|
182
176
|
}
|
183
177
|
|
178
|
+
ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
|
179
|
+
{
|
180
|
+
ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace;
|
181
|
+
|
182
|
+
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
183
|
+
if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */
|
184
|
+
|
185
|
+
ZSTD_initDCtx_internal(dctx);
|
186
|
+
dctx->staticSize = workspaceSize;
|
187
|
+
dctx->inBuff = (char*)(dctx+1);
|
188
|
+
return dctx;
|
189
|
+
}
|
190
|
+
|
184
191
|
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
|
185
192
|
{
|
186
193
|
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
@@ -195,19 +202,6 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
|
|
195
202
|
}
|
196
203
|
}
|
197
204
|
|
198
|
-
ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
|
199
|
-
{
|
200
|
-
ZSTD_DCtx* dctx = (ZSTD_DCtx*) workspace;
|
201
|
-
|
202
|
-
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
203
|
-
if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */
|
204
|
-
|
205
|
-
ZSTD_initDCtx_internal(dctx);
|
206
|
-
dctx->staticSize = workspaceSize;
|
207
|
-
dctx->inBuff = (char*)(dctx+1);
|
208
|
-
return dctx;
|
209
|
-
}
|
210
|
-
|
211
205
|
ZSTD_DCtx* ZSTD_createDCtx(void)
|
212
206
|
{
|
213
207
|
return ZSTD_createDCtx_advanced(ZSTD_defaultCMem);
|
@@ -250,7 +244,7 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
|
250
244
|
* Note 3 : Skippable Frame Identifiers are considered valid. */
|
251
245
|
unsigned ZSTD_isFrame(const void* buffer, size_t size)
|
252
246
|
{
|
253
|
-
if (size <
|
247
|
+
if (size < ZSTD_frameIdSize) return 0;
|
254
248
|
{ U32 const magic = MEM_readLE32(buffer);
|
255
249
|
if (magic == ZSTD_MAGICNUMBER) return 1;
|
256
250
|
if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
|
@@ -261,55 +255,70 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size)
|
|
261
255
|
return 0;
|
262
256
|
}
|
263
257
|
|
264
|
-
|
265
|
-
|
266
|
-
*
|
267
|
-
*
|
268
|
-
|
258
|
+
/** ZSTD_frameHeaderSize_internal() :
|
259
|
+
* srcSize must be large enough to reach header size fields.
|
260
|
+
* note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
|
261
|
+
* @return : size of the Frame Header
|
262
|
+
* or an error code, which can be tested with ZSTD_isError() */
|
263
|
+
static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
|
269
264
|
{
|
270
|
-
|
271
|
-
|
265
|
+
size_t const minInputSize = ZSTD_startingInputLength(format);
|
266
|
+
if (srcSize < minInputSize) return ERROR(srcSize_wrong);
|
267
|
+
|
268
|
+
{ BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
|
272
269
|
U32 const dictID= fhd & 3;
|
273
270
|
U32 const singleSegment = (fhd >> 5) & 1;
|
274
271
|
U32 const fcsId = fhd >> 6;
|
275
|
-
return
|
276
|
-
|
272
|
+
return minInputSize + !singleSegment
|
273
|
+
+ ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
|
274
|
+
+ (singleSegment && !fcsId);
|
277
275
|
}
|
278
276
|
}
|
279
277
|
|
278
|
+
/** ZSTD_frameHeaderSize() :
|
279
|
+
* srcSize must be >= ZSTD_frameHeaderSize_prefix.
|
280
|
+
* @return : size of the Frame Header */
|
281
|
+
size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
|
282
|
+
{
|
283
|
+
return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);
|
284
|
+
}
|
280
285
|
|
281
|
-
|
282
|
-
|
283
|
-
*
|
284
|
-
*
|
285
|
-
*
|
286
|
-
|
286
|
+
|
287
|
+
/** ZSTD_getFrameHeader_internal() :
|
288
|
+
* decode Frame Header, or require larger `srcSize`.
|
289
|
+
* note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
|
290
|
+
* @return : 0, `zfhPtr` is correctly filled,
|
291
|
+
* >0, `srcSize` is too small, value is wanted `srcSize` amount,
|
292
|
+
* or an error code, which can be tested using ZSTD_isError() */
|
293
|
+
static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
|
287
294
|
{
|
288
295
|
const BYTE* ip = (const BYTE*)src;
|
289
|
-
|
296
|
+
size_t const minInputSize = ZSTD_startingInputLength(format);
|
290
297
|
|
291
|
-
if (
|
298
|
+
if (srcSize < minInputSize) return minInputSize;
|
299
|
+
|
300
|
+
if ( (format != ZSTD_f_zstd1_magicless)
|
301
|
+
&& (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
|
292
302
|
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
293
303
|
/* skippable frame */
|
294
304
|
if (srcSize < ZSTD_skippableHeaderSize)
|
295
305
|
return ZSTD_skippableHeaderSize; /* magic number + frame length */
|
296
306
|
memset(zfhPtr, 0, sizeof(*zfhPtr));
|
297
|
-
zfhPtr->frameContentSize = MEM_readLE32((const char *)src +
|
307
|
+
zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_frameIdSize);
|
298
308
|
zfhPtr->frameType = ZSTD_skippableFrame;
|
299
|
-
zfhPtr->windowSize = 0;
|
300
309
|
return 0;
|
301
310
|
}
|
302
311
|
return ERROR(prefix_unknown);
|
303
312
|
}
|
304
313
|
|
305
314
|
/* ensure there is enough `srcSize` to fully read/decode frame header */
|
306
|
-
{ size_t const fhsize =
|
315
|
+
{ size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format);
|
307
316
|
if (srcSize < fhsize) return fhsize;
|
308
317
|
zfhPtr->headerSize = (U32)fhsize;
|
309
318
|
}
|
310
319
|
|
311
|
-
{ BYTE const fhdByte = ip[
|
312
|
-
size_t pos =
|
320
|
+
{ BYTE const fhdByte = ip[minInputSize-1];
|
321
|
+
size_t pos = minInputSize;
|
313
322
|
U32 const dictIDSizeCode = fhdByte&3;
|
314
323
|
U32 const checksumFlag = (fhdByte>>2)&1;
|
315
324
|
U32 const singleSegment = (fhdByte>>5)&1;
|
@@ -349,12 +358,25 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t src
|
|
349
358
|
zfhPtr->frameType = ZSTD_frame;
|
350
359
|
zfhPtr->frameContentSize = frameContentSize;
|
351
360
|
zfhPtr->windowSize = windowSize;
|
361
|
+
zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
|
352
362
|
zfhPtr->dictID = dictID;
|
353
363
|
zfhPtr->checksumFlag = checksumFlag;
|
354
364
|
}
|
355
365
|
return 0;
|
356
366
|
}
|
357
367
|
|
368
|
+
/** ZSTD_getFrameHeader() :
|
369
|
+
* decode Frame Header, or require larger `srcSize`.
|
370
|
+
* note : this function does not consume input, it only reads it.
|
371
|
+
* @return : 0, `zfhPtr` is correctly filled,
|
372
|
+
* >0, `srcSize` is too small, value is wanted `srcSize` amount,
|
373
|
+
* or an error code, which can be tested using ZSTD_isError() */
|
374
|
+
size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
|
375
|
+
{
|
376
|
+
return ZSTD_getFrameHeader_internal(zfhPtr, src, srcSize, ZSTD_f_zstd1);
|
377
|
+
}
|
378
|
+
|
379
|
+
|
358
380
|
/** ZSTD_getFrameContentSize() :
|
359
381
|
* compatible with legacy mode
|
360
382
|
* @return : decompressed size of the single frame pointed to be `src` if known, otherwise
|
@@ -388,14 +410,14 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
|
|
388
410
|
unsigned long long totalDstSize = 0;
|
389
411
|
|
390
412
|
while (srcSize >= ZSTD_frameHeaderSize_prefix) {
|
391
|
-
const
|
413
|
+
U32 const magicNumber = MEM_readLE32(src);
|
392
414
|
|
393
415
|
if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
394
416
|
size_t skippableSize;
|
395
417
|
if (srcSize < ZSTD_skippableHeaderSize)
|
396
418
|
return ERROR(srcSize_wrong);
|
397
|
-
skippableSize = MEM_readLE32((const BYTE *)src +
|
398
|
-
|
419
|
+
skippableSize = MEM_readLE32((const BYTE *)src + ZSTD_frameIdSize)
|
420
|
+
+ ZSTD_skippableHeaderSize;
|
399
421
|
if (srcSize < skippableSize) {
|
400
422
|
return ZSTD_CONTENTSIZE_ERROR;
|
401
423
|
}
|
@@ -420,11 +442,9 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
|
|
420
442
|
src = (const BYTE *)src + frameSrcSize;
|
421
443
|
srcSize -= frameSrcSize;
|
422
444
|
}
|
423
|
-
}
|
445
|
+
} /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
|
424
446
|
|
425
|
-
if (srcSize)
|
426
|
-
return ZSTD_CONTENTSIZE_ERROR;
|
427
|
-
}
|
447
|
+
if (srcSize) return ZSTD_CONTENTSIZE_ERROR;
|
428
448
|
|
429
449
|
return totalDstSize;
|
430
450
|
}
|
@@ -440,7 +460,8 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
|
|
440
460
|
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
|
441
461
|
{
|
442
462
|
unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
|
443
|
-
|
463
|
+
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN);
|
464
|
+
return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret;
|
444
465
|
}
|
445
466
|
|
446
467
|
|
@@ -449,9 +470,9 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
|
|
449
470
|
* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
|
450
471
|
static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
|
451
472
|
{
|
452
|
-
size_t const result =
|
453
|
-
if (ZSTD_isError(result)) return result;
|
454
|
-
if (result>0) return ERROR(srcSize_wrong);
|
473
|
+
size_t const result = ZSTD_getFrameHeader_internal(&(dctx->fParams), src, headerSize, dctx->format);
|
474
|
+
if (ZSTD_isError(result)) return result; /* invalid header */
|
475
|
+
if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
|
455
476
|
if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID))
|
456
477
|
return ERROR(dictionary_wrong);
|
457
478
|
if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
|
@@ -497,7 +518,8 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
|
|
497
518
|
}
|
498
519
|
|
499
520
|
/*! ZSTD_decodeLiteralsBlock() :
|
500
|
-
|
521
|
+
* @return : nb of bytes read from src (< srcSize )
|
522
|
+
* note : symbol not declared but exposed for fullbench */
|
501
523
|
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
502
524
|
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
503
525
|
{
|
@@ -698,9 +720,9 @@ static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
|
|
698
720
|
}; /* OF_defaultDTable */
|
699
721
|
|
700
722
|
/*! ZSTD_buildSeqTable() :
|
701
|
-
|
702
|
-
|
703
|
-
*/
|
723
|
+
* @return : nb bytes read from src,
|
724
|
+
* or an error code if it fails, testable with ZSTD_isError()
|
725
|
+
*/
|
704
726
|
static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
|
705
727
|
symbolEncodingType_e type, U32 max, U32 maxLog,
|
706
728
|
const void* src, size_t srcSize,
|
@@ -858,13 +880,25 @@ size_t ZSTD_execSequenceLast7(BYTE* op,
|
|
858
880
|
}
|
859
881
|
|
860
882
|
|
861
|
-
|
883
|
+
typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
|
884
|
+
|
885
|
+
/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
|
886
|
+
* offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1)
|
887
|
+
* bits before reloading. This value is the maximum number of bytes we read
|
888
|
+
* after reloading when we are decoding long offets.
|
889
|
+
*/
|
890
|
+
#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \
|
891
|
+
(ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \
|
892
|
+
? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \
|
893
|
+
: 0)
|
894
|
+
|
895
|
+
static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
862
896
|
{
|
863
897
|
seq_t seq;
|
864
898
|
|
865
899
|
U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
|
866
900
|
U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
|
867
|
-
U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <=
|
901
|
+
U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
|
868
902
|
|
869
903
|
U32 const llBits = LL_bits[llCode];
|
870
904
|
U32 const mlBits = ML_bits[mlCode];
|
@@ -891,15 +925,25 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
|
|
891
925
|
0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
|
892
926
|
0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
|
893
927
|
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
|
894
|
-
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
|
928
|
+
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
|
895
929
|
|
896
930
|
/* sequence */
|
897
931
|
{ size_t offset;
|
898
932
|
if (!ofCode)
|
899
933
|
offset = 0;
|
900
934
|
else {
|
901
|
-
|
902
|
-
|
935
|
+
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
936
|
+
ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
|
937
|
+
assert(ofBits <= MaxOff);
|
938
|
+
if (MEM_32bits() && longOffsets) {
|
939
|
+
U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
|
940
|
+
offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
|
941
|
+
if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
|
942
|
+
if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
|
943
|
+
} else {
|
944
|
+
offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
945
|
+
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
|
946
|
+
}
|
903
947
|
}
|
904
948
|
|
905
949
|
if (ofCode <= 1) {
|
@@ -923,13 +967,17 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
|
|
923
967
|
|
924
968
|
seq.matchLength = ML_base[mlCode]
|
925
969
|
+ ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
|
926
|
-
if (MEM_32bits() && (mlBits+llBits
|
970
|
+
if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
|
971
|
+
BIT_reloadDStream(&seqState->DStream);
|
972
|
+
if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
|
973
|
+
BIT_reloadDStream(&seqState->DStream);
|
974
|
+
/* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
|
975
|
+
ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
|
927
976
|
|
928
977
|
seq.litLength = LL_base[llCode]
|
929
978
|
+ ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
|
930
|
-
if (
|
931
|
-
|
932
|
-
BIT_reloadDStream(&seqState->DStream);
|
979
|
+
if (MEM_32bits())
|
980
|
+
BIT_reloadDStream(&seqState->DStream);
|
933
981
|
|
934
982
|
DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
|
935
983
|
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
|
@@ -1028,7 +1076,8 @@ size_t ZSTD_execSequence(BYTE* op,
|
|
1028
1076
|
static size_t ZSTD_decompressSequences(
|
1029
1077
|
ZSTD_DCtx* dctx,
|
1030
1078
|
void* dst, size_t maxDstSize,
|
1031
|
-
const void* seqStart, size_t seqSize
|
1079
|
+
const void* seqStart, size_t seqSize,
|
1080
|
+
const ZSTD_longOffset_e isLongOffset)
|
1032
1081
|
{
|
1033
1082
|
const BYTE* ip = (const BYTE*)seqStart;
|
1034
1083
|
const BYTE* const iend = ip + seqSize;
|
@@ -1063,7 +1112,7 @@ static size_t ZSTD_decompressSequences(
|
|
1063
1112
|
|
1064
1113
|
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
|
1065
1114
|
nbSeq--;
|
1066
|
-
{ seq_t const sequence = ZSTD_decodeSequence(&seqState);
|
1115
|
+
{ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
|
1067
1116
|
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
|
1068
1117
|
DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
|
1069
1118
|
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
@@ -1088,13 +1137,14 @@ static size_t ZSTD_decompressSequences(
|
|
1088
1137
|
}
|
1089
1138
|
|
1090
1139
|
|
1091
|
-
|
1140
|
+
HINT_INLINE
|
1141
|
+
seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
|
1092
1142
|
{
|
1093
1143
|
seq_t seq;
|
1094
1144
|
|
1095
1145
|
U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
|
1096
1146
|
U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
|
1097
|
-
U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <=
|
1147
|
+
U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
|
1098
1148
|
|
1099
1149
|
U32 const llBits = LL_bits[llCode];
|
1100
1150
|
U32 const mlBits = ML_bits[mlCode];
|
@@ -1121,15 +1171,18 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState
|
|
1121
1171
|
0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
|
1122
1172
|
0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
|
1123
1173
|
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
|
1124
|
-
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
|
1174
|
+
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
|
1125
1175
|
|
1126
1176
|
/* sequence */
|
1127
1177
|
{ size_t offset;
|
1128
1178
|
if (!ofCode)
|
1129
1179
|
offset = 0;
|
1130
1180
|
else {
|
1131
|
-
|
1132
|
-
|
1181
|
+
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
1182
|
+
ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
|
1183
|
+
assert(ofBits <= MaxOff);
|
1184
|
+
if (MEM_32bits() && longOffsets) {
|
1185
|
+
U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
|
1133
1186
|
offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
|
1134
1187
|
if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
|
1135
1188
|
if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
|
@@ -1159,11 +1212,16 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState
|
|
1159
1212
|
}
|
1160
1213
|
|
1161
1214
|
seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
|
1162
|
-
if (MEM_32bits() && (mlBits+llBits
|
1215
|
+
if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
|
1216
|
+
BIT_reloadDStream(&seqState->DStream);
|
1217
|
+
if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
|
1218
|
+
BIT_reloadDStream(&seqState->DStream);
|
1219
|
+
/* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
|
1220
|
+
ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
|
1163
1221
|
|
1164
1222
|
seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
|
1165
|
-
if (MEM_32bits()
|
1166
|
-
|
1223
|
+
if (MEM_32bits())
|
1224
|
+
BIT_reloadDStream(&seqState->DStream);
|
1167
1225
|
|
1168
1226
|
{ size_t const pos = seqState->pos + seq.litLength;
|
1169
1227
|
seq.match = seqState->base + pos - seq.offset; /* single memory segment */
|
@@ -1180,19 +1238,12 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState
|
|
1180
1238
|
return seq;
|
1181
1239
|
}
|
1182
1240
|
|
1183
|
-
static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, unsigned const windowSize) {
|
1184
|
-
if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) {
|
1185
|
-
return ZSTD_decodeSequenceLong_generic(seqState, 1);
|
1186
|
-
} else {
|
1187
|
-
return ZSTD_decodeSequenceLong_generic(seqState, 0);
|
1188
|
-
}
|
1189
|
-
}
|
1190
1241
|
|
1191
1242
|
HINT_INLINE
|
1192
1243
|
size_t ZSTD_execSequenceLong(BYTE* op,
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1244
|
+
BYTE* const oend, seq_t sequence,
|
1245
|
+
const BYTE** litPtr, const BYTE* const litLimit,
|
1246
|
+
const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
|
1196
1247
|
{
|
1197
1248
|
BYTE* const oLitEnd = op + sequence.litLength;
|
1198
1249
|
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
@@ -1202,11 +1253,9 @@ size_t ZSTD_execSequenceLong(BYTE* op,
|
|
1202
1253
|
const BYTE* match = sequence.match;
|
1203
1254
|
|
1204
1255
|
/* check */
|
1205
|
-
#if 1
|
1206
1256
|
if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
|
1207
1257
|
if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
|
1208
1258
|
if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
|
1209
|
-
#endif
|
1210
1259
|
|
1211
1260
|
/* copy Literals */
|
1212
1261
|
ZSTD_copy8(op, *litPtr);
|
@@ -1216,7 +1265,6 @@ size_t ZSTD_execSequenceLong(BYTE* op,
|
|
1216
1265
|
*litPtr = iLitEnd; /* update for next sequence */
|
1217
1266
|
|
1218
1267
|
/* copy Match */
|
1219
|
-
#if 1
|
1220
1268
|
if (sequence.offset > (size_t)(oLitEnd - base)) {
|
1221
1269
|
/* offset beyond prefix */
|
1222
1270
|
if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
|
@@ -1236,8 +1284,8 @@ size_t ZSTD_execSequenceLong(BYTE* op,
|
|
1236
1284
|
return sequenceLength;
|
1237
1285
|
}
|
1238
1286
|
} }
|
1239
|
-
|
1240
|
-
|
1287
|
+
assert(op <= oend_w);
|
1288
|
+
assert(sequence.matchLength >= MINMATCH);
|
1241
1289
|
|
1242
1290
|
/* match within prefix */
|
1243
1291
|
if (sequence.offset < 8) {
|
@@ -1273,7 +1321,8 @@ size_t ZSTD_execSequenceLong(BYTE* op,
|
|
1273
1321
|
static size_t ZSTD_decompressSequencesLong(
|
1274
1322
|
ZSTD_DCtx* dctx,
|
1275
1323
|
void* dst, size_t maxDstSize,
|
1276
|
-
const void* seqStart, size_t seqSize
|
1324
|
+
const void* seqStart, size_t seqSize,
|
1325
|
+
const ZSTD_longOffset_e isLongOffset)
|
1277
1326
|
{
|
1278
1327
|
const BYTE* ip = (const BYTE*)seqStart;
|
1279
1328
|
const BYTE* const iend = ip + seqSize;
|
@@ -1285,7 +1334,6 @@ static size_t ZSTD_decompressSequencesLong(
|
|
1285
1334
|
const BYTE* const base = (const BYTE*) (dctx->base);
|
1286
1335
|
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
|
1287
1336
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
1288
|
-
unsigned const windowSize32 = (unsigned)dctx->fParams.windowSize;
|
1289
1337
|
int nbSeq;
|
1290
1338
|
|
1291
1339
|
/* Build Decoding Tables */
|
@@ -1315,13 +1363,13 @@ static size_t ZSTD_decompressSequencesLong(
|
|
1315
1363
|
|
1316
1364
|
/* prepare in advance */
|
1317
1365
|
for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb<seqAdvance; seqNb++) {
|
1318
|
-
sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState,
|
1366
|
+
sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
|
1319
1367
|
}
|
1320
1368
|
if (seqNb<seqAdvance) return ERROR(corruption_detected);
|
1321
1369
|
|
1322
1370
|
/* decode and decompress */
|
1323
1371
|
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb<nbSeq ; seqNb++) {
|
1324
|
-
seq_t const sequence = ZSTD_decodeSequenceLong(&seqState,
|
1372
|
+
seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
|
1325
1373
|
size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
|
1326
1374
|
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
1327
1375
|
PREFETCH(sequence.match);
|
@@ -1355,10 +1403,20 @@ static size_t ZSTD_decompressSequencesLong(
|
|
1355
1403
|
|
1356
1404
|
static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
1357
1405
|
void* dst, size_t dstCapacity,
|
1358
|
-
const void* src, size_t srcSize)
|
1406
|
+
const void* src, size_t srcSize, const int frame)
|
1359
1407
|
{ /* blockType == blockCompressed */
|
1360
1408
|
const BYTE* ip = (const BYTE*)src;
|
1361
|
-
|
1409
|
+
/* isLongOffset must be true if there are long offsets.
|
1410
|
+
* Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN.
|
1411
|
+
* We don't expect that to be the case in 64-bit mode.
|
1412
|
+
* If we are in block mode we don't know the window size, so we have to be
|
1413
|
+
* conservative.
|
1414
|
+
*/
|
1415
|
+
ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN)));
|
1416
|
+
/* windowSize could be any value at this point, since it is only validated
|
1417
|
+
* in the streaming API.
|
1418
|
+
*/
|
1419
|
+
DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
|
1362
1420
|
|
1363
1421
|
if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
|
1364
1422
|
|
@@ -1369,13 +1427,9 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|
1369
1427
|
ip += litCSize;
|
1370
1428
|
srcSize -= litCSize;
|
1371
1429
|
}
|
1372
|
-
if (
|
1373
|
-
|
1374
|
-
|
1375
|
-
/* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
|
1376
|
-
if (dctx->fParams.windowSize > (1<<23))
|
1377
|
-
return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
|
1378
|
-
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
|
1430
|
+
if (frame && dctx->fParams.windowSize > (1<<23))
|
1431
|
+
return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
|
1432
|
+
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
|
1379
1433
|
}
|
1380
1434
|
|
1381
1435
|
|
@@ -1395,7 +1449,7 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
|
|
1395
1449
|
{
|
1396
1450
|
size_t dSize;
|
1397
1451
|
ZSTD_checkContinuity(dctx, dst);
|
1398
|
-
dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
|
1452
|
+
dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0);
|
1399
1453
|
dctx->previousDstEnd = (char*)dst + dSize;
|
1400
1454
|
return dSize;
|
1401
1455
|
}
|
@@ -1411,7 +1465,7 @@ ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, siz
|
|
1411
1465
|
}
|
1412
1466
|
|
1413
1467
|
|
1414
|
-
size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
|
1468
|
+
static size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
|
1415
1469
|
{
|
1416
1470
|
if (length > dstCapacity) return ERROR(dstSize_tooSmall);
|
1417
1471
|
memset(dst, byte, length);
|
@@ -1431,7 +1485,7 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
|
|
1431
1485
|
#endif
|
1432
1486
|
if ( (srcSize >= ZSTD_skippableHeaderSize)
|
1433
1487
|
&& (MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START ) {
|
1434
|
-
return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src +
|
1488
|
+
return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + ZSTD_frameIdSize);
|
1435
1489
|
} else {
|
1436
1490
|
const BYTE* ip = (const BYTE*)src;
|
1437
1491
|
const BYTE* const ipstart = ip;
|
@@ -1511,7 +1565,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
1511
1565
|
switch(blockProperties.blockType)
|
1512
1566
|
{
|
1513
1567
|
case bt_compressed:
|
1514
|
-
decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
|
1568
|
+
decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize, /* frame */ 1);
|
1515
1569
|
break;
|
1516
1570
|
case bt_raw :
|
1517
1571
|
decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
|
@@ -1533,6 +1587,10 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
1533
1587
|
if (blockProperties.lastBlock) break;
|
1534
1588
|
}
|
1535
1589
|
|
1590
|
+
if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
1591
|
+
if ((U64)(op-ostart) != dctx->fParams.frameContentSize) {
|
1592
|
+
return ERROR(corruption_detected);
|
1593
|
+
} }
|
1536
1594
|
if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
|
1537
1595
|
U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
|
1538
1596
|
U32 checkRead;
|
@@ -1590,13 +1648,15 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
1590
1648
|
#endif
|
1591
1649
|
|
1592
1650
|
magicNumber = MEM_readLE32(src);
|
1651
|
+
DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
|
1652
|
+
(U32)magicNumber, (U32)ZSTD_MAGICNUMBER);
|
1593
1653
|
if (magicNumber != ZSTD_MAGICNUMBER) {
|
1594
1654
|
if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
1595
1655
|
size_t skippableSize;
|
1596
1656
|
if (srcSize < ZSTD_skippableHeaderSize)
|
1597
1657
|
return ERROR(srcSize_wrong);
|
1598
|
-
skippableSize = MEM_readLE32((const BYTE
|
1599
|
-
|
1658
|
+
skippableSize = MEM_readLE32((const BYTE*)src + ZSTD_frameIdSize)
|
1659
|
+
+ ZSTD_skippableHeaderSize;
|
1600
1660
|
if (srcSize < skippableSize) return ERROR(srcSize_wrong);
|
1601
1661
|
|
1602
1662
|
src = (const BYTE *)src + skippableSize;
|
@@ -1699,33 +1759,31 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
1699
1759
|
{
|
1700
1760
|
DEBUGLOG(5, "ZSTD_decompressContinue");
|
1701
1761
|
/* Sanity check */
|
1702
|
-
if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
|
1762
|
+
if (srcSize != dctx->expected) return ERROR(srcSize_wrong); /* not allowed */
|
1703
1763
|
if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
|
1704
1764
|
|
1705
1765
|
switch (dctx->stage)
|
1706
1766
|
{
|
1707
1767
|
case ZSTDds_getFrameHeaderSize :
|
1708
|
-
if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* unauthorized */
|
1709
1768
|
assert(src != NULL);
|
1710
|
-
if (
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1769
|
+
if (dctx->format == ZSTD_f_zstd1) { /* allows header */
|
1770
|
+
assert(srcSize >= ZSTD_frameIdSize); /* to read skippable magic number */
|
1771
|
+
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
|
1772
|
+
memcpy(dctx->headerBuffer, src, srcSize);
|
1773
|
+
dctx->expected = ZSTD_skippableHeaderSize - srcSize; /* remaining to load to get full skippable frame header */
|
1774
|
+
dctx->stage = ZSTDds_decodeSkippableHeader;
|
1775
|
+
return 0;
|
1776
|
+
} }
|
1777
|
+
dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format);
|
1717
1778
|
if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
|
1718
|
-
memcpy(dctx->headerBuffer, src,
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
}
|
1724
|
-
dctx->expected = 0; /* not necessary to copy more */
|
1725
|
-
/* fall-through */
|
1779
|
+
memcpy(dctx->headerBuffer, src, srcSize);
|
1780
|
+
dctx->expected = dctx->headerSize - srcSize;
|
1781
|
+
dctx->stage = ZSTDds_decodeFrameHeader;
|
1782
|
+
return 0;
|
1783
|
+
|
1726
1784
|
case ZSTDds_decodeFrameHeader:
|
1727
1785
|
assert(src != NULL);
|
1728
|
-
memcpy(dctx->headerBuffer +
|
1786
|
+
memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
|
1729
1787
|
CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
|
1730
1788
|
dctx->expected = ZSTD_blockHeaderSize;
|
1731
1789
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
@@ -1757,6 +1815,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
1757
1815
|
}
|
1758
1816
|
return 0;
|
1759
1817
|
}
|
1818
|
+
|
1760
1819
|
case ZSTDds_decompressLastBlock:
|
1761
1820
|
case ZSTDds_decompressBlock:
|
1762
1821
|
DEBUGLOG(5, "case ZSTDds_decompressBlock");
|
@@ -1765,7 +1824,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
1765
1824
|
{
|
1766
1825
|
case bt_compressed:
|
1767
1826
|
DEBUGLOG(5, "case bt_compressed");
|
1768
|
-
rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
|
1827
|
+
rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1);
|
1769
1828
|
break;
|
1770
1829
|
case bt_raw :
|
1771
1830
|
rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
|
@@ -1778,9 +1837,16 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
1778
1837
|
return ERROR(corruption_detected);
|
1779
1838
|
}
|
1780
1839
|
if (ZSTD_isError(rSize)) return rSize;
|
1840
|
+
DEBUGLOG(5, "decoded size from block : %u", (U32)rSize);
|
1841
|
+
dctx->decodedSize += rSize;
|
1781
1842
|
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
|
1782
1843
|
|
1783
1844
|
if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
|
1845
|
+
DEBUGLOG(4, "decoded size from frame : %u", (U32)dctx->decodedSize);
|
1846
|
+
if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
1847
|
+
if (dctx->decodedSize != dctx->fParams.frameContentSize) {
|
1848
|
+
return ERROR(corruption_detected);
|
1849
|
+
} }
|
1784
1850
|
if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
|
1785
1851
|
dctx->expected = 4;
|
1786
1852
|
dctx->stage = ZSTDds_checkChecksum;
|
@@ -1795,26 +1861,31 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
1795
1861
|
}
|
1796
1862
|
return rSize;
|
1797
1863
|
}
|
1864
|
+
|
1798
1865
|
case ZSTDds_checkChecksum:
|
1866
|
+
assert(srcSize == 4); /* guaranteed by dctx->expected */
|
1799
1867
|
{ U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
|
1800
|
-
U32 const check32 = MEM_readLE32(src);
|
1868
|
+
U32 const check32 = MEM_readLE32(src);
|
1869
|
+
DEBUGLOG(4, "checksum : calculated %08X :: %08X read", h32, check32);
|
1801
1870
|
if (check32 != h32) return ERROR(checksum_wrong);
|
1802
1871
|
dctx->expected = 0;
|
1803
1872
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
1804
1873
|
return 0;
|
1805
1874
|
}
|
1875
|
+
|
1806
1876
|
case ZSTDds_decodeSkippableHeader:
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1877
|
+
assert(src != NULL);
|
1878
|
+
assert(srcSize <= ZSTD_skippableHeaderSize);
|
1879
|
+
memcpy(dctx->headerBuffer + (ZSTD_skippableHeaderSize - srcSize), src, srcSize); /* complete skippable header */
|
1880
|
+
dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_frameIdSize); /* note : dctx->expected can grow seriously large, beyond local buffer size */
|
1881
|
+
dctx->stage = ZSTDds_skipFrame;
|
1882
|
+
return 0;
|
1883
|
+
|
1813
1884
|
case ZSTDds_skipFrame:
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1885
|
+
dctx->expected = 0;
|
1886
|
+
dctx->stage = ZSTDds_getFrameHeaderSize;
|
1887
|
+
return 0;
|
1888
|
+
|
1818
1889
|
default:
|
1819
1890
|
return ERROR(GENERIC); /* impossible */
|
1820
1891
|
}
|
@@ -1895,7 +1966,7 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
|
|
1895
1966
|
if (magic != ZSTD_MAGIC_DICTIONARY) {
|
1896
1967
|
return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
|
1897
1968
|
} }
|
1898
|
-
dctx->dictID = MEM_readLE32((const char*)dict +
|
1969
|
+
dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_frameIdSize);
|
1899
1970
|
|
1900
1971
|
/* load entropy tables */
|
1901
1972
|
{ size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
|
@@ -1909,6 +1980,29 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
|
|
1909
1980
|
return ZSTD_refDictContent(dctx, dict, dictSize);
|
1910
1981
|
}
|
1911
1982
|
|
1983
|
+
/* Note : this function cannot fail */
|
1984
|
+
size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
1985
|
+
{
|
1986
|
+
assert(dctx != NULL);
|
1987
|
+
dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */
|
1988
|
+
dctx->stage = ZSTDds_getFrameHeaderSize;
|
1989
|
+
dctx->decodedSize = 0;
|
1990
|
+
dctx->previousDstEnd = NULL;
|
1991
|
+
dctx->base = NULL;
|
1992
|
+
dctx->vBase = NULL;
|
1993
|
+
dctx->dictEnd = NULL;
|
1994
|
+
dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
|
1995
|
+
dctx->litEntropy = dctx->fseEntropy = 0;
|
1996
|
+
dctx->dictID = 0;
|
1997
|
+
ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
|
1998
|
+
memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
|
1999
|
+
dctx->LLTptr = dctx->entropy.LLTable;
|
2000
|
+
dctx->MLTptr = dctx->entropy.MLTable;
|
2001
|
+
dctx->OFTptr = dctx->entropy.OFTable;
|
2002
|
+
dctx->HUFptr = dctx->entropy.hufTable;
|
2003
|
+
return 0;
|
2004
|
+
}
|
2005
|
+
|
1912
2006
|
size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
1913
2007
|
{
|
1914
2008
|
CHECK_F( ZSTD_decompressBegin(dctx) );
|
@@ -1975,7 +2069,7 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
|
|
1975
2069
|
{ U32 const magic = MEM_readLE32(ddict->dictContent);
|
1976
2070
|
if (magic != ZSTD_MAGIC_DICTIONARY) return 0; /* pure content mode */
|
1977
2071
|
}
|
1978
|
-
ddict->dictID = MEM_readLE32((const char*)ddict->dictContent +
|
2072
|
+
ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_frameIdSize);
|
1979
2073
|
|
1980
2074
|
/* load entropy tables */
|
1981
2075
|
CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted );
|
@@ -1984,9 +2078,9 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
|
|
1984
2078
|
}
|
1985
2079
|
|
1986
2080
|
|
1987
|
-
static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize,
|
2081
|
+
static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
|
1988
2082
|
{
|
1989
|
-
if ((
|
2083
|
+
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
|
1990
2084
|
ddict->dictBuffer = NULL;
|
1991
2085
|
ddict->dictContent = dict;
|
1992
2086
|
} else {
|
@@ -2005,7 +2099,7 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_
|
|
2005
2099
|
return 0;
|
2006
2100
|
}
|
2007
2101
|
|
2008
|
-
ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
|
2102
|
+
ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_customMem customMem)
|
2009
2103
|
{
|
2010
2104
|
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
2011
2105
|
|
@@ -2013,7 +2107,7 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigne
|
|
2013
2107
|
if (!ddict) return NULL;
|
2014
2108
|
ddict->cMem = customMem;
|
2015
2109
|
|
2016
|
-
if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize,
|
2110
|
+
if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, dictLoadMethod) )) {
|
2017
2111
|
ZSTD_freeDDict(ddict);
|
2018
2112
|
return NULL;
|
2019
2113
|
}
|
@@ -2029,7 +2123,7 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigne
|
|
2029
2123
|
ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
|
2030
2124
|
{
|
2031
2125
|
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
2032
|
-
return ZSTD_createDDict_advanced(dict, dictSize,
|
2126
|
+
return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, allocator);
|
2033
2127
|
}
|
2034
2128
|
|
2035
2129
|
/*! ZSTD_createDDict_byReference() :
|
@@ -2039,25 +2133,26 @@ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
|
|
2039
2133
|
ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
|
2040
2134
|
{
|
2041
2135
|
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
2042
|
-
return ZSTD_createDDict_advanced(dictBuffer, dictSize,
|
2136
|
+
return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, allocator);
|
2043
2137
|
}
|
2044
2138
|
|
2045
2139
|
|
2046
2140
|
ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
|
2047
2141
|
const void* dict, size_t dictSize,
|
2048
|
-
|
2142
|
+
ZSTD_dictLoadMethod_e dictLoadMethod)
|
2049
2143
|
{
|
2050
|
-
size_t const neededSpace =
|
2144
|
+
size_t const neededSpace =
|
2145
|
+
sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
|
2051
2146
|
ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace;
|
2052
2147
|
assert(workspace != NULL);
|
2053
2148
|
assert(dict != NULL);
|
2054
2149
|
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
2055
2150
|
if (workspaceSize < neededSpace) return NULL;
|
2056
|
-
if (
|
2151
|
+
if (dictLoadMethod == ZSTD_dlm_byCopy) {
|
2057
2152
|
memcpy(ddict+1, dict, dictSize); /* local copy */
|
2058
2153
|
dict = ddict+1;
|
2059
2154
|
}
|
2060
|
-
if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize,
|
2155
|
+
if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, ZSTD_dlm_byRef) ))
|
2061
2156
|
return NULL;
|
2062
2157
|
return ddict;
|
2063
2158
|
}
|
@@ -2075,10 +2170,10 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
|
|
2075
2170
|
|
2076
2171
|
/*! ZSTD_estimateDDictSize() :
|
2077
2172
|
* Estimate amount of memory that will be needed to create a dictionary for decompression.
|
2078
|
-
* Note : dictionary created
|
2079
|
-
size_t ZSTD_estimateDDictSize(size_t dictSize,
|
2173
|
+
* Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */
|
2174
|
+
size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
|
2080
2175
|
{
|
2081
|
-
return sizeof(ZSTD_DDict) + (
|
2176
|
+
return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
|
2082
2177
|
}
|
2083
2178
|
|
2084
2179
|
size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
|
@@ -2095,7 +2190,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
|
|
2095
2190
|
{
|
2096
2191
|
if (dictSize < 8) return 0;
|
2097
2192
|
if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0;
|
2098
|
-
return MEM_readLE32((const char*)dict +
|
2193
|
+
return MEM_readLE32((const char*)dict + ZSTD_frameIdSize);
|
2099
2194
|
}
|
2100
2195
|
|
2101
2196
|
/*! ZSTD_getDictID_fromDDict() :
|
@@ -2123,7 +2218,7 @@ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
|
|
2123
2218
|
* ZSTD_getFrameHeader(), which will provide a more precise error code. */
|
2124
2219
|
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
|
2125
2220
|
{
|
2126
|
-
ZSTD_frameHeader zfp = { 0, 0, ZSTD_frame, 0, 0, 0 };
|
2221
|
+
ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 };
|
2127
2222
|
size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
|
2128
2223
|
if (ZSTD_isError(hError)) return 0;
|
2129
2224
|
return zfp.dictID;
|
@@ -2190,13 +2285,15 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
|
|
2190
2285
|
return ZSTD_frameHeaderSize_prefix;
|
2191
2286
|
}
|
2192
2287
|
|
2288
|
+
/* note : this variant can't fail */
|
2193
2289
|
size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
2194
2290
|
{
|
2195
2291
|
return ZSTD_initDStream_usingDict(zds, NULL, 0);
|
2196
2292
|
}
|
2197
2293
|
|
2198
2294
|
/* ZSTD_initDStream_usingDDict() :
|
2199
|
-
* ddict will just be referenced, and must outlive decompression session
|
2295
|
+
* ddict will just be referenced, and must outlive decompression session
|
2296
|
+
* this function cannot fail */
|
2200
2297
|
size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict)
|
2201
2298
|
{
|
2202
2299
|
size_t const initResult = ZSTD_initDStream(zds);
|
@@ -2216,31 +2313,66 @@ size_t ZSTD_resetDStream(ZSTD_DStream* zds)
|
|
2216
2313
|
size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
|
2217
2314
|
ZSTD_DStreamParameter_e paramType, unsigned paramValue)
|
2218
2315
|
{
|
2316
|
+
ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
|
2317
|
+
if ((unsigned)zds->streamStage > (unsigned)zdss_loadHeader)
|
2318
|
+
return ERROR(stage_wrong);
|
2219
2319
|
switch(paramType)
|
2220
2320
|
{
|
2221
2321
|
default : return ERROR(parameter_unsupported);
|
2222
|
-
case DStream_p_maxWindowSize :
|
2322
|
+
case DStream_p_maxWindowSize :
|
2323
|
+
DEBUGLOG(4, "setting maxWindowSize = %u KB", paramValue >> 10);
|
2324
|
+
zds->maxWindowSize = paramValue ? paramValue : (U32)(-1);
|
2325
|
+
break;
|
2223
2326
|
}
|
2224
2327
|
return 0;
|
2225
2328
|
}
|
2226
2329
|
|
2330
|
+
size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
|
2331
|
+
{
|
2332
|
+
ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
|
2333
|
+
if ((unsigned)dctx->streamStage > (unsigned)zdss_loadHeader)
|
2334
|
+
return ERROR(stage_wrong);
|
2335
|
+
dctx->maxWindowSize = maxWindowSize;
|
2336
|
+
return 0;
|
2337
|
+
}
|
2338
|
+
|
2339
|
+
size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)
|
2340
|
+
{
|
2341
|
+
DEBUGLOG(4, "ZSTD_DCtx_setFormat : %u", (unsigned)format);
|
2342
|
+
ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
|
2343
|
+
if ((unsigned)dctx->streamStage > (unsigned)zdss_loadHeader)
|
2344
|
+
return ERROR(stage_wrong);
|
2345
|
+
dctx->format = format;
|
2346
|
+
return 0;
|
2347
|
+
}
|
2348
|
+
|
2227
2349
|
|
2228
2350
|
size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
|
2229
2351
|
{
|
2230
2352
|
return ZSTD_sizeof_DCtx(zds);
|
2231
2353
|
}
|
2232
2354
|
|
2355
|
+
size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
|
2356
|
+
{
|
2357
|
+
size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
|
2358
|
+
unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
|
2359
|
+
unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
|
2360
|
+
size_t const minRBSize = (size_t) neededSize;
|
2361
|
+
if ((unsigned long long)minRBSize != neededSize) return ERROR(frameParameter_windowTooLarge);
|
2362
|
+
return minRBSize;
|
2363
|
+
}
|
2364
|
+
|
2233
2365
|
size_t ZSTD_estimateDStreamSize(size_t windowSize)
|
2234
2366
|
{
|
2235
2367
|
size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
|
2236
2368
|
size_t const inBuffSize = blockSize; /* no block can be larger */
|
2237
|
-
size_t const outBuffSize = windowSize
|
2369
|
+
size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN);
|
2238
2370
|
return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
|
2239
2371
|
}
|
2240
2372
|
|
2241
|
-
|
2373
|
+
size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
|
2242
2374
|
{
|
2243
|
-
U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
|
2375
|
+
U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable */
|
2244
2376
|
ZSTD_frameHeader zfh;
|
2245
2377
|
size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
|
2246
2378
|
if (ZSTD_isError(err)) return err;
|
@@ -2272,7 +2404,18 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
2272
2404
|
U32 someMoreWork = 1;
|
2273
2405
|
|
2274
2406
|
DEBUGLOG(5, "ZSTD_decompressStream");
|
2407
|
+
if (input->pos > input->size) { /* forbidden */
|
2408
|
+
DEBUGLOG(5, "in: pos: %u vs size: %u",
|
2409
|
+
(U32)input->pos, (U32)input->size);
|
2410
|
+
return ERROR(srcSize_wrong);
|
2411
|
+
}
|
2412
|
+
if (output->pos > output->size) { /* forbidden */
|
2413
|
+
DEBUGLOG(5, "out: pos: %u vs size: %u",
|
2414
|
+
(U32)output->pos, (U32)output->size);
|
2415
|
+
return ERROR(dstSize_tooSmall);
|
2416
|
+
}
|
2275
2417
|
DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
|
2418
|
+
|
2276
2419
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
2277
2420
|
if (zds->legacyVersion) {
|
2278
2421
|
/* legacy support is incompatible with static dctx */
|
@@ -2289,7 +2432,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
2289
2432
|
/* fall-through */
|
2290
2433
|
|
2291
2434
|
case zdss_loadHeader :
|
2292
|
-
|
2435
|
+
DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
|
2436
|
+
{ size_t const hSize = ZSTD_getFrameHeader_internal(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
|
2437
|
+
DEBUGLOG(5, "header size : %u", (U32)hSize);
|
2293
2438
|
if (ZSTD_isError(hSize)) {
|
2294
2439
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
2295
2440
|
U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
|
@@ -2342,7 +2487,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
2342
2487
|
CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict));
|
2343
2488
|
|
2344
2489
|
if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
|
2345
|
-
zds->expected = MEM_readLE32(zds->headerBuffer +
|
2490
|
+
zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_frameIdSize);
|
2346
2491
|
zds->stage = ZSTDds_skipFrame;
|
2347
2492
|
} else {
|
2348
2493
|
CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
|
@@ -2351,20 +2496,20 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
2351
2496
|
}
|
2352
2497
|
|
2353
2498
|
/* control buffer memory usage */
|
2354
|
-
DEBUGLOG(4, "Control max buffer memory usage"
|
2499
|
+
DEBUGLOG(4, "Control max buffer memory usage (max %u KB)",
|
2500
|
+
(U32)(zds->maxWindowSize >> 10));
|
2355
2501
|
zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
2356
2502
|
if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
|
2357
2503
|
|
2358
2504
|
/* Adapt buffer sizes to frame header instructions */
|
2359
|
-
{ size_t const
|
2360
|
-
size_t const
|
2361
|
-
zds->
|
2362
|
-
|
2363
|
-
size_t const bufferSize = blockSize + neededOutSize;
|
2505
|
+
{ size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
|
2506
|
+
size_t const neededOutBuffSize = ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize);
|
2507
|
+
if ((zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize)) {
|
2508
|
+
size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
|
2364
2509
|
DEBUGLOG(4, "inBuff : from %u to %u",
|
2365
|
-
(U32)zds->inBuffSize, (U32)
|
2510
|
+
(U32)zds->inBuffSize, (U32)neededInBuffSize);
|
2366
2511
|
DEBUGLOG(4, "outBuff : from %u to %u",
|
2367
|
-
(U32)zds->outBuffSize, (U32)
|
2512
|
+
(U32)zds->outBuffSize, (U32)neededOutBuffSize);
|
2368
2513
|
if (zds->staticSize) { /* static DCtx */
|
2369
2514
|
DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
|
2370
2515
|
assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
|
@@ -2377,9 +2522,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
2377
2522
|
zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
|
2378
2523
|
if (zds->inBuff == NULL) return ERROR(memory_allocation);
|
2379
2524
|
}
|
2380
|
-
zds->inBuffSize =
|
2525
|
+
zds->inBuffSize = neededInBuffSize;
|
2381
2526
|
zds->outBuff = zds->inBuff + zds->inBuffSize;
|
2382
|
-
zds->outBuffSize =
|
2527
|
+
zds->outBuffSize = neededOutBuffSize;
|
2383
2528
|
} }
|
2384
2529
|
zds->streamStage = zdss_read;
|
2385
2530
|
/* fall-through */
|
@@ -2437,8 +2582,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
2437
2582
|
zds->outStart += flushedSize;
|
2438
2583
|
if (flushedSize == toFlushSize) { /* flush completed */
|
2439
2584
|
zds->streamStage = zdss_read;
|
2440
|
-
if (
|
2585
|
+
if ( (zds->outBuffSize < zds->fParams.frameContentSize)
|
2586
|
+
&& (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
|
2587
|
+
DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
|
2588
|
+
(int)(zds->outBuffSize - zds->outStart),
|
2589
|
+
(U32)zds->fParams.blockSizeMax);
|
2441
2590
|
zds->outStart = zds->outEnd = 0;
|
2591
|
+
}
|
2442
2592
|
break;
|
2443
2593
|
} }
|
2444
2594
|
/* cannot complete flush */
|
@@ -2476,3 +2626,30 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
2476
2626
|
return nextSrcSizeHint;
|
2477
2627
|
}
|
2478
2628
|
}
|
2629
|
+
|
2630
|
+
|
2631
|
+
size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
|
2632
|
+
{
|
2633
|
+
return ZSTD_decompressStream(dctx, output, input);
|
2634
|
+
}
|
2635
|
+
|
2636
|
+
size_t ZSTD_decompress_generic_simpleArgs (
|
2637
|
+
ZSTD_DCtx* dctx,
|
2638
|
+
void* dst, size_t dstCapacity, size_t* dstPos,
|
2639
|
+
const void* src, size_t srcSize, size_t* srcPos)
|
2640
|
+
{
|
2641
|
+
ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
|
2642
|
+
ZSTD_inBuffer input = { src, srcSize, *srcPos };
|
2643
|
+
/* ZSTD_compress_generic() will check validity of dstPos and srcPos */
|
2644
|
+
size_t const cErr = ZSTD_decompress_generic(dctx, &output, &input);
|
2645
|
+
*dstPos = output.pos;
|
2646
|
+
*srcPos = input.pos;
|
2647
|
+
return cErr;
|
2648
|
+
}
|
2649
|
+
|
2650
|
+
void ZSTD_DCtx_reset(ZSTD_DCtx* dctx)
|
2651
|
+
{
|
2652
|
+
(void)ZSTD_initDStream(dctx);
|
2653
|
+
dctx->format = ZSTD_f_zstd1;
|
2654
|
+
dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
|
2655
|
+
}
|