zstd-ruby 1.4.4.0 → 1.4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/zstdruby/libzstd/Makefile +123 -58
  4. data/ext/zstdruby/libzstd/README.md +34 -14
  5. data/ext/zstdruby/libzstd/common/bitstream.h +31 -37
  6. data/ext/zstdruby/libzstd/common/compiler.h +19 -3
  7. data/ext/zstdruby/libzstd/common/cpu.h +1 -1
  8. data/ext/zstdruby/libzstd/common/debug.c +11 -31
  9. data/ext/zstdruby/libzstd/common/debug.h +11 -31
  10. data/ext/zstdruby/libzstd/common/entropy_common.c +13 -33
  11. data/ext/zstdruby/libzstd/common/error_private.c +2 -1
  12. data/ext/zstdruby/libzstd/common/error_private.h +6 -2
  13. data/ext/zstdruby/libzstd/common/fse.h +11 -31
  14. data/ext/zstdruby/libzstd/common/fse_decompress.c +12 -37
  15. data/ext/zstdruby/libzstd/common/huf.h +15 -33
  16. data/ext/zstdruby/libzstd/common/mem.h +1 -1
  17. data/ext/zstdruby/libzstd/common/pool.c +1 -1
  18. data/ext/zstdruby/libzstd/common/pool.h +2 -2
  19. data/ext/zstdruby/libzstd/common/threading.c +4 -3
  20. data/ext/zstdruby/libzstd/common/threading.h +4 -3
  21. data/ext/zstdruby/libzstd/common/xxhash.c +15 -33
  22. data/ext/zstdruby/libzstd/common/xxhash.h +11 -31
  23. data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
  24. data/ext/zstdruby/libzstd/common/zstd_errors.h +2 -1
  25. data/ext/zstdruby/libzstd/common/zstd_internal.h +112 -15
  26. data/ext/zstdruby/libzstd/compress/fse_compress.c +17 -40
  27. data/ext/zstdruby/libzstd/compress/hist.c +15 -35
  28. data/ext/zstdruby/libzstd/compress/hist.h +12 -32
  29. data/ext/zstdruby/libzstd/compress/huf_compress.c +92 -92
  30. data/ext/zstdruby/libzstd/compress/zstd_compress.c +450 -275
  31. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +136 -14
  32. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +10 -6
  33. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +1 -1
  34. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +24 -20
  35. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +10 -3
  36. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +845 -0
  37. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +32 -0
  38. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +3 -13
  39. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +11 -8
  40. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +2 -2
  41. data/ext/zstdruby/libzstd/compress/zstd_fast.c +36 -24
  42. data/ext/zstdruby/libzstd/compress/zstd_fast.h +2 -2
  43. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +34 -11
  44. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +1 -1
  45. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +27 -5
  46. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +7 -2
  47. data/ext/zstdruby/libzstd/compress/zstd_opt.c +38 -84
  48. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  49. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +48 -21
  50. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +2 -2
  51. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +76 -62
  52. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +12 -8
  53. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +2 -2
  54. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +264 -148
  55. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +312 -203
  56. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +3 -3
  57. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +18 -4
  58. data/ext/zstdruby/libzstd/deprecated/zbuff.h +3 -3
  59. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +2 -2
  60. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
  61. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
  62. data/ext/zstdruby/libzstd/dictBuilder/cover.c +5 -5
  63. data/ext/zstdruby/libzstd/dictBuilder/cover.h +14 -4
  64. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +14 -4
  65. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +33 -9
  66. data/ext/zstdruby/libzstd/dictBuilder/zdict.h +51 -28
  67. data/ext/zstdruby/libzstd/dll/example/Makefile +2 -1
  68. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +4 -4
  69. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +18 -12
  70. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
  71. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +10 -6
  72. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
  73. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +10 -6
  74. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
  75. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +13 -7
  76. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
  77. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +17 -13
  78. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +2 -2
  79. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +17 -13
  80. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
  81. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +22 -14
  82. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
  83. data/ext/zstdruby/libzstd/libzstd.pc.in +2 -2
  84. data/ext/zstdruby/libzstd/zstd.h +62 -21
  85. data/lib/zstd-ruby/version.rb +1 -1
  86. metadata +7 -5
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -13,13 +13,13 @@
13
13
  ***************************************/
14
14
  #include <limits.h> /* INT_MAX */
15
15
  #include <string.h> /* memset */
16
- #include "cpu.h"
17
- #include "mem.h"
16
+ #include "../common/cpu.h"
17
+ #include "../common/mem.h"
18
18
  #include "hist.h" /* HIST_countFast_wksp */
19
19
  #define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
20
- #include "fse.h"
20
+ #include "../common/fse.h"
21
21
  #define HUF_STATIC_LINKING_ONLY
22
- #include "huf.h"
22
+ #include "../common/huf.h"
23
23
  #include "zstd_compress_internal.h"
24
24
  #include "zstd_compress_sequences.h"
25
25
  #include "zstd_compress_literals.h"
@@ -28,11 +28,19 @@
28
28
  #include "zstd_lazy.h"
29
29
  #include "zstd_opt.h"
30
30
  #include "zstd_ldm.h"
31
+ #include "zstd_compress_superblock.h"
31
32
 
32
33
 
33
34
  /*-*************************************
34
35
  * Helper functions
35
36
  ***************************************/
37
+ /* ZSTD_compressBound()
38
+ * Note that the result from this function is only compatible with the "normal"
39
+ * full-block strategy.
40
+ * When there are a lot of small blocks due to frequent flush in streaming mode
41
+ * the overhead of headers can make the compressed data to be larger than the
42
+ * return value of ZSTD_compressBound().
43
+ */
36
44
  size_t ZSTD_compressBound(size_t srcSize) {
37
45
  return ZSTD_COMPRESSBOUND(srcSize);
38
46
  }
@@ -82,7 +90,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
82
90
  }
83
91
  }
84
92
 
85
- ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
93
+ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
86
94
  {
87
95
  ZSTD_cwksp ws;
88
96
  ZSTD_CCtx* cctx;
@@ -91,9 +99,8 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
91
99
  ZSTD_cwksp_init(&ws, workspace, workspaceSize);
92
100
 
93
101
  cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
94
- if (cctx == NULL) {
95
- return NULL;
96
- }
102
+ if (cctx == NULL) return NULL;
103
+
97
104
  memset(cctx, 0, sizeof(ZSTD_CCtx));
98
105
  ZSTD_cwksp_move(&cctx->workspace, &ws);
99
106
  cctx->staticSize = workspaceSize;
@@ -102,8 +109,7 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
102
109
  if (!ZSTD_cwksp_check_available(&cctx->workspace, HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
103
110
  cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
104
111
  cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
105
- cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(
106
- &cctx->workspace, HUF_WORKSPACE_SIZE);
112
+ cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, HUF_WORKSPACE_SIZE);
107
113
  cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
108
114
  return cctx;
109
115
  }
@@ -227,7 +233,7 @@ size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params)
227
233
  }
228
234
 
229
235
  size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
230
- RETURN_ERROR_IF(!cctxParams, GENERIC);
236
+ RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
231
237
  memset(cctxParams, 0, sizeof(*cctxParams));
232
238
  cctxParams->compressionLevel = compressionLevel;
233
239
  cctxParams->fParams.contentSizeFlag = 1;
@@ -236,8 +242,8 @@ size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel)
236
242
 
237
243
  size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
238
244
  {
239
- RETURN_ERROR_IF(!cctxParams, GENERIC);
240
- FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
245
+ RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
246
+ FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
241
247
  memset(cctxParams, 0, sizeof(*cctxParams));
242
248
  assert(!ZSTD_checkCParams(params.cParams));
243
249
  cctxParams->cParams = params.cParams;
@@ -249,12 +255,12 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete
249
255
  /* ZSTD_assignParamsToCCtxParams() :
250
256
  * params is presumed valid at this stage */
251
257
  static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
252
- const ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
258
+ const ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params)
253
259
  {
254
260
  ZSTD_CCtx_params ret = *cctxParams;
255
- assert(!ZSTD_checkCParams(params.cParams));
256
- ret.cParams = params.cParams;
257
- ret.fParams = params.fParams;
261
+ assert(!ZSTD_checkCParams(params->cParams));
262
+ ret.cParams = params->cParams;
263
+ ret.fParams = params->fParams;
258
264
  ret.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
259
265
  return ret;
260
266
  }
@@ -339,8 +345,13 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
339
345
  return bounds;
340
346
 
341
347
  case ZSTD_c_overlapLog:
348
+ #ifdef ZSTD_MULTITHREAD
342
349
  bounds.lowerBound = ZSTD_OVERLAPLOG_MIN;
343
350
  bounds.upperBound = ZSTD_OVERLAPLOG_MAX;
351
+ #else
352
+ bounds.lowerBound = 0;
353
+ bounds.upperBound = 0;
354
+ #endif
344
355
  return bounds;
345
356
 
346
357
  case ZSTD_c_enableLongDistanceMatching:
@@ -408,9 +419,8 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
408
419
  return bounds;
409
420
 
410
421
  default:
411
- { ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };
412
- return boundError;
413
- }
422
+ bounds.error = ERROR(parameter_unsupported);
423
+ return bounds;
414
424
  }
415
425
  }
416
426
 
@@ -428,7 +438,7 @@ static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value)
428
438
 
429
439
  #define BOUNDCHECK(cParam, val) { \
430
440
  RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \
431
- parameter_outOfBound); \
441
+ parameter_outOfBound, "Param out of bounds"); \
432
442
  }
