zstd-ruby 1.3.2.0 → 1.3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/zstdruby/libzstd/BUCK +31 -10
  4. data/ext/zstdruby/libzstd/common/bitstream.h +1 -1
  5. data/ext/zstdruby/libzstd/common/mem.h +15 -13
  6. data/ext/zstdruby/libzstd/common/pool.c +1 -2
  7. data/ext/zstdruby/libzstd/common/zstd_common.c +10 -4
  8. data/ext/zstdruby/libzstd/common/zstd_internal.h +52 -170
  9. data/ext/zstdruby/libzstd/compress/zstd_compress.c +434 -337
  10. data/ext/zstdruby/libzstd/compress/{zstd_compress.h → zstd_compress_internal.h} +191 -36
  11. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +1 -0
  12. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
  13. data/ext/zstdruby/libzstd/compress/zstd_fast.c +1 -0
  14. data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
  15. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +66 -50
  16. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +3 -2
  17. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +3 -2
  18. data/ext/zstdruby/libzstd/compress/zstd_opt.c +504 -676
  19. data/ext/zstdruby/libzstd/compress/zstd_opt.h +2 -2
  20. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +130 -80
  21. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +15 -7
  22. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +41 -31
  23. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -0
  24. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +1 -1
  25. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
  26. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +1 -74
  27. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +1 -74
  28. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -72
  29. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -73
  30. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -77
  31. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -77
  32. data/ext/zstdruby/libzstd/zstd.h +43 -30
  33. data/lib/zstd-ruby/version.rb +1 -1
  34. metadata +4 -4
@@ -26,7 +26,7 @@
26
26
  #include "fse.h"
27
27
  #define HUF_STATIC_LINKING_ONLY
28
28
  #include "huf.h"
29
- #include "zstd_compress.h"
29
+ #include "zstd_compress_internal.h"
30
30
  #include "zstd_fast.h"
31
31
  #include "zstd_double_fast.h"
32
32
  #include "zstd_lazy.h"
@@ -42,17 +42,6 @@ size_t ZSTD_compressBound(size_t srcSize) {
42
42
  }
43
43
 
44
44
 
45
- /*-*************************************
46
- * Sequence storage
47
- ***************************************/
48
- static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
49
- {
50
- ssPtr->lit = ssPtr->litStart;
51
- ssPtr->sequences = ssPtr->sequencesStart;
52
- ssPtr->longLengthID = 0;
53
- }
54
-
55
-
56
45
  /*-*************************************
57
46
  * Context memory management
58
47
  ***************************************/
@@ -78,6 +67,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
78
67
  if (!cctx) return NULL;
79
68
  cctx->customMem = customMem;
80
69
  cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;
70
+ cctx->requestedParams.fParams.contentSizeFlag = 1;
81
71
  ZSTD_STATIC_ASSERT(zcss_init==0);
82
72
  ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
83
73
  return cctx;
@@ -152,28 +142,34 @@ const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStor
152
142
  #define ZSTD_CLEVEL_CUSTOM 999
153
143
 
154
144
  static ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
155
- ZSTD_CCtx_params params, U64 srcSizeHint, size_t dictSize)
145
+ ZSTD_CCtx_params CCtxParams, U64 srcSizeHint, size_t dictSize)
156
146
  {
157
- return (params.compressionLevel == ZSTD_CLEVEL_CUSTOM ?
158
- params.cParams :
159
- ZSTD_getCParams(params.compressionLevel, srcSizeHint, dictSize));
147
+ DEBUGLOG(4, "ZSTD_getCParamsFromCCtxParams: srcSize = %u, dictSize = %u",
148
+ (U32)srcSizeHint, (U32)dictSize);
149
+ return (CCtxParams.compressionLevel == ZSTD_CLEVEL_CUSTOM) ?
150
+ CCtxParams.cParams :
151
+ ZSTD_getCParams(CCtxParams.compressionLevel, srcSizeHint, dictSize);
160
152
  }
161
153
 
162
- static void ZSTD_cLevelToCCtxParams_srcSize(ZSTD_CCtx_params* params, U64 srcSize)
154
+ static void ZSTD_cLevelToCCtxParams_srcSize(ZSTD_CCtx_params* CCtxParams, U64 srcSize)
163
155
  {
164
- params->cParams = ZSTD_getCParamsFromCCtxParams(*params, srcSize, 0);
165
- params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
156
+ DEBUGLOG(4, "ZSTD_cLevelToCCtxParams_srcSize: srcSize = %u",
157
+ (U32)srcSize);
158
+ CCtxParams->cParams = ZSTD_getCParamsFromCCtxParams(*CCtxParams, srcSize, 0);
159
+ CCtxParams->compressionLevel = ZSTD_CLEVEL_CUSTOM;
166
160
  }
167
161
 
168
162
  static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
169
163
  {
164
+ DEBUGLOG(4, "ZSTD_cLevelToCParams: level=%i", cctx->requestedParams.compressionLevel);
170
165
  ZSTD_cLevelToCCtxParams_srcSize(
171
166
  &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1);
172
167
  }
173
168
 
174
- static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* params)
169
+ static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* CCtxParams)
175
170
  {
176
- ZSTD_cLevelToCCtxParams_srcSize(params, 0);
171
+ DEBUGLOG(4, "ZSTD_cLevelToCCtxParams");
172
+ ZSTD_cLevelToCCtxParams_srcSize(CCtxParams, ZSTD_CONTENTSIZE_UNKNOWN);
177
173
  }
178
174
 
179
175
  static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
@@ -251,6 +247,7 @@ static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
251
247
 
252
248
  size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
253
249
  {
250
+ DEBUGLOG(4, "ZSTD_CCtx_setParameter (%u, %u)", (U32)param, value);
254
251
  if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
255
252
 
256
253
  switch(param)
@@ -259,7 +256,6 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
259
256
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
260
257
 
261
258
  case ZSTD_p_compressionLevel:
262
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
263
259
  if (cctx->cdict) return ERROR(stage_wrong);
264
260
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
265
261
 
@@ -270,9 +266,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
270
266
  case ZSTD_p_minMatch:
271
267
  case ZSTD_p_targetLength:
272
268
  case ZSTD_p_compressionStrategy:
273
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
274
269
  if (cctx->cdict) return ERROR(stage_wrong);
275
- ZSTD_cLevelToCParams(cctx); /* Can optimize if srcSize is known */
270
+ if (value>0) ZSTD_cLevelToCParams(cctx); /* Can optimize if srcSize is known */
276
271
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
277
272
 
278
273
  case ZSTD_p_contentSizeFlag:
@@ -281,15 +276,12 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
281
276
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
282
277
 
283
278
  case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize,
284
- * even when referencing into Dictionary content
279
+ * even when referencing into Dictionary content.
285
280
  * default : 0 when using a CDict, 1 when using a Prefix */
286
- cctx->loadedDictEnd = 0;
287
281
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
288
282
 
289
283
  case ZSTD_p_nbThreads:
290
- if (value==0) return 0;
291
- DEBUGLOG(5, " setting nbThreads : %u", value);
292
- if (value > 1 && cctx->staticSize) {
284
+ if ((value > 1) && cctx->staticSize) {
293
285
  return ERROR(parameter_unsupported); /* MT not compatible with static alloc */
294
286
  }
295
287
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
@@ -298,22 +290,15 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
298
290
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
299
291
 
300
292
  case ZSTD_p_overlapSizeLog:
301
- DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->requestedParams.nbThreads);
302
293
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
303
294
 
304
295
  case ZSTD_p_enableLongDistanceMatching:
305
296
  if (cctx->cdict) return ERROR(stage_wrong);
306
- if (value != 0) {
307
- ZSTD_cLevelToCParams(cctx);
308
- }
297
+ if (value>0) ZSTD_cLevelToCParams(cctx);
309
298
  return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
310
299
 
311
300
  case ZSTD_p_ldmHashLog:
312
301
  case ZSTD_p_ldmMinMatch:
313
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
314
- if (cctx->cdict) return ERROR(stage_wrong);
315
- return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
316
-
317
302
  case ZSTD_p_ldmBucketSizeLog:
318
303
  case ZSTD_p_ldmHashEveryLog:
319
304
  if (cctx->cdict) return ERROR(stage_wrong);
@@ -324,160 +309,167 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
324
309
  }
325
310
 
