zstd-ruby 1.1.4.0 → 1.2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/Makefile +11 -1
- data/ext/zstdruby/libzstd/README.md +8 -0
- data/ext/zstdruby/libzstd/common/bitstream.h +56 -27
- data/ext/zstdruby/libzstd/common/error_private.c +2 -1
- data/ext/zstdruby/libzstd/common/fse.h +7 -3
- data/ext/zstdruby/libzstd/common/huf.h +42 -19
- data/ext/zstdruby/libzstd/common/mem.h +2 -3
- data/ext/zstdruby/libzstd/common/zstd_errors.h +1 -0
- data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -2
- data/ext/zstdruby/libzstd/compress/fse_compress.c +10 -10
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +455 -244
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +6 -4
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +40 -28
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +115 -219
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +34 -13
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +65 -43
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +7 -7
- data/ext/zstdruby/libzstd/dll/example/README.md +5 -5
- data/ext/zstdruby/libzstd/dll/example/build_package.bat +1 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +21 -21
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +20 -20
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +4 -4
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +2 -2
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +2 -2
- data/ext/zstdruby/libzstd/zstd.h +88 -68
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +3 -3
@@ -89,8 +89,7 @@ MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (size
|
|
89
89
|
#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
|
90
90
|
# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
|
91
91
|
# define MEM_FORCE_MEMORY_ACCESS 2
|
92
|
-
# elif defined(__INTEL_COMPILER)
|
93
|
-
(defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
|
92
|
+
# elif defined(__INTEL_COMPILER) || defined(__GNUC__)
|
94
93
|
# define MEM_FORCE_MEMORY_ACCESS 1
|
95
94
|
# endif
|
96
95
|
#endif
|
@@ -122,7 +121,7 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
|
|
122
121
|
/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
|
123
122
|
/* currently only defined for gcc and icc */
|
124
123
|
#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
|
125
|
-
|
124
|
+
__pragma( pack(push, 1) )
|
126
125
|
typedef union { U16 u16; U32 u32; U64 u64; size_t st; } unalign;
|
127
126
|
__pragma( pack(pop) )
|
128
127
|
#else
|
@@ -16,9 +16,9 @@
|
|
16
16
|
#ifdef _MSC_VER /* Visual Studio */
|
17
17
|
# define FORCE_INLINE static __forceinline
|
18
18
|
# include <intrin.h> /* For Visual 2005 */
|
19
|
+
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
|
19
20
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
20
21
|
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
21
|
-
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
|
22
22
|
#else
|
23
23
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
24
24
|
# ifdef __GNUC__
|
@@ -58,6 +58,8 @@
|
|
58
58
|
/*-*************************************
|
59
59
|
* shared macros
|
60
60
|
***************************************/
|
61
|
+
#undef MIN
|
62
|
+
#undef MAX
|
61
63
|
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
62
64
|
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
63
65
|
#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; } /* check and Forward error code */
|
@@ -104,7 +106,6 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy
|
|
104
106
|
#define LONGNBSEQ 0x7F00
|
105
107
|
|
106
108
|
#define MINMATCH 3
|
107
|
-
#define EQUAL_READ32 4
|
108
109
|
|
109
110
|
#define Litbits 8
|
110
111
|
#define MaxLit ((1<<Litbits) - 1)
|
@@ -291,7 +291,7 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
|
291
291
|
|
292
292
|
size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
|
293
293
|
{
|
294
|
-
if (tableLog > FSE_MAX_TABLELOG) return ERROR(
|
294
|
+
if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */
|
295
295
|
if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */
|
296
296
|
|
297
297
|
if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
|
@@ -476,20 +476,20 @@ void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
|
|
476
476
|
/* provides the minimum logSize to safely represent a distribution */
|
477
477
|
static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
|
478
478
|
{
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
479
|
+
U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
|
480
|
+
U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
|
481
|
+
U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
|
482
|
+
return minBits;
|
483
483
|
}
|
484
484
|
|
485
485
|
unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
|
486
486
|
{
|
487
|
-
|
487
|
+
U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
|
488
488
|
U32 tableLog = maxTableLog;
|
489
|
-
|
489
|
+
U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
|
490
490
|
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
491
|
-
|
492
|
-
|
491
|
+
if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */
|
492
|
+
if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
|
493
493
|
if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
|
494
494
|
if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
|
495
495
|
return tableLog;
|
@@ -808,7 +808,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
|
|
808
808
|
if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
|
809
809
|
|
810
810
|
/* Scan input and build symbol stats */
|
811
|
-
{ CHECK_V_F(maxCount,
|
811
|
+
{ CHECK_V_F(maxCount, FSE_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned*)scratchBuffer) );
|
812
812
|
if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
|
813
813
|
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
|
814
814
|
if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
|
@@ -20,6 +20,26 @@
|
|
20
20
|
#include "zstd_internal.h" /* includes zstd.h */
|
21
21
|
|
22
22
|
|
23
|
+
/*-*************************************
|
24
|
+
* Debug
|
25
|
+
***************************************/
|
26
|
+
#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
|
27
|
+
# include <assert.h>
|
28
|
+
#else
|
29
|
+
# define assert(condition) ((void)0)
|
30
|
+
#endif
|
31
|
+
|
32
|
+
#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
|
33
|
+
|
34
|
+
#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
|
35
|
+
# include <stdio.h>
|
36
|
+
static unsigned g_debugLevel = ZSTD_DEBUG;
|
37
|
+
# define DEBUGLOG(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __FILE__ ": "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, " \n"); }
|
38
|
+
#else
|
39
|
+
# define DEBUGLOG(l, ...) {} /* disabled */
|
40
|
+
#endif
|
41
|
+
|
42
|
+
|
23
43
|
/*-*************************************
|
24
44
|
* Constants
|
25
45
|
***************************************/
|
@@ -27,12 +47,22 @@ static const U32 g_searchStrength = 8; /* control skip over incompressible dat
|
|
27
47
|
#define HASH_READ_SIZE 8
|
28
48
|
typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
|
29
49
|
|
50
|
+
/* entropy tables always have same size */
|
51
|
+
static size_t const hufCTable_size = HUF_CTABLE_SIZE(255);
|
52
|
+
static size_t const litlengthCTable_size = FSE_CTABLE_SIZE(LLFSELog, MaxLL);
|
53
|
+
static size_t const offcodeCTable_size = FSE_CTABLE_SIZE(OffFSELog, MaxOff);
|
54
|
+
static size_t const matchlengthCTable_size = FSE_CTABLE_SIZE(MLFSELog, MaxML);
|
55
|
+
static size_t const entropyScratchSpace_size = HUF_WORKSPACE_SIZE;
|
56
|
+
|
30
57
|
|
31
58
|
/*-*************************************
|
32
59
|
* Helper functions
|
33
60
|
***************************************/
|
34
|
-
|
35
|
-
size_t
|
61
|
+
size_t ZSTD_compressBound(size_t srcSize) {
|
62
|
+
size_t const lowLimit = 256 KB;
|
63
|
+
size_t const margin = (srcSize < lowLimit) ? (lowLimit-srcSize) >> 12 : 0; /* from 64 to 0 */
|
64
|
+
return srcSize + (srcSize >> 8) + margin;
|
65
|
+
}
|
36
66
|
|
37
67
|
|
38
68
|
/*-*************************************
|
@@ -70,6 +100,7 @@ struct ZSTD_CCtx_s {
|
|
70
100
|
size_t workSpaceSize;
|
71
101
|
size_t blockSize;
|
72
102
|
U64 frameContentSize;
|
103
|
+
U64 consumedSrcSize;
|
73
104
|
XXH64_state_t xxhState;
|
74
105
|
ZSTD_customMem customMem;
|
75
106
|
|
@@ -77,13 +108,13 @@ struct ZSTD_CCtx_s {
|
|
77
108
|
U32* hashTable;
|
78
109
|
U32* hashTable3;
|
79
110
|
U32* chainTable;
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
FSE_CTable offcodeCTable
|
84
|
-
FSE_CTable matchlengthCTable
|
85
|
-
FSE_CTable litlengthCTable
|
86
|
-
unsigned
|
111
|
+
HUF_repeat hufCTable_repeatMode;
|
112
|
+
HUF_CElt* hufCTable;
|
113
|
+
U32 fseCTables_ready;
|
114
|
+
FSE_CTable* offcodeCTable;
|
115
|
+
FSE_CTable* matchlengthCTable;
|
116
|
+
FSE_CTable* litlengthCTable;
|
117
|
+
unsigned* entropyScratchSpace;
|
87
118
|
};
|
88
119
|
|
89
120
|
ZSTD_CCtx* ZSTD_createCCtx(void)
|
@@ -150,9 +181,7 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|
150
181
|
CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
|
151
182
|
CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
152
183
|
CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
153
|
-
|
154
|
-
U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1;
|
155
|
-
CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); }
|
184
|
+
CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
156
185
|
CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
|
157
186
|
if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) return ERROR(compressionParameter_unsupported);
|
158
187
|
return 0;
|
@@ -206,11 +235,14 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
|
|
206
235
|
size_t const hSize = ((size_t)1) << cParams.hashLog;
|
207
236
|
U32 const hashLog3 = (cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
|
208
237
|
size_t const h3Size = ((size_t)1) << hashLog3;
|
238
|
+
size_t const entropySpace = hufCTable_size + litlengthCTable_size
|
239
|
+
+ offcodeCTable_size + matchlengthCTable_size
|
240
|
+
+ entropyScratchSpace_size;
|
209
241
|
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
210
242
|
|
211
243
|
size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
|
212
244
|
+ (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
|
213
|
-
size_t const neededSpace =
|
245
|
+
size_t const neededSpace = entropySpace + tableSpace + tokenSpace
|
214
246
|
+ (((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btopt2)) ? optSpace : 0);
|
215
247
|
|
216
248
|
return sizeof(ZSTD_CCtx) + neededSpace;
|
@@ -232,6 +264,7 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra
|
|
232
264
|
U32 const end = (U32)(cctx->nextSrc - cctx->base);
|
233
265
|
cctx->params = params;
|
234
266
|
cctx->frameContentSize = frameContentSize;
|
267
|
+
cctx->consumedSrcSize = 0;
|
235
268
|
cctx->lowLimit = end;
|
236
269
|
cctx->dictLimit = end;
|
237
270
|
cctx->nextToUpdate = end+1;
|
@@ -246,16 +279,16 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra
|
|
246
279
|
|
247
280
|
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e;
|
248
281
|
|
249
|
-
/*!
|
282
|
+
/*! ZSTD_resetCCtx_internal() :
|
250
283
|
note : `params` must be validated */
|
251
|
-
static size_t
|
284
|
+
static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
|
252
285
|
ZSTD_parameters params, U64 frameContentSize,
|
253
286
|
ZSTD_compResetPolicy_e const crp)
|
254
287
|
{
|
255
288
|
if (crp == ZSTDcrp_continue)
|
256
289
|
if (ZSTD_equivalentParams(params, zc->params)) {
|
257
|
-
zc->
|
258
|
-
zc->
|
290
|
+
zc->fseCTables_ready = 0;
|
291
|
+
zc->hufCTable_repeatMode = HUF_repeat_none;
|
259
292
|
return ZSTD_continueCCtx(zc, params, frameContentSize);
|
260
293
|
}
|
261
294
|
|
@@ -271,41 +304,67 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|
271
304
|
void* ptr;
|
272
305
|
|
273
306
|
/* Check if workSpace is large enough, alloc a new one if needed */
|
274
|
-
{ size_t const
|
275
|
-
+
|
276
|
-
|
277
|
-
|
307
|
+
{ size_t const entropySpace = hufCTable_size + litlengthCTable_size
|
308
|
+
+ offcodeCTable_size + matchlengthCTable_size
|
309
|
+
+ entropyScratchSpace_size;
|
310
|
+
size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits)) * sizeof(U32)
|
311
|
+
+ (ZSTD_OPT_NUM+1) * (sizeof(ZSTD_match_t)+sizeof(ZSTD_optimal_t));
|
312
|
+
size_t const optSpace = ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) ? optPotentialSpace : 0;
|
313
|
+
size_t const neededSpace = entropySpace + optSpace + tableSpace + tokenSpace;
|
278
314
|
if (zc->workSpaceSize < neededSpace) {
|
315
|
+
zc->workSpaceSize = 0;
|
279
316
|
ZSTD_free(zc->workSpace, zc->customMem);
|
280
317
|
zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
|
281
318
|
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
282
319
|
zc->workSpaceSize = neededSpace;
|
320
|
+
ptr = zc->workSpace;
|
321
|
+
|
322
|
+
/* entropy space */
|
323
|
+
zc->hufCTable = (HUF_CElt*)ptr;
|
324
|
+
ptr = (char*)zc->hufCTable + hufCTable_size; /* note : HUF_CElt* is incomplete type, size is estimated via macro */
|
325
|
+
zc->offcodeCTable = (FSE_CTable*) ptr;
|
326
|
+
ptr = (char*)ptr + offcodeCTable_size;
|
327
|
+
zc->matchlengthCTable = (FSE_CTable*) ptr;
|
328
|
+
ptr = (char*)ptr + matchlengthCTable_size;
|
329
|
+
zc->litlengthCTable = (FSE_CTable*) ptr;
|
330
|
+
ptr = (char*)ptr + litlengthCTable_size;
|
331
|
+
assert(((size_t)ptr & 3) == 0); /* ensure correct alignment */
|
332
|
+
zc->entropyScratchSpace = (unsigned*) ptr;
|
283
333
|
} }
|
284
334
|
|
285
|
-
|
286
|
-
|
287
|
-
zc->
|
288
|
-
zc->
|
289
|
-
zc->
|
290
|
-
zc->hashTable3 = zc->chainTable + chainSize;
|
291
|
-
ptr = zc->hashTable3 + h3Size;
|
292
|
-
zc->hufTable = (HUF_CElt*)ptr;
|
293
|
-
zc->flagStaticTables = 0;
|
294
|
-
zc->flagStaticHufTable = HUF_repeat_none;
|
295
|
-
ptr = ((U32*)ptr) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
|
335
|
+
/* init params */
|
336
|
+
zc->params = params;
|
337
|
+
zc->blockSize = blockSize;
|
338
|
+
zc->frameContentSize = frameContentSize;
|
339
|
+
zc->consumedSrcSize = 0;
|
296
340
|
|
341
|
+
XXH64_reset(&zc->xxhState, 0);
|
342
|
+
zc->stage = ZSTDcs_init;
|
343
|
+
zc->dictID = 0;
|
344
|
+
zc->loadedDictEnd = 0;
|
345
|
+
zc->fseCTables_ready = 0;
|
346
|
+
zc->hufCTable_repeatMode = HUF_repeat_none;
|
297
347
|
zc->nextToUpdate = 1;
|
298
348
|
zc->nextSrc = NULL;
|
299
349
|
zc->base = NULL;
|
300
350
|
zc->dictBase = NULL;
|
301
351
|
zc->dictLimit = 0;
|
302
352
|
zc->lowLimit = 0;
|
303
|
-
zc->params = params;
|
304
|
-
zc->blockSize = blockSize;
|
305
|
-
zc->frameContentSize = frameContentSize;
|
306
353
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
|
354
|
+
zc->hashLog3 = hashLog3;
|
355
|
+
zc->seqStore.litLengthSum = 0;
|
356
|
+
|
357
|
+
/* ensure entropy tables are close together at the beginning */
|
358
|
+
assert((void*)zc->hufCTable == zc->workSpace);
|
359
|
+
assert((char*)zc->offcodeCTable == (char*)zc->hufCTable + hufCTable_size);
|
360
|
+
assert((char*)zc->matchlengthCTable == (char*)zc->offcodeCTable + offcodeCTable_size);
|
361
|
+
assert((char*)zc->litlengthCTable == (char*)zc->matchlengthCTable + matchlengthCTable_size);
|
362
|
+
assert((char*)zc->entropyScratchSpace == (char*)zc->litlengthCTable + litlengthCTable_size);
|
363
|
+
ptr = (char*)zc->entropyScratchSpace + entropyScratchSpace_size;
|
307
364
|
|
365
|
+
/* opt parser space */
|
308
366
|
if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) {
|
367
|
+
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
309
368
|
zc->seqStore.litFreq = (U32*)ptr;
|
310
369
|
zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
|
311
370
|
zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
|
@@ -315,8 +374,17 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|
315
374
|
ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
|
316
375
|
zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
|
317
376
|
ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
|
318
|
-
zc->seqStore.litLengthSum = 0;
|
319
377
|
}
|
378
|
+
|
379
|
+
/* table Space */
|
380
|
+
if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
|
381
|
+
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
382
|
+
zc->hashTable = (U32*)(ptr);
|
383
|
+
zc->chainTable = zc->hashTable + hSize;
|
384
|
+
zc->hashTable3 = zc->chainTable + chainSize;
|
385
|
+
ptr = zc->hashTable3 + h3Size;
|
386
|
+
|
387
|
+
/* sequences storage */
|
320
388
|
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
321
389
|
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
322
390
|
zc->seqStore.llCode = (BYTE*) ptr;
|
@@ -324,10 +392,6 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|
324
392
|
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
325
393
|
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
326
394
|
|
327
|
-
zc->stage = ZSTDcs_init;
|
328
|
-
zc->dictID = 0;
|
329
|
-
zc->loadedDictEnd = 0;
|
330
|
-
|
331
395
|
return 0;
|
332
396
|
}
|
333
397
|
}
|
@@ -341,27 +405,32 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
|
|
341
405
|
for (i=0; i<ZSTD_REP_NUM; i++) cctx->rep[i] = 0;
|
342
406
|
}
|
343
407
|
|
344
|
-
|
345
|
-
|
346
|
-
*
|
347
|
-
*
|
348
|
-
|
408
|
+
|
409
|
+
/*! ZSTD_copyCCtx_internal() :
|
410
|
+
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
|
411
|
+
* Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
|
412
|
+
* pledgedSrcSize=0 means "empty" if fParams.contentSizeFlag=1
|
413
|
+
* @return : 0, or an error code */
|
414
|
+
size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx,
|
415
|
+
ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize)
|
349
416
|
{
|
350
417
|
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
|
351
418
|
|
352
|
-
|
353
419
|
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
|
354
420
|
{ ZSTD_parameters params = srcCCtx->params;
|
355
|
-
params.fParams
|
356
|
-
|
421
|
+
params.fParams = fParams;
|
422
|
+
DEBUGLOG(5, "ZSTD_resetCCtx_internal : dictIDFlag : %u \n", !fParams.noDictIDFlag);
|
423
|
+
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
|
357
424
|
}
|
358
425
|
|
359
426
|
/* copy tables */
|
360
427
|
{ size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
|
361
|
-
size_t const hSize =
|
428
|
+
size_t const hSize = (size_t)1 << srcCCtx->params.cParams.hashLog;
|
362
429
|
size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
|
363
430
|
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
364
|
-
|
431
|
+
assert((U32*)dstCCtx->chainTable == (U32*)dstCCtx->hashTable + hSize); /* chainTable must follow hashTable */
|
432
|
+
assert((U32*)dstCCtx->hashTable3 == (U32*)dstCCtx->chainTable + chainSize);
|
433
|
+
memcpy(dstCCtx->hashTable, srcCCtx->hashTable, tableSpace); /* presumes all tables follow each other */
|
365
434
|
}
|
366
435
|
|
367
436
|
/* copy dictionary offsets */
|
@@ -376,23 +445,36 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long
|
|
376
445
|
dstCCtx->dictID = srcCCtx->dictID;
|
377
446
|
|
378
447
|
/* copy entropy tables */
|
379
|
-
dstCCtx->
|
380
|
-
|
381
|
-
|
382
|
-
memcpy(dstCCtx->
|
383
|
-
memcpy(dstCCtx->
|
384
|
-
memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable));
|
448
|
+
dstCCtx->fseCTables_ready = srcCCtx->fseCTables_ready;
|
449
|
+
if (srcCCtx->fseCTables_ready) {
|
450
|
+
memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, litlengthCTable_size);
|
451
|
+
memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, matchlengthCTable_size);
|
452
|
+
memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, offcodeCTable_size);
|
385
453
|
}
|
386
|
-
|
387
|
-
|
454
|
+
dstCCtx->hufCTable_repeatMode = srcCCtx->hufCTable_repeatMode;
|
455
|
+
if (srcCCtx->hufCTable_repeatMode) {
|
456
|
+
memcpy(dstCCtx->hufCTable, srcCCtx->hufCTable, hufCTable_size);
|
388
457
|
}
|
389
458
|
|
390
459
|
return 0;
|
391
460
|
}
|
392
461
|
|
462
|
+
/*! ZSTD_copyCCtx() :
|
463
|
+
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
|
464
|
+
* Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
|
465
|
+
* pledgedSrcSize==0 means "unknown".
|
466
|
+
* @return : 0, or an error code */
|
467
|
+
size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
|
468
|
+
{
|
469
|
+
ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
|
470
|
+
fParams.contentSizeFlag = pledgedSrcSize>0;
|
471
|
+
|
472
|
+
return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, fParams, pledgedSrcSize);
|
473
|
+
}
|
474
|
+
|
393
475
|
|
394
476
|
/*! ZSTD_reduceTable() :
|
395
|
-
*
|
477
|
+
* reduce table indexes by `reducerValue` */
|
396
478
|
static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reducerValue)
|
397
479
|
{
|
398
480
|
U32 u;
|
@@ -499,26 +581,28 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
|
|
499
581
|
|
500
582
|
/* small ? don't even attempt compression (speed opt) */
|
501
583
|
# define LITERAL_NOENTROPY 63
|
502
|
-
{ size_t const minLitSize = zc->
|
584
|
+
{ size_t const minLitSize = zc->hufCTable_repeatMode == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
|
503
585
|
if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
504
586
|
}
|
505
587
|
|
506
588
|
if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
507
|
-
{ HUF_repeat repeat = zc->
|
589
|
+
{ HUF_repeat repeat = zc->hufCTable_repeatMode;
|
508
590
|
int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
|
509
591
|
if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
|
510
|
-
cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
|
511
|
-
|
592
|
+
cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
|
593
|
+
zc->entropyScratchSpace, entropyScratchSpace_size, zc->hufCTable, &repeat, preferRepeat)
|
594
|
+
: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
|
595
|
+
zc->entropyScratchSpace, entropyScratchSpace_size, zc->hufCTable, &repeat, preferRepeat);
|
512
596
|
if (repeat != HUF_repeat_none) { hType = set_repeat; } /* reused the existing table */
|
513
|
-
else { zc->
|
597
|
+
else { zc->hufCTable_repeatMode = HUF_repeat_check; } /* now have a table to reuse */
|
514
598
|
}
|
515
599
|
|
516
600
|
if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) {
|
517
|
-
zc->
|
601
|
+
zc->hufCTable_repeatMode = HUF_repeat_none;
|
518
602
|
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
519
603
|
}
|
520
604
|
if (cLitSize==1) {
|
521
|
-
zc->
|
605
|
+
zc->hufCTable_repeatMode = HUF_repeat_none;
|
522
606
|
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
|
523
607
|
}
|
524
608
|
|
@@ -637,12 +721,12 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
|
|
637
721
|
|
638
722
|
/* CTable for Literal Lengths */
|
639
723
|
{ U32 max = MaxLL;
|
640
|
-
size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->
|
724
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->entropyScratchSpace);
|
641
725
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
642
726
|
*op++ = llCodeTable[0];
|
643
727
|
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
644
728
|
LLtype = set_rle;
|
645
|
-
} else if ((zc->
|
729
|
+
} else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
646
730
|
LLtype = set_repeat;
|
647
731
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
|
648
732
|
FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
|
@@ -653,7 +737,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
|
|
653
737
|
if (count[llCodeTable[nbSeq-1]]>1) { count[llCodeTable[nbSeq-1]]--; nbSeq_1--; }
|
654
738
|
FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
|
655
739
|
{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
656
|
-
if (FSE_isError(NCountSize)) return
|
740
|
+
if (FSE_isError(NCountSize)) return NCountSize;
|
657
741
|
op += NCountSize; }
|
658
742
|
FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
|
659
743
|
LLtype = set_compressed;
|
@@ -661,12 +745,12 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
|
|
661
745
|
|
662
746
|
/* CTable for Offsets */
|
663
747
|
{ U32 max = MaxOff;
|
664
|
-
size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->
|
748
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->entropyScratchSpace);
|
665
749
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
666
750
|
*op++ = ofCodeTable[0];
|
667
751
|
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
668
752
|
Offtype = set_rle;
|
669
|
-
} else if ((zc->
|
753
|
+
} else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
670
754
|
Offtype = set_repeat;
|
671
755
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
|
672
756
|
FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
|
@@ -677,7 +761,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
|
|
677
761
|
if (count[ofCodeTable[nbSeq-1]]>1) { count[ofCodeTable[nbSeq-1]]--; nbSeq_1--; }
|
678
762
|
FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
|
679
763
|
{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
680
|
-
if (FSE_isError(NCountSize)) return
|
764
|
+
if (FSE_isError(NCountSize)) return NCountSize;
|
681
765
|
op += NCountSize; }
|
682
766
|
FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
|
683
767
|
Offtype = set_compressed;
|
@@ -685,12 +769,12 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
|
|
685
769
|
|
686
770
|
/* CTable for MatchLengths */
|
687
771
|
{ U32 max = MaxML;
|
688
|
-
size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->
|
772
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->entropyScratchSpace);
|
689
773
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
690
774
|
*op++ = *mlCodeTable;
|
691
775
|
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
692
776
|
MLtype = set_rle;
|
693
|
-
} else if ((zc->
|
777
|
+
} else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
694
778
|
MLtype = set_repeat;
|
695
779
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
|
696
780
|
FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
|
@@ -701,14 +785,14 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
|
|
701
785
|
if (count[mlCodeTable[nbSeq-1]]>1) { count[mlCodeTable[nbSeq-1]]--; nbSeq_1--; }
|
702
786
|
FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
|
703
787
|
{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
704
|
-
if (FSE_isError(NCountSize)) return
|
788
|
+
if (FSE_isError(NCountSize)) return NCountSize;
|
705
789
|
op += NCountSize; }
|
706
790
|
FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
|
707
791
|
MLtype = set_compressed;
|
708
792
|
} }
|
709
793
|
|
710
794
|
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
|
711
|
-
zc->
|
795
|
+
zc->fseCTables_ready = 0;
|
712
796
|
|
713
797
|
/* Encoding Sequences */
|
714
798
|
{ BIT_CStream_t blockStream;
|
@@ -787,7 +871,7 @@ _check_compressibility:
|
|
787
871
|
{ size_t const minGain = ZSTD_minGain(srcSize);
|
788
872
|
size_t const maxCSize = srcSize - minGain;
|
789
873
|
if ((size_t)(op-ostart) >= maxCSize) {
|
790
|
-
zc->
|
874
|
+
zc->hufCTable_repeatMode = HUF_repeat_none;
|
791
875
|
return 0;
|
792
876
|
} }
|
793
877
|
|
@@ -816,7 +900,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
|
|
816
900
|
const U32 pos = (U32)((const BYTE*)literals - g_start);
|
817
901
|
if (g_start==NULL) g_start = (const BYTE*)literals;
|
818
902
|
if ((pos > 1895000) && (pos < 1895300))
|
819
|
-
|
903
|
+
DEBUGLOG(5, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
|
820
904
|
pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
|
821
905
|
}
|
822
906
|
#endif
|
@@ -825,14 +909,20 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
|
|
825
909
|
seqStorePtr->lit += litLength;
|
826
910
|
|
827
911
|
/* literal Length */
|
828
|
-
if (litLength>0xFFFF) {
|
912
|
+
if (litLength>0xFFFF) {
|
913
|
+
seqStorePtr->longLengthID = 1;
|
914
|
+
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
915
|
+
}
|
829
916
|
seqStorePtr->sequences[0].litLength = (U16)litLength;
|
830
917
|
|
831
918
|
/* match offset */
|
832
919
|
seqStorePtr->sequences[0].offset = offsetCode + 1;
|
833
920
|
|
834
921
|
/* match Length */
|
835
|
-
if (matchCode>0xFFFF) {
|
922
|
+
if (matchCode>0xFFFF) {
|
923
|
+
seqStorePtr->longLengthID = 2;
|
924
|
+
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
925
|
+
}
|
836
926
|
seqStorePtr->sequences[0].matchLength = (U16)matchCode;
|
837
927
|
|
838
928
|
seqStorePtr->sequences++;
|
@@ -853,7 +943,14 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
|
|
853
943
|
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
854
944
|
return (__builtin_ctzll((U64)val) >> 3);
|
855
945
|
# else
|
856
|
-
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
|
946
|
+
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
|
947
|
+
0, 3, 1, 3, 1, 4, 2, 7,
|
948
|
+
0, 2, 3, 6, 1, 5, 3, 5,
|
949
|
+
1, 3, 4, 4, 2, 5, 6, 7,
|
950
|
+
7, 0, 1, 2, 3, 3, 4, 6,
|
951
|
+
2, 6, 5, 5, 3, 4, 5, 6,
|
952
|
+
7, 1, 2, 4, 6, 4, 4, 5,
|
953
|
+
7, 2, 6, 5, 7, 6, 7, 7 };
|
857
954
|
return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
|
858
955
|
# endif
|
859
956
|
} else { /* 32 bits */
|
@@ -864,7 +961,10 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
|
|
864
961
|
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
865
962
|
return (__builtin_ctz((U32)val) >> 3);
|
866
963
|
# else
|
867
|
-
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
|
964
|
+
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
|
965
|
+
3, 2, 2, 1, 3, 2, 0, 1,
|
966
|
+
3, 3, 1, 2, 2, 2, 2, 0,
|
967
|
+
3, 1, 2, 0, 1, 0, 1, 1 };
|
868
968
|
return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
|
869
969
|
# endif
|
870
970
|
}
|
@@ -936,7 +1036,7 @@ static size_t ZSTD_count_2segments(const BYTE* ip, const BYTE* match, const BYTE
|
|
936
1036
|
***************************************/
|
937
1037
|
static const U32 prime3bytes = 506832829U;
|
938
1038
|
static U32 ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes) >> (32-h) ; }
|
939
|
-
MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); }
|
1039
|
+
MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */
|
940
1040
|
|
941
1041
|
static const U32 prime4bytes = 2654435761U;
|
942
1042
|
static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
|
@@ -1085,7 +1185,7 @@ static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
|
|
1085
1185
|
const U32 mls = ctx->params.cParams.searchLength;
|
1086
1186
|
switch(mls)
|
1087
1187
|
{
|
1088
|
-
default:
|
1188
|
+
default: /* includes case 3 */
|
1089
1189
|
case 4 :
|
1090
1190
|
ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
|
1091
1191
|
case 5 :
|
@@ -1135,7 +1235,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|
1135
1235
|
if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
|
1136
1236
|
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
|
1137
1237
|
const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
|
1138
|
-
mLength = ZSTD_count_2segments(ip+1+
|
1238
|
+
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
|
1139
1239
|
ip++;
|
1140
1240
|
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
|
1141
1241
|
} else {
|
@@ -1147,7 +1247,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|
1147
1247
|
{ const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
|
1148
1248
|
const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
|
1149
1249
|
U32 offset;
|
1150
|
-
mLength = ZSTD_count_2segments(ip+
|
1250
|
+
mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
|
1151
1251
|
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
1152
1252
|
offset = current - matchIndex;
|
1153
1253
|
offset_2 = offset_1;
|
@@ -1171,7 +1271,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|
1171
1271
|
if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
|
1172
1272
|
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
|
1173
1273
|
const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
|
1174
|
-
size_t repLength2 = ZSTD_count_2segments(ip+
|
1274
|
+
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
|
1175
1275
|
U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
|
1176
1276
|
ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
|
1177
1277
|
hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
|
@@ -1199,7 +1299,7 @@ static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
|
|
1199
1299
|
U32 const mls = ctx->params.cParams.searchLength;
|
1200
1300
|
switch(mls)
|
1201
1301
|
{
|
1202
|
-
default:
|
1302
|
+
default: /* includes case 3 */
|
1203
1303
|
case 4 :
|
1204
1304
|
ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
|
1205
1305
|
case 5 :
|
@@ -1274,7 +1374,9 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
|
|
1274
1374
|
const BYTE* match = base + matchIndexS;
|
1275
1375
|
hashLong[h2] = hashSmall[h] = current; /* update hash tables */
|
1276
1376
|
|
1277
|
-
|
1377
|
+
assert(offset_1 <= current); /* supposed guaranteed by construction */
|
1378
|
+
if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
|
1379
|
+
/* favor repcode */
|
1278
1380
|
mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
|
1279
1381
|
ip++;
|
1280
1382
|
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
|
@@ -1285,15 +1387,15 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
|
|
1285
1387
|
offset = (U32)(ip-matchLong);
|
1286
1388
|
while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
|
1287
1389
|
} else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
|
1288
|
-
size_t const
|
1289
|
-
U32 const
|
1290
|
-
const BYTE*
|
1291
|
-
hashLong[
|
1292
|
-
if ( (
|
1293
|
-
mLength = ZSTD_count(ip+9,
|
1390
|
+
size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
|
1391
|
+
U32 const matchIndexL3 = hashLong[hl3];
|
1392
|
+
const BYTE* matchL3 = base + matchIndexL3;
|
1393
|
+
hashLong[hl3] = current + 1;
|
1394
|
+
if ( (matchIndexL3 > lowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1)) ) {
|
1395
|
+
mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;
|
1294
1396
|
ip++;
|
1295
|
-
offset = (U32)(ip-
|
1296
|
-
while (((ip>anchor) & (
|
1397
|
+
offset = (U32)(ip-matchL3);
|
1398
|
+
while (((ip>anchor) & (matchL3>lowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
|
1297
1399
|
} else {
|
1298
1400
|
mLength = ZSTD_count(ip+4, match+4, iend) + 4;
|
1299
1401
|
offset = (U32)(ip-match);
|
@@ -1353,7 +1455,7 @@ static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_
|
|
1353
1455
|
const U32 mls = ctx->params.cParams.searchLength;
|
1354
1456
|
switch(mls)
|
1355
1457
|
{
|
1356
|
-
default:
|
1458
|
+
default: /* includes case 3 */
|
1357
1459
|
case 4 :
|
1358
1460
|
ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
|
1359
1461
|
case 5 :
|
@@ -1462,8 +1564,8 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
|
|
1462
1564
|
|
1463
1565
|
if (ip <= ilimit) {
|
1464
1566
|
/* Fill Table */
|
1465
|
-
|
1466
|
-
|
1567
|
+
hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
|
1568
|
+
hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
|
1467
1569
|
hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
|
1468
1570
|
hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
|
1469
1571
|
/* check immediate repcode */
|
@@ -1474,7 +1576,7 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
|
|
1474
1576
|
if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
|
1475
1577
|
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
|
1476
1578
|
const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
|
1477
|
-
size_t const repLength2 = ZSTD_count_2segments(ip+
|
1579
|
+
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
|
1478
1580
|
U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
|
1479
1581
|
ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
|
1480
1582
|
hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
|
@@ -1503,7 +1605,7 @@ static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
|
|
1503
1605
|
U32 const mls = ctx->params.cParams.searchLength;
|
1504
1606
|
switch(mls)
|
1505
1607
|
{
|
1506
|
-
default:
|
1608
|
+
default: /* includes case 3 */
|
1507
1609
|
case 4 :
|
1508
1610
|
ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
|
1509
1611
|
case 5 :
|
@@ -1588,7 +1690,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|
1588
1690
|
match = dictBase + matchIndex;
|
1589
1691
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
1590
1692
|
if (matchIndex+matchLength >= dictLimit)
|
1591
|
-
|
1693
|
+
match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
|
1592
1694
|
}
|
1593
1695
|
|
1594
1696
|
if (matchLength > bestLength) {
|
@@ -1667,7 +1769,7 @@ static size_t ZSTD_insertBtAndFindBestMatch (
|
|
1667
1769
|
match = dictBase + matchIndex;
|
1668
1770
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
1669
1771
|
if (matchIndex+matchLength >= dictLimit)
|
1670
|
-
|
1772
|
+
match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
|
1671
1773
|
}
|
1672
1774
|
|
1673
1775
|
if (matchLength > bestLength) {
|
@@ -1733,9 +1835,10 @@ static size_t ZSTD_BtFindBestMatch_selectMLS (
|
|
1733
1835
|
{
|
1734
1836
|
switch(matchLengthSearch)
|
1735
1837
|
{
|
1736
|
-
default :
|
1838
|
+
default : /* includes case 3 */
|
1737
1839
|
case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
|
1738
1840
|
case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
|
1841
|
+
case 7 :
|
1739
1842
|
case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
|
1740
1843
|
}
|
1741
1844
|
}
|
@@ -1772,9 +1875,10 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
|
|
1772
1875
|
{
|
1773
1876
|
switch(matchLengthSearch)
|
1774
1877
|
{
|
1775
|
-
default :
|
1878
|
+
default : /* includes case 3 */
|
1776
1879
|
case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
|
1777
1880
|
case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
|
1881
|
+
case 7 :
|
1778
1882
|
case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
|
1779
1883
|
}
|
1780
1884
|
}
|
@@ -1831,7 +1935,7 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
1831
1935
|
const U32 current = (U32)(ip-base);
|
1832
1936
|
const U32 minChain = current > chainSize ? current - chainSize : 0;
|
1833
1937
|
int nbAttempts=maxNbAttempts;
|
1834
|
-
size_t ml=
|
1938
|
+
size_t ml=4-1;
|
1835
1939
|
|
1836
1940
|
/* HC4 match finder */
|
1837
1941
|
U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
|
@@ -1846,11 +1950,15 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
1846
1950
|
} else {
|
1847
1951
|
match = dictBase + matchIndex;
|
1848
1952
|
if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
|
1849
|
-
currentMl = ZSTD_count_2segments(ip+
|
1953
|
+
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
|
1850
1954
|
}
|
1851
1955
|
|
1852
1956
|
/* save best solution */
|
1853
|
-
if (currentMl > ml) {
|
1957
|
+
if (currentMl > ml) {
|
1958
|
+
ml = currentMl;
|
1959
|
+
*offsetPtr = current - matchIndex + ZSTD_REP_MOVE;
|
1960
|
+
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
|
1961
|
+
}
|
1854
1962
|
|
1855
1963
|
if (matchIndex <= minChain) break;
|
1856
1964
|
matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
|
@@ -1868,9 +1976,10 @@ FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS (
|
|
1868
1976
|
{
|
1869
1977
|
switch(matchLengthSearch)
|
1870
1978
|
{
|
1871
|
-
default :
|
1979
|
+
default : /* includes case 3 */
|
1872
1980
|
case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
|
1873
1981
|
case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
|
1982
|
+
case 7 :
|
1874
1983
|
case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
|
1875
1984
|
}
|
1876
1985
|
}
|
@@ -1884,9 +1993,10 @@ FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
|
|
1884
1993
|
{
|
1885
1994
|
switch(matchLengthSearch)
|
1886
1995
|
{
|
1887
|
-
default :
|
1996
|
+
default : /* includes case 3 */
|
1888
1997
|
case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
|
1889
1998
|
case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
|
1999
|
+
case 7 :
|
1890
2000
|
case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
|
1891
2001
|
}
|
1892
2002
|
}
|
@@ -1934,7 +2044,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|
1934
2044
|
/* check repCode */
|
1935
2045
|
if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
|
1936
2046
|
/* repcode : we take it */
|
1937
|
-
matchLength = ZSTD_count(ip+1+
|
2047
|
+
matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
|
1938
2048
|
if (depth==0) goto _storeSequence;
|
1939
2049
|
}
|
1940
2050
|
|
@@ -1945,7 +2055,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|
1945
2055
|
matchLength = ml2, start = ip, offset=offsetFound;
|
1946
2056
|
}
|
1947
2057
|
|
1948
|
-
if (matchLength <
|
2058
|
+
if (matchLength < 4) {
|
1949
2059
|
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
1950
2060
|
continue;
|
1951
2061
|
}
|
@@ -1955,17 +2065,17 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|
1955
2065
|
while (ip<ilimit) {
|
1956
2066
|
ip ++;
|
1957
2067
|
if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
|
1958
|
-
size_t const mlRep = ZSTD_count(ip+
|
2068
|
+
size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
|
1959
2069
|
int const gain2 = (int)(mlRep * 3);
|
1960
2070
|
int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
|
1961
|
-
if ((mlRep >=
|
2071
|
+
if ((mlRep >= 4) && (gain2 > gain1))
|
1962
2072
|
matchLength = mlRep, offset = 0, start = ip;
|
1963
2073
|
}
|
1964
2074
|
{ size_t offset2=99999999;
|
1965
2075
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
1966
2076
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
1967
2077
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
|
1968
|
-
if ((ml2 >=
|
2078
|
+
if ((ml2 >= 4) && (gain2 > gain1)) {
|
1969
2079
|
matchLength = ml2, offset = offset2, start = ip;
|
1970
2080
|
continue; /* search a better one */
|
1971
2081
|
} }
|
@@ -1974,17 +2084,17 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|
1974
2084
|
if ((depth==2) && (ip<ilimit)) {
|
1975
2085
|
ip ++;
|
1976
2086
|
if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
|
1977
|
-
size_t const ml2 = ZSTD_count(ip+
|
2087
|
+
size_t const ml2 = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
|
1978
2088
|
int const gain2 = (int)(ml2 * 4);
|
1979
2089
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
|
1980
|
-
if ((ml2 >=
|
2090
|
+
if ((ml2 >= 4) && (gain2 > gain1))
|
1981
2091
|
matchLength = ml2, offset = 0, start = ip;
|
1982
2092
|
}
|
1983
2093
|
{ size_t offset2=99999999;
|
1984
2094
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
1985
2095
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
1986
2096
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
|
1987
|
-
if ((ml2 >=
|
2097
|
+
if ((ml2 >= 4) && (gain2 > gain1)) {
|
1988
2098
|
matchLength = ml2, offset = offset2, start = ip;
|
1989
2099
|
continue;
|
1990
2100
|
} } }
|
@@ -1993,7 +2103,9 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|
1993
2103
|
|
1994
2104
|
/* catch up */
|
1995
2105
|
if (offset) {
|
1996
|
-
while ((start
|
2106
|
+
while ( (start > anchor)
|
2107
|
+
&& (start > base+offset-ZSTD_REP_MOVE)
|
2108
|
+
&& (start[-1] == start[-1-offset+ZSTD_REP_MOVE]) ) /* only search for offset within prefix */
|
1997
2109
|
{ start--; matchLength++; }
|
1998
2110
|
offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
|
1999
2111
|
}
|
@@ -2010,7 +2122,7 @@ _storeSequence:
|
|
2010
2122
|
&& ((offset_2>0)
|
2011
2123
|
& (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
|
2012
2124
|
/* store sequence */
|
2013
|
-
matchLength = ZSTD_count(ip+
|
2125
|
+
matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
|
2014
2126
|
offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
|
2015
2127
|
ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
|
2016
2128
|
ip += matchLength;
|
@@ -2099,7 +2211,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|
2099
2211
|
if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
|
2100
2212
|
/* repcode detected we should take it */
|
2101
2213
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
2102
|
-
matchLength = ZSTD_count_2segments(ip+1+
|
2214
|
+
matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4;
|
2103
2215
|
if (depth==0) goto _storeSequence;
|
2104
2216
|
} }
|
2105
2217
|
|
@@ -2110,7 +2222,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|
2110
2222
|
matchLength = ml2, start = ip, offset=offsetFound;
|
2111
2223
|
}
|
2112
2224
|
|
2113
|
-
if (matchLength <
|
2225
|
+
if (matchLength < 4) {
|
2114
2226
|
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
2115
2227
|
continue;
|
2116
2228
|
}
|
@@ -2129,10 +2241,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|
2129
2241
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
2130
2242
|
/* repcode detected */
|
2131
2243
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
2132
|
-
size_t const repLength = ZSTD_count_2segments(ip+
|
2244
|
+
size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
|
2133
2245
|
int const gain2 = (int)(repLength * 3);
|
2134
2246
|
int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
|
2135
|
-
if ((repLength >=
|
2247
|
+
if ((repLength >= 4) && (gain2 > gain1))
|
2136
2248
|
matchLength = repLength, offset = 0, start = ip;
|
2137
2249
|
} }
|
2138
2250
|
|
@@ -2141,7 +2253,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|
2141
2253
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
2142
2254
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
2143
2255
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
|
2144
|
-
if ((ml2 >=
|
2256
|
+
if ((ml2 >= 4) && (gain2 > gain1)) {
|
2145
2257
|
matchLength = ml2, offset = offset2, start = ip;
|
2146
2258
|
continue; /* search a better one */
|
2147
2259
|
} }
|
@@ -2159,10 +2271,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|
2159
2271
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
2160
2272
|
/* repcode detected */
|
2161
2273
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
2162
|
-
size_t repLength = ZSTD_count_2segments(ip+
|
2163
|
-
int gain2 = (int)(repLength * 4);
|
2164
|
-
int gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
|
2165
|
-
if ((repLength >=
|
2274
|
+
size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
|
2275
|
+
int const gain2 = (int)(repLength * 4);
|
2276
|
+
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
|
2277
|
+
if ((repLength >= 4) && (gain2 > gain1))
|
2166
2278
|
matchLength = repLength, offset = 0, start = ip;
|
2167
2279
|
} }
|
2168
2280
|
|
@@ -2171,7 +2283,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|
2171
2283
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
2172
2284
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
2173
2285
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
|
2174
|
-
if ((ml2 >=
|
2286
|
+
if ((ml2 >= 4) && (gain2 > gain1)) {
|
2175
2287
|
matchLength = ml2, offset = offset2, start = ip;
|
2176
2288
|
continue;
|
2177
2289
|
} } }
|
@@ -2203,7 +2315,7 @@ _storeSequence:
|
|
2203
2315
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
2204
2316
|
/* repcode detected we should take it */
|
2205
2317
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
2206
|
-
matchLength = ZSTD_count_2segments(ip+
|
2318
|
+
matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
|
2207
2319
|
offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
|
2208
2320
|
ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
|
2209
2321
|
ip += matchLength;
|
@@ -2294,8 +2406,12 @@ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t sr
|
|
2294
2406
|
static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
|
2295
2407
|
{
|
2296
2408
|
static const ZSTD_blockCompressor blockCompressor[2][8] = {
|
2297
|
-
{ ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy,
|
2298
|
-
|
2409
|
+
{ ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy,
|
2410
|
+
ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2,
|
2411
|
+
ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
|
2412
|
+
{ ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict,
|
2413
|
+
ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict,
|
2414
|
+
ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
|
2299
2415
|
};
|
2300
2416
|
|
2301
2417
|
return blockCompressor[extDict][(U32)strat];
|
@@ -2311,7 +2427,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa
|
|
2311
2427
|
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */
|
2312
2428
|
ZSTD_resetSeqStore(&(zc->seqStore));
|
2313
2429
|
if (current > zc->nextToUpdate + 384)
|
2314
|
-
zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384)); /* update
|
2430
|
+
zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384)); /* limited update after finding a very long match */
|
2315
2431
|
blockCompressor(zc, src, srcSize);
|
2316
2432
|
return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
|
2317
2433
|
}
|
@@ -2343,7 +2459,8 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|
2343
2459
|
U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
|
2344
2460
|
size_t cSize;
|
2345
2461
|
|
2346
|
-
if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE)
|
2462
|
+
if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE)
|
2463
|
+
return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
|
2347
2464
|
if (remaining < blockSize) blockSize = remaining;
|
2348
2465
|
|
2349
2466
|
/* preemptive overflow correction */
|
@@ -2398,7 +2515,8 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|
2398
2515
|
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
2399
2516
|
ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
|
2400
2517
|
{ BYTE* const op = (BYTE*)dst;
|
2401
|
-
U32 const
|
2518
|
+
U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
|
2519
|
+
U32 const dictIDSizeCode = params.fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
|
2402
2520
|
U32 const checksumFlag = params.fParams.checksumFlag>0;
|
2403
2521
|
U32 const windowSize = 1U << params.cParams.windowLog;
|
2404
2522
|
U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
|
@@ -2410,6 +2528,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
|
2410
2528
|
size_t pos;
|
2411
2529
|
|
2412
2530
|
if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
|
2531
|
+
DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDFlag : %u \n", !params.fParams.noDictIDFlag);
|
2532
|
+
DEBUGLOG(5, "ZSTD_writeFrameHeader : dictID : %u \n", dictID);
|
2533
|
+
DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDSizeCode : %u \n", dictIDSizeCode);
|
2413
2534
|
|
2414
2535
|
MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
|
2415
2536
|
op[4] = frameHeaderDecriptionByte; pos=5;
|
@@ -2478,6 +2599,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
2478
2599
|
ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
|
2479
2600
|
ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
|
2480
2601
|
if (ZSTD_isError(cSize)) return cSize;
|
2602
|
+
cctx->consumedSrcSize += srcSize;
|
2481
2603
|
return cSize + fhSize;
|
2482
2604
|
} else
|
2483
2605
|
return fhSize;
|
@@ -2488,7 +2610,7 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
|
|
2488
2610
|
void* dst, size_t dstCapacity,
|
2489
2611
|
const void* src, size_t srcSize)
|
2490
2612
|
{
|
2491
|
-
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1
|
2613
|
+
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */);
|
2492
2614
|
}
|
2493
2615
|
|
2494
2616
|
|
@@ -2501,10 +2623,12 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
|
2501
2623
|
{
|
2502
2624
|
size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
|
2503
2625
|
if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
|
2504
|
-
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0
|
2626
|
+
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
|
2505
2627
|
}
|
2506
2628
|
|
2507
|
-
|
2629
|
+
/*! ZSTD_loadDictionaryContent() :
|
2630
|
+
* @return : 0, or an error code
|
2631
|
+
*/
|
2508
2632
|
static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
2509
2633
|
{
|
2510
2634
|
const BYTE* const ip = (const BYTE*) src;
|
@@ -2534,13 +2658,15 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
|
|
2534
2658
|
case ZSTD_greedy:
|
2535
2659
|
case ZSTD_lazy:
|
2536
2660
|
case ZSTD_lazy2:
|
2537
|
-
|
2661
|
+
if (srcSize >= HASH_READ_SIZE)
|
2662
|
+
ZSTD_insertAndFindFirstIndex(zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
|
2538
2663
|
break;
|
2539
2664
|
|
2540
2665
|
case ZSTD_btlazy2:
|
2541
2666
|
case ZSTD_btopt:
|
2542
2667
|
case ZSTD_btopt2:
|
2543
|
-
|
2668
|
+
if (srcSize >= HASH_READ_SIZE)
|
2669
|
+
ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
|
2544
2670
|
break;
|
2545
2671
|
|
2546
2672
|
default:
|
@@ -2567,18 +2693,15 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym
|
|
2567
2693
|
|
2568
2694
|
|
2569
2695
|
/* Dictionary format :
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2575
|
-
|
2576
|
-
|
2577
|
-
*/
|
2578
|
-
|
2579
|
-
@return : size read from dictionary
|
2580
|
-
note : magic number supposed already checked */
|
2581
|
-
static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
|
2696
|
+
* See :
|
2697
|
+
* https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
|
2698
|
+
*/
|
2699
|
+
/*! ZSTD_loadZstdDictionary() :
|
2700
|
+
* @return : 0, or an error code
|
2701
|
+
* assumptions : magic number supposed already checked
|
2702
|
+
* dictSize supposed > 8
|
2703
|
+
*/
|
2704
|
+
static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
|
2582
2705
|
{
|
2583
2706
|
const BYTE* dictPtr = (const BYTE*)dict;
|
2584
2707
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
@@ -2586,7 +2709,11 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
2586
2709
|
unsigned offcodeMaxValue = MaxOff;
|
2587
2710
|
BYTE scratchBuffer[1<<MAX(MLFSELog,LLFSELog)];
|
2588
2711
|
|
2589
|
-
|
2712
|
+
dictPtr += 4; /* skip magic number */
|
2713
|
+
cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr);
|
2714
|
+
dictPtr += 4;
|
2715
|
+
|
2716
|
+
{ size_t const hufHeaderSize = HUF_readCTable(cctx->hufCTable, 255, dictPtr, dictEnd-dictPtr);
|
2590
2717
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
2591
2718
|
dictPtr += hufHeaderSize;
|
2592
2719
|
}
|
@@ -2596,7 +2723,8 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
2596
2723
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
2597
2724
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
2598
2725
|
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
|
2599
|
-
CHECK_E
|
2726
|
+
CHECK_E( FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)),
|
2727
|
+
dictionary_corrupted);
|
2600
2728
|
dictPtr += offcodeHeaderSize;
|
2601
2729
|
}
|
2602
2730
|
|
@@ -2606,8 +2734,9 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
2606
2734
|
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
2607
2735
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
2608
2736
|
/* Every match length code must have non-zero probability */
|
2609
|
-
CHECK_F
|
2610
|
-
CHECK_E
|
2737
|
+
CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
|
2738
|
+
CHECK_E( FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)),
|
2739
|
+
dictionary_corrupted);
|
2611
2740
|
dictPtr += matchlengthHeaderSize;
|
2612
2741
|
}
|
2613
2742
|
|
@@ -2617,49 +2746,51 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
2617
2746
|
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
2618
2747
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
2619
2748
|
/* Every literal length code must have non-zero probability */
|
2620
|
-
CHECK_F
|
2621
|
-
CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)),
|
2749
|
+
CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
|
2750
|
+
CHECK_E( FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)),
|
2751
|
+
dictionary_corrupted);
|
2622
2752
|
dictPtr += litlengthHeaderSize;
|
2623
2753
|
}
|
2624
2754
|
|
2625
2755
|
if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
|
2626
|
-
cctx->rep[0] = MEM_readLE32(dictPtr+0);
|
2627
|
-
cctx->rep[1] = MEM_readLE32(dictPtr+4);
|
2628
|
-
cctx->rep[2] = MEM_readLE32(dictPtr+8);
|
2756
|
+
cctx->rep[0] = MEM_readLE32(dictPtr+0);
|
2757
|
+
cctx->rep[1] = MEM_readLE32(dictPtr+4);
|
2758
|
+
cctx->rep[2] = MEM_readLE32(dictPtr+8);
|
2629
2759
|
dictPtr += 12;
|
2630
2760
|
|
2631
|
-
{
|
2632
|
-
|
2633
|
-
|
2634
|
-
/*
|
2635
|
-
offcodeMax = ZSTD_highbit32(maxOffset);
|
2761
|
+
{ size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
|
2762
|
+
U32 offcodeMax = MaxOff;
|
2763
|
+
if (dictContentSize <= ((U32)-1) - 128 KB) {
|
2764
|
+
U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
|
2765
|
+
offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
|
2636
2766
|
}
|
2637
|
-
/*
|
2767
|
+
/* All offset values <= dictContentSize + 128 KB must be representable */
|
2638
2768
|
CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
|
2639
|
-
|
2769
|
+
/* All repCodes must be <= dictContentSize and != 0*/
|
2770
|
+
{ U32 u;
|
2771
|
+
for (u=0; u<3; u++) {
|
2772
|
+
if (cctx->rep[u] == 0) return ERROR(dictionary_corrupted);
|
2773
|
+
if (cctx->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
|
2774
|
+
} }
|
2640
2775
|
|
2641
|
-
|
2642
|
-
|
2643
|
-
|
2776
|
+
cctx->fseCTables_ready = 1;
|
2777
|
+
cctx->hufCTable_repeatMode = HUF_repeat_valid;
|
2778
|
+
return ZSTD_loadDictionaryContent(cctx, dictPtr, dictContentSize);
|
2779
|
+
}
|
2644
2780
|
}
|
2645
2781
|
|
2646
2782
|
/** ZSTD_compress_insertDictionary() :
|
2647
2783
|
* @return : 0, or an error code */
|
2648
|
-
static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx*
|
2784
|
+
static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
|
2649
2785
|
{
|
2650
2786
|
if ((dict==NULL) || (dictSize<=8)) return 0;
|
2651
2787
|
|
2652
2788
|
/* dict as pure content */
|
2653
|
-
if ((MEM_readLE32(dict) != ZSTD_DICT_MAGIC) || (
|
2654
|
-
return ZSTD_loadDictionaryContent(
|
2655
|
-
zc->dictID = zc->params.fParams.noDictIDFlag ? 0 : MEM_readLE32((const char*)dict+4);
|
2789
|
+
if ((MEM_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict))
|
2790
|
+
return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
|
2656
2791
|
|
2657
|
-
/*
|
2658
|
-
|
2659
|
-
size_t const eSize = loadError + 8;
|
2660
|
-
if (ZSTD_isError(loadError)) return loadError;
|
2661
|
-
return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
|
2662
|
-
}
|
2792
|
+
/* dict as zstd dictionary */
|
2793
|
+
return ZSTD_loadZstdDictionary(cctx, dict, dictSize);
|
2663
2794
|
}
|
2664
2795
|
|
2665
2796
|
/*! ZSTD_compressBegin_internal() :
|
@@ -2669,7 +2800,8 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
2669
2800
|
ZSTD_parameters params, U64 pledgedSrcSize)
|
2670
2801
|
{
|
2671
2802
|
ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue;
|
2672
|
-
|
2803
|
+
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
2804
|
+
CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, crp));
|
2673
2805
|
return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
|
2674
2806
|
}
|
2675
2807
|
|
@@ -2745,10 +2877,13 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
|
|
2745
2877
|
const void* src, size_t srcSize)
|
2746
2878
|
{
|
2747
2879
|
size_t endResult;
|
2748
|
-
size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1
|
2880
|
+
size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 1 /* last chunk */);
|
2749
2881
|
if (ZSTD_isError(cSize)) return cSize;
|
2750
2882
|
endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
|
2751
2883
|
if (ZSTD_isError(endResult)) return endResult;
|
2884
|
+
if (cctx->params.fParams.contentSizeFlag) { /* control src size */
|
2885
|
+
if (cctx->frameContentSize != cctx->consumedSrcSize) return ERROR(srcSize_wrong);
|
2886
|
+
}
|
2752
2887
|
return cSize + endResult;
|
2753
2888
|
}
|
2754
2889
|
|
@@ -2773,7 +2908,8 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|
2773
2908
|
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
2774
2909
|
}
|
2775
2910
|
|
2776
|
-
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
|
2911
|
+
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
|
2912
|
+
const void* dict, size_t dictSize, int compressionLevel)
|
2777
2913
|
{
|
2778
2914
|
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dict ? dictSize : 0);
|
2779
2915
|
params.fParams.contentSizeFlag = 1;
|
@@ -2812,8 +2948,16 @@ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
|
|
2812
2948
|
return ZSTD_sizeof_CCtx(cdict->refContext) + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
|
2813
2949
|
}
|
2814
2950
|
|
2951
|
+
static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_frameParameters fParams)
|
2952
|
+
{
|
2953
|
+
ZSTD_parameters params;
|
2954
|
+
params.cParams = cParams;
|
2955
|
+
params.fParams = fParams;
|
2956
|
+
return params;
|
2957
|
+
}
|
2958
|
+
|
2815
2959
|
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
|
2816
|
-
|
2960
|
+
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
|
2817
2961
|
{
|
2818
2962
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
2819
2963
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
@@ -2838,7 +2982,9 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
|
|
2838
2982
|
cdict->dictContent = internalBuffer;
|
2839
2983
|
}
|
2840
2984
|
|
2841
|
-
{
|
2985
|
+
{ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */, 0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
|
2986
|
+
ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
|
2987
|
+
size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
|
2842
2988
|
if (ZSTD_isError(errorCode)) {
|
2843
2989
|
ZSTD_free(cdict->dictBuffer, customMem);
|
2844
2990
|
ZSTD_free(cdict, customMem);
|
@@ -2855,17 +3001,15 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
|
|
2855
3001
|
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
|
2856
3002
|
{
|
2857
3003
|
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
2858
|
-
|
2859
|
-
|
2860
|
-
return ZSTD_createCDict_advanced(dict, dictSize, 0, params, allocator);
|
3004
|
+
ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
3005
|
+
return ZSTD_createCDict_advanced(dict, dictSize, 0, cParams, allocator);
|
2861
3006
|
}
|
2862
3007
|
|
2863
3008
|
ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
|
2864
3009
|
{
|
2865
3010
|
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
2866
|
-
|
2867
|
-
|
2868
|
-
return ZSTD_createCDict_advanced(dict, dictSize, 1, params, allocator);
|
3011
|
+
ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
3012
|
+
return ZSTD_createCDict_advanced(dict, dictSize, 1, cParams, allocator);
|
2869
3013
|
}
|
2870
3014
|
|
2871
3015
|
size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
@@ -2883,34 +3027,55 @@ static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
|
|
2883
3027
|
return ZSTD_getParamsFromCCtx(cdict->refContext);
|
2884
3028
|
}
|
2885
3029
|
|
2886
|
-
|
3030
|
+
/* ZSTD_compressBegin_usingCDict_advanced() :
|
3031
|
+
* cdict must be != NULL */
|
3032
|
+
size_t ZSTD_compressBegin_usingCDict_advanced(
|
3033
|
+
ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
|
3034
|
+
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
|
2887
3035
|
{
|
2888
|
-
if (cdict
|
3036
|
+
if (cdict==NULL) return ERROR(GENERIC); /* does not support NULL cdict */
|
3037
|
+
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced : dictIDFlag == %u \n", !fParams.noDictIDFlag);
|
3038
|
+
if (cdict->dictContentSize)
|
3039
|
+
CHECK_F( ZSTD_copyCCtx_internal(cctx, cdict->refContext, fParams, pledgedSrcSize) )
|
2889
3040
|
else {
|
2890
3041
|
ZSTD_parameters params = cdict->refContext->params;
|
2891
|
-
params.fParams
|
2892
|
-
CHECK_F(
|
3042
|
+
params.fParams = fParams;
|
3043
|
+
CHECK_F(ZSTD_compressBegin_internal(cctx, NULL, 0, params, pledgedSrcSize));
|
2893
3044
|
}
|
2894
3045
|
return 0;
|
2895
3046
|
}
|
2896
3047
|
|
3048
|
+
/* ZSTD_compressBegin_usingCDict() :
|
3049
|
+
* pledgedSrcSize=0 means "unknown"
|
3050
|
+
* if pledgedSrcSize>0, it will enable contentSizeFlag */
|
3051
|
+
size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
|
3052
|
+
{
|
3053
|
+
ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
|
3054
|
+
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u \n", !fParams.noDictIDFlag);
|
3055
|
+
return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, 0);
|
3056
|
+
}
|
3057
|
+
|
3058
|
+
size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
|
3059
|
+
void* dst, size_t dstCapacity,
|
3060
|
+
const void* src, size_t srcSize,
|
3061
|
+
const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
|
3062
|
+
{
|
3063
|
+
CHECK_F (ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize)); /* will check if cdict != NULL */
|
3064
|
+
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
|
3065
|
+
}
|
3066
|
+
|
2897
3067
|
/*! ZSTD_compress_usingCDict() :
|
2898
|
-
*
|
2899
|
-
*
|
2900
|
-
*
|
3068
|
+
* Compression using a digested Dictionary.
|
3069
|
+
* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
|
3070
|
+
* Note that compression parameters are decided at CDict creation time
|
3071
|
+
* while frame parameters are hardcoded */
|
2901
3072
|
size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
2902
3073
|
void* dst, size_t dstCapacity,
|
2903
3074
|
const void* src, size_t srcSize,
|
2904
3075
|
const ZSTD_CDict* cdict)
|
2905
3076
|
{
|
2906
|
-
|
2907
|
-
|
2908
|
-
if (cdict->refContext->params.fParams.contentSizeFlag==1) {
|
2909
|
-
cctx->params.fParams.contentSizeFlag = 1;
|
2910
|
-
cctx->frameContentSize = srcSize;
|
2911
|
-
}
|
2912
|
-
|
2913
|
-
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
|
3077
|
+
ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
|
3078
|
+
return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, fParams);
|
2914
3079
|
}
|
2915
3080
|
|
2916
3081
|
|
@@ -2939,7 +3104,6 @@ struct ZSTD_CStream_s {
|
|
2939
3104
|
U32 checksum;
|
2940
3105
|
U32 frameEnded;
|
2941
3106
|
U64 pledgedSrcSize;
|
2942
|
-
U64 inputProcessed;
|
2943
3107
|
ZSTD_parameters params;
|
2944
3108
|
ZSTD_customMem customMem;
|
2945
3109
|
}; /* typedef'd to ZSTD_CStream within "zstd.h" */
|
@@ -2970,9 +3134,13 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
|
|
2970
3134
|
if (zcs==NULL) return 0; /* support free on NULL */
|
2971
3135
|
{ ZSTD_customMem const cMem = zcs->customMem;
|
2972
3136
|
ZSTD_freeCCtx(zcs->cctx);
|
3137
|
+
zcs->cctx = NULL;
|
2973
3138
|
ZSTD_freeCDict(zcs->cdictLocal);
|
3139
|
+
zcs->cdictLocal = NULL;
|
2974
3140
|
ZSTD_free(zcs->inBuff, cMem);
|
3141
|
+
zcs->inBuff = NULL;
|
2975
3142
|
ZSTD_free(zcs->outBuff, cMem);
|
3143
|
+
zcs->outBuff = NULL;
|
2976
3144
|
ZSTD_free(zcs, cMem);
|
2977
3145
|
return 0;
|
2978
3146
|
}
|
@@ -2982,14 +3150,20 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
|
|
2982
3150
|
/*====== Initialization ======*/
|
2983
3151
|
|
2984
3152
|
size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
|
2985
|
-
|
3153
|
+
|
3154
|
+
size_t ZSTD_CStreamOutSize(void)
|
3155
|
+
{
|
3156
|
+
return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
|
3157
|
+
}
|
2986
3158
|
|
2987
3159
|
static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
2988
3160
|
{
|
2989
3161
|
if (zcs->inBuffSize==0) return ERROR(stage_wrong); /* zcs has not been init at least once => can't reset */
|
2990
3162
|
|
2991
|
-
|
2992
|
-
|
3163
|
+
DEBUGLOG(5, "ZSTD_resetCStream_internal : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag);
|
3164
|
+
|
3165
|
+
if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs->cctx, zcs->cdict, zcs->params.fParams, pledgedSrcSize))
|
3166
|
+
else CHECK_F(ZSTD_compressBegin_internal(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
|
2993
3167
|
|
2994
3168
|
zcs->inToCompress = 0;
|
2995
3169
|
zcs->inBuffPos = 0;
|
@@ -2998,7 +3172,6 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long p
|
|
2998
3172
|
zcs->stage = zcss_load;
|
2999
3173
|
zcs->frameEnded = 0;
|
3000
3174
|
zcs->pledgedSrcSize = pledgedSrcSize;
|
3001
|
-
zcs->inputProcessed = 0;
|
3002
3175
|
return 0; /* ready to go */
|
3003
3176
|
}
|
3004
3177
|
|
@@ -3006,70 +3179,109 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
|
3006
3179
|
{
|
3007
3180
|
|
3008
3181
|
zcs->params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
|
3009
|
-
|
3182
|
+
DEBUGLOG(5, "ZSTD_resetCStream : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag);
|
3010
3183
|
return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
|
3011
3184
|
}
|
3012
3185
|
|
3013
|
-
|
3014
|
-
|
3015
|
-
|
3186
|
+
/* ZSTD_initCStream_internal() :
|
3187
|
+
* params are supposed validated at this stage
|
3188
|
+
* and zcs->cdict is supposed to be correct */
|
3189
|
+
static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs,
|
3190
|
+
const ZSTD_parameters params,
|
3191
|
+
unsigned long long pledgedSrcSize)
|
3016
3192
|
{
|
3193
|
+
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
3194
|
+
|
3017
3195
|
/* allocate buffers */
|
3018
3196
|
{ size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
|
3019
3197
|
if (zcs->inBuffSize < neededInBuffSize) {
|
3020
|
-
zcs->inBuffSize =
|
3198
|
+
zcs->inBuffSize = 0;
|
3021
3199
|
ZSTD_free(zcs->inBuff, zcs->customMem);
|
3022
3200
|
zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
|
3023
3201
|
if (zcs->inBuff == NULL) return ERROR(memory_allocation);
|
3202
|
+
zcs->inBuffSize = neededInBuffSize;
|
3024
3203
|
}
|
3025
3204
|
zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
|
3026
3205
|
}
|
3027
3206
|
if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
|
3028
|
-
|
3207
|
+
size_t const outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
|
3208
|
+
zcs->outBuffSize = 0;
|
3029
3209
|
ZSTD_free(zcs->outBuff, zcs->customMem);
|
3030
|
-
zcs->outBuff = (char*) ZSTD_malloc(
|
3210
|
+
zcs->outBuff = (char*) ZSTD_malloc(outBuffSize, zcs->customMem);
|
3031
3211
|
if (zcs->outBuff == NULL) return ERROR(memory_allocation);
|
3212
|
+
zcs->outBuffSize = outBuffSize;
|
3032
3213
|
}
|
3033
3214
|
|
3034
|
-
if (dict && dictSize >= 8) {
|
3035
|
-
ZSTD_freeCDict(zcs->cdictLocal);
|
3036
|
-
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0, params, zcs->customMem);
|
3037
|
-
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
|
3038
|
-
zcs->cdict = zcs->cdictLocal;
|
3039
|
-
} else zcs->cdict = NULL;
|
3040
|
-
|
3041
3215
|
zcs->checksum = params.fParams.checksumFlag > 0;
|
3042
3216
|
zcs->params = params;
|
3043
3217
|
|
3218
|
+
DEBUGLOG(5, "ZSTD_initCStream_stage2 : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
|
3044
3219
|
return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
|
3045
3220
|
}
|
3046
3221
|
|
3222
|
+
/* ZSTD_initCStream_usingCDict_advanced() :
|
3223
|
+
* same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
|
3224
|
+
size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, ZSTD_frameParameters fParams)
|
3225
|
+
{
|
3226
|
+
if (!cdict) return ERROR(GENERIC); /* cannot handle NULL cdict (does not know what to do) */
|
3227
|
+
{ ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict);
|
3228
|
+
params.fParams = fParams;
|
3229
|
+
zcs->cdict = cdict;
|
3230
|
+
return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize);
|
3231
|
+
}
|
3232
|
+
}
|
3233
|
+
|
3047
3234
|
/* note : cdict must outlive compression session */
|
3048
3235
|
size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
|
3049
3236
|
{
|
3050
|
-
|
3051
|
-
|
3052
|
-
|
3053
|
-
|
3054
|
-
|
3237
|
+
ZSTD_frameParameters const fParams = { 0 /* content */, 0 /* checksum */, 0 /* noDictID */ };
|
3238
|
+
return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, 0, fParams);
|
3239
|
+
}
|
3240
|
+
|
3241
|
+
static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
3242
|
+
const void* dict, size_t dictSize,
|
3243
|
+
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
3244
|
+
{
|
3245
|
+
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
3246
|
+
zcs->cdict = NULL;
|
3247
|
+
|
3248
|
+
if (dict && dictSize >= 8) {
|
3249
|
+
ZSTD_freeCDict(zcs->cdictLocal);
|
3250
|
+
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* copy */, params.cParams, zcs->customMem);
|
3251
|
+
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
|
3252
|
+
zcs->cdict = zcs->cdictLocal;
|
3253
|
+
}
|
3254
|
+
|
3255
|
+
DEBUGLOG(5, "ZSTD_initCStream_internal : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
|
3256
|
+
return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize);
|
3257
|
+
}
|
3258
|
+
|
3259
|
+
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
3260
|
+
const void* dict, size_t dictSize,
|
3261
|
+
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
3262
|
+
{
|
3263
|
+
CHECK_F( ZSTD_checkCParams(params.cParams) );
|
3264
|
+
DEBUGLOG(5, "ZSTD_initCStream_advanced : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
|
3265
|
+
return ZSTD_initCStream_internal(zcs, dict, dictSize, params, pledgedSrcSize);
|
3055
3266
|
}
|
3056
3267
|
|
3057
3268
|
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
|
3058
3269
|
{
|
3059
3270
|
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
|
3060
|
-
return
|
3271
|
+
return ZSTD_initCStream_internal(zcs, dict, dictSize, params, 0);
|
3061
3272
|
}
|
3062
3273
|
|
3063
3274
|
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
|
3064
3275
|
{
|
3065
3276
|
ZSTD_parameters params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
|
3066
|
-
|
3067
|
-
return
|
3277
|
+
params.fParams.contentSizeFlag = (pledgedSrcSize>0);
|
3278
|
+
return ZSTD_initCStream_internal(zcs, NULL, 0, params, pledgedSrcSize);
|
3068
3279
|
}
|
3069
3280
|
|
3070
3281
|
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
|
3071
3282
|
{
|
3072
|
-
|
3283
|
+
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0);
|
3284
|
+
return ZSTD_initCStream_internal(zcs, NULL, 0, params, 0);
|
3073
3285
|
}
|
3074
3286
|
|
3075
3287
|
size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
|
@@ -3163,7 +3375,6 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
3163
3375
|
|
3164
3376
|
*srcSizePtr = ip - istart;
|
3165
3377
|
*dstCapacityPtr = op - ostart;
|
3166
|
-
zcs->inputProcessed += *srcSizePtr;
|
3167
3378
|
if (zcs->frameEnded) return 0;
|
3168
3379
|
{ size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
|
3169
3380
|
if (hintInSize==0) hintInSize = zcs->blockSize;
|
@@ -3208,14 +3419,12 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
|
3208
3419
|
BYTE* const oend = (BYTE*)(output->dst) + output->size;
|
3209
3420
|
BYTE* op = ostart;
|
3210
3421
|
|
3211
|
-
if ((zcs->pledgedSrcSize) && (zcs->inputProcessed != zcs->pledgedSrcSize))
|
3212
|
-
return ERROR(srcSize_wrong); /* pledgedSrcSize not respected */
|
3213
|
-
|
3214
3422
|
if (zcs->stage != zcss_final) {
|
3215
3423
|
/* flush whatever remains */
|
3216
3424
|
size_t srcSize = 0;
|
3217
3425
|
size_t sizeWritten = output->size - output->pos;
|
3218
|
-
size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten,
|
3426
|
+
size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten,
|
3427
|
+
&srcSize /* use a valid src address instead of NULL */, &srcSize, zsf_end);
|
3219
3428
|
size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
|
3220
3429
|
op += sizeWritten;
|
3221
3430
|
if (remainingToFlush) {
|
@@ -3225,7 +3434,9 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
|
3225
3434
|
/* create epilogue */
|
3226
3435
|
zcs->stage = zcss_final;
|
3227
3436
|
zcs->outBuffContentSize = !notEnded ? 0 :
|
3228
|
-
|
3437
|
+
/* write epilogue, including final empty block, into outBuff */
|
3438
|
+
ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0);
|
3439
|
+
if (ZSTD_isError(zcs->outBuffContentSize)) return zcs->outBuffContentSize;
|
3229
3440
|
}
|
3230
3441
|
|
3231
3442
|
/* flush epilogue */
|
@@ -3268,7 +3479,7 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3268
3479
|
{ 22, 21, 21, 5, 5, 16, ZSTD_btlazy2 }, /* level 15 */
|
3269
3480
|
{ 23, 22, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 16 */
|
3270
3481
|
{ 23, 21, 22, 4, 5, 24, ZSTD_btopt }, /* level 17 */
|
3271
|
-
{ 23,
|
3482
|
+
{ 23, 22, 22, 5, 4, 32, ZSTD_btopt }, /* level 18 */
|
3272
3483
|
{ 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19 */
|
3273
3484
|
{ 25, 25, 23, 7, 3, 64, ZSTD_btopt2 }, /* level 20 */
|
3274
3485
|
{ 26, 26, 23, 7, 3,256, ZSTD_btopt2 }, /* level 21 */
|