433
443
 
434
444
 
@@ -476,7 +486,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
476
486
  if (ZSTD_isUpdateAuthorized(param)) {
477
487
  cctx->cParamsChanged = 1;
478
488
  } else {
479
- RETURN_ERROR(stage_wrong);
489
+ RETURN_ERROR(stage_wrong, "can only set params in ctx init stage");
480
490
  } }
481
491
 
482
492
  switch(param)
@@ -513,7 +523,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
513
523
  case ZSTD_c_srcSizeHint:
514
524
  break;
515
525
 
516
- default: RETURN_ERROR(parameter_unsupported);
526
+ default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
517
527
  }
518
528
  return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value);
519
529
  }
@@ -530,7 +540,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
530
540
  return (size_t)CCtxParams->format;
531
541
 
532
542
  case ZSTD_c_compressionLevel : {
533
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
543
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
534
544
  if (value) { /* 0 : does not change current level */
535
545
  CCtxParams->compressionLevel = value;
536
546
  }
@@ -618,7 +628,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
618
628
  RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
619
629
  return 0;
620
630
  #else
621
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
631
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
622
632
  CCtxParams->nbWorkers = value;
623
633
  return CCtxParams->nbWorkers;
624
634
  #endif
@@ -631,7 +641,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
631
641
  /* Adjust to the minimum non-default value. */
632
642
  if (value != 0 && value < ZSTDMT_JOBSIZE_MIN)
633
643
  value = ZSTDMT_JOBSIZE_MIN;
634
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
644
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
635
645
  assert(value >= 0);
636
646
  CCtxParams->jobSize = value;
637
647
  return CCtxParams->jobSize;
@@ -642,7 +652,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
642
652
  RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
643
653
  return 0;
644
654
  #else
645
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));
655
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), "");
646
656
  CCtxParams->overlapLog = value;
647
657
  return CCtxParams->overlapLog;
648
658
  #endif
@@ -652,7 +662,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
652
662
  RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
653
663
  return 0;
654
664
  #else
655
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));
665
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), "");
656
666
  CCtxParams->rsyncable = value;
657
667
  return CCtxParams->rsyncable;
658
668
  #endif
@@ -681,7 +691,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
681
691
 
682
692
  case ZSTD_c_ldmHashRateLog :
683
693
  RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN,
684
- parameter_outOfBound);
694
+ parameter_outOfBound, "Param out of bounds!");
685
695
  CCtxParams->ldmParams.hashRateLog = value;
686
696
  return CCtxParams->ldmParams.hashRateLog;
687
697
 
@@ -821,8 +831,11 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
821
831
  ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
822
832
  {
823
833
  DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
824
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
825
- RETURN_ERROR_IF(cctx->cdict, stage_wrong);
834
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
835
+ "The context is in the wrong stage!");
836
+ RETURN_ERROR_IF(cctx->cdict, stage_wrong,
837
+ "Can't override parameters with cdict attached (some must "
838
+ "be inherited from the cdict).");
826
839
 
827
840
  cctx->requestedParams = *params;
828
841
  return 0;
@@ -831,7 +844,8 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
831
844
  ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
832
845
  {
833
846
  DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %u bytes", (U32)pledgedSrcSize);
834
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
847
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
848
+ "Can't set pledgedSrcSize when not in init stage.");
835
849
  cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
836
850
  return 0;
837
851
  }
@@ -845,7 +859,7 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
845
859
  {
846
860
  ZSTD_localDict* const dl = &cctx->localDict;
847
861
  ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(
848
- &cctx->requestedParams, 0, dl->dictSize);
862
+ &cctx->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN, dl->dictSize);
849
863
  if (dl->dict == NULL) {
850
864
  /* No local dictionary. */
851
865
  assert(dl->dictBuffer == NULL);
@@ -869,7 +883,7 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
869
883
  dl->dictContentType,
870
884
  cParams,
871
885
  cctx->customMem);
872
- RETURN_ERROR_IF(!dl->cdict, memory_allocation);
886
+ RETURN_ERROR_IF(!dl->cdict, memory_allocation, "ZSTD_createCDict_advanced failed");
873
887
  cctx->cdict = dl->cdict;
874
888
  return 0;
875
889
  }
@@ -878,7 +892,8 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
878
892
  ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
879
893
  ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
880
894
  {
881
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
895
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
896
+ "Can't load a dictionary when ctx is not in init stage.");
882
897
  RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
883
898
  "no malloc for static CCtx");
884
899
  DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
@@ -889,7 +904,7 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
889
904
  cctx->localDict.dict = dict;
890
905
  } else {
891
906
  void* dictBuffer = ZSTD_malloc(dictSize, cctx->customMem);
892
- RETURN_ERROR_IF(!dictBuffer, memory_allocation);
907
+ RETURN_ERROR_IF(!dictBuffer, memory_allocation, "NULL pointer!");
893
908
  memcpy(dictBuffer, dict, dictSize);
894
909
  cctx->localDict.dictBuffer = dictBuffer;
895
910
  cctx->localDict.dict = dictBuffer;
@@ -915,7 +930,8 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
915
930
 
916
931
  size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
917
932
  {
918
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
933
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
934
+ "Can't ref a dict when ctx not in init stage.");
919
935
  /* Free the existing local cdict (if any) to save memory. */
920
936
  ZSTD_clearAllDicts(cctx);
921
937
  cctx->cdict = cdict;
@@ -930,11 +946,14 @@ size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSiz
930
946
  size_t ZSTD_CCtx_refPrefix_advanced(
931
947
  ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
932
948
  {
933
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
949
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
950
+ "Can't ref a prefix when ctx not in init stage.");
934
951
  ZSTD_clearAllDicts(cctx);
935
- cctx->prefixDict.dict = prefix;
936
- cctx->prefixDict.dictSize = prefixSize;
937
- cctx->prefixDict.dictContentType = dictContentType;
952
+ if (prefix != NULL && prefixSize > 0) {
953
+ cctx->prefixDict.dict = prefix;
954
+ cctx->prefixDict.dictSize = prefixSize;
955
+ cctx->prefixDict.dictContentType = dictContentType;
956
+ }
938
957
  return 0;
939
958
  }
940
959
 
@@ -949,7 +968,8 @@ size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset)
949
968
  }
950
969
  if ( (reset == ZSTD_reset_parameters)
951
970
  || (reset == ZSTD_reset_session_and_parameters) ) {
952
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
971
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
972
+ "Can't reset parameters only when not in init stage.");
953
973
  ZSTD_clearAllDicts(cctx);
954
974
  return ZSTD_CCtxParams_reset(&cctx->requestedParams);
955
975
  }
@@ -996,7 +1016,7 @@ ZSTD_clampCParams(ZSTD_compressionParameters cParams)
996
1016
 
997
1017
  /** ZSTD_cycleLog() :
998
1018
  * condition for correct operation : hashLog > 1 */
999
- static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
1019
+ U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
1000
1020
  {
1001
1021
  U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
1002
1022
  return hashLog - btScale;
@@ -1006,7 +1026,7 @@ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
1006
1026
  * optimize `cPar` for a specified input (`srcSize` and `dictSize`).
1007
1027
  * mostly downsize to reduce memory consumption and initialization latency.
1008
1028
  * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
1009
- * note : for the time being, `srcSize==0` means "unknown" too, for compatibility with older convention.
1029
+ * note : `srcSize==0` means 0!
1010
1030
  * condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
1011
1031
  static ZSTD_compressionParameters
1012
1032
  ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
@@ -1017,10 +1037,8 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
1017
1037
  static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
1018
1038
  assert(ZSTD_checkCParams(cPar)==0);
1019
1039
 
1020
- if (dictSize && (srcSize+1<2) /* ZSTD_CONTENTSIZE_UNKNOWN and 0 mean "unknown" */ )
1021
- srcSize = minSrcSize; /* presumed small when there is a dictionary */
1022
- else if (srcSize == 0)
1023
- srcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* 0 == unknown : presumed large */
1040
+ if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
1041
+ srcSize = minSrcSize;
1024
1042
 
1025
1043
  /* resize windowLog if input is small enough, to use less memory */
1026
1044
  if ( (srcSize < maxWindowResize)
@@ -1049,9 +1067,13 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
1049
1067
  size_t dictSize)
1050
1068
  {
1051
1069
  cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */
1070
+ if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN;
1052
1071
  return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
1053
1072
  }
1054
1073
 
1074
+ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
1075
+ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
1076
+
1055
1077
  ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1056
1078
  const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
1057
1079
  {
@@ -1059,7 +1081,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1059
1081
  if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
1060
1082
  srcSizeHint = CCtxParams->srcSizeHint;
1061
1083
  }
1062
- cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
1084
+ cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize);
1063
1085
  if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
1064
1086
  if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
1065
1087
  if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
@@ -1069,6 +1091,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1069
1091
  if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
1070
1092
  if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
1071
1093
  assert(!ZSTD_checkCParams(cParams));
1094
+ /* srcSizeHint == 0 means 0 */
1072
1095
  return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
1073
1096
  }
1074
1097
 
@@ -1104,7 +1127,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
1104
1127
  {
1105
1128
  RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
1106
1129
  { ZSTD_compressionParameters const cParams =
1107
- ZSTD_getCParamsFromCCtxParams(params, 0, 0);
1130
+ ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0);
1108
1131
  size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
1109
1132
  U32 const divider = (cParams.minMatch==3) ? 3 : 4;
1110
1133
  size_t const maxNbSeq = blockSize / divider;
@@ -1118,13 +1141,26 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
1118
1141
  size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);