326
311
  size_t ZSTD_CCtxParam_setParameter(
327
- ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value)
312
+ ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, unsigned value)
328
313
  {
314
+ DEBUGLOG(4, "ZSTD_CCtxParam_setParameter (%u, %u)", (U32)param, value);
329
315
  switch(param)
330
316
  {
331
317
  case ZSTD_p_format :
332
318
  if (value > (unsigned)ZSTD_f_zstd1_magicless)
333
319
  return ERROR(parameter_unsupported);
334
- params->format = (ZSTD_format_e)value;
335
- return 0;
320
+ CCtxParams->format = (ZSTD_format_e)value;
321
+ return (size_t)CCtxParams->format;
336
322
 
337
323
  case ZSTD_p_compressionLevel :
338
324
  if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel();
339
- if (value == 0) return 0;
340
- params->compressionLevel = value;
341
- return 0;
325
+ if (value) /* 0 : does not change current level */
326
+ CCtxParams->compressionLevel = value;
327
+ return CCtxParams->compressionLevel;
342
328
 
343
329
  case ZSTD_p_windowLog :
344
- if (value == 0) return 0;
345
- CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
346
- ZSTD_cLevelToCCtxParams(params);
347
- params->cParams.windowLog = value;
348
- return 0;
330
+ DEBUGLOG(4, "ZSTD_CCtxParam_setParameter: set windowLog=%u", value);
331
+ if (value) { /* 0 : does not change current windowLog */
332
+ CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
333
+ ZSTD_cLevelToCCtxParams(CCtxParams);
334
+ CCtxParams->cParams.windowLog = value;
335
+ }
336
+ return CCtxParams->cParams.windowLog;
349
337
 
350
338
  case ZSTD_p_hashLog :
351
- if (value == 0) return 0;
352
- CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
353
- ZSTD_cLevelToCCtxParams(params);
354
- params->cParams.hashLog = value;
355
- return 0;
339
+ if (value) { /* 0 : does not change current hashLog */
340
+ CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
341
+ ZSTD_cLevelToCCtxParams(CCtxParams);
342
+ CCtxParams->cParams.hashLog = value;
343
+ }
344
+ return CCtxParams->cParams.hashLog;
356
345
 
357
346
  case ZSTD_p_chainLog :
358
- if (value == 0) return 0;
359
- CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
360
- ZSTD_cLevelToCCtxParams(params);
361
- params->cParams.chainLog = value;
362
- return 0;
347
+ if (value) { /* 0 : does not change current chainLog */
348
+ CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
349
+ ZSTD_cLevelToCCtxParams(CCtxParams);
350
+ CCtxParams->cParams.chainLog = value;
351
+ }
352
+ return CCtxParams->cParams.chainLog;
363
353
 
364
354
  case ZSTD_p_searchLog :
365
- if (value == 0) return 0;
366
- CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
367
- ZSTD_cLevelToCCtxParams(params);
368
- params->cParams.searchLog = value;
369
- return 0;
355
+ if (value) { /* 0 : does not change current searchLog */
356
+ CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
357
+ ZSTD_cLevelToCCtxParams(CCtxParams);
358
+ CCtxParams->cParams.searchLog = value;
359
+ }
360
+ return value;
370
361
 
371
362
  case ZSTD_p_minMatch :
372
- if (value == 0) return 0;
373
- CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
374
- ZSTD_cLevelToCCtxParams(params);
375
- params->cParams.searchLength = value;
376
- return 0;
363
+ if (value) { /* 0 : does not change current minMatch length */
364
+ CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
365
+ ZSTD_cLevelToCCtxParams(CCtxParams);
366
+ CCtxParams->cParams.searchLength = value;
367
+ }
368
+ return CCtxParams->cParams.searchLength;
377
369
 
378
370
  case ZSTD_p_targetLength :
379
- if (value == 0) return 0;
380
- CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
381
- ZSTD_cLevelToCCtxParams(params);
382
- params->cParams.targetLength = value;
383
- return 0;
371
+ if (value) { /* 0 : does not change current sufficient_len */
372
+ CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
373
+ ZSTD_cLevelToCCtxParams(CCtxParams);
374
+ CCtxParams->cParams.targetLength = value;
375
+ }
376
+ return CCtxParams->cParams.targetLength;
384
377
 
385
378
  case ZSTD_p_compressionStrategy :
386
- if (value == 0) return 0;
387
- CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
388
- ZSTD_cLevelToCCtxParams(params);
389
- params->cParams.strategy = (ZSTD_strategy)value;
390
- return 0;
379
+ if (value) { /* 0 : does not change currentstrategy */
380
+ CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
381
+ ZSTD_cLevelToCCtxParams(CCtxParams);
382
+ CCtxParams->cParams.strategy = (ZSTD_strategy)value;
383
+ }
384
+ return (size_t)CCtxParams->cParams.strategy;
391
385
 
392
386
  case ZSTD_p_contentSizeFlag :
393
387
  /* Content size written in frame header _when known_ (default:1) */
394
- DEBUGLOG(5, "set content size flag = %u", (value>0));
395
- params->fParams.contentSizeFlag = value > 0;
396
- return 0;
388
+ DEBUGLOG(4, "set content size flag = %u", (value>0));
389
+ CCtxParams->fParams.contentSizeFlag = value > 0;
390
+ return CCtxParams->fParams.contentSizeFlag;
397
391
 
398
392
  case ZSTD_p_checksumFlag :
399
393
  /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
400
- params->fParams.checksumFlag = value > 0;
401
- return 0;
394
+ CCtxParams->fParams.checksumFlag = value > 0;
395
+ return CCtxParams->fParams.checksumFlag;
402
396
 
403
397
  case ZSTD_p_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
404
- DEBUGLOG(5, "set dictIDFlag = %u", (value>0));
405
- params->fParams.noDictIDFlag = (value == 0);
406
- return 0;
398
+ DEBUGLOG(4, "set dictIDFlag = %u", (value>0));
399
+ CCtxParams->fParams.noDictIDFlag = (value == 0);
400
+ return !CCtxParams->fParams.noDictIDFlag;
407
401
 
408
402
  case ZSTD_p_forceMaxWindow :
409
- params->forceWindow = value > 0;
410
- return 0;
403
+ CCtxParams->forceWindow = (value > 0);
404
+ return CCtxParams->forceWindow;
411
405
 
412
406
  case ZSTD_p_nbThreads :
413
- if (value == 0) return 0;
407
+ if (value == 0) return CCtxParams->nbThreads;
414
408
  #ifndef ZSTD_MULTITHREAD
415
409
  if (value > 1) return ERROR(parameter_unsupported);
416
- return 0;
410
+ return 1;
417
411
  #else
418
- return ZSTDMT_initializeCCtxParameters(params, value);
412
+ return ZSTDMT_CCtxParam_setNbThreads(CCtxParams, value);
419
413
  #endif
420
414
 
421
415
  case ZSTD_p_jobSize :
422
416
  #ifndef ZSTD_MULTITHREAD
423
417
  return ERROR(parameter_unsupported);
424
418
  #else
425
- if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
426
- return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_sectionSize, value);
419
+ if (CCtxParams->nbThreads <= 1) return ERROR(parameter_unsupported);
420
+ return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_jobSize, value);
427
421
  #endif
428
422
 
429
423
  case ZSTD_p_overlapSizeLog :
430
424
  #ifndef ZSTD_MULTITHREAD
431
425
  return ERROR(parameter_unsupported);
432
426
  #else
433
- if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
434
- return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_overlapSectionLog, value);
427
+ if (CCtxParams->nbThreads <= 1) return ERROR(parameter_unsupported);
428
+ return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_overlapSectionLog, value);
435
429
  #endif
436
430
 
437
431
  case ZSTD_p_enableLongDistanceMatching :
438
- if (value != 0) {
439
- ZSTD_cLevelToCCtxParams(params);
440
- params->cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
432
+ if (value) {
433
+ ZSTD_cLevelToCCtxParams(CCtxParams);
434
+ CCtxParams->cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
441
435
  }
442
- return ZSTD_ldm_initializeParameters(&params->ldmParams, value);
436
+ return ZSTD_ldm_initializeParameters(&CCtxParams->ldmParams, value);
443
437
 
444
438
  case ZSTD_p_ldmHashLog :
445
- if (value == 0) return 0;
446
- CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
447
- params->ldmParams.hashLog = value;
448
- return 0;
439
+ if (value) { /* 0 : does not change current ldmHashLog */
440
+ CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
441
+ CCtxParams->ldmParams.hashLog = value;
442
+ }
443
+ return CCtxParams->ldmParams.hashLog;
449
444
 
450
445
  case ZSTD_p_ldmMinMatch :
451
- if (value == 0) return 0;
452
- CLAMPCHECK(value, ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX);
453
- params->ldmParams.minMatchLength = value;
454
- return 0;
446
+ if (value) { /* 0 : does not change current ldmMinMatch */
447
+ CLAMPCHECK(value, ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX);
448
+ CCtxParams->ldmParams.minMatchLength = value;
449
+ }
450
+ return CCtxParams->ldmParams.minMatchLength;
455
451
 
456
452
  case ZSTD_p_ldmBucketSizeLog :
457
453
  if (value > ZSTD_LDM_BUCKETSIZELOG_MAX) {
458
454
  return ERROR(parameter_outOfBound);
459
455
  }
460
- params->ldmParams.bucketSizeLog = value;
461
- return 0;
456
+ CCtxParams->ldmParams.bucketSizeLog = value;
457
+ return value;
462
458
 
463
459
  case ZSTD_p_ldmHashEveryLog :
464
460
  if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN) {
465
461
  return ERROR(parameter_outOfBound);
466
462
  }
467
- params->ldmParams.hashEveryLog = value;
468
- return 0;
463
+ CCtxParams->ldmParams.hashEveryLog = value;
464
+ return value;
469
465
 
470
466
  default: return ERROR(parameter_unsupported);
471
467
  }
472
468
  }
473
469
 
474
- /**
475
- * This function should be updated whenever ZSTD_CCtx_params is updated.
476
- * Parameters are copied manually before the dictionary is loaded.
477
- * The multithreading parameters jobSize and overlapSizeLog are set only if
478
- * nbThreads > 1.
479
- *
480
- * Pledged srcSize is treated as unknown.
470
+ /** ZSTD_CCtx_setParametersUsingCCtxParams() :
471
+ * just applies `params` into `cctx`
472
+ * no action is performed, parameters are merely stored.
481
473
  */
482
474
  size_t ZSTD_CCtx_setParametersUsingCCtxParams(
483
475
  ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
@@ -485,33 +477,14 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
485
477
  if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
486
478
  if (cctx->cdict) return ERROR(stage_wrong);
487
479
 
488
- /* Assume the compression and frame parameters are validated */
489
- cctx->requestedParams.cParams = params->cParams;
490
- cctx->requestedParams.fParams = params->fParams;
491
- cctx->requestedParams.compressionLevel = params->compressionLevel;
492
-
493
- /* Set force window explicitly since it sets cctx->loadedDictEnd */
494
- CHECK_F( ZSTD_CCtx_setParameter(
495
- cctx, ZSTD_p_forceMaxWindow, params->forceWindow) );
496
-
497
- /* Set multithreading parameters explicitly */
498
- CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_nbThreads, params->nbThreads) );
499
- if (params->nbThreads > 1) {
500
- CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_jobSize, params->jobSize) );
501
- CHECK_F( ZSTD_CCtx_setParameter(
502
- cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
503
- }
480
+ cctx->requestedParams = *params;
504
481
 
505
- /* Copy long distance matching parameters */
506
- cctx->requestedParams.ldmParams = params->ldmParams;
507
-
508
- /* customMem is used only for create/free params and can be ignored */
509
482
  return 0;
510
483
  }
