zstd-ruby 1.1.4.0 → 1.2.0.0

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