1119
1142
  size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq));
1120
1143
 
1121
- size_t const neededSpace = entropySpace + blockStateSpace + tokenSpace +
1122
- matchStateSize + ldmSpace + ldmSeqSpace;
1144
+ /* estimateCCtxSize is for one-shot compression. So no buffers should
1145
+ * be needed. However, we still allocate two 0-sized buffers, which can
1146
+ * take space under ASAN. */
1147
+ size_t const bufferSpace = ZSTD_cwksp_alloc_size(0)
1148
+ + ZSTD_cwksp_alloc_size(0);
1149
+
1123
1150
  size_t const cctxSpace = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx));
1124
1151
 
1125
- DEBUGLOG(5, "sizeof(ZSTD_CCtx) : %u", (U32)cctxSpace);
1152
+ size_t const neededSpace =
1153
+ cctxSpace +
1154
+ entropySpace +
1155
+ blockStateSpace +
1156
+ ldmSpace +
1157
+ ldmSeqSpace +
1158
+ matchStateSize +
1159
+ tokenSpace +
1160
+ bufferSpace;
1161
+
1126
1162
  DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
1127
- return cctxSpace + neededSpace;
1163
+ return neededSpace;
1128
1164
  }
1129
1165
  }
1130
1166
 
@@ -1136,7 +1172,7 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
1136
1172
 
1137
1173
  static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
1138
1174
  {
1139
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
1175
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
1140
1176
  return ZSTD_estimateCCtxSize_usingCParams(cParams);
1141
1177
  }
1142
1178
 
@@ -1155,7 +1191,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
1155
1191
  {
1156
1192
  RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
1157
1193
  { ZSTD_compressionParameters const cParams =
1158
- ZSTD_getCParamsFromCCtxParams(params, 0, 0);
1194
+ ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0);
1159
1195
  size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
1160
1196
  size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
1161
1197
  size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
@@ -1175,7 +1211,7 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
1175
1211
 
1176
1212
  static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
1177
1213
  {
1178
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
1214
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
1179
1215
  return ZSTD_estimateCStreamSize_usingCParams(cParams);
1180
1216
  }
1181
1217
 
@@ -1243,7 +1279,7 @@ static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
1243
1279
  assert(cParams1.strategy == cParams2.strategy);
1244
1280
  }
1245
1281
 
1246
- static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
1282
+ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
1247
1283
  {
1248
1284
  int i;
1249
1285
  for (i = 0; i < ZSTD_REP_NUM; ++i)
@@ -1320,10 +1356,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
1320
1356
 
1321
1357
  DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset);
1322
1358
  if (forceResetIndex == ZSTDirp_reset) {
1323
- memset(&ms->window, 0, sizeof(ms->window));
1324
- ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */
1325
- ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
1326
- ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */
1359
+ ZSTD_window_init(&ms->window);
1327
1360
  ZSTD_cwksp_mark_tables_dirty(ws);
1328
1361
  }
1329
1362
 
@@ -1416,13 +1449,13 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
1416
1449
  size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);
1417
1450
  size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
1418
1451
 
1419
- ZSTD_indexResetPolicy_e needsIndexReset = ZSTDirp_continue;
1452
+ ZSTD_indexResetPolicy_e needsIndexReset = zc->initialized ? ZSTDirp_continue : ZSTDirp_reset;
1420
1453
 
1421
1454
  if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
1422
1455
  needsIndexReset = ZSTDirp_reset;
1423
1456
  }
1424
1457
 
1425
- ZSTD_cwksp_bump_oversized_duration(ws, 0);
1458
+ if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
1426
1459
 
1427
1460
  /* Check if workspace is large enough, alloc a new one if needed */
1428
1461
  { size_t const cctxSpace = zc->staticSize ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
@@ -1459,7 +1492,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
1459
1492
  needsIndexReset = ZSTDirp_reset;
1460
1493
 
1461
1494
  ZSTD_cwksp_free(ws, zc->customMem);
1462
- FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem));
1495
+ FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem), "");
1463
1496
 
1464
1497
  DEBUGLOG(5, "reserving object space");
1465
1498
  /* Statically sized space.
@@ -1530,7 +1563,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
1530
1563
  &params.cParams,
1531
1564
  crp,
1532
1565
  needsIndexReset,
1533
- ZSTD_resetTarget_CCtx));
1566
+ ZSTD_resetTarget_CCtx), "");
1534
1567
 
1535
1568
  /* ldm hash table */
1536
1569
  if (params.ldmParams.enableLdm) {
@@ -1541,11 +1574,13 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
1541
1574
  zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
1542
1575
  zc->maxNbLdmSequences = maxNbLdmSeq;
1543
1576
 
1544
- memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
1577
+ ZSTD_window_init(&zc->ldmState.window);
1545
1578
  ZSTD_window_clear(&zc->ldmState.window);
1579
+ zc->ldmState.loadedDictEnd = 0;
1546
1580
  }
1547
1581
 
1548
1582
  DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
1583
+ zc->initialized = 1;
1549
1584
 
1550
1585
  return 0;
1551
1586
  }
@@ -1603,10 +1638,11 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
1603
1638
  assert(windowLog != 0);
1604
1639
  /* Resize working context table params for input only, since the dict
1605
1640
  * has its own tables. */
1641
+ /* pledgeSrcSize == 0 means 0! */
1606
1642
  params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
1607
1643
  params.cParams.windowLog = windowLog;
1608
1644
  FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
1609
- ZSTDcrp_makeClean, zbuff));
1645
+ ZSTDcrp_makeClean, zbuff), "");
1610
1646
  assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
1611
1647
  }
1612
1648
 
@@ -1655,7 +1691,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
1655
1691
  params.cParams = *cdict_cParams;
1656
1692
  params.cParams.windowLog = windowLog;
1657
1693
  FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
1658
- ZSTDcrp_leaveDirty, zbuff));
1694
+ ZSTDcrp_leaveDirty, zbuff), "");
1659
1695
  assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
1660
1696
  assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
1661
1697
  assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);
@@ -1736,7 +1772,8 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
1736
1772
  ZSTD_buffered_policy_e zbuff)
1737
1773
  {
1738
1774
  DEBUGLOG(5, "ZSTD_copyCCtx_internal");
1739
- RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong);
1775
+ RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong,
1776
+ "Can't copy a ctx that's not in init stage.");
1740
1777
 
1741
1778
  memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
1742
1779
  { ZSTD_CCtx_params params = dstCCtx->requestedParams;
@@ -1889,16 +1926,6 @@ static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* par
1889
1926
 
1890
1927
  /* See doc/zstd_compression_format.md for detailed format description */
1891
1928
 
1892
- static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
1893
- {
1894
- U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
1895
- RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
1896
- dstSize_tooSmall);
1897
- MEM_writeLE24(dst, cBlockHeader24);
1898
- memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
1899
- return ZSTD_blockHeaderSize + srcSize;
1900
- }
1901
-
1902
1929
  void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
1903
1930
  {
1904
1931
  const seqDef* const sequences = seqStorePtr->sequencesStart;
@@ -1921,19 +1948,14 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
1921
1948
  mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
1922
1949
  }
1923
1950
 
1924
- static int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)
1951
+ /* ZSTD_useTargetCBlockSize():
1952
+ * Returns if target compressed block size param is being used.
1953
+ * If used, compression will do best effort to make a compressed block size to be around targetCBlockSize.
1954
+ * Returns 1 if true, 0 otherwise. */
1955
+ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
1925
1956
  {
1926
- switch (cctxParams->literalCompressionMode) {
1927
- case ZSTD_lcm_huffman:
1928
- return 0;
1929
- case ZSTD_lcm_uncompressed:
1930
- return 1;
1931
- default:
1932
- assert(0 /* impossible: pre-validated */);
1933
- /* fall-through */
1934
- case ZSTD_lcm_auto:
1935
- return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
1936
- }
1957
+ DEBUGLOG(5, "ZSTD_useTargetCBlockSize (targetCBlockSize=%zu)", cctxParams->targetCBlockSize);
1958
+ return (cctxParams->targetCBlockSize != 0);
1937
1959
  }
1938
1960
 
1939
1961
  /* ZSTD_compressSequences_internal():
@@ -1979,14 +2001,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
1979
2001
  literals, litSize,
1980
2002
  entropyWorkspace, entropyWkspSize,
1981
2003
  bmi2);
1982
- FORWARD_IF_ERROR(cSize);
2004
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed");
1983
2005
  assert(cSize <= dstCapacity);
1984
2006
  op += cSize;
1985
2007
  }
1986
2008
 
1987
2009
  /* Sequences Header */
1988
2010
  RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
1989
- dstSize_tooSmall);
2011
+ dstSize_tooSmall, "Can't fit seq hdr in output buf!");
1990
2012
  if (nbSeq < 128) {
1991
2013
  *op++ = (BYTE)nbSeq;
1992
2014
  } else if (nbSeq < LONGNBSEQ) {
@@ -2031,7 +2053,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
2031
2053
  prevEntropy->fse.litlengthCTable,
2032
2054
  sizeof(prevEntropy->fse.litlengthCTable),
2033
2055
  entropyWorkspace, entropyWkspSize);
2034
- FORWARD_IF_ERROR(countSize);
2056
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
2035
2057
  if (LLtype == set_compressed)
2036
2058
  lastNCount = op;
2037
2059
  op += countSize;