511
484
 
512
485
  ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
513
486
  {
514
- DEBUGLOG(4, " setting pledgedSrcSize to %u", (U32)pledgedSrcSize);
487
+ DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %u bytes", (U32)pledgedSrcSize);
515
488
  if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
516
489
  cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
517
490
  return 0;
@@ -523,14 +496,14 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
523
496
  {
524
497
  if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
525
498
  if (cctx->staticSize) return ERROR(memory_allocation); /* no malloc for static CCtx */
526
- DEBUGLOG(4, "load dictionary of size %u", (U32)dictSize);
499
+ DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
527
500
  ZSTD_freeCDict(cctx->cdictLocal); /* in case one already exists */
528
501
  if (dict==NULL || dictSize==0) { /* no dictionary mode */
529
502
  cctx->cdictLocal = NULL;
530
503
  cctx->cdict = NULL;
531
504
  } else {
532
505
  ZSTD_compressionParameters const cParams =
533
- ZSTD_getCParamsFromCCtxParams(cctx->requestedParams, 0, dictSize);
506
+ ZSTD_getCParamsFromCCtxParams(cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, dictSize);
534
507
  cctx->cdictLocal = ZSTD_createCDict_advanced(
535
508
  dict, dictSize,
536
509
  dictLoadMethod, dictMode,
@@ -756,10 +729,7 @@ size_t ZSTD_estimateCStreamSize(int compressionLevel) {
756
729
  static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
757
730
  ZSTD_compressionParameters cParams2)
758
731
  {
759
- U32 bslog1 = MIN(cParams1.windowLog, ZSTD_BLOCKSIZELOG_MAX);
760
- U32 bslog2 = MIN(cParams2.windowLog, ZSTD_BLOCKSIZELOG_MAX);
761
- return (bslog1 == bslog2) /* same block size */
762
- & (cParams1.hashLog == cParams2.hashLog)
732
+ return (cParams1.hashLog == cParams2.hashLog)
763
733
  & (cParams1.chainLog == cParams2.chainLog)
764
734
  & (cParams1.strategy == cParams2.strategy) /* opt parser space */
765
735
  & ((cParams1.searchLength==3) == (cParams2.searchLength==3)); /* hashlog3 space */
@@ -778,12 +748,38 @@ static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
778
748
  ldmParams1.hashEveryLog == ldmParams2.hashEveryLog);
779
749
  }
780
750
 
751
+ typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
752
+
753
+ /* ZSTD_sufficientBuff() :
754
+ * check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
755
+ * Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
756
+ static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t blockSize1,
757
+ ZSTD_buffered_policy_e buffPol2,
758
+ ZSTD_compressionParameters cParams2,
759
+ U64 pledgedSrcSize)
760
+ {
761
+ size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
762
+ size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
763
+ size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
764
+ DEBUGLOG(4, "ZSTD_sufficientBuff: windowSize2=%u from wlog=%u",
765
+ (U32)windowSize2, cParams2.windowLog);
766
+ DEBUGLOG(4, "ZSTD_sufficientBuff: blockSize2 %u <=? blockSize1 %u",
767
+ (U32)blockSize2, (U32)blockSize1);
768
+ return (blockSize2 <= blockSize1) /* seqStore space depends on blockSize */
769
+ & (neededBufferSize2 <= bufferSize1);
770
+ }
771
+
781
772
  /** Equivalence for resetCCtx purposes */
782
773
  static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
783
- ZSTD_CCtx_params params2)
774
+ ZSTD_CCtx_params params2,
775
+ size_t buffSize1, size_t blockSize1,
776
+ ZSTD_buffered_policy_e buffPol2,
777
+ U64 pledgedSrcSize)
784
778
  {
779
+ DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
785
780
  return ZSTD_equivalentCParams(params1.cParams, params2.cParams) &&
786
- ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams);
781
+ ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams) &&
782
+ ZSTD_sufficientBuff(buffSize1, blockSize1, buffPol2, params2.cParams, pledgedSrcSize);
787
783
  }
788
784
 
789
785
  /*! ZSTD_continueCCtx() :
@@ -791,7 +787,11 @@ static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
791
787
  static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize)
792
788
  {
793
789
  U32 const end = (U32)(cctx->nextSrc - cctx->base);
794
- DEBUGLOG(4, "continue mode");
790
+ size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
791
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
792
+ DEBUGLOG(4, "ZSTD_continueCCtx");
793
+
794
+ cctx->blockSize = blockSize; /* previous block size could be different even for same windowLog, due to pledgedSrcSize */
795
795
  cctx->appliedParams = params;
796
796
  cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
797
797
  cctx->consumedSrcSize = 0;
@@ -812,7 +812,6 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pl
812
812
  }
813
813
 
814
814
  typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
815
- typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
816
815
 
817
816
  /*! ZSTD_resetCCtx_internal() :
818
817
  note : `params` are assumed fully validated at this stage */
@@ -821,13 +820,16 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
821
820
  ZSTD_compResetPolicy_e const crp,
822
821
  ZSTD_buffered_policy_e const zbuff)
823
822
  {
824
- DEBUGLOG(4, "ZSTD_resetCCtx_internal");
823
+ DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
824
+ (U32)pledgedSrcSize, params.cParams.windowLog);
825
825
  assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
826
- DEBUGLOG(4, "pledgedSrcSize: %u", (U32)pledgedSrcSize);
827
826
 
828
827
  if (crp == ZSTDcrp_continue) {
829
- if (ZSTD_equivalentParams(params, zc->appliedParams)) {
830
- DEBUGLOG(4, "ZSTD_equivalentParams()==1");
828
+ if (ZSTD_equivalentParams(zc->appliedParams, params,
829
+ zc->inBuffSize, zc->blockSize,
830
+ zbuff, pledgedSrcSize)) {
831
+ DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%u)",
832
+ zc->appliedParams.cParams.windowLog, (U32)zc->blockSize);
831
833
  assert(!(params.ldmParams.enableLdm &&
832
834
  params.ldmParams.hashEveryLog == ZSTD_LDM_HASHEVERYLOG_NOTSET));
833
835
  zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
@@ -836,6 +838,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
836
838
  zc->entropy->litlength_repeatMode = FSE_repeat_none;
837
839
  return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
838
840
  } }
841
+ DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
839
842
 
840
843
  if (params.ldmParams.enableLdm) {
841
844
  /* Adjust long distance matching parameters */
@@ -846,7 +849,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
846
849
  ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
847
850
  }
848
851
 
849
- { size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
852
+ { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
853
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
850
854
  U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
851
855
  size_t const maxNbSeq = blockSize / divider;
852
856
  size_t const tokenSpace = blockSize + 11*maxNbSeq;
@@ -858,7 +862,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
858
862
  size_t const h3Size = ((size_t)1) << hashLog3;
859
863
  size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
860
864
  size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
861
- size_t const buffInSize = (zbuff==ZSTDb_buffered) ? ((size_t)1 << params.cParams.windowLog) + blockSize : 0;
865
+ size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
862
866
  void* ptr;
863
867
 
864
868
  /* Check if workSpace is large enough, alloc a new one if needed */
@@ -874,11 +878,15 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
874
878
  : 0;
875
879
  size_t const neededSpace = entropySpace + optSpace + ldmSpace +
876
880
  tableSpace + tokenSpace + bufferSpace;
881
+ DEBUGLOG(4, "Need %uKB workspace, including %uKB for tables, and %uKB for buffers",
882
+ (U32)(neededSpace>>10), (U32)(tableSpace>>10), (U32)(bufferSpace>>10));
883
+ DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u - windowSize: %u - blockSize: %u",
884
+ (U32)chainSize, (U32)hSize, (U32)h3Size, (U32)windowSize, (U32)blockSize);
877
885
 
878
886
  if (zc->workSpaceSize < neededSpace) { /* too small : resize */
879
- DEBUGLOG(5, "Need to update workSpaceSize from %uK to %uK \n",
880
- (unsigned)zc->workSpaceSize>>10,
881
- (unsigned)neededSpace>>10);
887
+ DEBUGLOG(4, "Need to update workSpaceSize from %uK to %uK",
888
+ (unsigned)(zc->workSpaceSize>>10),
889
+ (unsigned)(neededSpace>>10));
882
890
  /* static cctx : no resize, error out */
883
891
  if (zc->staticSize) return ERROR(memory_allocation);
884
892
 
@@ -901,7 +909,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
901
909
  zc->consumedSrcSize = 0;
902
910
  if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
903
911
  zc->appliedParams.fParams.contentSizeFlag = 0;
904
- DEBUGLOG(5, "pledged content size : %u ; flag : %u",
912
+ DEBUGLOG(4, "pledged content size : %u ; flag : %u",
905
913
  (U32)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);
906
914
  zc->blockSize = blockSize;
907
915
 
@@ -927,7 +935,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
927
935
 
928
936
  /* opt parser space */
929
937
  if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btultra)) {
930
- DEBUGLOG(5, "reserving optimal parser space");
938
+ DEBUGLOG(4, "reserving optimal parser space");
931
939
  assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
932
940
  zc->optState.litFreq = (U32*)ptr;
933
941
  zc->optState.litLengthFreq = zc->optState.litFreq + (1<<Litbits);
@@ -951,6 +959,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
951
959
  }
952
960
 
953
961
  /* table Space */
962
+ DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_noMemset);
954
963
  if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
955
964
  assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
956
965
  zc->hashTable = (U32*)(ptr);
@@ -999,15 +1008,16 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
999
1008
 
1000
1009
  /*! ZSTD_copyCCtx_internal() :
1001
1010
  * Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
1002
- * The "context", in this case, refers to the hash and chain tables, entropy
1003
- * tables, and dictionary offsets.
1004
1011
  * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
1005
- * pledgedSrcSize=0 means "empty" if fParams.contentSizeFlag=1
1006
- * @return : 0, or an error code */
1012
+ * The "context", in this case, refers to the hash and chain tables,
1013
+ * entropy tables, and dictionary references.
1014
+ * `windowLog` value is enforced if != 0, otherwise value is copied from srcCCtx.
1015
+ * @return : 0, or an error code */
1007
1016
  static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
