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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +1 -1
  4. data/ext/zstdruby/libzstd/Makefile +11 -1
  5. data/ext/zstdruby/libzstd/README.md +8 -0
  6. data/ext/zstdruby/libzstd/common/bitstream.h +56 -27
  7. data/ext/zstdruby/libzstd/common/error_private.c +2 -1
  8. data/ext/zstdruby/libzstd/common/fse.h +7 -3
  9. data/ext/zstdruby/libzstd/common/huf.h +42 -19
  10. data/ext/zstdruby/libzstd/common/mem.h +2 -3
  11. data/ext/zstdruby/libzstd/common/zstd_errors.h +1 -0
  12. data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -2
  13. data/ext/zstdruby/libzstd/compress/fse_compress.c +10 -10
  14. data/ext/zstdruby/libzstd/compress/zstd_compress.c +455 -244
  15. data/ext/zstdruby/libzstd/compress/zstd_opt.h +6 -4
  16. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +40 -28
  17. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +115 -219
  18. data/ext/zstdruby/libzstd/dictBuilder/cover.c +34 -13
  19. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +65 -43
  20. data/ext/zstdruby/libzstd/dictBuilder/zdict.h +7 -7
  21. data/ext/zstdruby/libzstd/dll/example/README.md +5 -5
  22. data/ext/zstdruby/libzstd/dll/example/build_package.bat +1 -0
  23. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
  24. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +21 -21
  25. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +20 -20
  26. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +4 -4
  27. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +2 -2
  28. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +2 -2
  29. data/ext/zstdruby/libzstd/zstd.h +88 -68
  30. data/lib/zstd-ruby/version.rb +1 -1
  31. 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) /*|| defined(_MSC_VER)*/ || \
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
- __pragma( pack(push, 1) )
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
@@ -57,6 +57,7 @@ typedef enum {
57
57
  ZSTD_error_maxSymbolValue_tooSmall,
58
58
  ZSTD_error_dictionary_corrupted,
59
59
  ZSTD_error_dictionary_wrong,
60
+ ZSTD_error_dictionaryCreation_failed,
60
61
  ZSTD_error_maxCode
61
62
  } ZSTD_ErrorCode;
62
63
 
@@ -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(GENERIC); /* Unsupported */
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
- 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;
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
- U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
487
+ U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
488
488
  U32 tableLog = maxTableLog;