@@ -2059,7 +2081,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
2059
2081
  prevEntropy->fse.offcodeCTable,
2060
2082
  sizeof(prevEntropy->fse.offcodeCTable),
2061
2083
  entropyWorkspace, entropyWkspSize);
2062
- FORWARD_IF_ERROR(countSize);
2084
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
2063
2085
  if (Offtype == set_compressed)
2064
2086
  lastNCount = op;
2065
2087
  op += countSize;
@@ -2085,7 +2107,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
2085
2107
  prevEntropy->fse.matchlengthCTable,
2086
2108
  sizeof(prevEntropy->fse.matchlengthCTable),
2087
2109
  entropyWorkspace, entropyWkspSize);
2088
- FORWARD_IF_ERROR(countSize);
2110
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
2089
2111
  if (MLtype == set_compressed)
2090
2112
  lastNCount = op;
2091
2113
  op += countSize;
@@ -2101,7 +2123,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
2101
2123
  CTable_LitLength, llCodeTable,
2102
2124
  sequences, nbSeq,
2103
2125
  longOffsets, bmi2);
2104
- FORWARD_IF_ERROR(bitstreamSize);
2126
+ FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed");
2105
2127
  op += bitstreamSize;
2106
2128
  assert(op <= oend);
2107
2129
  /* zstd versions <= 1.3.4 mistakenly report corruption when
@@ -2145,7 +2167,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr,
2145
2167
  */
2146
2168
  if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
2147
2169
  return 0; /* block not compressed */
2148
- FORWARD_IF_ERROR(cSize);
2170
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressSequences_internal failed");
2149
2171
 
2150
2172
  /* Check compressibility */
2151
2173
  { size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
@@ -2271,7 +2293,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
2271
2293
  /* Updates ldmSeqStore.size */
2272
2294
  FORWARD_IF_ERROR(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore,
2273
2295
  &zc->appliedParams.ldmParams,
2274
- src, srcSize));
2296
+ src, srcSize), "");
2275
2297
  /* Updates ldmSeqStore.pos */
2276
2298
  lastLLSize =
2277
2299
  ZSTD_ldm_blockCompress(&ldmSeqStore,
@@ -2347,7 +2369,7 @@ size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
2347
2369
  void* dst = ZSTD_malloc(dstCapacity, ZSTD_defaultCMem);
2348
2370
  SeqCollector seqCollector;
2349
2371
 
2350
- RETURN_ERROR_IF(dst == NULL, memory_allocation);
2372
+ RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
2351
2373
 
2352
2374
  seqCollector.collectSequences = 1;
2353
2375
  seqCollector.seqStart = outSeqs;
@@ -2370,6 +2392,25 @@ static int ZSTD_isRLE(const BYTE *ip, size_t length) {
2370
2392
  return 1;
2371
2393
  }
2372
2394
 
2395
+ /* Returns true if the given block may be RLE.
2396
+ * This is just a heuristic based on the compressibility.
2397
+ * It may return both false positives and false negatives.
2398
+ */
2399
+ static int ZSTD_maybeRLE(seqStore_t const* seqStore)
2400
+ {
2401
+ size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
2402
+ size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart);
2403
+
2404
+ return nbSeqs < 4 && nbLits < 10;
2405
+ }
2406
+
2407
+ static void ZSTD_confirmRepcodesAndEntropyTables(ZSTD_CCtx* zc)
2408
+ {
2409
+ ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
2410
+ zc->blockState.prevCBlock = zc->blockState.nextCBlock;
2411
+ zc->blockState.nextCBlock = tmp;
2412
+ }
2413
+
2373
2414
  static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
2374
2415
  void* dst, size_t dstCapacity,
2375
2416
  const void* src, size_t srcSize, U32 frame)
@@ -2387,7 +2428,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
2387
2428
  (unsigned)zc->blockState.matchState.nextToUpdate);
2388
2429
 
2389
2430
  { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
2390
- FORWARD_IF_ERROR(bss);
2431
+ FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
2391
2432
  if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }
2392
2433
  }
2393
2434
 
@@ -2420,10 +2461,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
2420
2461
 
2421
2462
  out:
2422
2463
  if (!ZSTD_isError(cSize) && cSize > 1) {
2423
- /* confirm repcodes and entropy tables when emitting a compressed block */
2424
- ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
2425
- zc->blockState.prevCBlock = zc->blockState.nextCBlock;
2426
- zc->blockState.nextCBlock = tmp;
2464
+ ZSTD_confirmRepcodesAndEntropyTables(zc);
2427
2465
  }
2428
2466
  /* We check that dictionaries have offset codes available for the first
2429
2467
  * block. After the first block, the offcode table might not have large
@@ -2435,6 +2473,80 @@ out:
2435
2473
  return cSize;
2436
2474
  }
2437
2475
 
2476
+ static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc,
2477
+ void* dst, size_t dstCapacity,
2478
+ const void* src, size_t srcSize,
2479
+ const size_t bss, U32 lastBlock)
2480
+ {
2481
+ DEBUGLOG(6, "Attempting ZSTD_compressSuperBlock()");
2482
+ if (bss == ZSTDbss_compress) {
2483
+ if (/* We don't want to emit our first block as a RLE even if it qualifies because
2484
+ * doing so will cause the decoder (cli only) to throw a "should consume all input error."
2485
+ * This is only an issue for zstd <= v1.4.3
2486
+ */
2487
+ !zc->isFirstBlock &&
2488
+ ZSTD_maybeRLE(&zc->seqStore) &&
2489
+ ZSTD_isRLE((BYTE const*)src, srcSize))
2490
+ {
2491
+ return ZSTD_rleCompressBlock(dst, dstCapacity, *(BYTE const*)src, srcSize, lastBlock);
2492
+ }
2493
+ /* Attempt superblock compression.
2494
+ *
2495
+ * Note that compressed size of ZSTD_compressSuperBlock() is not bound by the
2496
+ * standard ZSTD_compressBound(). This is a problem, because even if we have
2497
+ * space now, taking an extra byte now could cause us to run out of space later
2498
+ * and violate ZSTD_compressBound().
2499
+ *
2500
+ * Define blockBound(blockSize) = blockSize + ZSTD_blockHeaderSize.
2501
+ *
2502
+ * In order to respect ZSTD_compressBound() we must attempt to emit a raw
2503
+ * uncompressed block in these cases:
2504
+ * * cSize == 0: Return code for an uncompressed block.
2505
+ * * cSize == dstSize_tooSmall: We may have expanded beyond blockBound(srcSize).
2506
+ * ZSTD_noCompressBlock() will return dstSize_tooSmall if we are really out of
2507
+ * output space.
2508
+ * * cSize >= blockBound(srcSize): We have expanded the block too much so
2509
+ * emit an uncompressed block.
2510
+ */
2511
+ {
2512
+ size_t const cSize = ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock);
2513
+ if (cSize != ERROR(dstSize_tooSmall)) {
2514
+ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy);
2515
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed");
2516
+ if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) {
2517
+ ZSTD_confirmRepcodesAndEntropyTables(zc);
2518
+ return cSize;
2519
+ }
2520
+ }
2521
+ }
2522
+ }
2523
+
2524
+ DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()");
2525
+ /* Superblock compression failed, attempt to emit a single no compress block.
2526
+ * The decoder will be able to stream this block since it is uncompressed.
2527
+ */
2528
+ return ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
2529
+ }
2530
+
2531
+ static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc,
2532
+ void* dst, size_t dstCapacity,
2533
+ const void* src, size_t srcSize,
2534
+ U32 lastBlock)
2535
+ {
2536
+ size_t cSize = 0;
2537
+ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
2538
+ DEBUGLOG(5, "ZSTD_compressBlock_targetCBlockSize (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u, srcSize=%zu)",
2539
+ (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate, srcSize);
2540
+ FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
2541
+
2542
+ cSize = ZSTD_compressBlock_targetCBlockSize_body(zc, dst, dstCapacity, src, srcSize, bss, lastBlock);
2543
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize_body failed");
2544
+
2545
+ if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
2546
+ zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
2547
+
2548
+ return cSize;
2549
+ }
2438
2550
 
2439
2551
  static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
2440
2552
  ZSTD_cwksp* ws,
@@ -2478,6 +2590,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
2478
2590
  BYTE* const ostart = (BYTE*)dst;
2479
2591
  BYTE* op = ostart;
2480
2592
  U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
2593
+
2481
2594
  assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
2482
2595
 
2483
2596
  DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
@@ -2500,21 +2613,31 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
2500
2613
  /* Ensure hash/chain table insertion resumes no sooner than lowlimit */
2501
2614
  if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
2502
2615
 
2503
- { size_t cSize = ZSTD_compressBlock_internal(cctx,
2504
- op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
2505
- ip, blockSize, 1 /* frame */);
2506
- FORWARD_IF_ERROR(cSize);
2507
- if (cSize == 0) { /* block is not compressible */
2508
- cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
2509
- FORWARD_IF_ERROR(cSize);
2616
+ { size_t cSize;
2617
+ if (ZSTD_useTargetCBlockSize(&cctx->appliedParams)) {
2618
+ cSize = ZSTD_compressBlock_targetCBlockSize(cctx, op, dstCapacity, ip, blockSize, lastBlock);
2619
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed");
2620
+ assert(cSize > 0);
2621
+ assert(cSize <= blockSize + ZSTD_blockHeaderSize);
2510
2622
  } else {
2511
- const U32 cBlockHeader = cSize == 1 ?
2512
- lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
2513
- lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
2514
- MEM_writeLE24(op, cBlockHeader);
2515
- cSize += ZSTD_blockHeaderSize;
2623
+ cSize = ZSTD_compressBlock_internal(cctx,
2624
+ op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
2625
+ ip, blockSize, 1 /* frame */);
2626
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_internal failed");
2627
+
2628
+ if (cSize == 0) { /* block is not compressible */
2629
+ cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
2630
+ FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
2631
+ } else {
2632
+ U32 const cBlockHeader = cSize == 1 ?
2633
+ lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
2634
+ lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
2635
+ MEM_writeLE24(op, cBlockHeader);
2636
+ cSize += ZSTD_blockHeaderSize;
2637
+ }
2516
2638
  }
2517
2639
 
2640
+
2518
2641
  ip += blockSize;
2519
2642
  assert(remaining >= blockSize);
2520
2643
  remaining -= blockSize;
@@ -2546,7 +2669,8 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
2546
2669
  size_t pos=0;
2547
2670
 
2548
2671
  assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
2549
- RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall);
2672
+ RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall,
2673
+ "dst buf is too small to fit worst-case frame header size.");
2550
2674
  DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
2551
2675
  !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
2552
2676
 
@@ -2582,7 +2706,8 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
2582
2706
  */
2583
2707
  size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
2584
2708
  {
2585
- RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall);
2709
+ RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall,
2710
+ "dst buf is too small to write frame trailer empty block.");
2586
2711
  { U32 const cBlockHeader24 = 1 /*lastBlock*/ + (((U32)bt_raw)<<1); /* 0 size */
2587
2712
  MEM_writeLE24(dst, cBlockHeader24);
2588
2713
  return ZSTD_blockHeaderSize;
@@ -2591,9 +2716,11 @@ size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
2591
2716
 
2592
2717
  size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq)
2593
2718
  {
2594
- RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong);
2719
+ RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong,
2720
+ "wrong cctx stage");
2595
2721
  RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm,