1008
1017
  const ZSTD_CCtx* srcCCtx,
1018
+ unsigned windowLog,
1009
1019
  ZSTD_frameParameters fParams,
1010
- unsigned long long pledgedSrcSize,
1020
+ U64 pledgedSrcSize,
1011
1021
  ZSTD_buffered_policy_e zbuff)
1012
1022
  {
1013
1023
  DEBUGLOG(5, "ZSTD_copyCCtx_internal");
@@ -1017,6 +1027,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
1017
1027
  { ZSTD_CCtx_params params = dstCCtx->requestedParams;
1018
1028
  /* Copy only compression parameters related to tables. */
1019
1029
  params.cParams = srcCCtx->appliedParams.cParams;
1030
+ if (windowLog) params.cParams.windowLog = windowLog;
1020
1031
  params.fParams = fParams;
1021
1032
  ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
1022
1033
  ZSTDcrp_noMemset, zbuff);
@@ -1045,6 +1056,12 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
1045
1056
 
1046
1057
  /* copy entropy tables */
1047
1058
  memcpy(dstCCtx->entropy, srcCCtx->entropy, sizeof(ZSTD_entropyCTables_t));
1059
+ /* copy repcodes */
1060
+ {
1061
+ int i;
1062
+ for (i = 0; i < ZSTD_REP_NUM; ++i)
1063
+ dstCCtx->seqStore.rep[i] = srcCCtx->seqStore.rep[i];
1064
+ }
1048
1065
 
1049
1066
  return 0;
1050
1067
  }
@@ -1059,9 +1076,12 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long
1059
1076
  ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
1060
1077
  ZSTD_buffered_policy_e const zbuff = (ZSTD_buffered_policy_e)(srcCCtx->inBuffSize>0);
1061
1078
  ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1);
1062
- fParams.contentSizeFlag = pledgedSrcSize>0;
1079
+ if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
1080
+ fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN);
1063
1081
 
1064
- return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, fParams, pledgedSrcSize, zbuff);
1082
+ return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx,
1083
+ 0 /*windowLog from srcCCtx*/, fParams, pledgedSrcSize,
1084
+ zbuff);
1065
1085
  }
1066
1086
 
1067
1087
 
@@ -1238,7 +1258,7 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t * entropy,
1238
1258
  ostart[4] = (BYTE)(cLitSize >> 10);
1239
1259
  break;
1240
1260
  }
1241
- default: /* not possible : lhSize is {3,4,5} */
1261
+ default: /* not possible : lhSize is {3,4,5} */
1242
1262
  assert(0);
1243
1263
  }
1244
1264
  return lhSize+cLitSize;
@@ -1247,8 +1267,6 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t * entropy,
1247
1267
 
1248
1268
  void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
1249
1269
  {
1250
- BYTE const LL_deltaCode = 19;
1251
- BYTE const ML_deltaCode = 36;
1252
1270
  const seqDef* const sequences = seqStorePtr->sequencesStart;
1253
1271
  BYTE* const llCodeTable = seqStorePtr->llCode;
1254
1272
  BYTE* const ofCodeTable = seqStorePtr->ofCode;
@@ -1258,9 +1276,9 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
1258
1276
  for (u=0; u<nbSeq; u++) {
1259
1277
  U32 const llv = sequences[u].litLength;
1260
1278
  U32 const mlv = sequences[u].matchLength;
1261
- llCodeTable[u] = (llv> 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv];
1279
+ llCodeTable[u] = (BYTE)ZSTD_LLcode(llv);
1262
1280
  ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
1263
- mlCodeTable[u] = (mlv>127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv];
1281
+ mlCodeTable[u] = (BYTE)ZSTD_MLcode(mlv);
1264
1282
  }
1265
1283
  if (seqStorePtr->longLengthID==1)
1266
1284
  llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
@@ -1273,7 +1291,8 @@ typedef enum {
1273
1291
  ZSTD_defaultAllowed = 1
1274
1292
  } ZSTD_defaultPolicy_e;
1275
1293
 
1276
- MEM_STATIC symbolEncodingType_e ZSTD_selectEncodingType(
1294
+ MEM_STATIC
1295
+ symbolEncodingType_e ZSTD_selectEncodingType(
1277
1296
  FSE_repeat* repeatMode, size_t const mostFrequent, size_t nbSeq,
1278
1297
  U32 defaultNormLog, ZSTD_defaultPolicy_e const isDefaultAllowed)
1279
1298
  {
@@ -1281,6 +1300,7 @@ MEM_STATIC symbolEncodingType_e ZSTD_selectEncodingType(
1281
1300
  #define MAX_SEQ_FOR_STATIC_FSE 1000
1282
1301
  ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
1283
1302
  if ((mostFrequent == nbSeq) && (!isDefaultAllowed || nbSeq > 2)) {
1303
+ DEBUGLOG(5, "Selected set_rle");
1284
1304
  /* Prefer set_basic over set_rle when there are 2 or less symbols,
1285
1305
  * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
1286
1306
  * If basic encoding isn't possible, always choose RLE.
@@ -1288,18 +1308,30 @@ MEM_STATIC symbolEncodingType_e ZSTD_selectEncodingType(
1288
1308
  *repeatMode = FSE_repeat_check;
1289
1309
  return set_rle;
1290
1310
  }
1291
- if (isDefaultAllowed && (*repeatMode == FSE_repeat_valid) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
1311
+ if ( isDefaultAllowed
1312
+ && (*repeatMode == FSE_repeat_valid) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
1313
+ DEBUGLOG(5, "Selected set_repeat");
1292
1314
  return set_repeat;
1293
1315
  }
1294
- if (isDefaultAllowed && ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (defaultNormLog-1))))) {
1295
- *repeatMode = FSE_repeat_valid;
1316
+ if ( isDefaultAllowed
1317
+ && ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (defaultNormLog-1)))) ) {
1318
+ DEBUGLOG(5, "Selected set_basic");
1319
+ /* The format allows default tables to be repeated, but it isn't useful.
1320
+ * When using simple heuristics to select encoding type, we don't want
1321
+ * to confuse these tables with dictionaries. When running more careful
1322
+ * analysis, we don't need to waste time checking both repeating tables
1323
+ * and default tables.
1324
+ */
1325
+ *repeatMode = FSE_repeat_none;
1296
1326
  return set_basic;
1297
1327
  }
1328
+ DEBUGLOG(5, "Selected set_compressed");
1298
1329
  *repeatMode = FSE_repeat_check;
1299
1330
  return set_compressed;
1300
1331
  }
1301
1332
 
1302
- MEM_STATIC size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
1333
+ MEM_STATIC
1334
+ size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
1303
1335
  FSE_CTable* CTable, U32 FSELog, symbolEncodingType_e type,
1304
1336
  U32* count, U32 max,
1305
1337
  BYTE const* codeTable, size_t nbSeq,
@@ -1317,7 +1349,7 @@ MEM_STATIC size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
1317
1349
  case set_repeat:
1318
1350
  return 0;
1319
1351
  case set_basic:
1320
- CHECK_F(FSE_buildCTable_wksp(CTable, defaultNorm, defaultMax, defaultNormLog, workspace, workspaceSize));
1352
+ CHECK_F(FSE_buildCTable_wksp(CTable, defaultNorm, defaultMax, defaultNormLog, workspace, workspaceSize)); /* note : could be pre-calculated */
1321
1353
  return 0;
1322
1354
  case set_compressed: {
1323
1355
  S16 norm[MaxSeq + 1];
@@ -1339,11 +1371,13 @@ MEM_STATIC size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
1339
1371
  }
1340
1372
  }
1341
1373
 
1342
- MEM_STATIC size_t ZSTD_encodeSequences(void* dst, size_t dstCapacity,
1343
- FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
1344
- FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
1345
- FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
1346
- seqDef const* sequences, size_t nbSeq, int longOffsets)
1374
+ MEM_STATIC
1375
+ size_t ZSTD_encodeSequences(
1376
+ void* dst, size_t dstCapacity,
1377
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
1378
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
1379
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
1380
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
1347
1381
  {
1348
1382
  BIT_CStream_t blockStream;
1349
1383
  FSE_CState_t stateMatchLength;
@@ -1380,8 +1414,12 @@ MEM_STATIC size_t ZSTD_encodeSequences(void* dst, size_t dstCapacity,
1380
1414
  BYTE const ofCode = ofCodeTable[n];
1381
1415
  BYTE const mlCode = mlCodeTable[n];
1382
1416
  U32 const llBits = LL_bits[llCode];
1383
- U32 const ofBits = ofCode; /* 32b*/ /* 64b*/
1417
+ U32 const ofBits = ofCode;
1384
1418
  U32 const mlBits = ML_bits[mlCode];
1419
+ DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
1420
+ sequences[n].litLength,
1421
+ sequences[n].matchLength + MINMATCH,
1422
+ sequences[n].offset); /* 32b*/ /* 64b*/
1385
1423
  /* (7)*/ /* (7)*/
1386
1424
  FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
1387
1425
  FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
@@ -1447,14 +1485,18 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
1447
1485
  entropy, cParams->strategy, op, dstCapacity, literals, litSize);
1448
1486
  if (ZSTD_isError(cSize))
1449
1487
  return cSize;
1488
+ assert(cSize <= dstCapacity);
1450
1489
  op += cSize;
1451
1490
  }
1452
1491
 
1453
1492
  /* Sequences Header */
1454
- if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall);
1455
- if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq;
1456
- else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
1457
- else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
1493
+ if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/) return ERROR(dstSize_tooSmall);
1494
+ if (nbSeq < 0x7F)
1495
+ *op++ = (BYTE)nbSeq;
1496
+ else if (nbSeq < LONGNBSEQ)
1497
+ op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
1498
+ else
1499
+ op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
1458
1500
  if (nbSeq==0) return op - ostart;
1459
1501
 
1460
1502
  /* seqHead : flags for FSE encoding type */
