zstd-ruby 1.3.1.1 → 1.3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|