zstd-ruby 1.1.4.0 → 1.2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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 */
|