@@ -1462,9 +1504,10 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
1462
1504
 
1463
1505
  /* convert length/distances into codes */
1464
1506
  ZSTD_seqToCodes(seqStorePtr);
1465
- /* CTable for Literal Lengths */
1507
+ /* build CTable for Literal Lengths */
1466
1508
  { U32 max = MaxLL;
1467
1509
  size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, entropy->workspace);
1510
+ DEBUGLOG(5, "Building LL table");
1468
1511
  LLtype = ZSTD_selectEncodingType(&entropy->litlength_repeatMode, mostFrequent, nbSeq, LL_defaultNormLog, ZSTD_defaultAllowed);
1469
1512
  { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
1470
1513
  count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
@@ -1472,11 +1515,12 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
1472
1515
  if (ZSTD_isError(countSize)) return countSize;
1473
1516
  op += countSize;
1474
1517
  } }
1475
- /* CTable for Offsets */
1518
+ /* build CTable for Offsets */
1476
1519
  { U32 max = MaxOff;
1477
1520
  size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, entropy->workspace);
1478
1521
  /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
1479
- ZSTD_defaultPolicy_e const defaultPolicy = max <= DefaultMaxOff ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
1522
+ ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
1523
+ DEBUGLOG(5, "Building OF table");
1480
1524
  Offtype = ZSTD_selectEncodingType(&entropy->offcode_repeatMode, mostFrequent, nbSeq, OF_defaultNormLog, defaultPolicy);
1481
1525
  { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
1482
1526
  count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
@@ -1484,9 +1528,10 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
1484
1528
  if (ZSTD_isError(countSize)) return countSize;
1485
1529
  op += countSize;
1486
1530
  } }
1487
- /* CTable for MatchLengths */
1531
+ /* build CTable for MatchLengths */
1488
1532
  { U32 max = MaxML;
1489
1533
  size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, entropy->workspace);
1534
+ DEBUGLOG(5, "Building ML table");
1490
1535
  MLtype = ZSTD_selectEncodingType(&entropy->matchlength_repeatMode, mostFrequent, nbSeq, ML_defaultNormLog, ZSTD_defaultAllowed);
1491
1536
  { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
1492
1537
  count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
@@ -1497,13 +1542,15 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
1497
1542
 
1498
1543
  *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
1499
1544
 
1500
- { size_t const streamSize = ZSTD_encodeSequences(op, oend - op,
1501
- CTable_MatchLength, mlCodeTable,
1502
- CTable_OffsetBits, ofCodeTable,
1503
- CTable_LitLength, llCodeTable,
1504
- sequences, nbSeq, longOffsets);
1505
- if (ZSTD_isError(streamSize)) return streamSize;
1506
- op += streamSize;
1545
+ { size_t const bitstreamSize = ZSTD_encodeSequences(
1546
+ op, oend - op,
1547
+ CTable_MatchLength, mlCodeTable,
1548
+ CTable_OffsetBits, ofCodeTable,
1549
+ CTable_LitLength, llCodeTable,
1550
+ sequences, nbSeq,
1551
+ longOffsets);
1552
+ if (ZSTD_isError(bitstreamSize)) return bitstreamSize;
1553
+ op += bitstreamSize;
1507
1554
  }
1508
1555
 
1509
1556
  return op - ostart;
@@ -1517,27 +1564,33 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
1517
1564
  {
1518
1565
  size_t const cSize = ZSTD_compressSequences_internal(seqStorePtr, entropy, cParams,
1519
1566
  dst, dstCapacity);
1520
- size_t const minGain = ZSTD_minGain(srcSize);
1521
- size_t const maxCSize = srcSize - minGain;
1522
1567
  /* If the srcSize <= dstCapacity, then there is enough space to write a
1523
1568
  * raw uncompressed block. Since we ran out of space, the block must not
1524
1569
  * be compressible, so fall back to a raw uncompressed block.
1525
1570
  */
1526
- int const uncompressibleError = cSize == ERROR(dstSize_tooSmall) && srcSize <= dstCapacity;
1527
-
1571
+ int const uncompressibleError = (cSize == ERROR(dstSize_tooSmall)) && (srcSize <= dstCapacity);
1528
1572
  if (ZSTD_isError(cSize) && !uncompressibleError)
1529
1573
  return cSize;
1574
+ /* We check that dictionaries have offset codes available for the first
1575
+ * block. After the first block, the offcode table might not have large
1576
+ * enough codes to represent the offsets in the data.
1577
+ */
1578
+ if (entropy->offcode_repeatMode == FSE_repeat_valid)
1579
+ entropy->offcode_repeatMode = FSE_repeat_check;
1580
+
1530
1581
  /* Check compressibility */
1531
- if (cSize >= maxCSize || uncompressibleError) {
1532
- entropy->hufCTable_repeatMode = HUF_repeat_none;
1533
- entropy->offcode_repeatMode = FSE_repeat_none;
1534
- entropy->matchlength_repeatMode = FSE_repeat_none;
1535
- entropy->litlength_repeatMode = FSE_repeat_none;
1536
- return 0;
1537
- }
1582
+ { size_t const minGain = ZSTD_minGain(srcSize); /* note : fixed formula, maybe should depend on compression level, or strategy */
1583
+ size_t const maxCSize = srcSize - minGain;
1584
+ if (cSize >= maxCSize || uncompressibleError) {
1585
+ entropy->hufCTable_repeatMode = HUF_repeat_none;
1586
+ entropy->offcode_repeatMode = FSE_repeat_none;
1587
+ entropy->matchlength_repeatMode = FSE_repeat_none;
1588
+ entropy->litlength_repeatMode = FSE_repeat_none;
1589
+ return 0; /* block not compressed */
1590
+ } }
1538
1591
  assert(!ZSTD_isError(cSize));
1539
1592
 
1540
- /* confirm repcodes */
1593
+ /* block is compressed => confirm repcodes in history */
1541
1594
  { int i; for (i=0; i<ZSTD_REP_NUM; i++) seqStorePtr->rep[i] = seqStorePtr->repToConfirm[i]; }
1542
1595
  return cSize;
1543
1596
  }
@@ -1559,9 +1612,9 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict
1559
1612
  ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btultra_extDict }
1560
1613
  };
1561
1614
  ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
1615
+
1562
1616
  assert((U32)strat >= (U32)ZSTD_fast);
1563
1617
  assert((U32)strat <= (U32)ZSTD_btultra);
1564
-
1565
1618
  return blockCompressor[extDict!=0][(U32)strat];
1566
1619
  }
1567
1620
 
@@ -1572,30 +1625,38 @@ static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
1572
1625
  seqStorePtr->lit += lastLLSize;
1573
1626
  }
1574
1627
 
1628
+ static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
1629
+ {
1630
+ ssPtr->lit = ssPtr->litStart;
1631
+ ssPtr->sequences = ssPtr->sequencesStart;
1632
+ ssPtr->longLengthID = 0;
1633
+ }
1634
+
1575
1635
  static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1576
1636
  {
1577
- const BYTE* const base = zc->base;
1578
- const BYTE* const istart = (const BYTE*)src;
1579
- const U32 current = (U32)(istart-base);
1580
- size_t lastLLSize;
1581
- const BYTE* anchor;
1582
- U32 const extDict = zc->lowLimit < zc->dictLimit;
1583
- const ZSTD_blockCompressor blockCompressor =
1584
- zc->appliedParams.ldmParams.enableLdm
1585
- ? (extDict ? ZSTD_compressBlock_ldm_extDict : ZSTD_compressBlock_ldm)
1586
- : ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, extDict);
1587
-
1588
- if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */
1637
+ DEBUGLOG(5, "ZSTD_compressBlock_internal : dstCapacity = %u", (U32)dstCapacity);
1638
+ if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1)
1639
+ return 0; /* don't even attempt compression below a certain srcSize */
1589
1640
  ZSTD_resetSeqStore(&(zc->seqStore));
1590
- if (current > zc->nextToUpdate + 384)
1591
- zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384)); /* limited update after finding a very long match */
1592
-
1593
- lastLLSize = blockCompressor(zc, src, srcSize);
1594
-
1595
- /* Last literals */
1596
- anchor = (const BYTE*)src + srcSize - lastLLSize;
1597
- ZSTD_storeLastLiterals(&zc->seqStore, anchor, lastLLSize);
1598
1641
 
1642
+ /* limited update after a very long match */
1643
+ { const BYTE* const base = zc->base;
1644
+ const BYTE* const istart = (const BYTE*)src;
1645
+ const U32 current = (U32)(istart-base);
1646
+ if (current > zc->nextToUpdate + 384)
1647
+ zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384));
1648
+ }
1649
+ /* find and store sequences */
1650
+ { U32 const extDict = zc->lowLimit < zc->dictLimit;
1651
+ const ZSTD_blockCompressor blockCompressor =
1652
+ zc->appliedParams.ldmParams.enableLdm
1653
+ ? (extDict ? ZSTD_compressBlock_ldm_extDict : ZSTD_compressBlock_ldm)
1654
+ : ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, extDict);
1655
+ size_t const lastLLSize = blockCompressor(zc, src, srcSize);
1656
+ const BYTE* const anchor = (const BYTE*)src + srcSize - lastLLSize;
1657
+ ZSTD_storeLastLiterals(&zc->seqStore, anchor, lastLLSize);
1658
+ }
1659
+ /* encode */
1599
1660
  return ZSTD_compressSequences(&zc->seqStore, zc->entropy, &zc->appliedParams.cParams, dst, dstCapacity, srcSize);
1600
1661
  }
1601
1662
 
@@ -1618,13 +1679,14 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
1618
1679
  BYTE* const ostart = (BYTE*)dst;
1619
1680
  BYTE* op = ostart;
1620
1681
  U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
1682
+ assert(cctx->appliedParams.cParams.windowLog <= 31);
1621
1683
 
1684
+ DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (U32)blockSize);
1622
1685
  if (cctx->appliedParams.fParams.checksumFlag && srcSize)