2596
- parameter_unsupported);
2722
+ parameter_unsupported,
2723
+ "incompatible with ldm");
2597
2724
  cctx->externSeqStore.seq = seq;
2598
2725
  cctx->externSeqStore.size = nbSeq;
2599
2726
  cctx->externSeqStore.capacity = nbSeq;
@@ -2618,7 +2745,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
2618
2745
  if (frame && (cctx->stage==ZSTDcs_init)) {
2619
2746
  fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams,
2620
2747
  cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
2621
- FORWARD_IF_ERROR(fhSize);
2748
+ FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed");
2622
2749
  assert(fhSize <= dstCapacity);
2623
2750
  dstCapacity -= fhSize;
2624
2751
  dst = (char*)dst + fhSize;
@@ -2645,7 +2772,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
2645
2772
  { size_t const cSize = frame ?
2646
2773
  ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
2647
2774
  ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);
2648
- FORWARD_IF_ERROR(cSize);
2775
+ FORWARD_IF_ERROR(cSize, "%s", frame ? "ZSTD_compress_frameChunk failed" : "ZSTD_compressBlock_internal failed");
2649
2776
  cctx->consumedSrcSize += srcSize;
2650
2777
  cctx->producedCSize += (cSize + fhSize);
2651
2778
  assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
@@ -2682,7 +2809,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
2682
2809
  {
2683
2810
  DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize);
2684
2811
  { size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
2685
- RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong); }
2812
+ RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong, "input is larger than a block"); }
2686
2813
 
2687
2814
  return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
2688
2815
  }
@@ -2691,6 +2818,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
2691
2818
  * @return : 0, or an error code
2692
2819
  */
2693
2820
  static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
2821
+ ldmState_t* ls,
2694
2822
  ZSTD_cwksp* ws,
2695
2823
  ZSTD_CCtx_params const* params,
2696
2824
  const void* src, size_t srcSize,
@@ -2702,6 +2830,11 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
2702
2830
  ZSTD_window_update(&ms->window, src, srcSize);
2703
2831
  ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
2704
2832
 
2833
+ if (params->ldmParams.enableLdm && ls != NULL) {
2834
+ ZSTD_window_update(&ls->window, src, srcSize);
2835
+ ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
2836
+ }
2837
+
2705
2838
  /* Assert that we the ms params match the params we're being given */
2706
2839
  ZSTD_assertEqualCParams(params->cParams, ms->cParams);
2707
2840
 
@@ -2714,6 +2847,9 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
2714
2847
 
2715
2848
  ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, ichunk);
2716
2849
 
2850
+ if (params->ldmParams.enableLdm && ls != NULL)
2851
+ ZSTD_ldm_fillHashTable(ls, (const BYTE*)src, (const BYTE*)src + srcSize, &params->ldmParams);
2852
+
2717
2853
  switch(params->cParams.strategy)
2718
2854
  {
2719
2855
  case ZSTD_fast:
@@ -2756,102 +2892,123 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
2756
2892
  NOTE: This behavior is not standard and could be improved in the future. */
2757
2893
  static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
2758
2894
  U32 s;
2759
- RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted);
2895
+ RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted, "dict fse tables don't have all symbols");
2760
2896
  for (s = 0; s <= maxSymbolValue; ++s) {
2761
- RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted);
2897
+ RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted, "dict fse tables don't have all symbols");
2762
2898
  }
2763
2899
  return 0;
2764
2900
  }
2765
2901
 
2766
-
2767
- /* Dictionary format :
2768
- * See :
2769
- * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
2770
- */
2771
- /*! ZSTD_loadZstdDictionary() :
2772
- * @return : dictID, or an error code
2773
- * assumptions : magic number supposed already checked
2774
- * dictSize supposed >= 8
2775
- */
2776
- static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
2777
- ZSTD_matchState_t* ms,
2778
- ZSTD_cwksp* ws,
2779
- ZSTD_CCtx_params const* params,
2780
- const void* dict, size_t dictSize,
2781
- ZSTD_dictTableLoadMethod_e dtlm,
2782
- void* workspace)
2902
+ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
2903
+ short* offcodeNCount, unsigned* offcodeMaxValue,
2904
+ const void* const dict, size_t dictSize)
2783
2905
  {
2784
- const BYTE* dictPtr = (const BYTE*)dict;
2906
+ const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */
2785
2907
  const BYTE* const dictEnd = dictPtr + dictSize;
2786
- short offcodeNCount[MaxOff+1];
2787
- unsigned offcodeMaxValue = MaxOff;
2788
- size_t dictID;
2908
+ dictPtr += 8;
2909
+ bs->entropy.huf.repeatMode = HUF_repeat_check;
2789
2910
 
2790
- ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
2791
- assert(dictSize >= 8);
2792
- assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
2911
+ { unsigned maxSymbolValue = 255;
2912
+ unsigned hasZeroWeights = 1;
2913
+ size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr,
2914
+ dictEnd-dictPtr, &hasZeroWeights);
2793
2915
 
2794
- dictPtr += 4; /* skip magic number */
2795
- dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr);
2796
- dictPtr += 4;
2916
+ /* We only set the loaded table as valid if it contains all non-zero
2917
+ * weights. Otherwise, we set it to check */
2918
+ if (!hasZeroWeights)
2919
+ bs->entropy.huf.repeatMode = HUF_repeat_valid;
2797
2920
 
2798
- { unsigned maxSymbolValue = 255;
2799
- size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
2800
- RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted);
2801
- RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted);
2921
+ RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, "");
2922
+ RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted, "");
2802
2923
  dictPtr += hufHeaderSize;
2803
2924
  }
2804
2925
 
2805
2926
  { unsigned offcodeLog;
2806
- size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
2807
- RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);
2808
- RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);
2927
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
2928
+ RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
2929
+ RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
2809
2930
  /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
2810
2931
  /* fill all offset symbols to avoid garbage at end of table */
2811
2932
  RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
2812
2933
  bs->entropy.fse.offcodeCTable,
2813
2934
  offcodeNCount, MaxOff, offcodeLog,
2814
2935
  workspace, HUF_WORKSPACE_SIZE)),
2815
- dictionary_corrupted);
2936
+ dictionary_corrupted, "");
2816
2937
  dictPtr += offcodeHeaderSize;
2817
2938
  }
2818
2939
 
2819
2940
  { short matchlengthNCount[MaxML+1];
2820
2941
  unsigned matchlengthMaxValue = MaxML, matchlengthLog;
2821
2942
  size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
2822
- RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);
2823
- RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);
2943
+ RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
2944
+ RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
2824
2945
  /* Every match length code must have non-zero probability */
2825
- FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
2946
+ FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML), "");
2826
2947
  RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
2827
2948
  bs->entropy.fse.matchlengthCTable,
2828
2949
  matchlengthNCount, matchlengthMaxValue, matchlengthLog,
2829
2950
  workspace, HUF_WORKSPACE_SIZE)),
2830
- dictionary_corrupted);
2951
+ dictionary_corrupted, "");
2831
2952
  dictPtr += matchlengthHeaderSize;
2832
2953
  }
2833
2954
 
2834
2955
  { short litlengthNCount[MaxLL+1];
2835
2956
  unsigned litlengthMaxValue = MaxLL, litlengthLog;
2836
2957
  size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
2837
- RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);
2838
- RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);
2958
+ RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
2959
+ RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
2839
2960
  /* Every literal length code must have non-zero probability */
2840
- FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
2961
+ FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL), "");
2841
2962
  RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