489
- U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
489
+ U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
490
490
  if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
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 */
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, FSE_count(count, &maxSymbolValue, src, srcSize) );
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
- #define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
35
- size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
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
- HUF_CElt* hufTable;
81
- U32 flagStaticTables;
82
- HUF_repeat flagStaticHufTable;
83
- FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
84
- FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
85
- FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
86
- unsigned tmpCounters[HUF_WORKSPACE_SIZE_U32];
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
- { U32 const searchLengthMin = ((cParams.strategy == ZSTD_fast) | (cParams.strategy == ZSTD_greedy)) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN;
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 = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
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
- /*! ZSTD_resetCCtx_advanced() :
282
+ /*! ZSTD_resetCCtx_internal() :
250
283
  note : `params` must be validated */
251
- static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
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->flagStaticTables = 0;
258
- zc->flagStaticHufTable = HUF_repeat_none;
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 optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
275
- + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
276
- size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
277
- + (((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) ? optSpace : 0);
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
- if (crp!=ZSTDcrp_noMemset) memset(zc->workSpace, 0, tableSpace); /* reset tables only */
286
- XXH64_reset(&zc->xxhState, 0);
287
- zc->hashLog3 = hashLog3;
288
- zc->hashTable = (U32*)(zc->workSpace);
289
- zc->chainTable = zc->hashTable + hSize;
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
- /*! ZSTD_copyCCtx() :
345
- * Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
346
- * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
347
- * @return : 0, or an error code */
348
- size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
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.contentSizeFlag = (pledgedSrcSize > 0);
356
- ZSTD_resetCCtx_advanced(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
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 = ((size_t)1) << srcCCtx->params.cParams.hashLog;
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
- memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace);
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->flagStaticTables = srcCCtx->flagStaticTables;
380
- dstCCtx->flagStaticHufTable = srcCCtx->flagStaticHufTable;
381
- if (srcCCtx->flagStaticTables) {
382
- memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable));
383
- memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable));
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
- if (srcCCtx->flagStaticHufTable) {
387
- memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
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
- * reduce table indexes by `reducerValue` */
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->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
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->flagStaticHufTable;
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, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat)
511
- : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat);
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->flagStaticHufTable = HUF_repeat_check; } /* now have a table to reuse */
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->flagStaticHufTable = HUF_repeat_none;
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->flagStaticHufTable = HUF_repeat_none;
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->tmpCounters);
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->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
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 ERROR(GENERIC);
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->tmpCounters);
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->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
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 ERROR(GENERIC);
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->tmpCounters);
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->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
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 ERROR(GENERIC);
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->flagStaticTables = 0;
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->flagStaticHufTable = HUF_repeat_none;
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
- fprintf(stderr, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
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) { seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
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) { seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
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, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
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, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
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); } /* only in zstd_opt.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+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
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+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
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+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
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
- if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
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 h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
1289
- U32 const matchIndex3 = hashLong[h3];
1290
- const BYTE* match3 = base + matchIndex3;
1291
- hashLong[h3] = current + 1;
1292
- if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
1293
- mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
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-match3);
1296
- while (((ip>anchor) & (match3>lowest)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
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
- hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
1466
- hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
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+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
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
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
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
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
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=EQUAL_READ32-1;
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+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
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) { ml = currentMl; *offsetPtr = current - matchIndex + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ }
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+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
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 < EQUAL_READ32) {
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+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
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 >= EQUAL_READ32) && (gain2 > gain1))
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 >= EQUAL_READ32) && (gain2 > gain1)) {
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+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
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 >= EQUAL_READ32) && (gain2 > gain1))
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 >= EQUAL_READ32) && (gain2 > gain1)) {
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>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE])) /* only search for offset within prefix */
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+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
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+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
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 < EQUAL_READ32) {
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+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
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 >= EQUAL_READ32) && (gain2 > gain1))
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 >= EQUAL_READ32) && (gain2 > gain1)) {
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+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
2163
- int gain2 = (int)(repLength * 4);
2164
- int gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
2165
- if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
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 >= EQUAL_READ32) && (gain2 > gain1)) {
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+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
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, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
2298
- { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
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 tree not updated after finding very long rep matches */
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) return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
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 dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
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, 0);
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, 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
- ZSTD_insertAndFindFirstIndex (zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
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
- ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
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
- Magic == ZSTD_DICT_MAGIC (4 bytes)
2571
- HUF_writeCTable(256)
2572
- FSE_writeNCount(off)
2573
- FSE_writeNCount(ml)
2574
- FSE_writeNCount(ll)
2575
- RepOffsets
2576
- Dictionary content
2577
- */
2578
- /*! ZSTD_loadDictEntropyStats() :
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
- { size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
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 (FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
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 (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
2610
- CHECK_E (FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
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 (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
2621
- CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
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); if (cctx->rep[0] == 0 || cctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
2627
- cctx->rep[1] = MEM_readLE32(dictPtr+4); if (cctx->rep[1] == 0 || cctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
2628
- cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] == 0 || cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
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
- { U32 offcodeMax = MaxOff;
2632
- if ((size_t)(dictEnd - dictPtr) <= ((U32)-1) - 128 KB) {
2633
- U32 const maxOffset = (U32)(dictEnd - dictPtr) + 128 KB; /* The maximum offset that must be supported */
2634
- /* Calculate minimum offset code required to represent maxOffset */
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
- /* Every possible supported offset <= dictContentSize + 128 KB must be representable */
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
- cctx->flagStaticTables = 1;
2642
- cctx->flagStaticHufTable = HUF_repeat_valid;
2643
- return dictPtr - (const BYTE*)dict;
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* zc, const void* dict, size_t dictSize)
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) || (zc->forceRawDict))
2654
- return ZSTD_loadDictionaryContent(zc, dict, dictSize);
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
- /* known magic number : dict is parsed for entropy stats and content */
2658
- { size_t const loadError = ZSTD_loadDictEntropyStats(zc, (const char*)dict+8 /* skip dictHeader */, dictSize-8);
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
- CHECK_F(ZSTD_resetCCtx_advanced(cctx, params, pledgedSrcSize, crp));
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, 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, const void* dict, size_t dictSize, int compressionLevel)
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
- ZSTD_parameters params, ZSTD_customMem customMem)
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
- { size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
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
- ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, dictSize);
2859
- params.fParams.contentSizeFlag = 1;
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
- ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, dictSize);
2867
- params.fParams.contentSizeFlag = 1;
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
- size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize)
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->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
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.contentSizeFlag = (pledgedSrcSize > 0);
2892
- CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, params, pledgedSrcSize));
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
- * Compression using a digested Dictionary.
2899
- * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
2900
- * Note that compression level is decided during dictionary creation */
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
- CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize));
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
- size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
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
- if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize))
2992
- else CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
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
- size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
3014
- const void* dict, size_t dictSize,
3015
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
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 = neededInBuffSize;
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
- zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
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(zcs->outBuffSize, zcs->customMem);
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
- ZSTD_parameters const params = ZSTD_getParamsFromCDict(cdict);
3051
- size_t const initError = ZSTD_initCStream_advanced(zcs, NULL, 0, params, 0);
3052
- zcs->cdict = cdict;
3053
- zcs->cctx->dictID = params.fParams.noDictIDFlag ? 0 : cdict->refContext->dictID;
3054
- return initError;
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 ZSTD_initCStream_advanced(zcs, dict, dictSize, params, 0);
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
- if (pledgedSrcSize) params.fParams.contentSizeFlag = 1;
3067
- return ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize);
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
- return ZSTD_initCStream_usingDict(zcs, NULL, 0, compressionLevel);
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, &srcSize, &srcSize, zsf_end); /* use a valid src address instead of NULL */
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
- ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0); /* write epilogue, including final empty block, into outBuff */
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, 23, 22, 6, 5, 32, ZSTD_btopt }, /* level 18 */
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 */