1623
1686
  XXH64_update(&cctx->xxhState, src, srcSize);
1624
1687
 
1625
1688
  while (remaining) {
1626
1689
  U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
1627
- size_t cSize;
1628
1690
 
1629
1691
  if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE)
1630
1692
  return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
@@ -1666,34 +1728,39 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
1666
1728
  else cctx->nextToUpdate -= correction;
1667
1729
  DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x\n", correction, cctx->lowLimit);
1668
1730
  }
1669
-
1731
+ /* enforce maxDist */
1670
1732
  if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
1671
- /* enforce maxDist */
1672
1733
  U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
1673
1734
  if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
1674
1735
  if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
1675
1736
  }
1676
1737
 
1677
- cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
1678
- if (ZSTD_isError(cSize)) return cSize;
1679
-
1680
- if (cSize == 0) { /* block is not compressible */
1681
- U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
1682
- if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
1683
- MEM_writeLE32(op, cBlockHeader24); /* no pb, 4th byte will be overwritten */
1684
- memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
1685
- cSize = ZSTD_blockHeaderSize+blockSize;
1686
- } else {
1687
- U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
1688
- MEM_writeLE24(op, cBlockHeader24);
1689
- cSize += ZSTD_blockHeaderSize;
1690
- }
1738
+ { size_t cSize = ZSTD_compressBlock_internal(cctx,
1739
+ op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
1740
+ ip, blockSize);
1741
+ if (ZSTD_isError(cSize)) return cSize;
1742
+
1743
+ if (cSize == 0) { /* block is not compressible */
1744
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
1745
+ if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
1746
+ MEM_writeLE32(op, cBlockHeader24); /* 4th byte will be overwritten */
1747
+ memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
1748
+ cSize = ZSTD_blockHeaderSize + blockSize;
1749
+ } else {
1750
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
1751
+ MEM_writeLE24(op, cBlockHeader24);
1752
+ cSize += ZSTD_blockHeaderSize;
1753
+ }
1691
1754
 
1692
- remaining -= blockSize;
1693
- dstCapacity -= cSize;
1694
- ip += blockSize;
1695
- op += cSize;
1696
- }
1755
+ ip += blockSize;
1756
+ assert(remaining >= blockSize);
1757
+ remaining -= blockSize;
1758
+ op += cSize;
1759
+ assert(dstCapacity >= cSize);
1760
+ dstCapacity -= cSize;
1761
+ DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u",
1762
+ (U32)cSize);
1763
+ } }
1697
1764
 
1698
1765
  if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
1699
1766
  return op-ostart;
@@ -1719,7 +1786,6 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
1719
1786
  !params.fParams.noDictIDFlag, dictID, dictIDSizeCode);
1720
1787
 
1721
1788
  if (params.format == ZSTD_f_zstd1) {
1722
- DEBUGLOG(4, "writing zstd magic number");
1723
1789
  MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
1724
1790
  pos = 4;
1725
1791
  }
@@ -1753,8 +1819,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
1753
1819
  const BYTE* const ip = (const BYTE*) src;
1754
1820
  size_t fhSize = 0;
1755
1821
 
1756
- DEBUGLOG(5, "ZSTD_compressContinue_internal");
1757
- DEBUGLOG(5, "stage: %u", cctx->stage);
1822
+ DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u", cctx->stage);
1758
1823
  if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
1759
1824
 
1760
1825
  if (frame && (cctx->stage==ZSTDcs_init)) {
@@ -1766,17 +1831,21 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
1766
1831
  cctx->stage = ZSTDcs_ongoing;
1767
1832
  }
1768
1833
 
1834
+ if (!srcSize) return fhSize; /* do not generate an empty block if no input */
1835
+
1769
1836
  /* Check if blocks follow each other */
1770
1837
  if (src != cctx->nextSrc) {
1771
1838
  /* not contiguous */
1772
- ptrdiff_t const delta = cctx->nextSrc - ip;
1839
+ size_t const distanceFromBase = (size_t)(cctx->nextSrc - cctx->base);
1773
1840
  cctx->lowLimit = cctx->dictLimit;
1774
- cctx->dictLimit = (U32)(cctx->nextSrc - cctx->base);
1841
+ assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */
1842
+ cctx->dictLimit = (U32)distanceFromBase;
1775
1843
  cctx->dictBase = cctx->base;
1776
- cctx->base -= delta;
1844
+ cctx->base = ip - distanceFromBase;
1777
1845
  cctx->nextToUpdate = cctx->dictLimit;
1778
1846
  if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit; /* too small extDict */
1779
1847
  }
1848
+ cctx->nextSrc = ip + srcSize;
1780
1849
 
1781
1850
  /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
1782
1851
  if ((ip+srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
@@ -1785,17 +1854,14 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
1785
1854
  cctx->lowLimit = lowLimitMax;
1786
1855
  }
1787
1856
 
1788
- cctx->nextSrc = ip + srcSize;
1789
-
1790
- if (srcSize) {
1791
- size_t const cSize = frame ?
1857
+ DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize);
1858
+ { size_t const cSize = frame ?
1792
1859
  ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
1793
1860
  ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
1794
1861
  if (ZSTD_isError(cSize)) return cSize;
1795
1862
  cctx->consumedSrcSize += srcSize;
1796
1863
  return cSize + fhSize;
1797
- } else
1798
- return fhSize;
1864
+ }
1799
1865
  }
1800
1866
 
1801
1867
  size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
@@ -1832,7 +1898,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
1832
1898
  zc->lowLimit = zc->dictLimit;
1833
1899
  zc->dictLimit = (U32)(zc->nextSrc - zc->base);
1834
1900
  zc->dictBase = zc->base;
1835
- zc->base += ip - zc->nextSrc;
1901
+ zc->base = ip - zc->dictLimit;
1836
1902
  zc->nextToUpdate = zc->dictLimit;
1837
1903
  zc->loadedDictEnd = zc->appliedParams.forceWindow ? 0 : (U32)(iend - zc->base);
1838
1904
 
@@ -1983,7 +2049,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
1983
2049
  const void* dict, size_t dictSize,
1984
2050
  ZSTD_dictMode_e dictMode)
1985
2051
  {
1986
- DEBUGLOG(5, "ZSTD_compress_insertDictionary");
2052
+ DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
1987
2053
  if ((dict==NULL) || (dictSize<=8)) return 0;
1988
2054
 
1989
2055
  /* dict restricted modes */
@@ -1992,7 +2058,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
1992
2058
 
1993
2059
  if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
1994
2060
  if (dictMode == ZSTD_dm_auto) {
1995
- DEBUGLOG(5, "raw content dictionary detected");
2061
+ DEBUGLOG(4, "raw content dictionary detected");
1996
2062
  return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
1997
2063
  }
1998
2064
  if (dictMode == ZSTD_dm_fullDict)
@@ -2006,21 +2072,22 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
2006
2072
 
2007
2073
  /*! ZSTD_compressBegin_internal() :
2008
2074
  * @return : 0, or an error code */
2009
- static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
2075
+ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
2010
2076
  const void* dict, size_t dictSize,
2011
2077
  ZSTD_dictMode_e dictMode,
2012
2078
  const ZSTD_CDict* cdict,
2013
- ZSTD_CCtx_params params, U64 pledgedSrcSize,
2014
- ZSTD_buffered_policy_e zbuff)
2079
+ ZSTD_CCtx_params params, U64 pledgedSrcSize,
2080
+ ZSTD_buffered_policy_e zbuff)
2015
2081
  {
2016
- DEBUGLOG(4, "ZSTD_compressBegin_internal");
2082
+ DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params.cParams.windowLog);
2017
2083
  /* params are supposed to be fully validated at this point */
2018
2084
  assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
2019
2085
  assert(!((dict) && (cdict))); /* either dict or cdict, not both */
2020
2086
 
2021
2087
  if (cdict && cdict->dictContentSize>0) {
2088
+ cctx->requestedParams = params;
2022
2089
  return ZSTD_copyCCtx_internal(cctx, cdict->refContext,
2023
- params.fParams, pledgedSrcSize,
2090
+ params.cParams.windowLog, params.fParams, pledgedSrcSize,
2024
2091
  zbuff);
2025
2092
  }
2026
2093
 
@@ -2029,16 +2096,19 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
2029
2096
  return ZSTD_compress_insertDictionary(cctx, dict, dictSize, dictMode);
2030
2097
  }
2031
2098
 
2032
- size_t ZSTD_compressBegin_advanced_internal(
2033
- ZSTD_CCtx* cctx,
2099
+ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
2034
2100
  const void* dict, size_t dictSize,
2035
2101
  ZSTD_dictMode_e dictMode,
2102
+ const ZSTD_CDict* cdict,
2036
2103
  ZSTD_CCtx_params params,
2037
2104
  unsigned long long pledgedSrcSize)
2038
2105
  {
2106
+ DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog);
2039
2107
  /* compression parameters verification and optimization */
2040
2108
  CHECK_F( ZSTD_checkCParams(params.cParams) );
2041
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, dictMode, NULL,
2109
+ return ZSTD_compressBegin_internal(cctx,
2110
+ dict, dictSize, dictMode,
2111
+ cdict,
2042
2112
  params, pledgedSrcSize,
2043
2113
  ZSTDb_not_buffered);
2044
2114
  }
@@ -2051,9 +2121,10 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
2051
2121
  {
2052
2122
  ZSTD_CCtx_params const cctxParams =
2053
2123
  ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
2054
- return ZSTD_compressBegin_advanced_internal(cctx, dict, dictSize, ZSTD_dm_auto,
2055
- cctxParams,
2056
- pledgedSrcSize);
2124
+ return ZSTD_compressBegin_advanced_internal(cctx,
2125
+ dict, dictSize, ZSTD_dm_auto,
2126
+ NULL /*cdict*/,
2127
+ cctxParams, pledgedSrcSize);
2057
2128
  }
2058
2129
 
2059
2130
  size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
@@ -2061,8 +2132,9 @@ size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t di
2061
2132
  ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
2062
2133
  ZSTD_CCtx_params const cctxParams =