2842
2963
  bs->entropy.fse.litlengthCTable,
2843
2964
  litlengthNCount, litlengthMaxValue, litlengthLog,
2844
2965
  workspace, HUF_WORKSPACE_SIZE)),
2845
- dictionary_corrupted);
2966
+ dictionary_corrupted, "");
2846
2967
  dictPtr += litlengthHeaderSize;
2847
2968
  }
2848
2969
 
2849
- RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);
2970
+ RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, "");
2850
2971
  bs->rep[0] = MEM_readLE32(dictPtr+0);
2851
2972
  bs->rep[1] = MEM_readLE32(dictPtr+4);
2852
2973
  bs->rep[2] = MEM_readLE32(dictPtr+8);
2853
2974
  dictPtr += 12;
2854
2975
 
2976
+ return dictPtr - (const BYTE*)dict;
2977
+ }
2978
+
2979
+ /* Dictionary format :
2980
+ * See :
2981
+ * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
2982
+ */
2983
+ /*! ZSTD_loadZstdDictionary() :
2984
+ * @return : dictID, or an error code
2985
+ * assumptions : magic number supposed already checked
2986
+ * dictSize supposed >= 8
2987
+ */
2988
+ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
2989
+ ZSTD_matchState_t* ms,
2990
+ ZSTD_cwksp* ws,
2991
+ ZSTD_CCtx_params const* params,
2992
+ const void* dict, size_t dictSize,
2993
+ ZSTD_dictTableLoadMethod_e dtlm,
2994
+ void* workspace)
2995
+ {
2996
+ const BYTE* dictPtr = (const BYTE*)dict;
2997
+ const BYTE* const dictEnd = dictPtr + dictSize;
2998
+ short offcodeNCount[MaxOff+1];
2999
+ unsigned offcodeMaxValue = MaxOff;
3000
+ size_t dictID;
3001
+ size_t eSize;
3002
+
3003
+ ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
3004
+ assert(dictSize >= 8);
3005
+ assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
3006
+
3007
+ dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ );
3008
+ eSize = ZSTD_loadCEntropy(bs, workspace, offcodeNCount, &offcodeMaxValue, dict, dictSize);
3009
+ FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed");
3010
+ dictPtr += eSize;
3011
+
2855
3012
  { size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
2856
3013
  U32 offcodeMax = MaxOff;
2857
3014
  if (dictContentSize <= ((U32)-1) - 128 KB) {
@@ -2859,20 +3016,19 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
2859
3016
  offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
2860
3017
  }
2861
3018
  /* All offset values <= dictContentSize + 128 KB must be representable */
2862
- FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
3019
+ FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)), "");
2863
3020
  /* All repCodes must be <= dictContentSize and != 0*/
2864
3021
  { U32 u;
2865
3022
  for (u=0; u<3; u++) {
2866
- RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted);
2867
- RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted);
3023
+ RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, "");
3024
+ RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
2868
3025
  } }
2869
3026
 
2870
- bs->entropy.huf.repeatMode = HUF_repeat_valid;
2871
3027
  bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
2872
3028
  bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
2873
3029
  bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
2874
3030
  FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(
2875
- ms, ws, params, dictPtr, dictContentSize, dtlm));
3031
+ ms, NULL, ws, params, dictPtr, dictContentSize, dtlm), "");
2876
3032
  return dictID;
2877
3033
  }
2878
3034
  }
@@ -2882,6 +3038,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
2882
3038
  static size_t
2883
3039
  ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
2884
3040
  ZSTD_matchState_t* ms,
3041
+ ldmState_t* ls,
2885
3042
  ZSTD_cwksp* ws,
2886
3043
  const ZSTD_CCtx_params* params,
2887
3044
  const void* dict, size_t dictSize,
@@ -2891,7 +3048,7 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
2891
3048
  {
2892
3049
  DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
2893
3050
  if ((dict==NULL) || (dictSize<8)) {
2894
- RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
3051
+ RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, "");
2895
3052
  return 0;
2896
3053
  }
2897
3054
 
@@ -2899,15 +3056,15 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
2899
3056
 
2900
3057
  /* dict restricted modes */
2901
3058
  if (dictContentType == ZSTD_dct_rawContent)
2902
- return ZSTD_loadDictionaryContent(ms, ws, params, dict, dictSize, dtlm);
3059
+ return ZSTD_loadDictionaryContent(ms, ls, ws, params, dict, dictSize, dtlm);
2903
3060
 
2904
3061
  if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
2905
3062
  if (dictContentType == ZSTD_dct_auto) {
2906
3063
  DEBUGLOG(4, "raw content dictionary detected");
2907
3064
  return ZSTD_loadDictionaryContent(
2908
- ms, ws, params, dict, dictSize, dtlm);
3065
+ ms, ls, ws, params, dict, dictSize, dtlm);
2909
3066
  }
2910
- RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
3067
+ RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, "");
2911
3068
  assert(0); /* impossible */
2912
3069
  }
2913
3070
 
@@ -2944,17 +3101,18 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
2944
3101
  }
2945
3102
 
2946
3103
  FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, *params, pledgedSrcSize,
2947
- ZSTDcrp_makeClean, zbuff) );
3104
+ ZSTDcrp_makeClean, zbuff) , "");
2948
3105
  { size_t const dictID = cdict ?
2949
3106
  ZSTD_compress_insertDictionary(
2950
3107
  cctx->blockState.prevCBlock, &cctx->blockState.matchState,
2951
- &cctx->workspace, params, cdict->dictContent, cdict->dictContentSize,
2952
- dictContentType, dtlm, cctx->entropyWorkspace)
3108
+ &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
3109
+ cdict->dictContentSize, dictContentType, dtlm,
3110
+ cctx->entropyWorkspace)
2953
3111
  : ZSTD_compress_insertDictionary(
2954
3112
  cctx->blockState.prevCBlock, &cctx->blockState.matchState,
2955
- &cctx->workspace, params, dict, dictSize,
3113
+ &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize,
2956
3114
  dictContentType, dtlm, cctx->entropyWorkspace);
2957
- FORWARD_IF_ERROR(dictID);
3115
+ FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
2958
3116
  assert(dictID <= UINT_MAX);
2959
3117
  cctx->dictID = (U32)dictID;
2960
3118
  }
@@ -2971,7 +3129,7 @@ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
2971
3129
  {
2972
3130
  DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog);
2973
3131
  /* compression parameters verification and optimization */
2974
- FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) );
3132
+ FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) , "");
2975
3133
  return ZSTD_compressBegin_internal(cctx,
2976
3134
  dict, dictSize, dictContentType, dtlm,
2977
3135
  cdict,
@@ -2986,7 +3144,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
2986
3144
  ZSTD_parameters params, unsigned long long pledgedSrcSize)
2987
3145
  {
2988
3146
  ZSTD_CCtx_params const cctxParams =
2989
- ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
3147
+ ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
2990
3148
  return ZSTD_compressBegin_advanced_internal(cctx,
2991
3149
  dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
2992
3150
  NULL /*cdict*/,
@@ -2995,9 +3153,9 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
2995
3153
 
2996
3154
  size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
2997
3155
  {
2998
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
3156
+ ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
2999
3157
  ZSTD_CCtx_params const cctxParams =
3000
- ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
3158
+ ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
3001
3159
  DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
3002
3160
  return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
3003
3161
  &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
@@ -3024,7 +3182,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
3024
3182
  /* special case : empty frame */
3025
3183
  if (cctx->stage == ZSTDcs_init) {
3026
3184
  fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0);
3027
- FORWARD_IF_ERROR(fhSize);
3185
+ FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed");
3028
3186
  dstCapacity -= fhSize;
3029
3187
  op += fhSize;
3030
3188
  cctx->stage = ZSTDcs_ongoing;
@@ -3033,7 +3191,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
3033
3191
  if (cctx->stage != ZSTDcs_ending) {
3034
3192
  /* write one last empty block, make it the "last" block */
3035
3193
  U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
3036
- RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);
3194
+ RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for epilogue");
3037
3195
  MEM_writeLE32(op, cBlockHeader24);
3038
3196
  op += ZSTD_blockHeaderSize;
3039
3197
  dstCapacity -= ZSTD_blockHeaderSize;
@@ -3041,7 +3199,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
3041
3199
 
3042
3200
  if (cctx->appliedParams.fParams.checksumFlag) {
3043
3201
  U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
3044
- RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);
3202
+ RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
3045
3203
  DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum);
3046
3204
  MEM_writeLE32(op, checksum);
3047
3205
  op += 4;
@@ -3059,9 +3217,9 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
3059
3217
  size_t const cSize = ZSTD_compressContinue_internal(cctx,
3060
3218
  dst, dstCapacity, src, srcSize,
3061
3219
  1 /* frame mode */, 1 /* last chunk */);
3062
- FORWARD_IF_ERROR(cSize);
3220
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressContinue_internal failed");
3063
3221
  endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
3064
- FORWARD_IF_ERROR(endResult);
3222
+ FORWARD_IF_ERROR(endResult, "ZSTD_writeEpilogue failed");
3065
3223
  assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
3066
3224
  if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */
3067
3225
  ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
@@ -3081,7 +3239,7 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
3081
3239
  void* dst, size_t dstCapacity,
3082
3240
  const void* src, size_t srcSize,
3083
3241
  const void* dict,size_t dictSize,
3084
- ZSTD_parameters params)
3242
+ const ZSTD_parameters* params)
3085
3243
  {
3086
3244
  ZSTD_CCtx_params const cctxParams =
3087
3245
  ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
@@ -3100,12 +3258,12 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
3100
3258
  ZSTD_parameters params)
