contrib/python-zstandard/zstd/compress/zstd_compress.c
changeset 42070 675775c33ab6
parent 40121 73fef626dae3
child 42937 69de49c4e39c
equal deleted inserted replaced
42069:668eff08387f 42070:675775c33ab6
     9  */
     9  */
    10 
    10 
    11 /*-*************************************
    11 /*-*************************************
    12 *  Dependencies
    12 *  Dependencies
    13 ***************************************/
    13 ***************************************/
       
    14 #include <limits.h>         /* INT_MAX */
    14 #include <string.h>         /* memset */
    15 #include <string.h>         /* memset */
    15 #include "cpu.h"
    16 #include "cpu.h"
    16 #include "mem.h"
    17 #include "mem.h"
    17 #include "hist.h"           /* HIST_countFast_wksp */
    18 #include "hist.h"           /* HIST_countFast_wksp */
    18 #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
    19 #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
    59 {
    60 {
    60     assert(cctx != NULL);
    61     assert(cctx != NULL);
    61     memset(cctx, 0, sizeof(*cctx));
    62     memset(cctx, 0, sizeof(*cctx));
    62     cctx->customMem = memManager;
    63     cctx->customMem = memManager;
    63     cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
    64     cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
    64     {   size_t const err = ZSTD_CCtx_resetParameters(cctx);
    65     {   size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters);
    65         assert(!ZSTD_isError(err));
    66         assert(!ZSTD_isError(err));
    66         (void)err;
    67         (void)err;
    67     }
    68     }
    68 }
    69 }
    69 
    70 
   126 static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
   127 static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
   127 {
   128 {
   128 #ifdef ZSTD_MULTITHREAD
   129 #ifdef ZSTD_MULTITHREAD
   129     return ZSTDMT_sizeof_CCtx(cctx->mtctx);
   130     return ZSTDMT_sizeof_CCtx(cctx->mtctx);
   130 #else
   131 #else
   131     (void) cctx;
   132     (void)cctx;
   132     return 0;
   133     return 0;
   133 #endif
   134 #endif
   134 }
   135 }
   135 
   136 
   136 
   137 
   224     ret.compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* should not matter, as all cParams are presumed properly defined */
   225     ret.compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* should not matter, as all cParams are presumed properly defined */
   225     assert(!ZSTD_checkCParams(params.cParams));
   226     assert(!ZSTD_checkCParams(params.cParams));
   226     return ret;
   227     return ret;
   227 }
   228 }
   228 
   229 
   229 #define CLAMPCHECK(val,min,max) {            \
   230 ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
   230     if (((val)<(min)) | ((val)>(max))) {     \
   231 {
   231         return ERROR(parameter_outOfBound);  \
   232     ZSTD_bounds bounds = { 0, 0, 0 };
   232 }   }
   233 
   233 
       
   234 
       
   235 static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
       
   236 {
       
   237     switch(param)
   234     switch(param)
   238     {
   235     {
   239     case ZSTD_p_compressionLevel:
   236     case ZSTD_c_compressionLevel:
   240     case ZSTD_p_hashLog:
   237         bounds.lowerBound = ZSTD_minCLevel();
   241     case ZSTD_p_chainLog:
   238         bounds.upperBound = ZSTD_maxCLevel();
   242     case ZSTD_p_searchLog:
   239         return bounds;
   243     case ZSTD_p_minMatch:
   240 
   244     case ZSTD_p_targetLength:
   241     case ZSTD_c_windowLog:
   245     case ZSTD_p_compressionStrategy:
   242         bounds.lowerBound = ZSTD_WINDOWLOG_MIN;
       
   243         bounds.upperBound = ZSTD_WINDOWLOG_MAX;
       
   244         return bounds;
       
   245 
       
   246     case ZSTD_c_hashLog:
       
   247         bounds.lowerBound = ZSTD_HASHLOG_MIN;
       
   248         bounds.upperBound = ZSTD_HASHLOG_MAX;
       
   249         return bounds;
       
   250 
       
   251     case ZSTD_c_chainLog:
       
   252         bounds.lowerBound = ZSTD_CHAINLOG_MIN;
       
   253         bounds.upperBound = ZSTD_CHAINLOG_MAX;
       
   254         return bounds;
       
   255 
       
   256     case ZSTD_c_searchLog:
       
   257         bounds.lowerBound = ZSTD_SEARCHLOG_MIN;
       
   258         bounds.upperBound = ZSTD_SEARCHLOG_MAX;
       
   259         return bounds;
       
   260 
       
   261     case ZSTD_c_minMatch:
       
   262         bounds.lowerBound = ZSTD_MINMATCH_MIN;
       
   263         bounds.upperBound = ZSTD_MINMATCH_MAX;
       
   264         return bounds;
       
   265 
       
   266     case ZSTD_c_targetLength:
       
   267         bounds.lowerBound = ZSTD_TARGETLENGTH_MIN;
       
   268         bounds.upperBound = ZSTD_TARGETLENGTH_MAX;
       
   269         return bounds;
       
   270 
       
   271     case ZSTD_c_strategy:
       
   272         bounds.lowerBound = ZSTD_STRATEGY_MIN;
       
   273         bounds.upperBound = ZSTD_STRATEGY_MAX;
       
   274         return bounds;
       
   275 
       
   276     case ZSTD_c_contentSizeFlag:
       
   277         bounds.lowerBound = 0;
       
   278         bounds.upperBound = 1;
       
   279         return bounds;
       
   280 
       
   281     case ZSTD_c_checksumFlag:
       
   282         bounds.lowerBound = 0;
       
   283         bounds.upperBound = 1;
       
   284         return bounds;
       
   285 
       
   286     case ZSTD_c_dictIDFlag:
       
   287         bounds.lowerBound = 0;
       
   288         bounds.upperBound = 1;
       
   289         return bounds;
       
   290 
       
   291     case ZSTD_c_nbWorkers:
       
   292         bounds.lowerBound = 0;
       
   293 #ifdef ZSTD_MULTITHREAD
       
   294         bounds.upperBound = ZSTDMT_NBWORKERS_MAX;
       
   295 #else
       
   296         bounds.upperBound = 0;
       
   297 #endif
       
   298         return bounds;
       
   299 
       
   300     case ZSTD_c_jobSize:
       
   301         bounds.lowerBound = 0;
       
   302 #ifdef ZSTD_MULTITHREAD
       
   303         bounds.upperBound = ZSTDMT_JOBSIZE_MAX;
       
   304 #else
       
   305         bounds.upperBound = 0;
       
   306 #endif
       
   307         return bounds;
       
   308 
       
   309     case ZSTD_c_overlapLog:
       
   310         bounds.lowerBound = ZSTD_OVERLAPLOG_MIN;
       
   311         bounds.upperBound = ZSTD_OVERLAPLOG_MAX;
       
   312         return bounds;
       
   313 
       
   314     case ZSTD_c_enableLongDistanceMatching:
       
   315         bounds.lowerBound = 0;
       
   316         bounds.upperBound = 1;
       
   317         return bounds;
       
   318 
       
   319     case ZSTD_c_ldmHashLog:
       
   320         bounds.lowerBound = ZSTD_LDM_HASHLOG_MIN;
       
   321         bounds.upperBound = ZSTD_LDM_HASHLOG_MAX;
       
   322         return bounds;
       
   323 
       
   324     case ZSTD_c_ldmMinMatch:
       
   325         bounds.lowerBound = ZSTD_LDM_MINMATCH_MIN;
       
   326         bounds.upperBound = ZSTD_LDM_MINMATCH_MAX;
       
   327         return bounds;
       
   328 
       
   329     case ZSTD_c_ldmBucketSizeLog:
       
   330         bounds.lowerBound = ZSTD_LDM_BUCKETSIZELOG_MIN;
       
   331         bounds.upperBound = ZSTD_LDM_BUCKETSIZELOG_MAX;
       
   332         return bounds;
       
   333 
       
   334     case ZSTD_c_ldmHashRateLog:
       
   335         bounds.lowerBound = ZSTD_LDM_HASHRATELOG_MIN;
       
   336         bounds.upperBound = ZSTD_LDM_HASHRATELOG_MAX;
       
   337         return bounds;
       
   338 
       
   339     /* experimental parameters */
       
   340     case ZSTD_c_rsyncable:
       
   341         bounds.lowerBound = 0;
       
   342         bounds.upperBound = 1;
       
   343         return bounds;
       
   344 
       
   345     case ZSTD_c_forceMaxWindow :
       
   346         bounds.lowerBound = 0;
       
   347         bounds.upperBound = 1;
       
   348         return bounds;
       
   349 
       
   350     case ZSTD_c_format:
       
   351         ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
       
   352         bounds.lowerBound = ZSTD_f_zstd1;
       
   353         bounds.upperBound = ZSTD_f_zstd1_magicless;   /* note : how to ensure at compile time that this is the highest value enum ? */
       
   354         return bounds;
       
   355 
       
   356     case ZSTD_c_forceAttachDict:
       
   357         ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceCopy);
       
   358         bounds.lowerBound = ZSTD_dictDefaultAttach;
       
   359         bounds.upperBound = ZSTD_dictForceCopy;       /* note : how to ensure at compile time that this is the highest value enum ? */
       
   360         return bounds;
       
   361 
       
   362     default:
       
   363         {   ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };
       
   364             return boundError;
       
   365         }
       
   366     }
       
   367 }
       
   368 
       
   369 /* ZSTD_cParam_withinBounds:
       
   370  * @return 1 if value is within cParam bounds,
       
   371  * 0 otherwise */
       
   372 static int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
       
   373 {
       
   374     ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
       
   375     if (ZSTD_isError(bounds.error)) return 0;
       
   376     if (value < bounds.lowerBound) return 0;
       
   377     if (value > bounds.upperBound) return 0;
       
   378     return 1;
       
   379 }
       
   380 
       
   381 #define BOUNDCHECK(cParam, val) {                  \
       
   382     if (!ZSTD_cParam_withinBounds(cParam,val)) {   \
       
   383         return ERROR(parameter_outOfBound);        \
       
   384 }   }
       
   385 
       
   386 
       
   387 static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
       
   388 {
       
   389     switch(param)
       
   390     {
       
   391     case ZSTD_c_compressionLevel:
       
   392     case ZSTD_c_hashLog:
       
   393     case ZSTD_c_chainLog:
       
   394     case ZSTD_c_searchLog:
       
   395     case ZSTD_c_minMatch:
       
   396     case ZSTD_c_targetLength:
       
   397     case ZSTD_c_strategy:
   246         return 1;
   398         return 1;
   247 
   399 
   248     case ZSTD_p_format:
   400     case ZSTD_c_format:
   249     case ZSTD_p_windowLog:
   401     case ZSTD_c_windowLog:
   250     case ZSTD_p_contentSizeFlag:
   402     case ZSTD_c_contentSizeFlag:
   251     case ZSTD_p_checksumFlag:
   403     case ZSTD_c_checksumFlag:
   252     case ZSTD_p_dictIDFlag:
   404     case ZSTD_c_dictIDFlag:
   253     case ZSTD_p_forceMaxWindow :
   405     case ZSTD_c_forceMaxWindow :
   254     case ZSTD_p_nbWorkers:
   406     case ZSTD_c_nbWorkers:
   255     case ZSTD_p_jobSize:
   407     case ZSTD_c_jobSize:
   256     case ZSTD_p_overlapSizeLog:
   408     case ZSTD_c_overlapLog:
   257     case ZSTD_p_enableLongDistanceMatching:
   409     case ZSTD_c_rsyncable:
   258     case ZSTD_p_ldmHashLog:
   410     case ZSTD_c_enableLongDistanceMatching:
   259     case ZSTD_p_ldmMinMatch:
   411     case ZSTD_c_ldmHashLog:
   260     case ZSTD_p_ldmBucketSizeLog:
   412     case ZSTD_c_ldmMinMatch:
   261     case ZSTD_p_ldmHashEveryLog:
   413     case ZSTD_c_ldmBucketSizeLog:
   262     case ZSTD_p_forceAttachDict:
   414     case ZSTD_c_ldmHashRateLog:
       
   415     case ZSTD_c_forceAttachDict:
   263     default:
   416     default:
   264         return 0;
   417         return 0;
   265     }
   418     }
   266 }
   419 }
   267 
   420 
   268 size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
   421 size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
   269 {
   422 {
   270     DEBUGLOG(4, "ZSTD_CCtx_setParameter (%u, %u)", (U32)param, value);
   423     DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value);
   271     if (cctx->streamStage != zcss_init) {
   424     if (cctx->streamStage != zcss_init) {
   272         if (ZSTD_isUpdateAuthorized(param)) {
   425         if (ZSTD_isUpdateAuthorized(param)) {
   273             cctx->cParamsChanged = 1;
   426             cctx->cParamsChanged = 1;
   274         } else {
   427         } else {
   275             return ERROR(stage_wrong);
   428             return ERROR(stage_wrong);
   276     }   }
   429     }   }
   277 
   430 
   278     switch(param)
   431     switch(param)
   279     {
   432     {
   280     case ZSTD_p_format :
   433     case ZSTD_c_format :
   281         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   434         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   282 
   435 
   283     case ZSTD_p_compressionLevel:
   436     case ZSTD_c_compressionLevel:
   284         if (cctx->cdict) return ERROR(stage_wrong);
   437         if (cctx->cdict) return ERROR(stage_wrong);
   285         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   438         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   286 
   439 
   287     case ZSTD_p_windowLog:
   440     case ZSTD_c_windowLog:
   288     case ZSTD_p_hashLog:
   441     case ZSTD_c_hashLog:
   289     case ZSTD_p_chainLog:
   442     case ZSTD_c_chainLog:
   290     case ZSTD_p_searchLog:
   443     case ZSTD_c_searchLog:
   291     case ZSTD_p_minMatch:
   444     case ZSTD_c_minMatch:
   292     case ZSTD_p_targetLength:
   445     case ZSTD_c_targetLength:
   293     case ZSTD_p_compressionStrategy:
   446     case ZSTD_c_strategy:
   294         if (cctx->cdict) return ERROR(stage_wrong);
   447         if (cctx->cdict) return ERROR(stage_wrong);
   295         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   448         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   296 
   449 
   297     case ZSTD_p_contentSizeFlag:
   450     case ZSTD_c_contentSizeFlag:
   298     case ZSTD_p_checksumFlag:
   451     case ZSTD_c_checksumFlag:
   299     case ZSTD_p_dictIDFlag:
   452     case ZSTD_c_dictIDFlag:
   300         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   453         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   301 
   454 
   302     case ZSTD_p_forceMaxWindow :  /* Force back-references to remain < windowSize,
   455     case ZSTD_c_forceMaxWindow :  /* Force back-references to remain < windowSize,
   303                                    * even when referencing into Dictionary content.
   456                                    * even when referencing into Dictionary content.
   304                                    * default : 0 when using a CDict, 1 when using a Prefix */
   457                                    * default : 0 when using a CDict, 1 when using a Prefix */
   305         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   458         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   306 
   459 
   307     case ZSTD_p_forceAttachDict:
   460     case ZSTD_c_forceAttachDict:
   308         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   461         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   309 
   462 
   310     case ZSTD_p_nbWorkers:
   463     case ZSTD_c_nbWorkers:
   311         if ((value>0) && cctx->staticSize) {
   464         if ((value!=0) && cctx->staticSize) {
   312             return ERROR(parameter_unsupported);  /* MT not compatible with static alloc */
   465             return ERROR(parameter_unsupported);  /* MT not compatible with static alloc */
   313         }
   466         }
   314         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   467         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   315 
   468 
   316     case ZSTD_p_jobSize:
   469     case ZSTD_c_jobSize:
   317     case ZSTD_p_overlapSizeLog:
   470     case ZSTD_c_overlapLog:
       
   471     case ZSTD_c_rsyncable:
   318         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   472         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   319 
   473 
   320     case ZSTD_p_enableLongDistanceMatching:
   474     case ZSTD_c_enableLongDistanceMatching:
   321     case ZSTD_p_ldmHashLog:
   475     case ZSTD_c_ldmHashLog:
   322     case ZSTD_p_ldmMinMatch:
   476     case ZSTD_c_ldmMinMatch:
   323     case ZSTD_p_ldmBucketSizeLog:
   477     case ZSTD_c_ldmBucketSizeLog:
   324     case ZSTD_p_ldmHashEveryLog:
   478     case ZSTD_c_ldmHashRateLog:
   325         if (cctx->cdict) return ERROR(stage_wrong);
   479         if (cctx->cdict) return ERROR(stage_wrong);
   326         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   480         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   327 
   481 
   328     default: return ERROR(parameter_unsupported);
   482     default: return ERROR(parameter_unsupported);
   329     }
   483     }
   330 }
   484 }
   331 
   485 
   332 size_t ZSTD_CCtxParam_setParameter(
   486 size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* CCtxParams,
   333         ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, unsigned value)
   487                                    ZSTD_cParameter param, int value)
   334 {
   488 {
   335     DEBUGLOG(4, "ZSTD_CCtxParam_setParameter (%u, %u)", (U32)param, value);
   489     DEBUGLOG(4, "ZSTD_CCtxParam_setParameter (%i, %i)", (int)param, value);
   336     switch(param)
   490     switch(param)
   337     {
   491     {
   338     case ZSTD_p_format :
   492     case ZSTD_c_format :
   339         if (value > (unsigned)ZSTD_f_zstd1_magicless)
   493         BOUNDCHECK(ZSTD_c_format, value);
   340             return ERROR(parameter_unsupported);
       
   341         CCtxParams->format = (ZSTD_format_e)value;
   494         CCtxParams->format = (ZSTD_format_e)value;
   342         return (size_t)CCtxParams->format;
   495         return (size_t)CCtxParams->format;
   343 
   496 
   344     case ZSTD_p_compressionLevel : {
   497     case ZSTD_c_compressionLevel : {
   345         int cLevel = (int)value;  /* cast expected to restore negative sign */
   498         int cLevel = value;
   346         if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
   499         if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
       
   500         if (cLevel < ZSTD_minCLevel()) cLevel = ZSTD_minCLevel();
   347         if (cLevel) {  /* 0 : does not change current level */
   501         if (cLevel) {  /* 0 : does not change current level */
   348             CCtxParams->compressionLevel = cLevel;
   502             CCtxParams->compressionLevel = cLevel;
   349         }
   503         }
   350         if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
   504         if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
   351         return 0;  /* return type (size_t) cannot represent negative values */
   505         return 0;  /* return type (size_t) cannot represent negative values */
   352     }
   506     }
   353 
   507 
   354     case ZSTD_p_windowLog :
   508     case ZSTD_c_windowLog :
   355         if (value>0)   /* 0 => use default */
   509         if (value!=0)   /* 0 => use default */
   356             CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
   510             BOUNDCHECK(ZSTD_c_windowLog, value);
   357         CCtxParams->cParams.windowLog = value;
   511         CCtxParams->cParams.windowLog = value;
   358         return CCtxParams->cParams.windowLog;
   512         return CCtxParams->cParams.windowLog;
   359 
   513 
   360     case ZSTD_p_hashLog :
   514     case ZSTD_c_hashLog :
   361         if (value>0)   /* 0 => use default */
   515         if (value!=0)   /* 0 => use default */
   362             CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   516             BOUNDCHECK(ZSTD_c_hashLog, value);
   363         CCtxParams->cParams.hashLog = value;
   517         CCtxParams->cParams.hashLog = value;
   364         return CCtxParams->cParams.hashLog;
   518         return CCtxParams->cParams.hashLog;
   365 
   519 
   366     case ZSTD_p_chainLog :
   520     case ZSTD_c_chainLog :
   367         if (value>0)   /* 0 => use default */
   521         if (value!=0)   /* 0 => use default */
   368             CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
   522             BOUNDCHECK(ZSTD_c_chainLog, value);
   369         CCtxParams->cParams.chainLog = value;
   523         CCtxParams->cParams.chainLog = value;
   370         return CCtxParams->cParams.chainLog;
   524         return CCtxParams->cParams.chainLog;
   371 
   525 
   372     case ZSTD_p_searchLog :
   526     case ZSTD_c_searchLog :
   373         if (value>0)   /* 0 => use default */
   527         if (value!=0)   /* 0 => use default */
   374             CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
   528             BOUNDCHECK(ZSTD_c_searchLog, value);
   375         CCtxParams->cParams.searchLog = value;
   529         CCtxParams->cParams.searchLog = value;
   376         return value;
   530         return value;
   377 
   531 
   378     case ZSTD_p_minMatch :
   532     case ZSTD_c_minMatch :
   379         if (value>0)   /* 0 => use default */
   533         if (value!=0)   /* 0 => use default */
   380             CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
   534             BOUNDCHECK(ZSTD_c_minMatch, value);
   381         CCtxParams->cParams.searchLength = value;
   535         CCtxParams->cParams.minMatch = value;
   382         return CCtxParams->cParams.searchLength;
   536         return CCtxParams->cParams.minMatch;
   383 
   537 
   384     case ZSTD_p_targetLength :
   538     case ZSTD_c_targetLength :
   385         /* all values are valid. 0 => use default */
   539         BOUNDCHECK(ZSTD_c_targetLength, value);
   386         CCtxParams->cParams.targetLength = value;
   540         CCtxParams->cParams.targetLength = value;
   387         return CCtxParams->cParams.targetLength;
   541         return CCtxParams->cParams.targetLength;
   388 
   542 
   389     case ZSTD_p_compressionStrategy :
   543     case ZSTD_c_strategy :
   390         if (value>0)   /* 0 => use default */
   544         if (value!=0)   /* 0 => use default */
   391             CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
   545             BOUNDCHECK(ZSTD_c_strategy, value);
   392         CCtxParams->cParams.strategy = (ZSTD_strategy)value;
   546         CCtxParams->cParams.strategy = (ZSTD_strategy)value;
   393         return (size_t)CCtxParams->cParams.strategy;
   547         return (size_t)CCtxParams->cParams.strategy;
   394 
   548 
   395     case ZSTD_p_contentSizeFlag :
   549     case ZSTD_c_contentSizeFlag :
   396         /* Content size written in frame header _when known_ (default:1) */
   550         /* Content size written in frame header _when known_ (default:1) */
   397         DEBUGLOG(4, "set content size flag = %u", (value>0));
   551         DEBUGLOG(4, "set content size flag = %u", (value!=0));
   398         CCtxParams->fParams.contentSizeFlag = value > 0;
   552         CCtxParams->fParams.contentSizeFlag = value != 0;
   399         return CCtxParams->fParams.contentSizeFlag;
   553         return CCtxParams->fParams.contentSizeFlag;
   400 
   554 
   401     case ZSTD_p_checksumFlag :
   555     case ZSTD_c_checksumFlag :
   402         /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
   556         /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
   403         CCtxParams->fParams.checksumFlag = value > 0;
   557         CCtxParams->fParams.checksumFlag = value != 0;
   404         return CCtxParams->fParams.checksumFlag;
   558         return CCtxParams->fParams.checksumFlag;
   405 
   559 
   406     case ZSTD_p_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
   560     case ZSTD_c_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
   407         DEBUGLOG(4, "set dictIDFlag = %u", (value>0));
   561         DEBUGLOG(4, "set dictIDFlag = %u", (value!=0));
   408         CCtxParams->fParams.noDictIDFlag = !value;
   562         CCtxParams->fParams.noDictIDFlag = !value;
   409         return !CCtxParams->fParams.noDictIDFlag;
   563         return !CCtxParams->fParams.noDictIDFlag;
   410 
   564 
   411     case ZSTD_p_forceMaxWindow :
   565     case ZSTD_c_forceMaxWindow :
   412         CCtxParams->forceWindow = (value > 0);
   566         CCtxParams->forceWindow = (value != 0);
   413         return CCtxParams->forceWindow;
   567         return CCtxParams->forceWindow;
   414 
   568 
   415     case ZSTD_p_forceAttachDict :
   569     case ZSTD_c_forceAttachDict : {
   416         CCtxParams->attachDictPref = value ?
   570         const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value;
   417                                     (value > 0 ? ZSTD_dictForceAttach : ZSTD_dictForceCopy) :
   571         BOUNDCHECK(ZSTD_c_forceAttachDict, pref);
   418                                      ZSTD_dictDefaultAttach;
   572         CCtxParams->attachDictPref = pref;
   419         return CCtxParams->attachDictPref;
   573         return CCtxParams->attachDictPref;
   420 
   574     }
   421     case ZSTD_p_nbWorkers :
   575 
       
   576     case ZSTD_c_nbWorkers :
   422 #ifndef ZSTD_MULTITHREAD
   577 #ifndef ZSTD_MULTITHREAD
   423         if (value>0) return ERROR(parameter_unsupported);
   578         if (value!=0) return ERROR(parameter_unsupported);
   424         return 0;
   579         return 0;
   425 #else
   580 #else
   426         return ZSTDMT_CCtxParam_setNbWorkers(CCtxParams, value);
   581         return ZSTDMT_CCtxParam_setNbWorkers(CCtxParams, value);
   427 #endif
   582 #endif
   428 
   583 
   429     case ZSTD_p_jobSize :
   584     case ZSTD_c_jobSize :
   430 #ifndef ZSTD_MULTITHREAD
   585 #ifndef ZSTD_MULTITHREAD
   431         return ERROR(parameter_unsupported);
   586         return ERROR(parameter_unsupported);
   432 #else
   587 #else
   433         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_jobSize, value);
   588         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_jobSize, value);
   434 #endif
   589 #endif
   435 
   590 
   436     case ZSTD_p_overlapSizeLog :
   591     case ZSTD_c_overlapLog :
   437 #ifndef ZSTD_MULTITHREAD
   592 #ifndef ZSTD_MULTITHREAD
   438         return ERROR(parameter_unsupported);
   593         return ERROR(parameter_unsupported);
   439 #else
   594 #else
   440         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_overlapSectionLog, value);
   595         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_overlapLog, value);
   441 #endif
   596 #endif
   442 
   597 
   443     case ZSTD_p_enableLongDistanceMatching :
   598     case ZSTD_c_rsyncable :
   444         CCtxParams->ldmParams.enableLdm = (value>0);
   599 #ifndef ZSTD_MULTITHREAD
       
   600         return ERROR(parameter_unsupported);
       
   601 #else
       
   602         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_rsyncable, value);
       
   603 #endif
       
   604 
       
   605     case ZSTD_c_enableLongDistanceMatching :
       
   606         CCtxParams->ldmParams.enableLdm = (value!=0);
   445         return CCtxParams->ldmParams.enableLdm;
   607         return CCtxParams->ldmParams.enableLdm;
   446 
   608 
   447     case ZSTD_p_ldmHashLog :
   609     case ZSTD_c_ldmHashLog :
   448         if (value>0)   /* 0 ==> auto */
   610         if (value!=0)   /* 0 ==> auto */
   449             CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   611             BOUNDCHECK(ZSTD_c_ldmHashLog, value);
   450         CCtxParams->ldmParams.hashLog = value;
   612         CCtxParams->ldmParams.hashLog = value;
   451         return CCtxParams->ldmParams.hashLog;
   613         return CCtxParams->ldmParams.hashLog;
   452 
   614 
   453     case ZSTD_p_ldmMinMatch :
   615     case ZSTD_c_ldmMinMatch :
   454         if (value>0)   /* 0 ==> default */
   616         if (value!=0)   /* 0 ==> default */
   455             CLAMPCHECK(value, ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX);
   617             BOUNDCHECK(ZSTD_c_ldmMinMatch, value);
   456         CCtxParams->ldmParams.minMatchLength = value;
   618         CCtxParams->ldmParams.minMatchLength = value;
   457         return CCtxParams->ldmParams.minMatchLength;
   619         return CCtxParams->ldmParams.minMatchLength;
   458 
   620 
   459     case ZSTD_p_ldmBucketSizeLog :
   621     case ZSTD_c_ldmBucketSizeLog :
   460         if (value > ZSTD_LDM_BUCKETSIZELOG_MAX)
   622         if (value!=0)   /* 0 ==> default */
   461             return ERROR(parameter_outOfBound);
   623             BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value);
   462         CCtxParams->ldmParams.bucketSizeLog = value;
   624         CCtxParams->ldmParams.bucketSizeLog = value;
   463         return CCtxParams->ldmParams.bucketSizeLog;
   625         return CCtxParams->ldmParams.bucketSizeLog;
   464 
   626 
   465     case ZSTD_p_ldmHashEveryLog :
   627     case ZSTD_c_ldmHashRateLog :
   466         if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)
   628         if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)
   467             return ERROR(parameter_outOfBound);
   629             return ERROR(parameter_outOfBound);
   468         CCtxParams->ldmParams.hashEveryLog = value;
   630         CCtxParams->ldmParams.hashRateLog = value;
   469         return CCtxParams->ldmParams.hashEveryLog;
   631         return CCtxParams->ldmParams.hashRateLog;
   470 
   632 
   471     default: return ERROR(parameter_unsupported);
   633     default: return ERROR(parameter_unsupported);
   472     }
   634     }
   473 }
   635 }
   474 
   636 
   475 size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned* value)
   637 size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value)
   476 {
   638 {
   477     return ZSTD_CCtxParam_getParameter(&cctx->requestedParams, param, value);
   639     return ZSTD_CCtxParam_getParameter(&cctx->requestedParams, param, value);
   478 }
   640 }
   479 
   641 
   480 size_t ZSTD_CCtxParam_getParameter(
   642 size_t ZSTD_CCtxParam_getParameter(
   481         ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, unsigned* value)
   643         ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, int* value)
   482 {
   644 {
   483     switch(param)
   645     switch(param)
   484     {
   646     {
   485     case ZSTD_p_format :
   647     case ZSTD_c_format :
   486         *value = CCtxParams->format;
   648         *value = CCtxParams->format;
   487         break;
   649         break;
   488     case ZSTD_p_compressionLevel :
   650     case ZSTD_c_compressionLevel :
   489         *value = CCtxParams->compressionLevel;
   651         *value = CCtxParams->compressionLevel;
   490         break;
   652         break;
   491     case ZSTD_p_windowLog :
   653     case ZSTD_c_windowLog :
   492         *value = CCtxParams->cParams.windowLog;
   654         *value = CCtxParams->cParams.windowLog;
   493         break;
   655         break;
   494     case ZSTD_p_hashLog :
   656     case ZSTD_c_hashLog :
   495         *value = CCtxParams->cParams.hashLog;
   657         *value = CCtxParams->cParams.hashLog;
   496         break;
   658         break;
   497     case ZSTD_p_chainLog :
   659     case ZSTD_c_chainLog :
   498         *value = CCtxParams->cParams.chainLog;
   660         *value = CCtxParams->cParams.chainLog;
   499         break;
   661         break;
   500     case ZSTD_p_searchLog :
   662     case ZSTD_c_searchLog :
   501         *value = CCtxParams->cParams.searchLog;
   663         *value = CCtxParams->cParams.searchLog;
   502         break;
   664         break;
   503     case ZSTD_p_minMatch :
   665     case ZSTD_c_minMatch :
   504         *value = CCtxParams->cParams.searchLength;
   666         *value = CCtxParams->cParams.minMatch;
   505         break;
   667         break;
   506     case ZSTD_p_targetLength :
   668     case ZSTD_c_targetLength :
   507         *value = CCtxParams->cParams.targetLength;
   669         *value = CCtxParams->cParams.targetLength;
   508         break;
   670         break;
   509     case ZSTD_p_compressionStrategy :
   671     case ZSTD_c_strategy :
   510         *value = (unsigned)CCtxParams->cParams.strategy;
   672         *value = (unsigned)CCtxParams->cParams.strategy;
   511         break;
   673         break;
   512     case ZSTD_p_contentSizeFlag :
   674     case ZSTD_c_contentSizeFlag :
   513         *value = CCtxParams->fParams.contentSizeFlag;
   675         *value = CCtxParams->fParams.contentSizeFlag;
   514         break;
   676         break;
   515     case ZSTD_p_checksumFlag :
   677     case ZSTD_c_checksumFlag :
   516         *value = CCtxParams->fParams.checksumFlag;
   678         *value = CCtxParams->fParams.checksumFlag;
   517         break;
   679         break;
   518     case ZSTD_p_dictIDFlag :
   680     case ZSTD_c_dictIDFlag :
   519         *value = !CCtxParams->fParams.noDictIDFlag;
   681         *value = !CCtxParams->fParams.noDictIDFlag;
   520         break;
   682         break;
   521     case ZSTD_p_forceMaxWindow :
   683     case ZSTD_c_forceMaxWindow :
   522         *value = CCtxParams->forceWindow;
   684         *value = CCtxParams->forceWindow;
   523         break;
   685         break;
   524     case ZSTD_p_forceAttachDict :
   686     case ZSTD_c_forceAttachDict :
   525         *value = CCtxParams->attachDictPref;
   687         *value = CCtxParams->attachDictPref;
   526         break;
   688         break;
   527     case ZSTD_p_nbWorkers :
   689     case ZSTD_c_nbWorkers :
   528 #ifndef ZSTD_MULTITHREAD
   690 #ifndef ZSTD_MULTITHREAD
   529         assert(CCtxParams->nbWorkers == 0);
   691         assert(CCtxParams->nbWorkers == 0);
   530 #endif
   692 #endif
   531         *value = CCtxParams->nbWorkers;
   693         *value = CCtxParams->nbWorkers;
   532         break;
   694         break;
   533     case ZSTD_p_jobSize :
   695     case ZSTD_c_jobSize :
   534 #ifndef ZSTD_MULTITHREAD
   696 #ifndef ZSTD_MULTITHREAD
   535         return ERROR(parameter_unsupported);
   697         return ERROR(parameter_unsupported);
   536 #else
   698 #else
   537         *value = CCtxParams->jobSize;
   699         assert(CCtxParams->jobSize <= INT_MAX);
       
   700         *value = (int)CCtxParams->jobSize;
   538         break;
   701         break;
   539 #endif
   702 #endif
   540     case ZSTD_p_overlapSizeLog :
   703     case ZSTD_c_overlapLog :
   541 #ifndef ZSTD_MULTITHREAD
   704 #ifndef ZSTD_MULTITHREAD
   542         return ERROR(parameter_unsupported);
   705         return ERROR(parameter_unsupported);
   543 #else
   706 #else
   544         *value = CCtxParams->overlapSizeLog;
   707         *value = CCtxParams->overlapLog;
   545         break;
   708         break;
   546 #endif
   709 #endif
   547     case ZSTD_p_enableLongDistanceMatching :
   710     case ZSTD_c_rsyncable :
       
   711 #ifndef ZSTD_MULTITHREAD
       
   712         return ERROR(parameter_unsupported);
       
   713 #else
       
   714         *value = CCtxParams->rsyncable;
       
   715         break;
       
   716 #endif
       
   717     case ZSTD_c_enableLongDistanceMatching :
   548         *value = CCtxParams->ldmParams.enableLdm;
   718         *value = CCtxParams->ldmParams.enableLdm;
   549         break;
   719         break;
   550     case ZSTD_p_ldmHashLog :
   720     case ZSTD_c_ldmHashLog :
   551         *value = CCtxParams->ldmParams.hashLog;
   721         *value = CCtxParams->ldmParams.hashLog;
   552         break;
   722         break;
   553     case ZSTD_p_ldmMinMatch :
   723     case ZSTD_c_ldmMinMatch :
   554         *value = CCtxParams->ldmParams.minMatchLength;
   724         *value = CCtxParams->ldmParams.minMatchLength;
   555         break;
   725         break;
   556     case ZSTD_p_ldmBucketSizeLog :
   726     case ZSTD_c_ldmBucketSizeLog :
   557         *value = CCtxParams->ldmParams.bucketSizeLog;
   727         *value = CCtxParams->ldmParams.bucketSizeLog;
   558         break;
   728         break;
   559     case ZSTD_p_ldmHashEveryLog :
   729     case ZSTD_c_ldmHashRateLog :
   560         *value = CCtxParams->ldmParams.hashEveryLog;
   730         *value = CCtxParams->ldmParams.hashRateLog;
   561         break;
   731         break;
   562     default: return ERROR(parameter_unsupported);
   732     default: return ERROR(parameter_unsupported);
   563     }
   733     }
   564     return 0;
   734     return 0;
   565 }
   735 }
   653     return 0;
   823     return 0;
   654 }
   824 }
   655 
   825 
   656 /*! ZSTD_CCtx_reset() :
   826 /*! ZSTD_CCtx_reset() :
   657  *  Also dumps dictionary */
   827  *  Also dumps dictionary */
   658 void ZSTD_CCtx_reset(ZSTD_CCtx* cctx)
   828 size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset)
   659 {
   829 {
   660     cctx->streamStage = zcss_init;
   830     if ( (reset == ZSTD_reset_session_only)
   661     cctx->pledgedSrcSizePlusOne = 0;
   831       || (reset == ZSTD_reset_session_and_parameters) ) {
   662 }
   832         cctx->streamStage = zcss_init;
   663 
   833         cctx->pledgedSrcSizePlusOne = 0;
   664 size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx)
   834     }
   665 {
   835     if ( (reset == ZSTD_reset_parameters)
   666     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   836       || (reset == ZSTD_reset_session_and_parameters) ) {
   667     cctx->cdict = NULL;
   837         if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   668     return ZSTD_CCtxParams_reset(&cctx->requestedParams);
   838         cctx->cdict = NULL;
   669 }
   839         return ZSTD_CCtxParams_reset(&cctx->requestedParams);
       
   840     }
       
   841     return 0;
       
   842 }
       
   843 
   670 
   844 
   671 /** ZSTD_checkCParams() :
   845 /** ZSTD_checkCParams() :
   672     control CParam values remain within authorized range.
   846     control CParam values remain within authorized range.
   673     @return : 0, or an error code if one value is beyond authorized range */
   847     @return : 0, or an error code if one value is beyond authorized range */
   674 size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
   848 size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
   675 {
   849 {
   676     CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
   850     BOUNDCHECK(ZSTD_c_windowLog, cParams.windowLog);
   677     CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
   851     BOUNDCHECK(ZSTD_c_chainLog,  cParams.chainLog);
   678     CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   852     BOUNDCHECK(ZSTD_c_hashLog,   cParams.hashLog);
   679     CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
   853     BOUNDCHECK(ZSTD_c_searchLog, cParams.searchLog);
   680     CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
   854     BOUNDCHECK(ZSTD_c_minMatch,  cParams.minMatch);
   681     ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0);
   855     BOUNDCHECK(ZSTD_c_targetLength,cParams.targetLength);
   682     if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX)
   856     BOUNDCHECK(ZSTD_c_strategy,  cParams.strategy);
   683         return ERROR(parameter_outOfBound);
       
   684     if ((U32)(cParams.strategy) > (U32)ZSTD_btultra)
       
   685         return ERROR(parameter_unsupported);
       
   686     return 0;
   857     return 0;
   687 }
   858 }
   688 
   859 
   689 /** ZSTD_clampCParams() :
   860 /** ZSTD_clampCParams() :
   690  *  make CParam values within valid range.
   861  *  make CParam values within valid range.
   691  *  @return : valid CParams */
   862  *  @return : valid CParams */
   692 static ZSTD_compressionParameters
   863 static ZSTD_compressionParameters
   693 ZSTD_clampCParams(ZSTD_compressionParameters cParams)
   864 ZSTD_clampCParams(ZSTD_compressionParameters cParams)
   694 {
   865 {
   695 #   define CLAMP(val,min,max) {      \
   866 #   define CLAMP_TYPE(cParam, val, type) {                                \
   696         if (val<min) val=min;        \
   867         ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);         \
   697         else if (val>max) val=max;   \
   868         if ((int)val<bounds.lowerBound) val=(type)bounds.lowerBound;      \
   698     }
   869         else if ((int)val>bounds.upperBound) val=(type)bounds.upperBound; \
   699     CLAMP(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
   870     }
   700     CLAMP(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
   871 #   define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, int)
   701     CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   872     CLAMP(ZSTD_c_windowLog, cParams.windowLog);
   702     CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
   873     CLAMP(ZSTD_c_chainLog,  cParams.chainLog);
   703     CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
   874     CLAMP(ZSTD_c_hashLog,   cParams.hashLog);
   704     ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0);
   875     CLAMP(ZSTD_c_searchLog, cParams.searchLog);
   705     if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX)
   876     CLAMP(ZSTD_c_minMatch,  cParams.minMatch);
   706         cParams.targetLength = ZSTD_TARGETLENGTH_MAX;
   877     CLAMP(ZSTD_c_targetLength,cParams.targetLength);
   707     CLAMP(cParams.strategy, ZSTD_fast, ZSTD_btultra);
   878     CLAMP_TYPE(ZSTD_c_strategy,cParams.strategy, ZSTD_strategy);
   708     return cParams;
   879     return cParams;
   709 }
   880 }
   710 
   881 
   711 /** ZSTD_cycleLog() :
   882 /** ZSTD_cycleLog() :
   712  *  condition for correct operation : hashLog > 1 */
   883  *  condition for correct operation : hashLog > 1 */
   772     if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
   943     if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
   773     if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
   944     if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
   774     if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
   945     if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
   775     if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
   946     if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
   776     if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
   947     if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
   777     if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
   948     if (CCtxParams->cParams.minMatch) cParams.minMatch = CCtxParams->cParams.minMatch;
   778     if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
   949     if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
   779     if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
   950     if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
   780     assert(!ZSTD_checkCParams(cParams));
   951     assert(!ZSTD_checkCParams(cParams));
   781     return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
   952     return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
   782 }
   953 }
   785 ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
   956 ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
   786                        const U32 forCCtx)
   957                        const U32 forCCtx)
   787 {
   958 {
   788     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
   959     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
   789     size_t const hSize = ((size_t)1) << cParams->hashLog;
   960     size_t const hSize = ((size_t)1) << cParams->hashLog;
   790     U32    const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
   961     U32    const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
   791     size_t const h3Size = ((size_t)1) << hashLog3;
   962     size_t const h3Size = ((size_t)1) << hashLog3;
   792     size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
   963     size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
   793     size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits)) * sizeof(U32)
   964     size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits)) * sizeof(U32)
   794                           + (ZSTD_OPT_NUM+1) * (sizeof(ZSTD_match_t)+sizeof(ZSTD_optimal_t));
   965                           + (ZSTD_OPT_NUM+1) * (sizeof(ZSTD_match_t)+sizeof(ZSTD_optimal_t));
   795     size_t const optSpace = (forCCtx && ((cParams->strategy == ZSTD_btopt) ||
   966     size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
   796                                          (cParams->strategy == ZSTD_btultra)))
       
   797                                 ? optPotentialSpace
   967                                 ? optPotentialSpace
   798                                 : 0;
   968                                 : 0;
   799     DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u",
   969     DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u",
   800                 (U32)chainSize, (U32)hSize, (U32)h3Size);
   970                 (U32)chainSize, (U32)hSize, (U32)h3Size);
   801     return tableSpace + optSpace;
   971     return tableSpace + optSpace;
   806     /* Estimate CCtx size is supported for single-threaded compression only. */
   976     /* Estimate CCtx size is supported for single-threaded compression only. */
   807     if (params->nbWorkers > 0) { return ERROR(GENERIC); }
   977     if (params->nbWorkers > 0) { return ERROR(GENERIC); }
   808     {   ZSTD_compressionParameters const cParams =
   978     {   ZSTD_compressionParameters const cParams =
   809                 ZSTD_getCParamsFromCCtxParams(params, 0, 0);
   979                 ZSTD_getCParamsFromCCtxParams(params, 0, 0);
   810         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
   980         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
   811         U32    const divider = (cParams.searchLength==3) ? 3 : 4;
   981         U32    const divider = (cParams.minMatch==3) ? 3 : 4;
   812         size_t const maxNbSeq = blockSize / divider;
   982         size_t const maxNbSeq = blockSize / divider;
   813         size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
   983         size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
   814         size_t const entropySpace = HUF_WORKSPACE_SIZE;
   984         size_t const entropySpace = HUF_WORKSPACE_SIZE;
   815         size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
   985         size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
   816         size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
   986         size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
   841 
  1011 
   842 size_t ZSTD_estimateCCtxSize(int compressionLevel)
  1012 size_t ZSTD_estimateCCtxSize(int compressionLevel)
   843 {
  1013 {
   844     int level;
  1014     int level;
   845     size_t memBudget = 0;
  1015     size_t memBudget = 0;
   846     for (level=1; level<=compressionLevel; level++) {
  1016     for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) {
   847         size_t const newMB = ZSTD_estimateCCtxSize_internal(level);
  1017         size_t const newMB = ZSTD_estimateCCtxSize_internal(level);
   848         if (newMB > memBudget) memBudget = newMB;
  1018         if (newMB > memBudget) memBudget = newMB;
   849     }
  1019     }
   850     return memBudget;
  1020     return memBudget;
   851 }
  1021 }
   877 
  1047 
   878 size_t ZSTD_estimateCStreamSize(int compressionLevel)
  1048 size_t ZSTD_estimateCStreamSize(int compressionLevel)
   879 {
  1049 {
   880     int level;
  1050     int level;
   881     size_t memBudget = 0;
  1051     size_t memBudget = 0;
   882     for (level=1; level<=compressionLevel; level++) {
  1052     for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) {
   883         size_t const newMB = ZSTD_estimateCStreamSize_internal(level);
  1053         size_t const newMB = ZSTD_estimateCStreamSize_internal(level);
   884         if (newMB > memBudget) memBudget = newMB;
  1054         if (newMB > memBudget) memBudget = newMB;
   885     }
  1055     }
   886     return memBudget;
  1056     return memBudget;
   887 }
  1057 }
   931                                   ZSTD_compressionParameters cParams2)
  1101                                   ZSTD_compressionParameters cParams2)
   932 {
  1102 {
   933     return (cParams1.hashLog  == cParams2.hashLog)
  1103     return (cParams1.hashLog  == cParams2.hashLog)
   934          & (cParams1.chainLog == cParams2.chainLog)
  1104          & (cParams1.chainLog == cParams2.chainLog)
   935          & (cParams1.strategy == cParams2.strategy)   /* opt parser space */
  1105          & (cParams1.strategy == cParams2.strategy)   /* opt parser space */
   936          & ((cParams1.searchLength==3) == (cParams2.searchLength==3));  /* hashlog3 space */
  1106          & ((cParams1.minMatch==3) == (cParams2.minMatch==3));  /* hashlog3 space */
   937 }
  1107 }
   938 
  1108 
   939 static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
  1109 static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
   940                                     ZSTD_compressionParameters cParams2)
  1110                                     ZSTD_compressionParameters cParams2)
   941 {
  1111 {
   943     (void)cParams2;
  1113     (void)cParams2;
   944     assert(cParams1.windowLog    == cParams2.windowLog);
  1114     assert(cParams1.windowLog    == cParams2.windowLog);
   945     assert(cParams1.chainLog     == cParams2.chainLog);
  1115     assert(cParams1.chainLog     == cParams2.chainLog);
   946     assert(cParams1.hashLog      == cParams2.hashLog);
  1116     assert(cParams1.hashLog      == cParams2.hashLog);
   947     assert(cParams1.searchLog    == cParams2.searchLog);
  1117     assert(cParams1.searchLog    == cParams2.searchLog);
   948     assert(cParams1.searchLength == cParams2.searchLength);
  1118     assert(cParams1.minMatch     == cParams2.minMatch);
   949     assert(cParams1.targetLength == cParams2.targetLength);
  1119     assert(cParams1.targetLength == cParams2.targetLength);
   950     assert(cParams1.strategy     == cParams2.strategy);
  1120     assert(cParams1.strategy     == cParams2.strategy);
   951 }
  1121 }
   952 
  1122 
   953 /** The parameters are equivalent if ldm is not enabled in both sets or
  1123 /** The parameters are equivalent if ldm is not enabled in both sets or
   958     return (!ldmParams1.enableLdm && !ldmParams2.enableLdm) ||
  1128     return (!ldmParams1.enableLdm && !ldmParams2.enableLdm) ||
   959            (ldmParams1.enableLdm == ldmParams2.enableLdm &&
  1129            (ldmParams1.enableLdm == ldmParams2.enableLdm &&
   960             ldmParams1.hashLog == ldmParams2.hashLog &&
  1130             ldmParams1.hashLog == ldmParams2.hashLog &&
   961             ldmParams1.bucketSizeLog == ldmParams2.bucketSizeLog &&
  1131             ldmParams1.bucketSizeLog == ldmParams2.bucketSizeLog &&
   962             ldmParams1.minMatchLength == ldmParams2.minMatchLength &&
  1132             ldmParams1.minMatchLength == ldmParams2.minMatchLength &&
   963             ldmParams1.hashEveryLog == ldmParams2.hashEveryLog);
  1133             ldmParams1.hashRateLog == ldmParams2.hashRateLog);
   964 }
  1134 }
   965 
  1135 
   966 typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
  1136 typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
   967 
  1137 
   968 /* ZSTD_sufficientBuff() :
  1138 /* ZSTD_sufficientBuff() :
   974                             ZSTD_compressionParameters cParams2,
  1144                             ZSTD_compressionParameters cParams2,
   975                             U64 pledgedSrcSize)
  1145                             U64 pledgedSrcSize)
   976 {
  1146 {
   977     size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
  1147     size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
   978     size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
  1148     size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
   979     size_t const maxNbSeq2 = blockSize2 / ((cParams2.searchLength == 3) ? 3 : 4);
  1149     size_t const maxNbSeq2 = blockSize2 / ((cParams2.minMatch == 3) ? 3 : 4);
   980     size_t const maxNbLit2 = blockSize2;
  1150     size_t const maxNbLit2 = blockSize2;
   981     size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
  1151     size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
   982     DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u",
  1152     DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u",
   983                 (U32)neededBufferSize2, (U32)bufferSize1);
  1153                 (U32)neededBufferSize2, (U32)bufferSize1);
   984     DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u",
  1154     DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u",
  1032  */
  1202  */
  1033 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
  1203 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
  1034 {
  1204 {
  1035     ZSTD_window_clear(&ms->window);
  1205     ZSTD_window_clear(&ms->window);
  1036 
  1206 
  1037     ms->nextToUpdate = ms->window.dictLimit + 1;
  1207     ms->nextToUpdate = ms->window.dictLimit;
  1038     ms->nextToUpdate3 = ms->window.dictLimit + 1;
  1208     ms->nextToUpdate3 = ms->window.dictLimit;
  1039     ms->loadedDictEnd = 0;
  1209     ms->loadedDictEnd = 0;
  1040     ms->opt.litLengthSum = 0;  /* force reset of btopt stats */
  1210     ms->opt.litLengthSum = 0;  /* force reset of btopt stats */
  1041     ms->dictMatchState = NULL;
  1211     ms->dictMatchState = NULL;
  1042 }
  1212 }
  1043 
  1213 
  1078                 const ZSTD_compressionParameters* cParams,
  1248                 const ZSTD_compressionParameters* cParams,
  1079                       ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
  1249                       ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
  1080 {
  1250 {
  1081     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
  1251     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
  1082     size_t const hSize = ((size_t)1) << cParams->hashLog;
  1252     size_t const hSize = ((size_t)1) << cParams->hashLog;
  1083     U32    const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
  1253     U32    const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
  1084     size_t const h3Size = ((size_t)1) << hashLog3;
  1254     size_t const h3Size = ((size_t)1) << hashLog3;
  1085     size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
  1255     size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
  1086 
  1256 
  1087     assert(((size_t)ptr & 3) == 0);
  1257     assert(((size_t)ptr & 3) == 0);
  1088 
  1258 
  1092     ms->window.lowLimit = 1;     /* it ensures first and later CCtx usages compress the same */
  1262     ms->window.lowLimit = 1;     /* it ensures first and later CCtx usages compress the same */
  1093     ms->window.nextSrc = ms->window.base + 1;   /* see issue #1241 */
  1263     ms->window.nextSrc = ms->window.base + 1;   /* see issue #1241 */
  1094     ZSTD_invalidateMatchState(ms);
  1264     ZSTD_invalidateMatchState(ms);
  1095 
  1265 
  1096     /* opt parser space */
  1266     /* opt parser space */
  1097     if (forCCtx && ((cParams->strategy == ZSTD_btopt) | (cParams->strategy == ZSTD_btultra))) {
  1267     if (forCCtx && (cParams->strategy >= ZSTD_btopt)) {
  1098         DEBUGLOG(4, "reserving optimal parser space");
  1268         DEBUGLOG(4, "reserving optimal parser space");
  1099         ms->opt.litFreq = (U32*)ptr;
  1269         ms->opt.litFreq = (unsigned*)ptr;
  1100         ms->opt.litLengthFreq = ms->opt.litFreq + (1<<Litbits);
  1270         ms->opt.litLengthFreq = ms->opt.litFreq + (1<<Litbits);
  1101         ms->opt.matchLengthFreq = ms->opt.litLengthFreq + (MaxLL+1);
  1271         ms->opt.matchLengthFreq = ms->opt.litLengthFreq + (MaxLL+1);
  1102         ms->opt.offCodeFreq = ms->opt.matchLengthFreq + (MaxML+1);
  1272         ms->opt.offCodeFreq = ms->opt.matchLengthFreq + (MaxML+1);
  1103         ptr = ms->opt.offCodeFreq + (MaxOff+1);
  1273         ptr = ms->opt.offCodeFreq + (MaxOff+1);
  1104         ms->opt.matchTable = (ZSTD_match_t*)ptr;
  1274         ms->opt.matchTable = (ZSTD_match_t*)ptr;
  1156 
  1326 
  1157     if (params.ldmParams.enableLdm) {
  1327     if (params.ldmParams.enableLdm) {
  1158         /* Adjust long distance matching parameters */
  1328         /* Adjust long distance matching parameters */
  1159         ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
  1329         ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
  1160         assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
  1330         assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
  1161         assert(params.ldmParams.hashEveryLog < 32);
  1331         assert(params.ldmParams.hashRateLog < 32);
  1162         zc->ldmState.hashPower = ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
  1332         zc->ldmState.hashPower = ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength);
  1163     }
  1333     }
  1164 
  1334 
  1165     {   size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
  1335     {   size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
  1166         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
  1336         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
  1167         U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
  1337         U32    const divider = (params.cParams.minMatch==3) ? 3 : 4;
  1168         size_t const maxNbSeq = blockSize / divider;
  1338         size_t const maxNbSeq = blockSize / divider;
  1169         size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
  1339         size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
  1170         size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
  1340         size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
  1171         size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
  1341         size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
  1172         size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);
  1342         size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);
  1225         zc->consumedSrcSize = 0;
  1395         zc->consumedSrcSize = 0;
  1226         zc->producedCSize = 0;
  1396         zc->producedCSize = 0;
  1227         if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
  1397         if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
  1228             zc->appliedParams.fParams.contentSizeFlag = 0;
  1398             zc->appliedParams.fParams.contentSizeFlag = 0;
  1229         DEBUGLOG(4, "pledged content size : %u ; flag : %u",
  1399         DEBUGLOG(4, "pledged content size : %u ; flag : %u",
  1230             (U32)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);
  1400             (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);
  1231         zc->blockSize = blockSize;
  1401         zc->blockSize = blockSize;
  1232 
  1402 
  1233         XXH64_reset(&zc->xxhState, 0);
  1403         XXH64_reset(&zc->xxhState, 0);
  1234         zc->stage = ZSTDcs_init;
  1404         zc->stage = ZSTDcs_init;
  1235         zc->dictID = 0;
  1405         zc->dictID = 0;
  1304 
  1474 
  1305 /* These are the approximate sizes for each strategy past which copying the
  1475 /* These are the approximate sizes for each strategy past which copying the
  1306  * dictionary tables into the working context is faster than using them
  1476  * dictionary tables into the working context is faster than using them
  1307  * in-place.
  1477  * in-place.
  1308  */
  1478  */
  1309 static const size_t attachDictSizeCutoffs[(unsigned)ZSTD_btultra+1] = {
  1479 static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = {
  1310     8 KB, /* unused */
  1480     8 KB,  /* unused */
  1311     8 KB, /* ZSTD_fast */
  1481     8 KB,  /* ZSTD_fast */
  1312     16 KB, /* ZSTD_dfast */
  1482     16 KB, /* ZSTD_dfast */
  1313     32 KB, /* ZSTD_greedy */
  1483     32 KB, /* ZSTD_greedy */
  1314     32 KB, /* ZSTD_lazy */
  1484     32 KB, /* ZSTD_lazy */
  1315     32 KB, /* ZSTD_lazy2 */
  1485     32 KB, /* ZSTD_lazy2 */
  1316     32 KB, /* ZSTD_btlazy2 */
  1486     32 KB, /* ZSTD_btlazy2 */
  1317     32 KB, /* ZSTD_btopt */
  1487     32 KB, /* ZSTD_btopt */
  1318     8 KB /* ZSTD_btultra */
  1488     8 KB,  /* ZSTD_btultra */
       
  1489     8 KB   /* ZSTD_btultra2 */
  1319 };
  1490 };
  1320 
  1491 
  1321 static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
  1492 static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
  1322                                  ZSTD_CCtx_params params,
  1493                                  ZSTD_CCtx_params params,
  1323                                  U64 pledgedSrcSize)
  1494                                  U64 pledgedSrcSize)
  1445                             ZSTD_CCtx_params params,
  1616                             ZSTD_CCtx_params params,
  1446                             U64 pledgedSrcSize,
  1617                             U64 pledgedSrcSize,
  1447                             ZSTD_buffered_policy_e zbuff)
  1618                             ZSTD_buffered_policy_e zbuff)
  1448 {
  1619 {
  1449 
  1620 
  1450     DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
  1621     DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)",
       
  1622                 (unsigned)pledgedSrcSize);
  1451 
  1623 
  1452     if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {
  1624     if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {
  1453         return ZSTD_resetCCtx_byAttachingCDict(
  1625         return ZSTD_resetCCtx_byAttachingCDict(
  1454             cctx, cdict, params, pledgedSrcSize, zbuff);
  1626             cctx, cdict, params, pledgedSrcSize, zbuff);
  1455     } else {
  1627     } else {
  1668  * minimum compression required
  1840  * minimum compression required
  1669  * to generate a compress block or a compressed literals section.
  1841  * to generate a compress block or a compressed literals section.
  1670  * note : use same formula for both situations */
  1842  * note : use same formula for both situations */
  1671 static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
  1843 static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
  1672 {
  1844 {
  1673     U32 const minlog = (strat==ZSTD_btultra) ? 7 : 6;
  1845     U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;
       
  1846     ZSTD_STATIC_ASSERT(ZSTD_btultra == 8);
       
  1847     assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
  1674     return (srcSize >> minlog) + 2;
  1848     return (srcSize >> minlog) + 2;
  1675 }
  1849 }
  1676 
  1850 
  1677 static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
  1851 static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
  1678                                      ZSTD_hufCTables_t* nextHuf,
  1852                                      ZSTD_hufCTables_t* nextHuf,
  1679                                      ZSTD_strategy strategy, int disableLiteralCompression,
  1853                                      ZSTD_strategy strategy, int disableLiteralCompression,
  1680                                      void* dst, size_t dstCapacity,
  1854                                      void* dst, size_t dstCapacity,
  1681                                const void* src, size_t srcSize,
  1855                                const void* src, size_t srcSize,
  1682                                      U32* workspace, const int bmi2)
  1856                                      void* workspace, size_t wkspSize,
       
  1857                                const int bmi2)
  1683 {
  1858 {
  1684     size_t const minGain = ZSTD_minGain(srcSize, strategy);
  1859     size_t const minGain = ZSTD_minGain(srcSize, strategy);
  1685     size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
  1860     size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
  1686     BYTE*  const ostart = (BYTE*)dst;
  1861     BYTE*  const ostart = (BYTE*)dst;
  1687     U32 singleStream = srcSize < 256;
  1862     U32 singleStream = srcSize < 256;
  1706     if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
  1881     if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
  1707     {   HUF_repeat repeat = prevHuf->repeatMode;
  1882     {   HUF_repeat repeat = prevHuf->repeatMode;
  1708         int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
  1883         int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
  1709         if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
  1884         if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
  1710         cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1885         cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1711                                       workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
  1886                                       workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
  1712                                 : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1887                                 : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1713                                       workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
  1888                                       workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
  1714         if (repeat != HUF_repeat_none) {
  1889         if (repeat != HUF_repeat_none) {
  1715             /* reused the existing table */
  1890             /* reused the existing table */
  1716             hType = set_repeat;
  1891             hType = set_repeat;
  1717         }
  1892         }
  1718     }
  1893     }
  1975             assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
  2150             assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
  1976         }
  2151         }
  1977         assert(!ZSTD_isError(NCountCost));
  2152         assert(!ZSTD_isError(NCountCost));
  1978         assert(compressedCost < ERROR(maxCode));
  2153         assert(compressedCost < ERROR(maxCode));
  1979         DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
  2154         DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
  1980                     (U32)basicCost, (U32)repeatCost, (U32)compressedCost);
  2155                     (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);
  1981         if (basicCost <= repeatCost && basicCost <= compressedCost) {
  2156         if (basicCost <= repeatCost && basicCost <= compressedCost) {
  1982             DEBUGLOG(5, "Selected set_basic");
  2157             DEBUGLOG(5, "Selected set_basic");
  1983             assert(isDefaultAllowed);
  2158             assert(isDefaultAllowed);
  1984             *repeatMode = FSE_repeat_none;
  2159             *repeatMode = FSE_repeat_none;
  1985             return set_basic;
  2160             return set_basic;
  1997 }
  2172 }
  1998 
  2173 
  1999 MEM_STATIC size_t
  2174 MEM_STATIC size_t
  2000 ZSTD_buildCTable(void* dst, size_t dstCapacity,
  2175 ZSTD_buildCTable(void* dst, size_t dstCapacity,
  2001                 FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
  2176                 FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
  2002                 U32* count, U32 max,
  2177                 unsigned* count, U32 max,
  2003                 const BYTE* codeTable, size_t nbSeq,
  2178                 const BYTE* codeTable, size_t nbSeq,
  2004                 const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
  2179                 const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
  2005                 const FSE_CTable* prevCTable, size_t prevCTableSize,
  2180                 const FSE_CTable* prevCTable, size_t prevCTableSize,
  2006                 void* workspace, size_t workspaceSize)
  2181                 void* workspace, size_t workspaceSize)
  2007 {
  2182 {
  2008     BYTE* op = (BYTE*)dst;
  2183     BYTE* op = (BYTE*)dst;
  2009     const BYTE* const oend = op + dstCapacity;
  2184     const BYTE* const oend = op + dstCapacity;
       
  2185     DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity);
  2010 
  2186 
  2011     switch (type) {
  2187     switch (type) {
  2012     case set_rle:
  2188     case set_rle:
       
  2189         CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max));
       
  2190         if (dstCapacity==0) return ERROR(dstSize_tooSmall);
  2013         *op = codeTable[0];
  2191         *op = codeTable[0];
  2014         CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max));
       
  2015         return 1;
  2192         return 1;
  2016     case set_repeat:
  2193     case set_repeat:
  2017         memcpy(nextCTable, prevCTable, prevCTableSize);
  2194         memcpy(nextCTable, prevCTable, prevCTableSize);
  2018         return 0;
  2195         return 0;
  2019     case set_basic:
  2196     case set_basic:
  2051     FSE_CState_t  stateMatchLength;
  2228     FSE_CState_t  stateMatchLength;
  2052     FSE_CState_t  stateOffsetBits;
  2229     FSE_CState_t  stateOffsetBits;
  2053     FSE_CState_t  stateLitLength;
  2230     FSE_CState_t  stateLitLength;
  2054 
  2231 
  2055     CHECK_E(BIT_initCStream(&blockStream, dst, dstCapacity), dstSize_tooSmall); /* not enough space remaining */
  2232     CHECK_E(BIT_initCStream(&blockStream, dst, dstCapacity), dstSize_tooSmall); /* not enough space remaining */
       
  2233     DEBUGLOG(6, "available space for bitstream : %i  (dstCapacity=%u)",
       
  2234                 (int)(blockStream.endPtr - blockStream.startPtr),
       
  2235                 (unsigned)dstCapacity);
  2056 
  2236 
  2057     /* first symbols */
  2237     /* first symbols */
  2058     FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
  2238     FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
  2059     FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);
  2239     FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);
  2060     FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);
  2240     FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);
  2083             BYTE const mlCode = mlCodeTable[n];
  2263             BYTE const mlCode = mlCodeTable[n];
  2084             U32  const llBits = LL_bits[llCode];
  2264             U32  const llBits = LL_bits[llCode];
  2085             U32  const ofBits = ofCode;
  2265             U32  const ofBits = ofCode;
  2086             U32  const mlBits = ML_bits[mlCode];
  2266             U32  const mlBits = ML_bits[mlCode];
  2087             DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
  2267             DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
  2088                         sequences[n].litLength,
  2268                         (unsigned)sequences[n].litLength,
  2089                         sequences[n].matchLength + MINMATCH,
  2269                         (unsigned)sequences[n].matchLength + MINMATCH,
  2090                         sequences[n].offset);
  2270                         (unsigned)sequences[n].offset);
  2091                                                                             /* 32b*/  /* 64b*/
  2271                                                                             /* 32b*/  /* 64b*/
  2092                                                                             /* (7)*/  /* (7)*/
  2272                                                                             /* (7)*/  /* (7)*/
  2093             FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode);       /* 15 */  /* 15 */
  2273             FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode);       /* 15 */  /* 15 */
  2094             FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);      /* 24 */  /* 24 */
  2274             FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);      /* 24 */  /* 24 */
  2095             if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
  2275             if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
  2110                             ofBits - extraBits);                            /* 31 */
  2290                             ofBits - extraBits);                            /* 31 */
  2111             } else {
  2291             } else {
  2112                 BIT_addBits(&blockStream, sequences[n].offset, ofBits);     /* 31 */
  2292                 BIT_addBits(&blockStream, sequences[n].offset, ofBits);     /* 31 */
  2113             }
  2293             }
  2114             BIT_flushBits(&blockStream);                                    /* (7)*/
  2294             BIT_flushBits(&blockStream);                                    /* (7)*/
       
  2295             DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
  2115     }   }
  2296     }   }
  2116 
  2297 
  2117     DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
  2298     DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
  2118     FSE_flushCState(&blockStream, &stateMatchLength);
  2299     FSE_flushCState(&blockStream, &stateMatchLength);
  2119     DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
  2300     DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
  2167             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
  2348             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
  2168             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
  2349             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
  2169             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
  2350             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
  2170             seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
  2351             seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
  2171 {
  2352 {
       
  2353     DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity);
  2172 #if DYNAMIC_BMI2
  2354 #if DYNAMIC_BMI2
  2173     if (bmi2) {
  2355     if (bmi2) {
  2174         return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
  2356         return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
  2175                                          CTable_MatchLength, mlCodeTable,
  2357                                          CTable_MatchLength, mlCodeTable,
  2176                                          CTable_OffsetBits, ofCodeTable,
  2358                                          CTable_OffsetBits, ofCodeTable,
  2184                                         CTable_OffsetBits, ofCodeTable,
  2366                                         CTable_OffsetBits, ofCodeTable,
  2185                                         CTable_LitLength, llCodeTable,
  2367                                         CTable_LitLength, llCodeTable,
  2186                                         sequences, nbSeq, longOffsets);
  2368                                         sequences, nbSeq, longOffsets);
  2187 }
  2369 }
  2188 
  2370 
  2189 MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
  2371 /* ZSTD_compressSequences_internal():
  2190                               ZSTD_entropyCTables_t const* prevEntropy,
  2372  * actually compresses both literals and sequences */
  2191                               ZSTD_entropyCTables_t* nextEntropy,
  2373 MEM_STATIC size_t
  2192                               ZSTD_CCtx_params const* cctxParams,
  2374 ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
  2193                               void* dst, size_t dstCapacity, U32* workspace,
  2375                           const ZSTD_entropyCTables_t* prevEntropy,
  2194                               const int bmi2)
  2376                                 ZSTD_entropyCTables_t* nextEntropy,
       
  2377                           const ZSTD_CCtx_params* cctxParams,
       
  2378                                 void* dst, size_t dstCapacity,
       
  2379                                 void* workspace, size_t wkspSize,
       
  2380                           const int bmi2)
  2195 {
  2381 {
  2196     const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
  2382     const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
  2197     ZSTD_strategy const strategy = cctxParams->cParams.strategy;
  2383     ZSTD_strategy const strategy = cctxParams->cParams.strategy;
  2198     U32 count[MaxSeq+1];
  2384     unsigned count[MaxSeq+1];
  2199     FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
  2385     FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
  2200     FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
  2386     FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
  2201     FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
  2387     FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
  2202     U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
  2388     U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
  2203     const seqDef* const sequences = seqStorePtr->sequencesStart;
  2389     const seqDef* const sequences = seqStorePtr->sequencesStart;
  2210     size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
  2396     size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
  2211     BYTE* seqHead;
  2397     BYTE* seqHead;
  2212     BYTE* lastNCount = NULL;
  2398     BYTE* lastNCount = NULL;
  2213 
  2399 
  2214     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
  2400     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
       
  2401     DEBUGLOG(5, "ZSTD_compressSequences_internal");
  2215 
  2402 
  2216     /* Compress literals */
  2403     /* Compress literals */
  2217     {   const BYTE* const literals = seqStorePtr->litStart;
  2404     {   const BYTE* const literals = seqStorePtr->litStart;
  2218         size_t const litSize = seqStorePtr->lit - literals;
  2405         size_t const litSize = seqStorePtr->lit - literals;
  2219         int const disableLiteralCompression = (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
  2406         int const disableLiteralCompression = (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
  2220         size_t const cSize = ZSTD_compressLiterals(
  2407         size_t const cSize = ZSTD_compressLiterals(
  2221                                     &prevEntropy->huf, &nextEntropy->huf,
  2408                                     &prevEntropy->huf, &nextEntropy->huf,
  2222                                     cctxParams->cParams.strategy, disableLiteralCompression,
  2409                                     cctxParams->cParams.strategy, disableLiteralCompression,
  2223                                     op, dstCapacity,
  2410                                     op, dstCapacity,
  2224                                     literals, litSize,
  2411                                     literals, litSize,
  2225                                     workspace, bmi2);
  2412                                     workspace, wkspSize,
       
  2413                                     bmi2);
  2226         if (ZSTD_isError(cSize))
  2414         if (ZSTD_isError(cSize))
  2227           return cSize;
  2415           return cSize;
  2228         assert(cSize <= dstCapacity);
  2416         assert(cSize <= dstCapacity);
  2229         op += cSize;
  2417         op += cSize;
  2230     }
  2418     }
  2247     seqHead = op++;
  2435     seqHead = op++;
  2248 
  2436 
  2249     /* convert length/distances into codes */
  2437     /* convert length/distances into codes */
  2250     ZSTD_seqToCodes(seqStorePtr);
  2438     ZSTD_seqToCodes(seqStorePtr);
  2251     /* build CTable for Literal Lengths */
  2439     /* build CTable for Literal Lengths */
  2252     {   U32 max = MaxLL;
  2440     {   unsigned max = MaxLL;
  2253         size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace);   /* can't fail */
  2441         size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace, wkspSize);   /* can't fail */
  2254         DEBUGLOG(5, "Building LL table");
  2442         DEBUGLOG(5, "Building LL table");
  2255         nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
  2443         nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
  2256         LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode, count, max, mostFrequent, nbSeq, LLFSELog, prevEntropy->fse.litlengthCTable, LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultAllowed, strategy);
  2444         LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode,
       
  2445                                         count, max, mostFrequent, nbSeq,
       
  2446                                         LLFSELog, prevEntropy->fse.litlengthCTable,
       
  2447                                         LL_defaultNorm, LL_defaultNormLog,
       
  2448                                         ZSTD_defaultAllowed, strategy);
  2257         assert(set_basic < set_compressed && set_rle < set_compressed);
  2449         assert(set_basic < set_compressed && set_rle < set_compressed);
  2258         assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2450         assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2259         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
  2451         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
  2260                                                     count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
  2452                                                     count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
  2261                                                     prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
  2453                                                     prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
  2262                                                     workspace, HUF_WORKSPACE_SIZE);
  2454                                                     workspace, wkspSize);
  2263             if (ZSTD_isError(countSize)) return countSize;
  2455             if (ZSTD_isError(countSize)) return countSize;
  2264             if (LLtype == set_compressed)
  2456             if (LLtype == set_compressed)
  2265                 lastNCount = op;
  2457                 lastNCount = op;
  2266             op += countSize;
  2458             op += countSize;
  2267     }   }
  2459     }   }
  2268     /* build CTable for Offsets */
  2460     /* build CTable for Offsets */
  2269     {   U32 max = MaxOff;
  2461     {   unsigned max = MaxOff;
  2270         size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace);  /* can't fail */
  2462         size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace, wkspSize);  /* can't fail */
  2271         /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
  2463         /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
  2272         ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
  2464         ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
  2273         DEBUGLOG(5, "Building OF table");
  2465         DEBUGLOG(5, "Building OF table");
  2274         nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode;
  2466         nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode;
  2275         Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode, count, max, mostFrequent, nbSeq, OffFSELog, prevEntropy->fse.offcodeCTable, OF_defaultNorm, OF_defaultNormLog, defaultPolicy, strategy);
  2467         Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode,
       
  2468                                         count, max, mostFrequent, nbSeq,
       
  2469                                         OffFSELog, prevEntropy->fse.offcodeCTable,
       
  2470                                         OF_defaultNorm, OF_defaultNormLog,
       
  2471                                         defaultPolicy, strategy);
  2276         assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2472         assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2277         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
  2473         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
  2278                                                     count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  2474                                                     count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  2279                                                     prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
  2475                                                     prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
  2280                                                     workspace, HUF_WORKSPACE_SIZE);
  2476                                                     workspace, wkspSize);
  2281             if (ZSTD_isError(countSize)) return countSize;
  2477             if (ZSTD_isError(countSize)) return countSize;
  2282             if (Offtype == set_compressed)
  2478             if (Offtype == set_compressed)
  2283                 lastNCount = op;
  2479                 lastNCount = op;
  2284             op += countSize;
  2480             op += countSize;
  2285     }   }
  2481     }   }
  2286     /* build CTable for MatchLengths */
  2482     /* build CTable for MatchLengths */
  2287     {   U32 max = MaxML;
  2483     {   unsigned max = MaxML;
  2288         size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace);   /* can't fail */
  2484         size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace, wkspSize);   /* can't fail */
  2289         DEBUGLOG(5, "Building ML table");
  2485         DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
  2290         nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
  2486         nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
  2291         MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode, count, max, mostFrequent, nbSeq, MLFSELog, prevEntropy->fse.matchlengthCTable, ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultAllowed, strategy);
  2487         MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode,
       
  2488                                         count, max, mostFrequent, nbSeq,
       
  2489                                         MLFSELog, prevEntropy->fse.matchlengthCTable,
       
  2490                                         ML_defaultNorm, ML_defaultNormLog,
       
  2491                                         ZSTD_defaultAllowed, strategy);
  2292         assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2492         assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2293         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
  2493         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
  2294                                                     count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
  2494                                                     count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
  2295                                                     prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
  2495                                                     prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
  2296                                                     workspace, HUF_WORKSPACE_SIZE);
  2496                                                     workspace, wkspSize);
  2297             if (ZSTD_isError(countSize)) return countSize;
  2497             if (ZSTD_isError(countSize)) return countSize;
  2298             if (MLtype == set_compressed)
  2498             if (MLtype == set_compressed)
  2299                 lastNCount = op;
  2499                 lastNCount = op;
  2300             op += countSize;
  2500             op += countSize;
  2301     }   }
  2501     }   }
  2326                         "emitting an uncompressed block.");
  2526                         "emitting an uncompressed block.");
  2327             return 0;
  2527             return 0;
  2328         }
  2528         }
  2329     }
  2529     }
  2330 
  2530 
       
  2531     DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart));
  2331     return op - ostart;
  2532     return op - ostart;
  2332 }
  2533 }
  2333 
  2534 
  2334 MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
  2535 MEM_STATIC size_t
  2335                         const ZSTD_entropyCTables_t* prevEntropy,
  2536 ZSTD_compressSequences(seqStore_t* seqStorePtr,
  2336                               ZSTD_entropyCTables_t* nextEntropy,
  2537                        const ZSTD_entropyCTables_t* prevEntropy,
  2337                         const ZSTD_CCtx_params* cctxParams,
  2538                              ZSTD_entropyCTables_t* nextEntropy,
  2338                               void* dst, size_t dstCapacity,
  2539                        const ZSTD_CCtx_params* cctxParams,
  2339                               size_t srcSize, U32* workspace, int bmi2)
  2540                              void* dst, size_t dstCapacity,
       
  2541                              size_t srcSize,
       
  2542                              void* workspace, size_t wkspSize,
       
  2543                              int bmi2)
  2340 {
  2544 {
  2341     size_t const cSize = ZSTD_compressSequences_internal(
  2545     size_t const cSize = ZSTD_compressSequences_internal(
  2342             seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity,
  2546                             seqStorePtr, prevEntropy, nextEntropy, cctxParams,
  2343             workspace, bmi2);
  2547                             dst, dstCapacity,
       
  2548                             workspace, wkspSize, bmi2);
  2344     if (cSize == 0) return 0;
  2549     if (cSize == 0) return 0;
  2345     /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
  2550     /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
  2346      * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
  2551      * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
  2347      */
  2552      */
  2348     if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
  2553     if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
  2360 /* ZSTD_selectBlockCompressor() :
  2565 /* ZSTD_selectBlockCompressor() :
  2361  * Not static, but internal use only (used by long distance matcher)
  2566  * Not static, but internal use only (used by long distance matcher)
  2362  * assumption : strat is a valid strategy */
  2567  * assumption : strat is a valid strategy */
  2363 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
  2568 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
  2364 {
  2569 {
  2365     static const ZSTD_blockCompressor blockCompressor[3][(unsigned)ZSTD_btultra+1] = {
  2570     static const ZSTD_blockCompressor blockCompressor[3][ZSTD_STRATEGY_MAX+1] = {
  2366         { ZSTD_compressBlock_fast  /* default for 0 */,
  2571         { ZSTD_compressBlock_fast  /* default for 0 */,
  2367           ZSTD_compressBlock_fast,
  2572           ZSTD_compressBlock_fast,
  2368           ZSTD_compressBlock_doubleFast,
  2573           ZSTD_compressBlock_doubleFast,
  2369           ZSTD_compressBlock_greedy,
  2574           ZSTD_compressBlock_greedy,
  2370           ZSTD_compressBlock_lazy,
  2575           ZSTD_compressBlock_lazy,
  2371           ZSTD_compressBlock_lazy2,
  2576           ZSTD_compressBlock_lazy2,
  2372           ZSTD_compressBlock_btlazy2,
  2577           ZSTD_compressBlock_btlazy2,
  2373           ZSTD_compressBlock_btopt,
  2578           ZSTD_compressBlock_btopt,
  2374           ZSTD_compressBlock_btultra },
  2579           ZSTD_compressBlock_btultra,
       
  2580           ZSTD_compressBlock_btultra2 },
  2375         { ZSTD_compressBlock_fast_extDict  /* default for 0 */,
  2581         { ZSTD_compressBlock_fast_extDict  /* default for 0 */,
  2376           ZSTD_compressBlock_fast_extDict,
  2582           ZSTD_compressBlock_fast_extDict,
  2377           ZSTD_compressBlock_doubleFast_extDict,
  2583           ZSTD_compressBlock_doubleFast_extDict,
  2378           ZSTD_compressBlock_greedy_extDict,
  2584           ZSTD_compressBlock_greedy_extDict,
  2379           ZSTD_compressBlock_lazy_extDict,
  2585           ZSTD_compressBlock_lazy_extDict,
  2380           ZSTD_compressBlock_lazy2_extDict,
  2586           ZSTD_compressBlock_lazy2_extDict,
  2381           ZSTD_compressBlock_btlazy2_extDict,
  2587           ZSTD_compressBlock_btlazy2_extDict,
  2382           ZSTD_compressBlock_btopt_extDict,
  2588           ZSTD_compressBlock_btopt_extDict,
       
  2589           ZSTD_compressBlock_btultra_extDict,
  2383           ZSTD_compressBlock_btultra_extDict },
  2590           ZSTD_compressBlock_btultra_extDict },
  2384         { ZSTD_compressBlock_fast_dictMatchState  /* default for 0 */,
  2591         { ZSTD_compressBlock_fast_dictMatchState  /* default for 0 */,
  2385           ZSTD_compressBlock_fast_dictMatchState,
  2592           ZSTD_compressBlock_fast_dictMatchState,
  2386           ZSTD_compressBlock_doubleFast_dictMatchState,
  2593           ZSTD_compressBlock_doubleFast_dictMatchState,
  2387           ZSTD_compressBlock_greedy_dictMatchState,
  2594           ZSTD_compressBlock_greedy_dictMatchState,
  2388           ZSTD_compressBlock_lazy_dictMatchState,
  2595           ZSTD_compressBlock_lazy_dictMatchState,
  2389           ZSTD_compressBlock_lazy2_dictMatchState,
  2596           ZSTD_compressBlock_lazy2_dictMatchState,
  2390           ZSTD_compressBlock_btlazy2_dictMatchState,
  2597           ZSTD_compressBlock_btlazy2_dictMatchState,
  2391           ZSTD_compressBlock_btopt_dictMatchState,
  2598           ZSTD_compressBlock_btopt_dictMatchState,
       
  2599           ZSTD_compressBlock_btultra_dictMatchState,
  2392           ZSTD_compressBlock_btultra_dictMatchState }
  2600           ZSTD_compressBlock_btultra_dictMatchState }
  2393     };
  2601     };
  2394     ZSTD_blockCompressor selectedCompressor;
  2602     ZSTD_blockCompressor selectedCompressor;
  2395     ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
  2603     ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
  2396 
  2604 
  2397     assert((U32)strat >= (U32)ZSTD_fast);
  2605     assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
  2398     assert((U32)strat <= (U32)ZSTD_btultra);
  2606     selectedCompressor = blockCompressor[(int)dictMode][(int)strat];
  2399     selectedCompressor = blockCompressor[(int)dictMode][(U32)strat];
       
  2400     assert(selectedCompressor != NULL);
  2607     assert(selectedCompressor != NULL);
  2401     return selectedCompressor;
  2608     return selectedCompressor;
  2402 }
  2609 }
  2403 
  2610 
  2404 static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
  2611 static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
  2419                                         void* dst, size_t dstCapacity,
  2626                                         void* dst, size_t dstCapacity,
  2420                                         const void* src, size_t srcSize)
  2627                                         const void* src, size_t srcSize)
  2421 {
  2628 {
  2422     ZSTD_matchState_t* const ms = &zc->blockState.matchState;
  2629     ZSTD_matchState_t* const ms = &zc->blockState.matchState;
  2423     size_t cSize;
  2630     size_t cSize;
  2424     DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%zu, dictLimit=%u, nextToUpdate=%u)",
  2631     DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
  2425                 dstCapacity, ms->window.dictLimit, ms->nextToUpdate);
  2632                 (unsigned)dstCapacity, (unsigned)ms->window.dictLimit, (unsigned)ms->nextToUpdate);
  2426     assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
  2633     assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
  2427 
  2634 
  2428     /* Assert that we have correctly flushed the ctx params into the ms's copy */
  2635     /* Assert that we have correctly flushed the ctx params into the ms's copy */
  2429     ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
  2636     ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
  2430 
  2637 
  2431     if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
  2638     if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
  2432         ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength);
  2639         ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
  2433         cSize = 0;
  2640         cSize = 0;
  2434         goto out;  /* don't even attempt compression below a certain srcSize */
  2641         goto out;  /* don't even attempt compression below a certain srcSize */
  2435     }
  2642     }
  2436     ZSTD_resetSeqStore(&(zc->seqStore));
  2643     ZSTD_resetSeqStore(&(zc->seqStore));
  2437     ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;   /* required for optimal parser to read stats from dictionary */
  2644     ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;   /* required for optimal parser to read stats from dictionary */
  2438 
  2645 
  2439     /* a gap between an attached dict and the current window is not safe,
  2646     /* a gap between an attached dict and the current window is not safe,
  2440      * they must remain adjacent, and when that stops being the case, the dict
  2647      * they must remain adjacent,
  2441      * must be unset */
  2648      * and when that stops being the case, the dict must be unset */
  2442     assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
  2649     assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
  2443 
  2650 
  2444     /* limited update after a very long match */
  2651     /* limited update after a very long match */
  2445     {   const BYTE* const base = ms->window.base;
  2652     {   const BYTE* const base = ms->window.base;
  2446         const BYTE* const istart = (const BYTE*)src;
  2653         const BYTE* const istart = (const BYTE*)src;
  2493     /* encode sequences and literals */
  2700     /* encode sequences and literals */
  2494     cSize = ZSTD_compressSequences(&zc->seqStore,
  2701     cSize = ZSTD_compressSequences(&zc->seqStore,
  2495             &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
  2702             &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
  2496             &zc->appliedParams,
  2703             &zc->appliedParams,
  2497             dst, dstCapacity,
  2704             dst, dstCapacity,
  2498             srcSize, zc->entropyWorkspace, zc->bmi2);
  2705             srcSize,
       
  2706             zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
       
  2707             zc->bmi2);
  2499 
  2708 
  2500 out:
  2709 out:
  2501     if (!ZSTD_isError(cSize) && cSize != 0) {
  2710     if (!ZSTD_isError(cSize) && cSize != 0) {
  2502         /* confirm repcodes and entropy tables when emitting a compressed block */
  2711         /* confirm repcodes and entropy tables when emitting a compressed block */
  2503         ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
  2712         ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
  2533     BYTE* const ostart = (BYTE*)dst;
  2742     BYTE* const ostart = (BYTE*)dst;
  2534     BYTE* op = ostart;
  2743     BYTE* op = ostart;
  2535     U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
  2744     U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
  2536     assert(cctx->appliedParams.cParams.windowLog <= 31);
  2745     assert(cctx->appliedParams.cParams.windowLog <= 31);
  2537 
  2746 
  2538     DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (U32)blockSize);
  2747     DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
  2539     if (cctx->appliedParams.fParams.checksumFlag && srcSize)
  2748     if (cctx->appliedParams.fParams.checksumFlag && srcSize)
  2540         XXH64_update(&cctx->xxhState, src, srcSize);
  2749         XXH64_update(&cctx->xxhState, src, srcSize);
  2541 
  2750 
  2542     while (remaining) {
  2751     while (remaining) {
  2543         ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2752         ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2581             remaining -= blockSize;
  2790             remaining -= blockSize;
  2582             op += cSize;
  2791             op += cSize;
  2583             assert(dstCapacity >= cSize);
  2792             assert(dstCapacity >= cSize);
  2584             dstCapacity -= cSize;
  2793             dstCapacity -= cSize;
  2585             DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u",
  2794             DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u",
  2586                         (U32)cSize);
  2795                         (unsigned)cSize);
  2587     }   }
  2796     }   }
  2588 
  2797 
  2589     if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
  2798     if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
  2590     return op-ostart;
  2799     return op-ostart;
  2591 }
  2800 }
  2604                      (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */
  2813                      (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */
  2605     BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
  2814     BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
  2606     size_t pos=0;
  2815     size_t pos=0;
  2607 
  2816 
  2608     assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
  2817     assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
  2609     if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
  2818     if (dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX) return ERROR(dstSize_tooSmall);
  2610     DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
  2819     DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
  2611                 !params.fParams.noDictIDFlag, dictID,  dictIDSizeCode);
  2820                 !params.fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
  2612 
  2821 
  2613     if (params.format == ZSTD_f_zstd1) {
  2822     if (params.format == ZSTD_f_zstd1) {
  2614         MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
  2823         MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
  2615         pos = 4;
  2824         pos = 4;
  2616     }
  2825     }
  2670 {
  2879 {
  2671     ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2880     ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2672     size_t fhSize = 0;
  2881     size_t fhSize = 0;
  2673 
  2882 
  2674     DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
  2883     DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
  2675                 cctx->stage, (U32)srcSize);
  2884                 cctx->stage, (unsigned)srcSize);
  2676     if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
  2885     if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
  2677 
  2886 
  2678     if (frame && (cctx->stage==ZSTDcs_init)) {
  2887     if (frame && (cctx->stage==ZSTDcs_init)) {
  2679         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
  2888         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
  2680                                        cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
  2889                                        cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
  2707             ms->loadedDictEnd = 0;
  2916             ms->loadedDictEnd = 0;
  2708             ms->dictMatchState = NULL;
  2917             ms->dictMatchState = NULL;
  2709         }
  2918         }
  2710     }
  2919     }
  2711 
  2920 
  2712     DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize);
  2921     DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
  2713     {   size_t const cSize = frame ?
  2922     {   size_t const cSize = frame ?
  2714                              ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
  2923                              ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
  2715                              ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
  2924                              ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
  2716         if (ZSTD_isError(cSize)) return cSize;
  2925         if (ZSTD_isError(cSize)) return cSize;
  2717         cctx->consumedSrcSize += srcSize;
  2926         cctx->consumedSrcSize += srcSize;
  2719         assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
  2928         assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
  2720         if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  2929         if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  2721             ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  2930             ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  2722             if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
  2931             if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
  2723                 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
  2932                 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
  2724                     (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
  2933                     (unsigned)cctx->pledgedSrcSizePlusOne-1, (unsigned)cctx->consumedSrcSize);
  2725                 return ERROR(srcSize_wrong);
  2934                 return ERROR(srcSize_wrong);
  2726             }
  2935             }
  2727         }
  2936         }
  2728         return cSize + fhSize;
  2937         return cSize + fhSize;
  2729     }
  2938     }
  2731 
  2940 
  2732 size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
  2941 size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
  2733                               void* dst, size_t dstCapacity,
  2942                               void* dst, size_t dstCapacity,
  2734                         const void* src, size_t srcSize)
  2943                         const void* src, size_t srcSize)
  2735 {
  2944 {
  2736     DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (U32)srcSize);
  2945     DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (unsigned)srcSize);
  2737     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */);
  2946     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */);
  2738 }
  2947 }
  2739 
  2948 
  2740 
  2949 
  2741 size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
  2950 size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
  2789         break;
  2998         break;
  2790 
  2999 
  2791     case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */
  3000     case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */
  2792     case ZSTD_btopt:
  3001     case ZSTD_btopt:
  2793     case ZSTD_btultra:
  3002     case ZSTD_btultra:
       
  3003     case ZSTD_btultra2:
  2794         if (srcSize >= HASH_READ_SIZE)
  3004         if (srcSize >= HASH_READ_SIZE)
  2795             ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
  3005             ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
  2796         break;
  3006         break;
  2797 
  3007 
  2798     default:
  3008     default:
  2859         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
  3069         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
  2860         if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
  3070         if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
  2861         if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
  3071         if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
  2862         /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
  3072         /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
  2863         /* fill all offset symbols to avoid garbage at end of table */
  3073         /* fill all offset symbols to avoid garbage at end of table */
  2864         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.offcodeCTable, offcodeNCount, MaxOff, offcodeLog, workspace, HUF_WORKSPACE_SIZE),
  3074         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.offcodeCTable,
       
  3075                                     offcodeNCount, MaxOff, offcodeLog,
       
  3076                                     workspace, HUF_WORKSPACE_SIZE),
  2865                  dictionary_corrupted);
  3077                  dictionary_corrupted);
  2866         dictPtr += offcodeHeaderSize;
  3078         dictPtr += offcodeHeaderSize;
  2867     }
  3079     }
  2868 
  3080 
  2869     {   short matchlengthNCount[MaxML+1];
  3081     {   short matchlengthNCount[MaxML+1];
  2871         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
  3083         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
  2872         if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
  3084         if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2873         if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
  3085         if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
  2874         /* Every match length code must have non-zero probability */
  3086         /* Every match length code must have non-zero probability */
  2875         CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
  3087         CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
  2876         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
  3088         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.matchlengthCTable,
       
  3089                                     matchlengthNCount, matchlengthMaxValue, matchlengthLog,
       
  3090                                     workspace, HUF_WORKSPACE_SIZE),
  2877                  dictionary_corrupted);
  3091                  dictionary_corrupted);
  2878         dictPtr += matchlengthHeaderSize;
  3092         dictPtr += matchlengthHeaderSize;
  2879     }
  3093     }
  2880 
  3094 
  2881     {   short litlengthNCount[MaxLL+1];
  3095     {   short litlengthNCount[MaxLL+1];
  2883         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
  3097         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
  2884         if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
  3098         if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2885         if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
  3099         if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
  2886         /* Every literal length code must have non-zero probability */
  3100         /* Every literal length code must have non-zero probability */
  2887         CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
  3101         CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
  2888         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
  3102         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.litlengthCTable,
       
  3103                                     litlengthNCount, litlengthMaxValue, litlengthLog,
       
  3104                                     workspace, HUF_WORKSPACE_SIZE),
  2889                  dictionary_corrupted);
  3105                  dictionary_corrupted);
  2890         dictPtr += litlengthHeaderSize;
  3106         dictPtr += litlengthHeaderSize;
  2891     }
  3107     }
  2892 
  3108 
  2893     if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
  3109     if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
  3021 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
  3237 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
  3022 {
  3238 {
  3023     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
  3239     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
  3024     ZSTD_CCtx_params const cctxParams =
  3240     ZSTD_CCtx_params const cctxParams =
  3025             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  3241             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  3026     DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize);
  3242     DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
  3027     return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  3243     return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  3028                                        cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
  3244                                        cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
  3029 }
  3245 }
  3030 
  3246 
  3031 size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
  3247 size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
  3065     }
  3281     }
  3066 
  3282 
  3067     if (cctx->appliedParams.fParams.checksumFlag) {
  3283     if (cctx->appliedParams.fParams.checksumFlag) {
  3068         U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
  3284         U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
  3069         if (dstCapacity<4) return ERROR(dstSize_tooSmall);
  3285         if (dstCapacity<4) return ERROR(dstSize_tooSmall);
  3070         DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", checksum);
  3286         DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum);
  3071         MEM_writeLE32(op, checksum);
  3287         MEM_writeLE32(op, checksum);
  3072         op += 4;
  3288         op += 4;
  3073     }
  3289     }
  3074 
  3290 
  3075     cctx->stage = ZSTDcs_created;  /* return to "created but no init" status */
  3291     cctx->stage = ZSTDcs_created;  /* return to "created but no init" status */
  3091     if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  3307     if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  3092         ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  3308         ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  3093         DEBUGLOG(4, "end of frame : controlling src size");
  3309         DEBUGLOG(4, "end of frame : controlling src size");
  3094         if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) {
  3310         if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) {
  3095             DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u",
  3311             DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u",
  3096                 (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
  3312                 (unsigned)cctx->pledgedSrcSizePlusOne-1, (unsigned)cctx->consumedSrcSize);
  3097             return ERROR(srcSize_wrong);
  3313             return ERROR(srcSize_wrong);
  3098     }   }
  3314     }   }
  3099     return cSize + endResult;
  3315     return cSize + endResult;
  3100 }
  3316 }
  3101 
  3317 
  3137         void* dst, size_t dstCapacity,
  3353         void* dst, size_t dstCapacity,
  3138         const void* src, size_t srcSize,
  3354         const void* src, size_t srcSize,
  3139         const void* dict,size_t dictSize,
  3355         const void* dict,size_t dictSize,
  3140         ZSTD_CCtx_params params)
  3356         ZSTD_CCtx_params params)
  3141 {
  3357 {
  3142     DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (U32)srcSize);
  3358     DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
  3143     CHECK_F( ZSTD_compressBegin_internal(cctx,
  3359     CHECK_F( ZSTD_compressBegin_internal(cctx,
  3144                          dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  3360                          dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  3145                          params, srcSize, ZSTDb_not_buffered) );
  3361                          params, srcSize, ZSTDb_not_buffered) );
  3146     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  3362     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  3147 }
  3363 }
  3161 size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
  3377 size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
  3162                          void* dst, size_t dstCapacity,
  3378                          void* dst, size_t dstCapacity,
  3163                    const void* src, size_t srcSize,
  3379                    const void* src, size_t srcSize,
  3164                          int compressionLevel)
  3380                          int compressionLevel)
  3165 {
  3381 {
  3166     DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize);
  3382     DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (unsigned)srcSize);
  3167     assert(cctx != NULL);
  3383     assert(cctx != NULL);
  3168     return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
  3384     return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
  3169 }
  3385 }
  3170 
  3386 
  3171 size_t ZSTD_compress(void* dst, size_t dstCapacity,
  3387 size_t ZSTD_compress(void* dst, size_t dstCapacity,
  3187  *  Estimate amount of memory that will be needed to create a dictionary with following arguments */
  3403  *  Estimate amount of memory that will be needed to create a dictionary with following arguments */
  3188 size_t ZSTD_estimateCDictSize_advanced(
  3404 size_t ZSTD_estimateCDictSize_advanced(
  3189         size_t dictSize, ZSTD_compressionParameters cParams,
  3405         size_t dictSize, ZSTD_compressionParameters cParams,
  3190         ZSTD_dictLoadMethod_e dictLoadMethod)
  3406         ZSTD_dictLoadMethod_e dictLoadMethod)
  3191 {
  3407 {
  3192     DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
  3408     DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict));
  3193     return sizeof(ZSTD_CDict) + HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0)
  3409     return sizeof(ZSTD_CDict) + HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0)
  3194            + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
  3410            + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
  3195 }
  3411 }
  3196 
  3412 
  3197 size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
  3413 size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
  3201 }
  3417 }
  3202 
  3418 
  3203 size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
  3419 size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
  3204 {
  3420 {
  3205     if (cdict==NULL) return 0;   /* support sizeof on NULL */
  3421     if (cdict==NULL) return 0;   /* support sizeof on NULL */
  3206     DEBUGLOG(5, "sizeof(*cdict) : %u", (U32)sizeof(*cdict));
  3422     DEBUGLOG(5, "sizeof(*cdict) : %u", (unsigned)sizeof(*cdict));
  3207     return cdict->workspaceSize + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
  3423     return cdict->workspaceSize + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
  3208 }
  3424 }
  3209 
  3425 
  3210 static size_t ZSTD_initCDict_internal(
  3426 static size_t ZSTD_initCDict_internal(
  3211                     ZSTD_CDict* cdict,
  3427                     ZSTD_CDict* cdict,
  3212               const void* dictBuffer, size_t dictSize,
  3428               const void* dictBuffer, size_t dictSize,
  3213                     ZSTD_dictLoadMethod_e dictLoadMethod,
  3429                     ZSTD_dictLoadMethod_e dictLoadMethod,
  3214                     ZSTD_dictContentType_e dictContentType,
  3430                     ZSTD_dictContentType_e dictContentType,
  3215                     ZSTD_compressionParameters cParams)
  3431                     ZSTD_compressionParameters cParams)
  3216 {
  3432 {
  3217     DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (U32)dictContentType);
  3433     DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType);
  3218     assert(!ZSTD_checkCParams(cParams));
  3434     assert(!ZSTD_checkCParams(cParams));
  3219     cdict->matchState.cParams = cParams;
  3435     cdict->matchState.cParams = cParams;
  3220     if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
  3436     if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
  3221         cdict->dictBuffer = NULL;
  3437         cdict->dictBuffer = NULL;
  3222         cdict->dictContent = dictBuffer;
  3438         cdict->dictContent = dictBuffer;
  3262 ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
  3478 ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
  3263                                       ZSTD_dictLoadMethod_e dictLoadMethod,
  3479                                       ZSTD_dictLoadMethod_e dictLoadMethod,
  3264                                       ZSTD_dictContentType_e dictContentType,
  3480                                       ZSTD_dictContentType_e dictContentType,
  3265                                       ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
  3481                                       ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
  3266 {
  3482 {
  3267     DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (U32)dictContentType);
  3483     DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (unsigned)dictContentType);
  3268     if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
  3484     if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
  3269 
  3485 
  3270     {   ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
  3486     {   ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
  3271         size_t const workspaceSize = HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
  3487         size_t const workspaceSize = HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
  3272         void* const workspace = ZSTD_malloc(workspaceSize, customMem);
  3488         void* const workspace = ZSTD_malloc(workspaceSize, customMem);
  3343                             + HUF_WORKSPACE_SIZE + matchStateSize;
  3559                             + HUF_WORKSPACE_SIZE + matchStateSize;
  3344     ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
  3560     ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
  3345     void* ptr;
  3561     void* ptr;
  3346     if ((size_t)workspace & 7) return NULL;  /* 8-aligned */
  3562     if ((size_t)workspace & 7) return NULL;  /* 8-aligned */
  3347     DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
  3563     DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
  3348         (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
  3564         (unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
  3349     if (workspaceSize < neededSize) return NULL;
  3565     if (workspaceSize < neededSize) return NULL;
  3350 
  3566 
  3351     if (dictLoadMethod == ZSTD_dlm_byCopy) {
  3567     if (dictLoadMethod == ZSTD_dlm_byCopy) {
  3352         memcpy(cdict+1, dict, dictSize);
  3568         memcpy(cdict+1, dict, dictSize);
  3353         dict = cdict+1;
  3569         dict = cdict+1;
  3503 /* ZSTD_resetCStream():
  3719 /* ZSTD_resetCStream():
  3504  * pledgedSrcSize == 0 means "unknown" */
  3720  * pledgedSrcSize == 0 means "unknown" */
  3505 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
  3721 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
  3506 {
  3722 {
  3507     ZSTD_CCtx_params params = zcs->requestedParams;
  3723     ZSTD_CCtx_params params = zcs->requestedParams;
  3508     DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize);
  3724     DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (unsigned)pledgedSrcSize);
  3509     if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
  3725     if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
  3510     params.fParams.contentSizeFlag = 1;
  3726     params.fParams.contentSizeFlag = 1;
  3511     return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
  3727     return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
  3512 }
  3728 }
  3513 
  3729 
  3523     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
  3739     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
  3524     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  3740     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  3525     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3741     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3526 
  3742 
  3527     if (dict && dictSize >= 8) {
  3743     if (dict && dictSize >= 8) {
  3528         DEBUGLOG(4, "loading dictionary of size %u", (U32)dictSize);
  3744         DEBUGLOG(4, "loading dictionary of size %u", (unsigned)dictSize);
  3529         if (zcs->staticSize) {   /* static CCtx : never uses malloc */
  3745         if (zcs->staticSize) {   /* static CCtx : never uses malloc */
  3530             /* incompatible with internal cdict creation */
  3746             /* incompatible with internal cdict creation */
  3531             return ERROR(memory_allocation);
  3747             return ERROR(memory_allocation);
  3532         }
  3748         }
  3533         ZSTD_freeCDict(zcs->cdictLocal);
  3749         ZSTD_freeCDict(zcs->cdictLocal);
  3582 size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
  3798 size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
  3583                                  const void* dict, size_t dictSize,
  3799                                  const void* dict, size_t dictSize,
  3584                                  ZSTD_parameters params, unsigned long long pledgedSrcSize)
  3800                                  ZSTD_parameters params, unsigned long long pledgedSrcSize)
  3585 {
  3801 {
  3586     DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u",
  3802     DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u",
  3587                 (U32)pledgedSrcSize, params.fParams.contentSizeFlag);
  3803                 (unsigned)pledgedSrcSize, params.fParams.contentSizeFlag);
  3588     CHECK_F( ZSTD_checkCParams(params.cParams) );
  3804     CHECK_F( ZSTD_checkCParams(params.cParams) );
  3589     if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;  /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */
  3805     if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;  /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */
  3590     zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
  3806     zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
  3591     return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, zcs->requestedParams, pledgedSrcSize);
  3807     return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, zcs->requestedParams, pledgedSrcSize);
  3592 }
  3808 }
  3610     return ZSTD_initCStream_srcSize(zcs, compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN);
  3826     return ZSTD_initCStream_srcSize(zcs, compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN);
  3611 }
  3827 }
  3612 
  3828 
  3613 /*======   Compression   ======*/
  3829 /*======   Compression   ======*/
  3614 
  3830 
  3615 MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,
  3831 static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
  3616                            const void* src, size_t srcSize)
  3832 {
       
  3833     size_t hintInSize = cctx->inBuffTarget - cctx->inBuffPos;
       
  3834     if (hintInSize==0) hintInSize = cctx->blockSize;
       
  3835     return hintInSize;
       
  3836 }
       
  3837 
       
  3838 static size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,
       
  3839                        const void* src, size_t srcSize)
  3617 {
  3840 {
  3618     size_t const length = MIN(dstCapacity, srcSize);
  3841     size_t const length = MIN(dstCapacity, srcSize);
  3619     if (length) memcpy(dst, src, length);
  3842     if (length) memcpy(dst, src, length);
  3620     return length;
  3843     return length;
  3621 }
  3844 }
  3622 
  3845 
  3623 /** ZSTD_compressStream_generic():
  3846 /** ZSTD_compressStream_generic():
  3624  *  internal function for all *compressStream*() variants and *compress_generic()
  3847  *  internal function for all *compressStream*() variants
  3625  *  non-static, because can be called from zstdmt_compress.c
  3848  *  non-static, because can be called from zstdmt_compress.c
  3626  * @return : hint size for next input */
  3849  * @return : hint size for next input */
  3627 size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
  3850 size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
  3628                                    ZSTD_outBuffer* output,
  3851                                    ZSTD_outBuffer* output,
  3629                                    ZSTD_inBuffer* input,
  3852                                    ZSTD_inBuffer* input,
  3636     char* const oend = ostart + output->size;
  3859     char* const oend = ostart + output->size;
  3637     char* op = ostart + output->pos;
  3860     char* op = ostart + output->pos;
  3638     U32 someMoreWork = 1;
  3861     U32 someMoreWork = 1;
  3639 
  3862 
  3640     /* check expectations */
  3863     /* check expectations */
  3641     DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%u", (U32)flushMode);
  3864     DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%u", (unsigned)flushMode);
  3642     assert(zcs->inBuff != NULL);
  3865     assert(zcs->inBuff != NULL);
  3643     assert(zcs->inBuffSize > 0);
  3866     assert(zcs->inBuffSize > 0);
  3644     assert(zcs->outBuff !=  NULL);
  3867     assert(zcs->outBuff !=  NULL);
  3645     assert(zcs->outBuffSize > 0);
  3868     assert(zcs->outBuffSize > 0);
  3646     assert(output->pos <= output->size);
  3869     assert(output->pos <= output->size);
  3658               && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip))  /* enough dstCapacity */
  3881               && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip))  /* enough dstCapacity */
  3659               && (zcs->inBuffPos == 0) ) {
  3882               && (zcs->inBuffPos == 0) ) {
  3660                 /* shortcut to compression pass directly into output buffer */
  3883                 /* shortcut to compression pass directly into output buffer */
  3661                 size_t const cSize = ZSTD_compressEnd(zcs,
  3884                 size_t const cSize = ZSTD_compressEnd(zcs,
  3662                                                 op, oend-op, ip, iend-ip);
  3885                                                 op, oend-op, ip, iend-ip);
  3663                 DEBUGLOG(4, "ZSTD_compressEnd : %u", (U32)cSize);
  3886                 DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
  3664                 if (ZSTD_isError(cSize)) return cSize;
  3887                 if (ZSTD_isError(cSize)) return cSize;
  3665                 ip = iend;
  3888                 ip = iend;
  3666                 op += cSize;
  3889                 op += cSize;
  3667                 zcs->frameEnded = 1;
  3890                 zcs->frameEnded = 1;
  3668                 ZSTD_CCtx_reset(zcs);
  3891                 ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
  3669                 someMoreWork = 0; break;
  3892                 someMoreWork = 0; break;
  3670             }
  3893             }
  3671             /* complete loading into inBuffer */
  3894             /* complete loading into inBuffer */
  3672             {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
  3895             {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
  3673                 size_t const loaded = ZSTD_limitCopy(
  3896                 size_t const loaded = ZSTD_limitCopy(
  3707                 /* prepare next block */
  3930                 /* prepare next block */
  3708                 zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
  3931                 zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
  3709                 if (zcs->inBuffTarget > zcs->inBuffSize)
  3932                 if (zcs->inBuffTarget > zcs->inBuffSize)
  3710                     zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
  3933                     zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
  3711                 DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
  3934                 DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
  3712                          (U32)zcs->inBuffTarget, (U32)zcs->inBuffSize);
  3935                          (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
  3713                 if (!lastBlock)
  3936                 if (!lastBlock)
  3714                     assert(zcs->inBuffTarget <= zcs->inBuffSize);
  3937                     assert(zcs->inBuffTarget <= zcs->inBuffSize);
  3715                 zcs->inToCompress = zcs->inBuffPos;
  3938                 zcs->inToCompress = zcs->inBuffPos;
  3716                 if (cDst == op) {  /* no need to flush */
  3939                 if (cDst == op) {  /* no need to flush */
  3717                     op += cSize;
  3940                     op += cSize;
  3718                     if (zcs->frameEnded) {
  3941                     if (zcs->frameEnded) {
  3719                         DEBUGLOG(5, "Frame completed directly in outBuffer");
  3942                         DEBUGLOG(5, "Frame completed directly in outBuffer");
  3720                         someMoreWork = 0;
  3943                         someMoreWork = 0;
  3721                         ZSTD_CCtx_reset(zcs);
  3944                         ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
  3722                     }
  3945                     }
  3723                     break;
  3946                     break;
  3724                 }
  3947                 }
  3725                 zcs->outBuffContentSize = cSize;
  3948                 zcs->outBuffContentSize = cSize;
  3726                 zcs->outBuffFlushedSize = 0;
  3949                 zcs->outBuffFlushedSize = 0;
  3731             DEBUGLOG(5, "flush stage");
  3954             DEBUGLOG(5, "flush stage");
  3732             {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
  3955             {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
  3733                 size_t const flushed = ZSTD_limitCopy(op, oend-op,
  3956                 size_t const flushed = ZSTD_limitCopy(op, oend-op,
  3734                             zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
  3957                             zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
  3735                 DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
  3958                 DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
  3736                             (U32)toFlush, (U32)(oend-op), (U32)flushed);
  3959                             (unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);
  3737                 op += flushed;
  3960                 op += flushed;
  3738                 zcs->outBuffFlushedSize += flushed;
  3961                 zcs->outBuffFlushedSize += flushed;
  3739                 if (toFlush!=flushed) {
  3962                 if (toFlush!=flushed) {
  3740                     /* flush not fully completed, presumably because dst is too small */
  3963                     /* flush not fully completed, presumably because dst is too small */
  3741                     assert(op==oend);
  3964                     assert(op==oend);
  3744                 }
  3967                 }
  3745                 zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
  3968                 zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
  3746                 if (zcs->frameEnded) {
  3969                 if (zcs->frameEnded) {
  3747                     DEBUGLOG(5, "Frame completed on flush");
  3970                     DEBUGLOG(5, "Frame completed on flush");
  3748                     someMoreWork = 0;
  3971                     someMoreWork = 0;
  3749                     ZSTD_CCtx_reset(zcs);
  3972                     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
  3750                     break;
  3973                     break;
  3751                 }
  3974                 }
  3752                 zcs->streamStage = zcss_load;
  3975                 zcs->streamStage = zcss_load;
  3753                 break;
  3976                 break;
  3754             }
  3977             }
  3759     }
  3982     }
  3760 
  3983 
  3761     input->pos = ip - istart;
  3984     input->pos = ip - istart;
  3762     output->pos = op - ostart;
  3985     output->pos = op - ostart;
  3763     if (zcs->frameEnded) return 0;
  3986     if (zcs->frameEnded) return 0;
  3764     {   size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
  3987     return ZSTD_nextInputSizeHint(zcs);
  3765         if (hintInSize==0) hintInSize = zcs->blockSize;
  3988 }
  3766         return hintInSize;
  3989 
  3767     }
  3990 static size_t ZSTD_nextInputSizeHint_MTorST(const ZSTD_CCtx* cctx)
       
  3991 {
       
  3992 #ifdef ZSTD_MULTITHREAD
       
  3993     if (cctx->appliedParams.nbWorkers >= 1) {
       
  3994         assert(cctx->mtctx != NULL);
       
  3995         return ZSTDMT_nextInputSizeHint(cctx->mtctx);
       
  3996     }
       
  3997 #endif
       
  3998     return ZSTD_nextInputSizeHint(cctx);
       
  3999 
  3768 }
  4000 }
  3769 
  4001 
  3770 size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
  4002 size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
  3771 {
  4003 {
  3772     /* check conditions */
  4004     CHECK_F( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) );
  3773     if (output->pos > output->size) return ERROR(GENERIC);
  4005     return ZSTD_nextInputSizeHint_MTorST(zcs);
  3774     if (input->pos  > input->size)  return ERROR(GENERIC);
  4006 }
  3775 
  4007 
  3776     return ZSTD_compressStream_generic(zcs, output, input, ZSTD_e_continue);
  4008 
  3777 }
  4009 size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
  3778 
  4010                              ZSTD_outBuffer* output,
  3779 
  4011                              ZSTD_inBuffer* input,
  3780 size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
  4012                              ZSTD_EndDirective endOp)
  3781                               ZSTD_outBuffer* output,
  4013 {
  3782                               ZSTD_inBuffer* input,
  4014     DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
  3783                               ZSTD_EndDirective endOp)
       
  3784 {
       
  3785     DEBUGLOG(5, "ZSTD_compress_generic, endOp=%u ", (U32)endOp);
       
  3786     /* check conditions */
  4015     /* check conditions */
  3787     if (output->pos > output->size) return ERROR(GENERIC);
  4016     if (output->pos > output->size) return ERROR(GENERIC);
  3788     if (input->pos  > input->size)  return ERROR(GENERIC);
  4017     if (input->pos  > input->size)  return ERROR(GENERIC);
  3789     assert(cctx!=NULL);
  4018     assert(cctx!=NULL);
  3790 
  4019 
  3791     /* transparent initialization stage */
  4020     /* transparent initialization stage */
  3792     if (cctx->streamStage == zcss_init) {
  4021     if (cctx->streamStage == zcss_init) {
  3793         ZSTD_CCtx_params params = cctx->requestedParams;
  4022         ZSTD_CCtx_params params = cctx->requestedParams;
  3794         ZSTD_prefixDict const prefixDict = cctx->prefixDict;
  4023         ZSTD_prefixDict const prefixDict = cctx->prefixDict;
  3795         memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));  /* single usage */
  4024         memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));   /* single usage */
  3796         assert(prefixDict.dict==NULL || cctx->cdict==NULL);   /* only one can be set */
  4025         assert(prefixDict.dict==NULL || cctx->cdict==NULL);    /* only one can be set */
  3797         DEBUGLOG(4, "ZSTD_compress_generic : transparent init stage");
  4026         DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
  3798         if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */
  4027         if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */
  3799         params.cParams = ZSTD_getCParamsFromCCtxParams(
  4028         params.cParams = ZSTD_getCParamsFromCCtxParams(
  3800                 &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
  4029                 &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
  3801 
  4030 
  3802 
  4031 
  3805             params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
  4034             params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
  3806         }
  4035         }
  3807         if (params.nbWorkers > 0) {
  4036         if (params.nbWorkers > 0) {
  3808             /* mt context creation */
  4037             /* mt context creation */
  3809             if (cctx->mtctx == NULL) {
  4038             if (cctx->mtctx == NULL) {
  3810                 DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u",
  4039                 DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
  3811                             params.nbWorkers);
  4040                             params.nbWorkers);
  3812                 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
  4041                 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
  3813                 if (cctx->mtctx == NULL) return ERROR(memory_allocation);
  4042                 if (cctx->mtctx == NULL) return ERROR(memory_allocation);
  3814             }
  4043             }
  3815             /* mt compression */
  4044             /* mt compression */
  3827                             cctx->cdict,
  4056                             cctx->cdict,
  3828                             params, cctx->pledgedSrcSizePlusOne-1) );
  4057                             params, cctx->pledgedSrcSizePlusOne-1) );
  3829             assert(cctx->streamStage == zcss_load);
  4058             assert(cctx->streamStage == zcss_load);
  3830             assert(cctx->appliedParams.nbWorkers == 0);
  4059             assert(cctx->appliedParams.nbWorkers == 0);
  3831     }   }
  4060     }   }
       
  4061     /* end of transparent initialization stage */
  3832 
  4062 
  3833     /* compression stage */
  4063     /* compression stage */
  3834 #ifdef ZSTD_MULTITHREAD
  4064 #ifdef ZSTD_MULTITHREAD
  3835     if (cctx->appliedParams.nbWorkers > 0) {
  4065     if (cctx->appliedParams.nbWorkers > 0) {
  3836         if (cctx->cParamsChanged) {
  4066         if (cctx->cParamsChanged) {
  3838             cctx->cParamsChanged = 0;
  4068             cctx->cParamsChanged = 0;
  3839         }
  4069         }
  3840         {   size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
  4070         {   size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
  3841             if ( ZSTD_isError(flushMin)
  4071             if ( ZSTD_isError(flushMin)
  3842               || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
  4072               || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
  3843                 ZSTD_CCtx_reset(cctx);
  4073                 ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
  3844             }
  4074             }
  3845             DEBUGLOG(5, "completed ZSTD_compress_generic delegating to ZSTDMT_compressStream_generic");
  4075             DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
  3846             return flushMin;
  4076             return flushMin;
  3847     }   }
  4077     }   }
  3848 #endif
  4078 #endif
  3849     CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
  4079     CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
  3850     DEBUGLOG(5, "completed ZSTD_compress_generic");
  4080     DEBUGLOG(5, "completed ZSTD_compressStream2");
  3851     return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
  4081     return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
  3852 }
  4082 }
  3853 
  4083 
  3854 size_t ZSTD_compress_generic_simpleArgs (
  4084 size_t ZSTD_compressStream2_simpleArgs (
  3855                             ZSTD_CCtx* cctx,
  4085                             ZSTD_CCtx* cctx,
  3856                             void* dst, size_t dstCapacity, size_t* dstPos,
  4086                             void* dst, size_t dstCapacity, size_t* dstPos,
  3857                       const void* src, size_t srcSize, size_t* srcPos,
  4087                       const void* src, size_t srcSize, size_t* srcPos,
  3858                             ZSTD_EndDirective endOp)
  4088                             ZSTD_EndDirective endOp)
  3859 {
  4089 {
  3860     ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
  4090     ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
  3861     ZSTD_inBuffer  input  = { src, srcSize, *srcPos };
  4091     ZSTD_inBuffer  input  = { src, srcSize, *srcPos };
  3862     /* ZSTD_compress_generic() will check validity of dstPos and srcPos */
  4092     /* ZSTD_compressStream2() will check validity of dstPos and srcPos */
  3863     size_t const cErr = ZSTD_compress_generic(cctx, &output, &input, endOp);
  4093     size_t const cErr = ZSTD_compressStream2(cctx, &output, &input, endOp);
  3864     *dstPos = output.pos;
  4094     *dstPos = output.pos;
  3865     *srcPos = input.pos;
  4095     *srcPos = input.pos;
  3866     return cErr;
  4096     return cErr;
  3867 }
  4097 }
  3868 
  4098 
       
  4099 size_t ZSTD_compress2(ZSTD_CCtx* cctx,
       
  4100                       void* dst, size_t dstCapacity,
       
  4101                       const void* src, size_t srcSize)
       
  4102 {
       
  4103     ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
       
  4104     {   size_t oPos = 0;
       
  4105         size_t iPos = 0;
       
  4106         size_t const result = ZSTD_compressStream2_simpleArgs(cctx,
       
  4107                                         dst, dstCapacity, &oPos,
       
  4108                                         src, srcSize, &iPos,
       
  4109                                         ZSTD_e_end);
       
  4110         if (ZSTD_isError(result)) return result;
       
  4111         if (result != 0) {  /* compression not completed, due to lack of output space */
       
  4112             assert(oPos == dstCapacity);
       
  4113             return ERROR(dstSize_tooSmall);
       
  4114         }
       
  4115         assert(iPos == srcSize);   /* all input is expected consumed */
       
  4116         return oPos;
       
  4117     }
       
  4118 }
  3869 
  4119 
  3870 /*======   Finalize   ======*/
  4120 /*======   Finalize   ======*/
  3871 
  4121 
  3872 /*! ZSTD_flushStream() :
  4122 /*! ZSTD_flushStream() :
  3873  * @return : amount of data remaining to flush */
  4123  * @return : amount of data remaining to flush */
  3874 size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
  4124 size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
  3875 {
  4125 {
  3876     ZSTD_inBuffer input = { NULL, 0, 0 };
  4126     ZSTD_inBuffer input = { NULL, 0, 0 };
  3877     if (output->pos > output->size) return ERROR(GENERIC);
  4127     return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush);
  3878     CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_flush) );
       
  3879     return zcs->outBuffContentSize - zcs->outBuffFlushedSize;  /* remaining to flush */
       
  3880 }
  4128 }
  3881 
  4129 
  3882 
  4130 
  3883 size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
  4131 size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
  3884 {
  4132 {
  3885     ZSTD_inBuffer input = { NULL, 0, 0 };
  4133     ZSTD_inBuffer input = { NULL, 0, 0 };
  3886     if (output->pos > output->size) return ERROR(GENERIC);
  4134     size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
  3887     CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_end) );
  4135     CHECK_F( remainingToFlush );
       
  4136     if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush;   /* minimal estimation */
       
  4137     /* single thread mode : attempt to calculate remaining to flush more precisely */
  3888     {   size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
  4138     {   size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
  3889         size_t const checksumSize = zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4;
  4139         size_t const checksumSize = zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4;
  3890         size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize + lastBlockSize + checksumSize;
  4140         size_t const toFlush = remainingToFlush + lastBlockSize + checksumSize;
  3891         DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (U32)toFlush);
  4141         DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (unsigned)toFlush);
  3892         return toFlush;
  4142         return toFlush;
  3893     }
  4143     }
  3894 }
  4144 }
  3895 
  4145 
  3896 
  4146 
  3903 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
  4153 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
  3904 {   /* "default" - guarantees a monotonically increasing memory budget */
  4154 {   /* "default" - guarantees a monotonically increasing memory budget */
  3905     /* W,  C,  H,  S,  L, TL, strat */
  4155     /* W,  C,  H,  S,  L, TL, strat */
  3906     { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */
  4156     { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */
  3907     { 19, 13, 14,  1,  7,  0, ZSTD_fast    },  /* level  1 */
  4157     { 19, 13, 14,  1,  7,  0, ZSTD_fast    },  /* level  1 */
  3908     { 19, 15, 16,  1,  6,  0, ZSTD_fast    },  /* level  2 */
  4158     { 20, 15, 16,  1,  6,  0, ZSTD_fast    },  /* level  2 */
  3909     { 20, 16, 17,  1,  5,  1, ZSTD_dfast   },  /* level  3 */
  4159     { 21, 16, 17,  1,  5,  1, ZSTD_dfast   },  /* level  3 */
  3910     { 20, 18, 18,  1,  5,  1, ZSTD_dfast   },  /* level  4 */
  4160     { 21, 18, 18,  1,  5,  1, ZSTD_dfast   },  /* level  4 */
  3911     { 20, 18, 18,  2,  5,  2, ZSTD_greedy  },  /* level  5 */
  4161     { 21, 18, 19,  2,  5,  2, ZSTD_greedy  },  /* level  5 */
  3912     { 21, 18, 19,  2,  5,  4, ZSTD_lazy    },  /* level  6 */
  4162     { 21, 19, 19,  3,  5,  4, ZSTD_greedy  },  /* level  6 */
  3913     { 21, 18, 19,  3,  5,  8, ZSTD_lazy2   },  /* level  7 */
  4163     { 21, 19, 19,  3,  5,  8, ZSTD_lazy    },  /* level  7 */
  3914     { 21, 19, 19,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
  4164     { 21, 19, 19,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
  3915     { 21, 19, 20,  4,  5, 16, ZSTD_lazy2   },  /* level  9 */
  4165     { 21, 19, 20,  4,  5, 16, ZSTD_lazy2   },  /* level  9 */
  3916     { 21, 20, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
  4166     { 22, 20, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
  3917     { 21, 21, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
  4167     { 22, 21, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
  3918     { 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
  4168     { 22, 21, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
  3919     { 22, 21, 22,  4,  5, 32, ZSTD_btlazy2 },  /* level 13 */
  4169     { 22, 21, 22,  5,  5, 32, ZSTD_btlazy2 },  /* level 13 */
  3920     { 22, 21, 22,  5,  5, 32, ZSTD_btlazy2 },  /* level 14 */
  4170     { 22, 22, 23,  5,  5, 32, ZSTD_btlazy2 },  /* level 14 */
  3921     { 22, 22, 22,  6,  5, 32, ZSTD_btlazy2 },  /* level 15 */
  4171     { 22, 23, 23,  6,  5, 32, ZSTD_btlazy2 },  /* level 15 */
  3922     { 22, 21, 22,  4,  5, 48, ZSTD_btopt   },  /* level 16 */
  4172     { 22, 22, 22,  5,  5, 48, ZSTD_btopt   },  /* level 16 */
  3923     { 23, 22, 22,  4,  4, 64, ZSTD_btopt   },  /* level 17 */
  4173     { 23, 23, 22,  5,  4, 64, ZSTD_btopt   },  /* level 17 */
  3924     { 23, 23, 22,  6,  3,256, ZSTD_btopt   },  /* level 18 */
  4174     { 23, 23, 22,  6,  3, 64, ZSTD_btultra },  /* level 18 */
  3925     { 23, 24, 22,  7,  3,256, ZSTD_btultra },  /* level 19 */
  4175     { 23, 24, 22,  7,  3,256, ZSTD_btultra2},  /* level 19 */
  3926     { 25, 25, 23,  7,  3,256, ZSTD_btultra },  /* level 20 */
  4176     { 25, 25, 23,  7,  3,256, ZSTD_btultra2},  /* level 20 */
  3927     { 26, 26, 24,  7,  3,512, ZSTD_btultra },  /* level 21 */
  4177     { 26, 26, 24,  7,  3,512, ZSTD_btultra2},  /* level 21 */
  3928     { 27, 27, 25,  9,  3,999, ZSTD_btultra },  /* level 22 */
  4178     { 27, 27, 25,  9,  3,999, ZSTD_btultra2},  /* level 22 */
  3929 },
  4179 },
  3930 {   /* for srcSize <= 256 KB */
  4180 {   /* for srcSize <= 256 KB */
  3931     /* W,  C,  H,  S,  L,  T, strat */
  4181     /* W,  C,  H,  S,  L,  T, strat */
  3932     { 18, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  4182     { 18, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3933     { 18, 13, 14,  1,  6,  0, ZSTD_fast    },  /* level  1 */
  4183     { 18, 13, 14,  1,  6,  0, ZSTD_fast    },  /* level  1 */
  3938     { 18, 18, 19,  3,  5,  4, ZSTD_lazy    },  /* level  6.*/
  4188     { 18, 18, 19,  3,  5,  4, ZSTD_lazy    },  /* level  6.*/
  3939     { 18, 18, 19,  4,  4,  4, ZSTD_lazy    },  /* level  7 */
  4189     { 18, 18, 19,  4,  4,  4, ZSTD_lazy    },  /* level  7 */
  3940     { 18, 18, 19,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  4190     { 18, 18, 19,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  3941     { 18, 18, 19,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  4191     { 18, 18, 19,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  3942     { 18, 18, 19,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  4192     { 18, 18, 19,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  3943     { 18, 18, 19,  5,  4, 16, ZSTD_btlazy2 },  /* level 11.*/
  4193     { 18, 18, 19,  5,  4, 12, ZSTD_btlazy2 },  /* level 11.*/
  3944     { 18, 19, 19,  6,  4, 16, ZSTD_btlazy2 },  /* level 12.*/
  4194     { 18, 19, 19,  7,  4, 12, ZSTD_btlazy2 },  /* level 12.*/
  3945     { 18, 19, 19,  8,  4, 16, ZSTD_btlazy2 },  /* level 13 */
  4195     { 18, 18, 19,  4,  4, 16, ZSTD_btopt   },  /* level 13 */
  3946     { 18, 18, 19,  4,  4, 24, ZSTD_btopt   },  /* level 14.*/
  4196     { 18, 18, 19,  4,  3, 32, ZSTD_btopt   },  /* level 14.*/
  3947     { 18, 18, 19,  4,  3, 24, ZSTD_btopt   },  /* level 15.*/
  4197     { 18, 18, 19,  6,  3,128, ZSTD_btopt   },  /* level 15.*/
  3948     { 18, 19, 19,  6,  3, 64, ZSTD_btopt   },  /* level 16.*/
  4198     { 18, 19, 19,  6,  3,128, ZSTD_btultra },  /* level 16.*/
  3949     { 18, 19, 19,  8,  3,128, ZSTD_btopt   },  /* level 17.*/
  4199     { 18, 19, 19,  8,  3,256, ZSTD_btultra },  /* level 17.*/
  3950     { 18, 19, 19, 10,  3,256, ZSTD_btopt   },  /* level 18.*/
  4200     { 18, 19, 19,  6,  3,128, ZSTD_btultra2},  /* level 18.*/
  3951     { 18, 19, 19, 10,  3,256, ZSTD_btultra },  /* level 19.*/
  4201     { 18, 19, 19,  8,  3,256, ZSTD_btultra2},  /* level 19.*/
  3952     { 18, 19, 19, 11,  3,512, ZSTD_btultra },  /* level 20.*/
  4202     { 18, 19, 19, 10,  3,512, ZSTD_btultra2},  /* level 20.*/
  3953     { 18, 19, 19, 12,  3,512, ZSTD_btultra },  /* level 21.*/
  4203     { 18, 19, 19, 12,  3,512, ZSTD_btultra2},  /* level 21.*/
  3954     { 18, 19, 19, 13,  3,999, ZSTD_btultra },  /* level 22.*/
  4204     { 18, 19, 19, 13,  3,999, ZSTD_btultra2},  /* level 22.*/
  3955 },
  4205 },
  3956 {   /* for srcSize <= 128 KB */
  4206 {   /* for srcSize <= 128 KB */
  3957     /* W,  C,  H,  S,  L,  T, strat */
  4207     /* W,  C,  H,  S,  L,  T, strat */
  3958     { 17, 12, 12,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  4208     { 17, 12, 12,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3959     { 17, 12, 13,  1,  6,  0, ZSTD_fast    },  /* level  1 */
  4209     { 17, 12, 13,  1,  6,  0, ZSTD_fast    },  /* level  1 */
  3964     { 17, 17, 17,  3,  4,  4, ZSTD_lazy    },  /* level  6 */
  4214     { 17, 17, 17,  3,  4,  4, ZSTD_lazy    },  /* level  6 */
  3965     { 17, 17, 17,  3,  4,  8, ZSTD_lazy2   },  /* level  7 */
  4215     { 17, 17, 17,  3,  4,  8, ZSTD_lazy2   },  /* level  7 */
  3966     { 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  4216     { 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  3967     { 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  4217     { 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  3968     { 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  4218     { 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  3969     { 17, 17, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 11 */
  4219     { 17, 17, 17,  5,  4,  8, ZSTD_btlazy2 },  /* level 11 */
  3970     { 17, 18, 17,  6,  4, 16, ZSTD_btlazy2 },  /* level 12 */
  4220     { 17, 18, 17,  7,  4, 12, ZSTD_btlazy2 },  /* level 12 */
  3971     { 17, 18, 17,  8,  4, 16, ZSTD_btlazy2 },  /* level 13.*/
  4221     { 17, 18, 17,  3,  4, 12, ZSTD_btopt   },  /* level 13.*/
  3972     { 17, 18, 17,  4,  4, 32, ZSTD_btopt   },  /* level 14.*/
  4222     { 17, 18, 17,  4,  3, 32, ZSTD_btopt   },  /* level 14.*/
  3973     { 17, 18, 17,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
  4223     { 17, 18, 17,  6,  3,256, ZSTD_btopt   },  /* level 15.*/
  3974     { 17, 18, 17,  7,  3,128, ZSTD_btopt   },  /* level 16.*/
  4224     { 17, 18, 17,  6,  3,128, ZSTD_btultra },  /* level 16.*/
  3975     { 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 17.*/
  4225     { 17, 18, 17,  8,  3,256, ZSTD_btultra },  /* level 17.*/
  3976     { 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 18.*/
  4226     { 17, 18, 17, 10,  3,512, ZSTD_btultra },  /* level 18.*/
  3977     { 17, 18, 17,  8,  3,256, ZSTD_btultra },  /* level 19.*/
  4227     { 17, 18, 17,  5,  3,256, ZSTD_btultra2},  /* level 19.*/
  3978     { 17, 18, 17,  9,  3,256, ZSTD_btultra },  /* level 20.*/
  4228     { 17, 18, 17,  7,  3,512, ZSTD_btultra2},  /* level 20.*/
  3979     { 17, 18, 17, 10,  3,256, ZSTD_btultra },  /* level 21.*/
  4229     { 17, 18, 17,  9,  3,512, ZSTD_btultra2},  /* level 21.*/
  3980     { 17, 18, 17, 11,  3,512, ZSTD_btultra },  /* level 22.*/
  4230     { 17, 18, 17, 11,  3,999, ZSTD_btultra2},  /* level 22.*/
  3981 },
  4231 },
  3982 {   /* for srcSize <= 16 KB */
  4232 {   /* for srcSize <= 16 KB */
  3983     /* W,  C,  H,  S,  L,  T, strat */
  4233     /* W,  C,  H,  S,  L,  T, strat */
  3984     { 14, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  4234     { 14, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3985     { 14, 14, 15,  1,  5,  0, ZSTD_fast    },  /* level  1 */
  4235     { 14, 14, 15,  1,  5,  0, ZSTD_fast    },  /* level  1 */
  3986     { 14, 14, 15,  1,  4,  0, ZSTD_fast    },  /* level  2 */
  4236     { 14, 14, 15,  1,  4,  0, ZSTD_fast    },  /* level  2 */
  3987     { 14, 14, 14,  2,  4,  1, ZSTD_dfast   },  /* level  3.*/
  4237     { 14, 14, 15,  2,  4,  1, ZSTD_dfast   },  /* level  3 */
  3988     { 14, 14, 14,  4,  4,  2, ZSTD_greedy  },  /* level  4.*/
  4238     { 14, 14, 14,  4,  4,  2, ZSTD_greedy  },  /* level  4 */
  3989     { 14, 14, 14,  3,  4,  4, ZSTD_lazy    },  /* level  5.*/
  4239     { 14, 14, 14,  3,  4,  4, ZSTD_lazy    },  /* level  5.*/
  3990     { 14, 14, 14,  4,  4,  8, ZSTD_lazy2   },  /* level  6 */
  4240     { 14, 14, 14,  4,  4,  8, ZSTD_lazy2   },  /* level  6 */
  3991     { 14, 14, 14,  6,  4,  8, ZSTD_lazy2   },  /* level  7 */
  4241     { 14, 14, 14,  6,  4,  8, ZSTD_lazy2   },  /* level  7 */
  3992     { 14, 14, 14,  8,  4,  8, ZSTD_lazy2   },  /* level  8.*/
  4242     { 14, 14, 14,  8,  4,  8, ZSTD_lazy2   },  /* level  8.*/
  3993     { 14, 15, 14,  5,  4,  8, ZSTD_btlazy2 },  /* level  9.*/
  4243     { 14, 15, 14,  5,  4,  8, ZSTD_btlazy2 },  /* level  9.*/
  3994     { 14, 15, 14,  9,  4,  8, ZSTD_btlazy2 },  /* level 10.*/
  4244     { 14, 15, 14,  9,  4,  8, ZSTD_btlazy2 },  /* level 10.*/
  3995     { 14, 15, 14,  3,  4, 12, ZSTD_btopt   },  /* level 11.*/
  4245     { 14, 15, 14,  3,  4, 12, ZSTD_btopt   },  /* level 11.*/
  3996     { 14, 15, 14,  6,  3, 16, ZSTD_btopt   },  /* level 12.*/
  4246     { 14, 15, 14,  4,  3, 24, ZSTD_btopt   },  /* level 12.*/
  3997     { 14, 15, 14,  6,  3, 24, ZSTD_btopt   },  /* level 13.*/
  4247     { 14, 15, 14,  5,  3, 32, ZSTD_btultra },  /* level 13.*/
  3998     { 14, 15, 15,  6,  3, 48, ZSTD_btopt   },  /* level 14.*/
  4248     { 14, 15, 15,  6,  3, 64, ZSTD_btultra },  /* level 14.*/
  3999     { 14, 15, 15,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
  4249     { 14, 15, 15,  7,  3,256, ZSTD_btultra },  /* level 15.*/
  4000     { 14, 15, 15,  6,  3, 96, ZSTD_btopt   },  /* level 16.*/
  4250     { 14, 15, 15,  5,  3, 48, ZSTD_btultra2},  /* level 16.*/
  4001     { 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
  4251     { 14, 15, 15,  6,  3,128, ZSTD_btultra2},  /* level 17.*/
  4002     { 14, 15, 15,  8,  3,256, ZSTD_btopt   },  /* level 18.*/
  4252     { 14, 15, 15,  7,  3,256, ZSTD_btultra2},  /* level 18.*/
  4003     { 14, 15, 15,  6,  3,256, ZSTD_btultra },  /* level 19.*/
  4253     { 14, 15, 15,  8,  3,256, ZSTD_btultra2},  /* level 19.*/
  4004     { 14, 15, 15,  8,  3,256, ZSTD_btultra },  /* level 20.*/
  4254     { 14, 15, 15,  8,  3,512, ZSTD_btultra2},  /* level 20.*/
  4005     { 14, 15, 15,  9,  3,256, ZSTD_btultra },  /* level 21.*/
  4255     { 14, 15, 15,  9,  3,512, ZSTD_btultra2},  /* level 21.*/
  4006     { 14, 15, 15, 10,  3,512, ZSTD_btultra },  /* level 22.*/
  4256     { 14, 15, 15, 10,  3,999, ZSTD_btultra2},  /* level 22.*/
  4007 },
  4257 },
  4008 };
  4258 };
  4009 
  4259 
  4010 /*! ZSTD_getCParams() :
  4260 /*! ZSTD_getCParams() :
  4011 *  @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
  4261 *  @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
  4020     if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT;   /* 0 == default */
  4270     if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT;   /* 0 == default */
  4021     if (compressionLevel < 0) row = 0;   /* entry 0 is baseline for fast mode */
  4271     if (compressionLevel < 0) row = 0;   /* entry 0 is baseline for fast mode */
  4022     if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
  4272     if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
  4023     {   ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
  4273     {   ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
  4024         if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel);   /* acceleration factor */
  4274         if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel);   /* acceleration factor */
  4025         return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); }
  4275         return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);
  4026 
  4276     }
  4027 }
  4277 }
  4028 
  4278 
  4029 /*! ZSTD_getParams() :
  4279 /*! ZSTD_getParams() :
  4030 *   same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
  4280 *   same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
  4031 *   All fields of `ZSTD_frameParameters` are set to default (0) */
  4281 *   All fields of `ZSTD_frameParameters` are set to default (0) */