2063
2134
  ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
2135
+ DEBUGLOG(4, "ZSTD_compressBegin_usingDict");
2064
2136
  return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
2065
- cctxParams, 0, ZSTDb_not_buffered);
2137
+ cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
2066
2138
  }
2067
2139
 
2068
2140
  size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
@@ -2143,6 +2215,7 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
2143
2215
  {
2144
2216
  ZSTD_CCtx_params const cctxParams =
2145
2217
  ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
2218
+ DEBUGLOG(4, "ZSTD_compress_internal");
2146
2219
  return ZSTD_compress_advanced_internal(cctx,
2147
2220
  dst, dstCapacity,
2148
2221
  src, srcSize,
@@ -2156,6 +2229,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
2156
2229
  const void* dict,size_t dictSize,
2157
2230
  ZSTD_parameters params)
2158
2231
  {
2232
+ DEBUGLOG(4, "ZSTD_compress_advanced");
2159
2233
  CHECK_F(ZSTD_checkCParams(params.cParams));
2160
2234
  return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
2161
2235
  }
@@ -2168,6 +2242,7 @@ size_t ZSTD_compress_advanced_internal(
2168
2242
  const void* dict,size_t dictSize,
2169
2243
  ZSTD_CCtx_params params)
2170
2244
  {
2245
+ DEBUGLOG(4, "ZSTD_compress_advanced_internal");
2171
2246
  CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
2172
2247
  params, srcSize, ZSTDb_not_buffered) );
2173
2248
  return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
@@ -2176,8 +2251,10 @@ size_t ZSTD_compress_advanced_internal(
2176
2251
  size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
2177
2252
  const void* dict, size_t dictSize, int compressionLevel)
2178
2253
  {
2179
- ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dict ? dictSize : 0);
2254
+ ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize ? srcSize : 1, dict ? dictSize : 0);
2180
2255
  params.fParams.contentSizeFlag = 1;
2256
+ DEBUGLOG(4, "ZSTD_compress_usingDict (level=%i, srcSize=%u, dictSize=%u)",
2257
+ compressionLevel, (U32)srcSize, (U32)dictSize);
2181
2258
  return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
2182
2259
  }
2183
2260
 
@@ -2234,7 +2311,7 @@ static size_t ZSTD_initCDict_internal(
2234
2311
  ZSTD_dictMode_e dictMode,
2235
2312
  ZSTD_compressionParameters cParams)
2236
2313
  {
2237
- DEBUGLOG(5, "ZSTD_initCDict_internal, mode %u", (U32)dictMode);
2314
+ DEBUGLOG(3, "ZSTD_initCDict_internal, mode %u", (U32)dictMode);
2238
2315
  if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
2239
2316
  cdict->dictBuffer = NULL;
2240
2317
  cdict->dictContent = dictBuffer;
@@ -2264,7 +2341,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
2264
2341
  ZSTD_dictMode_e dictMode,
2265
2342
  ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
2266
2343
  {
2267
- DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
2344
+ DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
2268
2345
  if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
2269
2346
 
2270
2347
  { ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
@@ -2339,9 +2416,9 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
2339
2416
  + cctxSize;
2340
2417
  ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
2341
2418
  void* ptr;
2342
- DEBUGLOG(5, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
2419
+ DEBUGLOG(4, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
2343
2420
  if ((size_t)workspace & 7) return NULL; /* 8-aligned */
2344
- DEBUGLOG(5, "(workspaceSize < neededSize) : (%u < %u) => %u",
2421
+ DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
2345
2422
  (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
2346
2423
  if (workspaceSize < neededSize) return NULL;
2347
2424
 
@@ -2373,11 +2450,11 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
2373
2450
  ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
2374
2451
  ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
2375
2452
  {
2453
+ DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
2376
2454
  if (cdict==NULL) return ERROR(dictionary_wrong);
2377
2455
  { ZSTD_CCtx_params params = cctx->requestedParams;
2378
2456
  params.cParams = ZSTD_getCParamsFromCDict(cdict);
2379
2457
  params.fParams = fParams;
2380
- DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
2381
2458
  return ZSTD_compressBegin_internal(cctx,
2382
2459
  NULL, 0, ZSTD_dm_auto,
2383
2460
  cdict,
@@ -2392,7 +2469,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
2392
2469
  size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
2393
2470
  {
2394
2471
  ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
2395
- DEBUGLOG(5, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
2472
+ DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
2396
2473
  return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, 0);
2397
2474
  }
2398
2475
 
@@ -2427,6 +2504,7 @@ size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
2427
2504
 
2428
2505
  ZSTD_CStream* ZSTD_createCStream(void)
2429
2506
  {
2507
+ DEBUGLOG(3, "ZSTD_createCStream");
2430
2508
  return ZSTD_createCStream_advanced(ZSTD_defaultCMem);
2431
2509
  }
2432
2510
 
@@ -2457,9 +2535,9 @@ size_t ZSTD_CStreamOutSize(void)
2457
2535
  }
2458
2536
 
2459
2537
  static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
2460
- const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
2461
- const ZSTD_CDict* cdict,
2462
- const ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
2538
+ const void* const dict, size_t const dictSize, ZSTD_dictMode_e const dictMode,
2539
+ const ZSTD_CDict* const cdict,
2540
+ ZSTD_CCtx_params const params, unsigned long long const pledgedSrcSize)
2463
2541
  {
2464
2542
  DEBUGLOG(4, "ZSTD_resetCStream_internal");
2465
2543
  /* params are supposed to be fully validated at this point */
@@ -2467,31 +2545,35 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
2467
2545
  assert(!((dict) && (cdict))); /* either dict or cdict, not both */
2468
2546
 
2469
2547
  CHECK_F( ZSTD_compressBegin_internal(zcs,
2470
- dict, dictSize, dictMode,
2471
- cdict,
2472
- params, pledgedSrcSize,
2473
- ZSTDb_buffered) );
2548
+ dict, dictSize, dictMode,
2549
+ cdict,
2550
+ params, pledgedSrcSize,
2551
+ ZSTDb_buffered) );
2474
2552
 
2475
2553
  zcs->inToCompress = 0;
2476
2554
  zcs->inBuffPos = 0;
2477
- zcs->inBuffTarget = zcs->blockSize;
2555
+ zcs->inBuffTarget = zcs->blockSize
2556
+ + (zcs->blockSize == pledgedSrcSize); /* for small input: avoid automatic flush on reaching end of block, since it would require to add a 3-bytes null block to end frame */
2478
2557
  zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
2479
2558
  zcs->streamStage = zcss_load;
2480
2559
  zcs->frameEnded = 0;
2481
2560
  return 0; /* ready to go */
2482
2561
  }
2483
2562
 
2563
+ /* ZSTD_resetCStream():
2564
+ * pledgedSrcSize == 0 means "unknown" */
2484
2565
  size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
2485
2566
  {
2486
2567
  ZSTD_CCtx_params params = zcs->requestedParams;
2487
- params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
2568
+ DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize);
2569
+ if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
2570
+ params.fParams.contentSizeFlag = 1;
2488
2571
  params.cParams = ZSTD_getCParamsFromCCtxParams(params, pledgedSrcSize, 0);
2489
- DEBUGLOG(4, "ZSTD_resetCStream");
2490
2572
  return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dm_auto, zcs->cdict, params, pledgedSrcSize);
2491
2573
  }
2492
2574
 
2493
2575
  /*! ZSTD_initCStream_internal() :
2494
- * Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
2576
+ * Note : for lib/compress only. Used by zstdmt_compress.c.
2495
2577
  * Assumption 1 : params are valid
2496
2578
  * Assumption 2 : either dict, or cdict, is defined, not both */
2497
2579
  size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
@@ -2503,7 +2585,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
2503
2585
  assert(!((dict) && (cdict))); /* either dict or cdict, not both */
2504
2586
 
2505
2587
  if (dict && dictSize >= 8) {
2506
- DEBUGLOG(5, "loading dictionary of size %u", (U32)dictSize);
2588
+ DEBUGLOG(4, "loading dictionary of size %u", (U32)dictSize);
2507
2589
  if (zcs->staticSize) { /* static CCtx : never uses malloc */
2508
2590
  /* incompatible with internal cdict creation */
2509
2591
  return ERROR(memory_allocation);
@@ -2516,14 +2598,14 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
2516
2598
  if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
2517
2599
  } else {
2518
2600
  if (cdict) {
2519
- params.cParams = ZSTD_getCParamsFromCDict(cdict); /* cParams are enforced from cdict */
2601
+ params.cParams = ZSTD_getCParamsFromCDict(cdict); /* cParams are enforced from cdict; it includes windowLog */
2520
2602
  }
2521
2603
  ZSTD_freeCDict(zcs->cdictLocal);
2522
2604
  zcs->cdictLocal = NULL;
2523
2605
  zcs->cdict = cdict;
2524
2606
  }
2525
2607
 
2526
- params.compressionLevel = ZSTD_CLEVEL_CUSTOM;
2608
+ params.compressionLevel = ZSTD_CLEVEL_CUSTOM; /* enforce usage of cParams, instead of a dynamic derivation from cLevel (but does that happen ?) */
2527
2609
  zcs->requestedParams = params;
2528
2610
 
2529
2611
  return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dm_auto, zcs->cdict, params, pledgedSrcSize);
@@ -2535,8 +2617,9 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
2535
2617
  const ZSTD_CDict* cdict,
2536
2618
  ZSTD_frameParameters fParams,
2537
2619
  unsigned long long pledgedSrcSize)
2538
- { /* cannot handle NULL cdict (does not know what to do) */
2539
- if (!cdict) return ERROR(dictionary_wrong);
2620
+ {
2621
+ DEBUGLOG(4, "ZSTD_initCStream_usingCDict_advanced");
2622
+ if (!cdict) return ERROR(dictionary_wrong); /* cannot handle NULL cdict (does not know what to do) */
2540
2623
  { ZSTD_CCtx_params params = zcs->requestedParams;
2541
2624
  params.cParams = ZSTD_getCParamsFromCDict(cdict);
2542
2625
  params.fParams = fParams;
@@ -2549,18 +2632,25 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
2549
2632
  /* note : cdict must outlive compression session */
2550
2633
  size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
2551
2634
  {
2552
- ZSTD_frameParameters const fParams = { 0 /* contentSize */, 0 /* checksum */, 0 /* hideDictID */ };
2553
- return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, fParams, 0); /* note : will check that cdict != NULL */
2635
+ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */, 0 /* checksum */, 0 /* hideDictID */ };
2636
+ DEBUGLOG(4, "ZSTD_initCStream_usingCDict");
2637
+ return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); /* note : will check that cdict != NULL */
2554
2638
  }
2555
2639
 
2640
+ /* ZSTD_initCStream_advanced() :
2641
+ * pledgedSrcSize must be correct.
2642
+ * if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
2643
+ * dict is loaded with default parameters ZSTD_dm_auto and ZSTD_dlm_byCopy. */
2556
2644
  size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
2557
2645
  const void* dict, size_t dictSize,
2558
2646
  ZSTD_parameters params, unsigned long long pledgedSrcSize)
2559
2647
  {
2560
- ZSTD_CCtx_params const cctxParams =
2561
- ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
2648
+ ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
2649
+ DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u",
2650
+ (U32)pledgedSrcSize, params.fParams.contentSizeFlag);
2562
2651
  CHECK_F( ZSTD_checkCParams(params.cParams) );
2563
- return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
2652
+ if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */
2653
+ return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, cctxParams, pledgedSrcSize);
2564
2654
  }