3101
3259
  {
3102
3260
  DEBUGLOG(4, "ZSTD_compress_advanced");
3103
- FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams));
3261
+ FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), "");
3104
3262
  return ZSTD_compress_internal(cctx,
3105
3263
  dst, dstCapacity,
3106
3264
  src, srcSize,
3107
3265
  dict, dictSize,
3108
- params);
3266
+ &params);
3109
3267
  }
3110
3268
 
3111
3269
  /* Internal */
@@ -3119,7 +3277,7 @@ size_t ZSTD_compress_advanced_internal(
3119
3277
  DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
3120
3278
  FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
3121
3279
  dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
3122
- params, srcSize, ZSTDb_not_buffered) );
3280
+ params, srcSize, ZSTDb_not_buffered) , "");
3123
3281
  return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
3124
3282
  }
3125
3283
 
@@ -3129,8 +3287,9 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
3129
3287
  const void* dict, size_t dictSize,
3130
3288
  int compressionLevel)
3131
3289
  {
3132
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);
3133
- ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
3290
+ ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0);
3291
+ ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
3292
+ DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize);
3134
3293
  assert(params.fParams.contentSizeFlag == 1);
3135
3294
  return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctxParams);
3136
3295
  }
@@ -3176,7 +3335,7 @@ size_t ZSTD_estimateCDictSize_advanced(
3176
3335
 
3177
3336
  size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
3178
3337
  {
3179
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
3338
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
3180
3339
  return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
3181
3340
  }
3182
3341
 
@@ -3203,7 +3362,7 @@ static size_t ZSTD_initCDict_internal(
3203
3362
  cdict->dictContent = dictBuffer;
3204
3363
  } else {
3205
3364
  void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
3206
- RETURN_ERROR_IF(!internalBuffer, memory_allocation);
3365
+ RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!");
3207
3366
  cdict->dictContent = internalBuffer;
3208
3367
  memcpy(internalBuffer, dictBuffer, dictSize);
3209
3368
  }
@@ -3220,7 +3379,7 @@ static size_t ZSTD_initCDict_internal(
3220
3379
  &cParams,
3221
3380
  ZSTDcrp_makeClean,
3222
3381
  ZSTDirp_reset,
3223
- ZSTD_resetTarget_CDict));
3382
+ ZSTD_resetTarget_CDict), "");
3224
3383
  /* (Maybe) load the dictionary
3225
3384
  * Skips loading the dictionary if it is < 8 bytes.
3226
3385
  */
@@ -3230,10 +3389,10 @@ static size_t ZSTD_initCDict_internal(
3230
3389
  params.fParams.contentSizeFlag = 1;
3231
3390
  params.cParams = cParams;
3232
3391
  { size_t const dictID = ZSTD_compress_insertDictionary(
3233
- &cdict->cBlockState, &cdict->matchState, &cdict->workspace,
3392
+ &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace,
3234
3393
  &params, cdict->dictContent, cdict->dictContentSize,
3235
3394
  dictContentType, ZSTD_dtlm_full, cdict->entropyWorkspace);
3236
- FORWARD_IF_ERROR(dictID);
3395
+ FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
3237
3396
  assert(dictID <= (size_t)(U32)-1);
3238
3397
  cdict->dictID = (U32)dictID;
3239
3398
  }
@@ -3287,7 +3446,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
3287
3446
 
3288
3447
  ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
3289
3448
  {
3290
- ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
3449
+ ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
3291
3450
  ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dict, dictSize,
3292
3451
  ZSTD_dlm_byCopy, ZSTD_dct_auto,
3293
3452
  cParams, ZSTD_defaultCMem);
@@ -3298,7 +3457,7 @@ ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionL
3298
3457
 
3299
3458
  ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
3300
3459
  {
3301
- ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
3460
+ ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
3302
3461
  return ZSTD_createCDict_advanced(dict, dictSize,
3303
3462
  ZSTD_dlm_byRef, ZSTD_dct_auto,
3304
3463
  cParams, ZSTD_defaultCMem);
@@ -3381,7 +3540,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
3381
3540
  ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
3382
3541
  {
3383
3542
  DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
3384
- RETURN_ERROR_IF(cdict==NULL, dictionary_wrong);
3543
+ RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!");
3385
3544
  { ZSTD_CCtx_params params = cctx->requestedParams;
3386
3545
  params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
3387
3546
  || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
@@ -3425,7 +3584,7 @@ size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
3425
3584
  const void* src, size_t srcSize,
3426
3585
  const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
3427
3586
  {
3428
- FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize)); /* will check if cdict != NULL */
3587
+ FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */
3429
3588
  return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
3430
3589
  }
3431
3590
 
@@ -3497,7 +3656,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
3497
3656
  dict, dictSize, dictContentType, ZSTD_dtlm_fast,
3498
3657
  cdict,
3499
3658
  &params, pledgedSrcSize,
3500
- ZSTDb_buffered) );
3659
+ ZSTDb_buffered) , "");
3501
3660
 
3502
3661
  cctx->inToCompress = 0;
3503
3662
  cctx->inBuffPos = 0;
@@ -3519,8 +3678,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss)
3519
3678
  */
3520
3679
  U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
3521
3680
  DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (unsigned)pledgedSrcSize);
3522
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3523
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
3681
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3682
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
3524
3683
  return 0;
3525
3684
  }
3526
3685
 
@@ -3534,16 +3693,16 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
3534
3693
  unsigned long long pledgedSrcSize)
3535
3694
  {
3536
3695
  DEBUGLOG(4, "ZSTD_initCStream_internal");
3537
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3538
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
3696
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3697
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
3539
3698
  assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
3540
3699
  zcs->requestedParams = *params;
3541
3700
  assert(!((dict) && (cdict))); /* either dict or cdict, not both */
3542
3701
  if (dict) {
3543
- FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
3702
+ FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
3544
3703
  } else {
3545
3704
  /* Dictionary is cleared if !cdict */
3546
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
3705
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
3547
3706
  }
3548
3707
  return 0;
3549
3708
  }
@@ -3556,10 +3715,10 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
3556
3715
  unsigned long long pledgedSrcSize)
3557
3716
  {
3558
3717
  DEBUGLOG(4, "ZSTD_initCStream_usingCDict_advanced");
3559
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3560
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
3718
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3719
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
3561
3720
  zcs->requestedParams.fParams = fParams;
3562
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
3721
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
3563
3722
  return 0;
3564
3723
  }
3565
3724
 
@@ -3567,8 +3726,8 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
3567
3726
  size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
3568
3727
  {
3569
3728
  DEBUGLOG(4, "ZSTD_initCStream_usingCDict");
3570
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3571
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
3729
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3730
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
3572
3731
  return 0;
3573
3732
  }
3574
3733
 
@@ -3587,20 +3746,20 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
3587
3746
  */
3588
3747
  U64 const pledgedSrcSize = (pss==0 && params.fParams.contentSizeFlag==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
3589
3748
  DEBUGLOG(4, "ZSTD_initCStream_advanced");
3590
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3591
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
3592
- FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
3593
- zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, params);
3594
- FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
3749
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3750
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
3751
+ FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
3752
+ zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, &params);
3753
+ FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
3595
3754
  return 0;
3596
3755
  }
3597
3756
 
3598
3757
  size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
3599
3758
  {
3600
3759
  DEBUGLOG(4, "ZSTD_initCStream_usingDict");
3601
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3602
- FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
3603
- FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
3760
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3761
+ FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , "");
3762
+ FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
3604
3763
  return 0;
3605
3764
  }
3606
3765
 
@@ -3612,19 +3771,19 @@ size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigne
3612
3771
  */
3613
3772
  U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
3614
3773
  DEBUGLOG(4, "ZSTD_initCStream_srcSize");
3615
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3616
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );
3617
- FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
3618
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
3774
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3775
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) , "");
3776
+ FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , "");
3777
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
3619
3778
  return 0;
3620
3779
  }
3621
3780
 
3622
3781
  size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
3623
3782
  {
3624
3783
  DEBUGLOG(4, "ZSTD_initCStream");
3625
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
3626
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );
3627
- FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
3784
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
3785
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) , "");
3786
+ FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , "");
3628
3787
  return 0;
3629
3788
  }
3630
3789
 
@@ -3637,14 +3796,6 @@ static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
3637
3796
  return hintInSize;
3638
3797
  }
3639
3798
 
3640
- static size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,
3641
- const void* src, size_t srcSize)
3642
- {
3643
- size_t const length = MIN(dstCapacity, srcSize);
3644
- if (length) memcpy(dst, src, length);
3645
- return length;
3646
- }
3647
-
3648
3799
  /** ZSTD_compressStream_generic():
3649
3800
  * internal function for all *compressStream*() variants
3650
3801
  * non-static, because can be called from zstdmt_compress.c
@@ -3655,11 +3806,11 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
3655
3806
  ZSTD_EndDirective const flushMode)
3656
3807
  {
3657
3808
  const char* const istart = (const char*)input->src;
3658
- const char* const iend = istart + input->size;
3659
- const char* ip = istart + input->pos;
3809
+ const char* const iend = input->size != 0 ? istart + input->size : istart;
3810
+ const char* ip = input->pos != 0 ? istart + input->pos : istart;
3660
3811
  char* const ostart = (char*)output->dst;
3661
- char* const oend = ostart + output->size;
3662
- char* op = ostart + output->pos;
3812
+ char* const oend = output->size != 0 ? ostart + output->size : ostart;
3813
+ char* op = output->pos != 0 ? ostart + output->pos : ostart;
3663
3814
  U32 someMoreWork = 1;
3664
3815
 
3665
3816
  /* check expectations */
@@ -3685,7 +3836,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
3685
3836
  size_t const cSize = ZSTD_compressEnd(zcs,
3686
3837
  op, oend-op, ip, iend-ip);
3687
3838
  DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
3688
- FORWARD_IF_ERROR(cSize);
3839
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed");
3689
3840
  ip = iend;
3690
3841
  op += cSize;
3691
3842
  zcs->frameEnded = 1;
@@ -3698,7 +3849,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
3698
3849
  zcs->inBuff + zcs->inBuffPos, toLoad,
3699
3850
  ip, iend-ip);
3700
3851
  zcs->inBuffPos += loaded;
3701
- ip += loaded;
3852
+ if (loaded != 0)
3853
+ ip += loaded;
3702
3854
  if ( (flushMode == ZSTD_e_continue)
3703
3855
  && (zcs->inBuffPos < zcs->inBuffTarget) ) {
3704
3856
  /* not enough input to fill full block : stop here */
@@ -3726,7 +3878,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
3726
3878
  zcs->inBuff + zcs->inToCompress, iSize) :
3727
3879
  ZSTD_compressContinue(zcs, cDst, oSize,
3728
3880
  zcs->inBuff + zcs->inToCompress, iSize);
3729
- FORWARD_IF_ERROR(cSize);
3881
+ FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
3730
3882
  zcs->frameEnded = lastBlock;
3731
3883
  /* prepare next block */
3732
3884
  zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
@@ -3758,7 +3910,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
3758
3910
  zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
3759
3911
  DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
3760
3912
  (unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);
3761
- op += flushed;
3913
+ if (flushed)
3914
+ op += flushed;
3762
3915
  zcs->outBuffFlushedSize += flushed;
3763
3916
  if (toFlush!=flushed) {
3764
3917
  /* flush not fully completed, presumably because dst is too small */
@@ -3802,7 +3955,7 @@ static size_t ZSTD_nextInputSizeHint_MTorST(const ZSTD_CCtx* cctx)
3802
3955
 
3803
3956
  size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
3804
3957
  {
3805
- FORWARD_IF_ERROR( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) );
3958
+ FORWARD_IF_ERROR( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) , "");
3806
3959
  return ZSTD_nextInputSizeHint_MTorST(zcs);
3807
3960
  }
3808
3961
 
@@ -3814,15 +3967,15 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
3814
3967
  {
3815
3968
  DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
3816
3969
  /* check conditions */
3817
- RETURN_ERROR_IF(output->pos > output->size, GENERIC);
3818
- RETURN_ERROR_IF(input->pos > input->size, GENERIC);
3970
+ RETURN_ERROR_IF(output->pos > output->size, GENERIC, "invalid buffer");
3971
+ RETURN_ERROR_IF(input->pos > input->size, GENERIC, "invalid buffer");
3819
3972
  assert(cctx!=NULL);
3820
3973
 
3821
3974
  /* transparent initialization stage */
3822
3975
  if (cctx->streamStage == zcss_init) {
3823
3976
  ZSTD_CCtx_params params = cctx->requestedParams;
3824
3977
  ZSTD_prefixDict const prefixDict = cctx->prefixDict;
3825
- FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) ); /* Init the local dict if present. */
3978
+ FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */
3826
3979
  memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
3827
3980
  assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
3828
3981
  DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
@@ -3841,14 +3994,14 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
3841
3994
  DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
3842
3995
  params.nbWorkers);
3843
3996
  cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem);
3844
- RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation);
3997
+ RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!");
3845
3998
  }
3846
3999
  /* mt compression */
3847
4000
  DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
3848
4001
  FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(
3849
4002
  cctx->mtctx,
3850
- prefixDict.dict, prefixDict.dictSize, ZSTD_dct_rawContent,
3851
- cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
4003
+ prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
4004
+ cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
3852
4005
  cctx->streamStage = zcss_load;
3853
4006
  cctx->appliedParams.nbWorkers = params.nbWorkers;
3854
4007
  } else
@@ -3856,7 +4009,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
3856
4009
  { FORWARD_IF_ERROR( ZSTD_resetCStream_internal(cctx,
3857
4010
  prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
3858
4011
  cctx->cdict,
3859
- params, cctx->pledgedSrcSizePlusOne-1) );
4012
+ params, cctx->pledgedSrcSizePlusOne-1) , "");
3860
4013
  assert(cctx->streamStage == zcss_load);
3861
4014
  assert(cctx->appliedParams.nbWorkers == 0);
3862
4015
  } }
@@ -3878,7 +4031,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
3878
4031
  || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
3879
4032
  ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
3880
4033
  }
3881
- FORWARD_IF_ERROR(flushMin);
4034
+ FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed");
3882
4035
  } while (forceMaxProgress && flushMin != 0 && output->pos < output->size);
3883
4036
  DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
3884
4037
  /* Either we don't require maximum forward progress, we've finished the
@@ -3888,7 +4041,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
3888
4041
  return flushMin;
3889
4042
  }
3890
4043
  #endif
3891
- FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) );
4044
+ FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) , "");
3892
4045
  DEBUGLOG(5, "completed ZSTD_compressStream2");
3893
4046
  return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
3894
4047
  }
@@ -3912,6 +4065,7 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
3912
4065
  void* dst, size_t dstCapacity,
3913
4066
  const void* src, size_t srcSize)
3914
4067
  {
4068
+ DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize);
3915
4069
  ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
3916
4070
  { size_t oPos = 0;
3917
4071
  size_t iPos = 0;
@@ -3919,10 +4073,10 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
3919
4073
  dst, dstCapacity, &oPos,
3920
4074
  src, srcSize, &iPos,
3921
4075
  ZSTD_e_end);
3922
- FORWARD_IF_ERROR(result);
4076
+ FORWARD_IF_ERROR(result, "ZSTD_compressStream2_simpleArgs failed");
3923
4077
  if (result != 0) { /* compression not completed, due to lack of output space */
3924
4078
  assert(oPos == dstCapacity);
3925
- RETURN_ERROR(dstSize_tooSmall);
4079
+ RETURN_ERROR(dstSize_tooSmall, "");
3926
4080
  }
3927
4081
  assert(iPos == srcSize); /* all input is expected consumed */
3928
4082
  return oPos;
@@ -3944,7 +4098,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
3944
4098
  {
3945
4099
  ZSTD_inBuffer input = { NULL, 0, 0 };
3946
4100
  size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
3947
- FORWARD_IF_ERROR( remainingToFlush );
4101
+ FORWARD_IF_ERROR( remainingToFlush , "ZSTD_compressStream2 failed");
3948
4102
  if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush; /* minimal estimation */
3949
4103
  /* single thread mode : attempt to calculate remaining to flush more precisely */
3950
4104
  { size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
@@ -4069,35 +4223,56 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
4069
4223
  },
4070
4224
  };
4071
4225
 
4072
- /*! ZSTD_getCParams() :
4226
+ /*! ZSTD_getCParams_internal() :
4073
4227
  * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
4074
- * Size values are optional, provide 0 if not known or unused */
4075
- ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
4228
+ * Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown.
4229
+ * Use dictSize == 0 for unknown or unused. */
4230
+ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
4076
4231
  {
4077
- size_t const addedSize = srcSizeHint ? 0 : 500;
4078
- U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : ZSTD_CONTENTSIZE_UNKNOWN; /* intentional overflow for srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN */
4232
+ int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN;
4233
+ size_t const addedSize = unknown && dictSize > 0 ? 500 : 0;
4234
+ U64 const rSize = unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize;
4079
4235
  U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
4080
4236
  int row = compressionLevel;
4081
- DEBUGLOG(5, "ZSTD_getCParams (cLevel=%i)", compressionLevel);
4237
+ DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel);
4082
4238
  if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
4083
4239
  if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */
4084
4240
  if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
4085
4241
  { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
4086
4242
  if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel); /* acceleration factor */
4087
- return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); /* refine parameters based on srcSize & dictSize */
4243
+ /* refine parameters based on srcSize & dictSize */
4244
+ return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);
4088
4245
  }
4089
4246
  }
4090
4247
 
4248
+ /*! ZSTD_getCParams() :
4249
+ * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
4250
+ * Size values are optional, provide 0 if not known or unused */
4251
+ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
4252
+ {
4253
+ if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
4254
+ return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
4255
+ }
4256
+
4091
4257
  /*! ZSTD_getParams() :
4092
4258
  * same idea as ZSTD_getCParams()
4093
4259
  * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
4094
4260
  * Fields of `ZSTD_frameParameters` are set to default values */
4095
- ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
4261
+ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
4096
4262
  ZSTD_parameters params;
4097
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);
4263
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
4098
4264
  DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
4099
4265
  memset(&params, 0, sizeof(params));
4100
4266
  params.cParams = cParams;
4101
4267
  params.fParams.contentSizeFlag = 1;
4102
4268
  return params;
4103
4269
  }
4270
+
4271
+ /*! ZSTD_getParams() :
4272
+ * same idea as ZSTD_getCParams()
4273
+ * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
4274
+ * Fields of `ZSTD_frameParameters` are set to default values */
4275
+ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
4276
+ if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
4277
+ return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize);
4278
+ }