2565
2655
 
2566
2656
  size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
@@ -2568,21 +2658,21 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t di
2568
2658
  ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
2569
2659
  ZSTD_CCtx_params const cctxParams =
2570
2660
  ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
2571
- return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, 0);
2661
+ return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN);
2572
2662
  }
2573
2663
 
2574
- size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
2664
+ size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)
2575
2665
  {
2576
- ZSTD_CCtx_params cctxParams;
2666
+ U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss; /* temporary : 0 interpreted as "unknown" during transition period. Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN. `0` will be interpreted as "empty" in the future */
2577
2667
  ZSTD_parameters const params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
2578
- cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
2579
- cctxParams.fParams.contentSizeFlag = (pledgedSrcSize>0);
2668
+ ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
2580
2669
  return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, pledgedSrcSize);
2581
2670
  }
2582
2671
 
2583
2672
  size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
2584
2673
  {
2585
- return ZSTD_initCStream_srcSize(zcs, compressionLevel, 0);
2674
+ DEBUGLOG(4, "ZSTD_initCStream");
2675
+ return ZSTD_initCStream_srcSize(zcs, compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN);
2586
2676
  }
2587
2677
 
2588
2678
  /*====== Compression ======*/
@@ -2615,9 +2705,9 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
2615
2705
  /* check expectations */
2616
2706
  DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%u", (U32)flushMode);
2617
2707
  assert(zcs->inBuff != NULL);
2618
- assert(zcs->inBuffSize>0);
2619
- assert(zcs->outBuff!= NULL);
2620
- assert(zcs->outBuffSize>0);
2708
+ assert(zcs->inBuffSize > 0);
2709
+ assert(zcs->outBuff != NULL);
2710
+ assert(zcs->outBuffSize > 0);
2621
2711
  assert(output->pos <= output->size);
2622
2712
  assert(input->pos <= input->size);
2623
2713
 
@@ -2757,7 +2847,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
2757
2847
  ZSTD_inBuffer* input,
2758
2848
  ZSTD_EndDirective endOp)
2759
2849
  {
2760
- DEBUGLOG(5, "ZSTD_compress_generic");
2850
+ DEBUGLOG(5, "ZSTD_compress_generic, endOp=%u ", (U32)endOp);
2761
2851
  /* check conditions */
2762
2852
  if (output->pos > output->size) return ERROR(GENERIC);
2763
2853
  if (input->pos > input->size) return ERROR(GENERIC);
@@ -2765,42 +2855,47 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
2765
2855
 
2766
2856
  /* transparent initialization stage */
2767
2857
  if (cctx->streamStage == zcss_init) {
2768
- ZSTD_prefixDict const prefixDict = cctx->prefixDict;
2769
2858
  ZSTD_CCtx_params params = cctx->requestedParams;
2770
- params.cParams = ZSTD_getCParamsFromCCtxParams(
2771
- cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
2859
+ ZSTD_prefixDict const prefixDict = cctx->prefixDict;
2772
2860
  memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
2773
2861
  assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
2774
2862
  DEBUGLOG(4, "ZSTD_compress_generic : transparent init stage");
2863
+ if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1; /* auto-fix pledgedSrcSize */
2864
+ params.cParams = ZSTD_getCParamsFromCCtxParams(
2865
+ cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
2775
2866
 
2776
2867
  #ifdef ZSTD_MULTITHREAD
2868
+ if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN)
2869
+ params.nbThreads = 1; /* do not invoke multi-threading when src size is too small */
2777
2870
  if (params.nbThreads > 1) {
2778
- if (cctx->mtctx == NULL || cctx->appliedParams.nbThreads != params.nbThreads) {
2871
+ if (cctx->mtctx == NULL || (params.nbThreads != ZSTDMT_getNbThreads(cctx->mtctx))) {
2872
+ DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbThreads=%u (previous: %u)",
2873
+ params.nbThreads, ZSTDMT_getNbThreads(cctx->mtctx));
2779
2874
  ZSTDMT_freeCCtx(cctx->mtctx);
2780
2875
  cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbThreads, cctx->customMem);
2781
2876
  if (cctx->mtctx == NULL) return ERROR(memory_allocation);
2782
2877
  }
2783
2878
  DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
2784
2879
  CHECK_F( ZSTDMT_initCStream_internal(
2785
- cctx->mtctx,
2786
- prefixDict.dict, prefixDict.dictSize, ZSTD_dm_rawContent,
2787
- cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
2880
+ cctx->mtctx,
2881
+ prefixDict.dict, prefixDict.dictSize, ZSTD_dm_rawContent,
2882
+ cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
2788
2883
  cctx->streamStage = zcss_load;
2789
2884
  cctx->appliedParams.nbThreads = params.nbThreads;
2790
2885
  } else
2791
2886
  #endif
2792
- {
2793
- CHECK_F( ZSTD_resetCStream_internal(
2887
+ { CHECK_F( ZSTD_resetCStream_internal(
2794
2888
  cctx, prefixDict.dict, prefixDict.dictSize,
2795
2889
  prefixDict.dictMode, cctx->cdict, params,
2796
2890
  cctx->pledgedSrcSizePlusOne-1) );
2891
+ assert(cctx->streamStage == zcss_load);
2892
+ assert(cctx->appliedParams.nbThreads <= 1);
2797
2893
  } }
2798
2894
 
2799
2895
  /* compression stage */
2800
2896
  #ifdef ZSTD_MULTITHREAD
2801
2897
  if (cctx->appliedParams.nbThreads > 1) {
2802
2898
  size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
2803
- DEBUGLOG(5, "ZSTDMT_compressStream_generic result : %u", (U32)flushMin);
2804
2899
  if ( ZSTD_isError(flushMin)
2805
2900
  || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
2806
2901
  ZSTD_startNewCompression(cctx);
@@ -2850,8 +2945,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
2850
2945
  { size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
2851
2946
  size_t const checksumSize = zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4;
2852
2947
  size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize + lastBlockSize + checksumSize;
2853
- DEBUGLOG(5, "ZSTD_endStream : remaining to flush : %u",
2854
- (unsigned)toFlush);
2948
+ DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (U32)toFlush);
2855
2949
  return toFlush;
2856
2950
  }
2857
2951
  }
@@ -2880,12 +2974,12 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
2880
2974
  { 22, 20, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */
2881
2975
  { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 13 */
2882
2976
  { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 14 */
2883
- { 22, 21, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 15 */
2884
- { 23, 22, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 16 */
2885
- { 23, 22, 22, 4, 5, 24, ZSTD_btopt }, /* level 17 */
2886
- { 23, 22, 22, 5, 4, 32, ZSTD_btopt }, /* level 18 */
2887
- { 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19 */
2888
- { 25, 25, 23, 7, 3, 64, ZSTD_btultra }, /* level 20 */
2977
+ { 22, 21, 22, 4, 5, 16, ZSTD_btlazy2 }, /* level 15 */
2978
+ { 22, 21, 22, 4, 5, 48, ZSTD_btopt }, /* level 16 */
2979
+ { 23, 22, 22, 4, 4, 48, ZSTD_btopt }, /* level 17 */
2980
+ { 23, 22, 22, 5, 3, 64, ZSTD_btopt }, /* level 18 */
2981
+ { 23, 23, 22, 7, 3,128, ZSTD_btopt }, /* level 19 */
2982
+ { 25, 25, 23, 7, 3,128, ZSTD_btultra }, /* level 20 */
2889
2983
  { 26, 26, 24, 7, 3,256, ZSTD_btultra }, /* level 21 */
2890
2984
  { 27, 27, 25, 9, 3,512, ZSTD_btultra }, /* level 22 */
2891
2985
  },
@@ -3004,6 +3098,8 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
3004
3098
  }
3005
3099
  #endif
3006
3100
 
3101
+ DEBUGLOG(4, "ZSTD_getCParams: cLevel=%i, srcSize=%u, dictSize=%u => table %u",
3102
+ compressionLevel, (U32)srcSizeHint, (U32)dictSize, tableID);
3007
3103
  if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default; no negative compressionLevel yet */
3008
3104
  if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
3009
3105
  { ZSTD_compressionParameters const cp = ZSTD_defaultCParameters[tableID][compressionLevel];
@@ -3019,5 +3115,6 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeH
3019
3115
  ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);
3020
3116
  memset(&params, 0, sizeof(params));
3021
3117
  params.cParams = cParams;
3118
+ params.fParams.contentSizeFlag = 1;
3022
3119
  return params;
3023
3120
  }