contrib/python-zstandard/zstd/compress/zstd_compress.c
changeset 42937 69de49c4e39c
parent 42070 675775c33ab6
child 43994 de7838053207
equal deleted inserted replaced
42936:2da754532dd3 42937:69de49c4e39c
    19 #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
    19 #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
    20 #include "fse.h"
    20 #include "fse.h"
    21 #define HUF_STATIC_LINKING_ONLY
    21 #define HUF_STATIC_LINKING_ONLY
    22 #include "huf.h"
    22 #include "huf.h"
    23 #include "zstd_compress_internal.h"
    23 #include "zstd_compress_internal.h"
       
    24 #include "zstd_compress_sequences.h"
       
    25 #include "zstd_compress_literals.h"
    24 #include "zstd_fast.h"
    26 #include "zstd_fast.h"
    25 #include "zstd_double_fast.h"
    27 #include "zstd_double_fast.h"
    26 #include "zstd_lazy.h"
    28 #include "zstd_lazy.h"
    27 #include "zstd_opt.h"
    29 #include "zstd_opt.h"
    28 #include "zstd_ldm.h"
    30 #include "zstd_ldm.h"
   101     }
   103     }
   102     cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
   104     cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
   103     return cctx;
   105     return cctx;
   104 }
   106 }
   105 
   107 
       
   108 /**
       
   109  * Clears and frees all of the dictionaries in the CCtx.
       
   110  */
       
   111 static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx)
       
   112 {
       
   113     ZSTD_free(cctx->localDict.dictBuffer, cctx->customMem);
       
   114     ZSTD_freeCDict(cctx->localDict.cdict);
       
   115     memset(&cctx->localDict, 0, sizeof(cctx->localDict));
       
   116     memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));
       
   117     cctx->cdict = NULL;
       
   118 }
       
   119 
       
   120 static size_t ZSTD_sizeof_localDict(ZSTD_localDict dict)
       
   121 {
       
   122     size_t const bufferSize = dict.dictBuffer != NULL ? dict.dictSize : 0;
       
   123     size_t const cdictSize = ZSTD_sizeof_CDict(dict.cdict);
       
   124     return bufferSize + cdictSize;
       
   125 }
       
   126 
   106 static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
   127 static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
   107 {
   128 {
   108     assert(cctx != NULL);
   129     assert(cctx != NULL);
   109     assert(cctx->staticSize == 0);
   130     assert(cctx->staticSize == 0);
   110     ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
   131     ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
   111     ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL;
   132     ZSTD_clearAllDicts(cctx);
   112 #ifdef ZSTD_MULTITHREAD
   133 #ifdef ZSTD_MULTITHREAD
   113     ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
   134     ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
   114 #endif
   135 #endif
   115 }
   136 }
   116 
   137 
   117 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
   138 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
   118 {
   139 {
   119     if (cctx==NULL) return 0;   /* support free on NULL */
   140     if (cctx==NULL) return 0;   /* support free on NULL */
   120     if (cctx->staticSize) return ERROR(memory_allocation);   /* not compatible with static CCtx */
   141     RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
       
   142                     "not compatible with static CCtx");
   121     ZSTD_freeCCtxContent(cctx);
   143     ZSTD_freeCCtxContent(cctx);
   122     ZSTD_free(cctx, cctx->customMem);
   144     ZSTD_free(cctx, cctx->customMem);
   123     return 0;
   145     return 0;
   124 }
   146 }
   125 
   147 
   137 
   159 
   138 size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
   160 size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
   139 {
   161 {
   140     if (cctx==NULL) return 0;   /* support sizeof on NULL */
   162     if (cctx==NULL) return 0;   /* support sizeof on NULL */
   141     return sizeof(*cctx) + cctx->workSpaceSize
   163     return sizeof(*cctx) + cctx->workSpaceSize
   142            + ZSTD_sizeof_CDict(cctx->cdictLocal)
   164            + ZSTD_sizeof_localDict(cctx->localDict)
   143            + ZSTD_sizeof_mtctx(cctx);
   165            + ZSTD_sizeof_mtctx(cctx);
   144 }
   166 }
   145 
   167 
   146 size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
   168 size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
   147 {
   169 {
   193 {
   215 {
   194     return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);
   216     return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);
   195 }
   217 }
   196 
   218 
   197 size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
   219 size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
   198     if (!cctxParams) { return ERROR(GENERIC); }
   220     RETURN_ERROR_IF(!cctxParams, GENERIC);
   199     memset(cctxParams, 0, sizeof(*cctxParams));
   221     memset(cctxParams, 0, sizeof(*cctxParams));
   200     cctxParams->compressionLevel = compressionLevel;
   222     cctxParams->compressionLevel = compressionLevel;
   201     cctxParams->fParams.contentSizeFlag = 1;
   223     cctxParams->fParams.contentSizeFlag = 1;
   202     return 0;
   224     return 0;
   203 }
   225 }
   204 
   226 
   205 size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
   227 size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
   206 {
   228 {
   207     if (!cctxParams) { return ERROR(GENERIC); }
   229     RETURN_ERROR_IF(!cctxParams, GENERIC);
   208     CHECK_F( ZSTD_checkCParams(params.cParams) );
   230     FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
   209     memset(cctxParams, 0, sizeof(*cctxParams));
   231     memset(cctxParams, 0, sizeof(*cctxParams));
   210     cctxParams->cParams = params.cParams;
   232     cctxParams->cParams = params.cParams;
   211     cctxParams->fParams = params.fParams;
   233     cctxParams->fParams = params.fParams;
   212     cctxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* should not matter, as all cParams are presumed properly defined */
   234     cctxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* should not matter, as all cParams are presumed properly defined */
   213     assert(!ZSTD_checkCParams(params.cParams));
   235     assert(!ZSTD_checkCParams(params.cParams));
   357         ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceCopy);
   379         ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceCopy);
   358         bounds.lowerBound = ZSTD_dictDefaultAttach;
   380         bounds.lowerBound = ZSTD_dictDefaultAttach;
   359         bounds.upperBound = ZSTD_dictForceCopy;       /* note : how to ensure at compile time that this is the highest value enum ? */
   381         bounds.upperBound = ZSTD_dictForceCopy;       /* note : how to ensure at compile time that this is the highest value enum ? */
   360         return bounds;
   382         return bounds;
   361 
   383 
       
   384     case ZSTD_c_literalCompressionMode:
       
   385         ZSTD_STATIC_ASSERT(ZSTD_lcm_auto < ZSTD_lcm_huffman && ZSTD_lcm_huffman < ZSTD_lcm_uncompressed);
       
   386         bounds.lowerBound = ZSTD_lcm_auto;
       
   387         bounds.upperBound = ZSTD_lcm_uncompressed;
       
   388         return bounds;
       
   389 
       
   390     case ZSTD_c_targetCBlockSize:
       
   391         bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN;
       
   392         bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX;
       
   393         return bounds;
       
   394 
   362     default:
   395     default:
   363         {   ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };
   396         {   ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };
   364             return boundError;
   397             return boundError;
   365         }
   398         }
   366     }
   399     }
   367 }
   400 }
   368 
   401 
   369 /* ZSTD_cParam_withinBounds:
   402 /* ZSTD_cParam_clampBounds:
   370  * @return 1 if value is within cParam bounds,
   403  * Clamps the value into the bounded range.
   371  * 0 otherwise */
   404  */
   372 static int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
   405 static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value)
   373 {
   406 {
   374     ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
   407     ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
   375     if (ZSTD_isError(bounds.error)) return 0;
   408     if (ZSTD_isError(bounds.error)) return bounds.error;
   376     if (value < bounds.lowerBound) return 0;
   409     if (*value < bounds.lowerBound) *value = bounds.lowerBound;
   377     if (value > bounds.upperBound) return 0;
   410     if (*value > bounds.upperBound) *value = bounds.upperBound;
   378     return 1;
   411     return 0;
   379 }
   412 }
   380 
   413 
   381 #define BOUNDCHECK(cParam, val) {                  \
   414 #define BOUNDCHECK(cParam, val) { \
   382     if (!ZSTD_cParam_withinBounds(cParam,val)) {   \
   415     RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \
   383         return ERROR(parameter_outOfBound);        \
   416                     parameter_outOfBound); \
   384 }   }
   417 }
   385 
   418 
   386 
   419 
   387 static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
   420 static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
   388 {
   421 {
   389     switch(param)
   422     switch(param)
   411     case ZSTD_c_ldmHashLog:
   444     case ZSTD_c_ldmHashLog:
   412     case ZSTD_c_ldmMinMatch:
   445     case ZSTD_c_ldmMinMatch:
   413     case ZSTD_c_ldmBucketSizeLog:
   446     case ZSTD_c_ldmBucketSizeLog:
   414     case ZSTD_c_ldmHashRateLog:
   447     case ZSTD_c_ldmHashRateLog:
   415     case ZSTD_c_forceAttachDict:
   448     case ZSTD_c_forceAttachDict:
       
   449     case ZSTD_c_literalCompressionMode:
       
   450     case ZSTD_c_targetCBlockSize:
   416     default:
   451     default:
   417         return 0;
   452         return 0;
   418     }
   453     }
   419 }
   454 }
   420 
   455 
   423     DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value);
   458     DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value);
   424     if (cctx->streamStage != zcss_init) {
   459     if (cctx->streamStage != zcss_init) {
   425         if (ZSTD_isUpdateAuthorized(param)) {
   460         if (ZSTD_isUpdateAuthorized(param)) {
   426             cctx->cParamsChanged = 1;
   461             cctx->cParamsChanged = 1;
   427         } else {
   462         } else {
   428             return ERROR(stage_wrong);
   463             RETURN_ERROR(stage_wrong);
   429     }   }
   464     }   }
   430 
   465 
   431     switch(param)
   466     switch(param)
   432     {
   467     {
   433     case ZSTD_c_format :
   468     case ZSTD_c_nbWorkers:
   434         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   469         RETURN_ERROR_IF((value!=0) && cctx->staticSize, parameter_unsupported,
       
   470                         "MT not compatible with static alloc");
       
   471         break;
   435 
   472 
   436     case ZSTD_c_compressionLevel:
   473     case ZSTD_c_compressionLevel:
   437         if (cctx->cdict) return ERROR(stage_wrong);
       
   438         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
       
   439 
       
   440     case ZSTD_c_windowLog:
   474     case ZSTD_c_windowLog:
   441     case ZSTD_c_hashLog:
   475     case ZSTD_c_hashLog:
   442     case ZSTD_c_chainLog:
   476     case ZSTD_c_chainLog:
   443     case ZSTD_c_searchLog:
   477     case ZSTD_c_searchLog:
   444     case ZSTD_c_minMatch:
   478     case ZSTD_c_minMatch:
   445     case ZSTD_c_targetLength:
   479     case ZSTD_c_targetLength:
   446     case ZSTD_c_strategy:
   480     case ZSTD_c_strategy:
   447         if (cctx->cdict) return ERROR(stage_wrong);
   481     case ZSTD_c_ldmHashRateLog:
   448         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   482     case ZSTD_c_format:
   449 
       
   450     case ZSTD_c_contentSizeFlag:
   483     case ZSTD_c_contentSizeFlag:
   451     case ZSTD_c_checksumFlag:
   484     case ZSTD_c_checksumFlag:
   452     case ZSTD_c_dictIDFlag:
   485     case ZSTD_c_dictIDFlag:
   453         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   486     case ZSTD_c_forceMaxWindow:
   454 
       
   455     case ZSTD_c_forceMaxWindow :  /* Force back-references to remain < windowSize,
       
   456                                    * even when referencing into Dictionary content.
       
   457                                    * default : 0 when using a CDict, 1 when using a Prefix */
       
   458         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
       
   459 
       
   460     case ZSTD_c_forceAttachDict:
   487     case ZSTD_c_forceAttachDict:
   461         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   488     case ZSTD_c_literalCompressionMode:
   462 
       
   463     case ZSTD_c_nbWorkers:
       
   464         if ((value!=0) && cctx->staticSize) {
       
   465             return ERROR(parameter_unsupported);  /* MT not compatible with static alloc */
       
   466         }
       
   467         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
       
   468 
       
   469     case ZSTD_c_jobSize:
   489     case ZSTD_c_jobSize:
   470     case ZSTD_c_overlapLog:
   490     case ZSTD_c_overlapLog:
   471     case ZSTD_c_rsyncable:
   491     case ZSTD_c_rsyncable:
   472         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
       
   473 
       
   474     case ZSTD_c_enableLongDistanceMatching:
   492     case ZSTD_c_enableLongDistanceMatching:
   475     case ZSTD_c_ldmHashLog:
   493     case ZSTD_c_ldmHashLog:
   476     case ZSTD_c_ldmMinMatch:
   494     case ZSTD_c_ldmMinMatch:
   477     case ZSTD_c_ldmBucketSizeLog:
   495     case ZSTD_c_ldmBucketSizeLog:
   478     case ZSTD_c_ldmHashRateLog:
   496     case ZSTD_c_targetCBlockSize:
   479         if (cctx->cdict) return ERROR(stage_wrong);
   497         break;
   480         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   498 
   481 
   499     default: RETURN_ERROR(parameter_unsupported);
   482     default: return ERROR(parameter_unsupported);
   500     }
   483     }
   501     return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value);
   484 }
   502 }
   485 
   503 
   486 size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* CCtxParams,
   504 size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
   487                                    ZSTD_cParameter param, int value)
   505                                     ZSTD_cParameter param, int value)
   488 {
   506 {
   489     DEBUGLOG(4, "ZSTD_CCtxParam_setParameter (%i, %i)", (int)param, value);
   507     DEBUGLOG(4, "ZSTD_CCtxParams_setParameter (%i, %i)", (int)param, value);
   490     switch(param)
   508     switch(param)
   491     {
   509     {
   492     case ZSTD_c_format :
   510     case ZSTD_c_format :
   493         BOUNDCHECK(ZSTD_c_format, value);
   511         BOUNDCHECK(ZSTD_c_format, value);
   494         CCtxParams->format = (ZSTD_format_e)value;
   512         CCtxParams->format = (ZSTD_format_e)value;
   495         return (size_t)CCtxParams->format;
   513         return (size_t)CCtxParams->format;
   496 
   514 
   497     case ZSTD_c_compressionLevel : {
   515     case ZSTD_c_compressionLevel : {
   498         int cLevel = value;
   516         FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
   499         if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
   517         if (value) {  /* 0 : does not change current level */
   500         if (cLevel < ZSTD_minCLevel()) cLevel = ZSTD_minCLevel();
   518             CCtxParams->compressionLevel = value;
   501         if (cLevel) {  /* 0 : does not change current level */
       
   502             CCtxParams->compressionLevel = cLevel;
       
   503         }
   519         }
   504         if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
   520         if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
   505         return 0;  /* return type (size_t) cannot represent negative values */
   521         return 0;  /* return type (size_t) cannot represent negative values */
   506     }
   522     }
   507 
   523 
   571         BOUNDCHECK(ZSTD_c_forceAttachDict, pref);
   587         BOUNDCHECK(ZSTD_c_forceAttachDict, pref);
   572         CCtxParams->attachDictPref = pref;
   588         CCtxParams->attachDictPref = pref;
   573         return CCtxParams->attachDictPref;
   589         return CCtxParams->attachDictPref;
   574     }
   590     }
   575 
   591 
       
   592     case ZSTD_c_literalCompressionMode : {
       
   593         const ZSTD_literalCompressionMode_e lcm = (ZSTD_literalCompressionMode_e)value;
       
   594         BOUNDCHECK(ZSTD_c_literalCompressionMode, lcm);
       
   595         CCtxParams->literalCompressionMode = lcm;
       
   596         return CCtxParams->literalCompressionMode;
       
   597     }
       
   598 
   576     case ZSTD_c_nbWorkers :
   599     case ZSTD_c_nbWorkers :
   577 #ifndef ZSTD_MULTITHREAD
   600 #ifndef ZSTD_MULTITHREAD
   578         if (value!=0) return ERROR(parameter_unsupported);
   601         RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
   579         return 0;
   602         return 0;
   580 #else
   603 #else
   581         return ZSTDMT_CCtxParam_setNbWorkers(CCtxParams, value);
   604         FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
       
   605         CCtxParams->nbWorkers = value;
       
   606         return CCtxParams->nbWorkers;
   582 #endif
   607 #endif
   583 
   608 
   584     case ZSTD_c_jobSize :
   609     case ZSTD_c_jobSize :
   585 #ifndef ZSTD_MULTITHREAD
   610 #ifndef ZSTD_MULTITHREAD
   586         return ERROR(parameter_unsupported);
   611         RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
       
   612         return 0;
   587 #else
   613 #else
   588         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_jobSize, value);
   614         /* Adjust to the minimum non-default value. */
       
   615         if (value != 0 && value < ZSTDMT_JOBSIZE_MIN)
       
   616             value = ZSTDMT_JOBSIZE_MIN;
       
   617         FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
       
   618         assert(value >= 0);
       
   619         CCtxParams->jobSize = value;
       
   620         return CCtxParams->jobSize;
   589 #endif
   621 #endif
   590 
   622 
   591     case ZSTD_c_overlapLog :
   623     case ZSTD_c_overlapLog :
   592 #ifndef ZSTD_MULTITHREAD
   624 #ifndef ZSTD_MULTITHREAD
   593         return ERROR(parameter_unsupported);
   625         RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
       
   626         return 0;
   594 #else
   627 #else
   595         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_overlapLog, value);
   628         FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));
       
   629         CCtxParams->overlapLog = value;
       
   630         return CCtxParams->overlapLog;
   596 #endif
   631 #endif
   597 
   632 
   598     case ZSTD_c_rsyncable :
   633     case ZSTD_c_rsyncable :
   599 #ifndef ZSTD_MULTITHREAD
   634 #ifndef ZSTD_MULTITHREAD
   600         return ERROR(parameter_unsupported);
   635         RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
       
   636         return 0;
   601 #else
   637 #else
   602         return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_rsyncable, value);
   638         FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));
       
   639         CCtxParams->rsyncable = value;
       
   640         return CCtxParams->rsyncable;
   603 #endif
   641 #endif
   604 
   642 
   605     case ZSTD_c_enableLongDistanceMatching :
   643     case ZSTD_c_enableLongDistanceMatching :
   606         CCtxParams->ldmParams.enableLdm = (value!=0);
   644         CCtxParams->ldmParams.enableLdm = (value!=0);
   607         return CCtxParams->ldmParams.enableLdm;
   645         return CCtxParams->ldmParams.enableLdm;
   623             BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value);
   661             BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value);
   624         CCtxParams->ldmParams.bucketSizeLog = value;
   662         CCtxParams->ldmParams.bucketSizeLog = value;
   625         return CCtxParams->ldmParams.bucketSizeLog;
   663         return CCtxParams->ldmParams.bucketSizeLog;
   626 
   664 
   627     case ZSTD_c_ldmHashRateLog :
   665     case ZSTD_c_ldmHashRateLog :
   628         if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)
   666         RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN,
   629             return ERROR(parameter_outOfBound);
   667                         parameter_outOfBound);
   630         CCtxParams->ldmParams.hashRateLog = value;
   668         CCtxParams->ldmParams.hashRateLog = value;
   631         return CCtxParams->ldmParams.hashRateLog;
   669         return CCtxParams->ldmParams.hashRateLog;
   632 
   670 
   633     default: return ERROR(parameter_unsupported);
   671     case ZSTD_c_targetCBlockSize :
       
   672         if (value!=0)   /* 0 ==> default */
       
   673             BOUNDCHECK(ZSTD_c_targetCBlockSize, value);
       
   674         CCtxParams->targetCBlockSize = value;
       
   675         return CCtxParams->targetCBlockSize;
       
   676 
       
   677     default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
   634     }
   678     }
   635 }
   679 }
   636 
   680 
   637 size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value)
   681 size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value)
   638 {
   682 {
   639     return ZSTD_CCtxParam_getParameter(&cctx->requestedParams, param, value);
   683     return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value);
   640 }
   684 }
   641 
   685 
   642 size_t ZSTD_CCtxParam_getParameter(
   686 size_t ZSTD_CCtxParams_getParameter(
   643         ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, int* value)
   687         ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, int* value)
   644 {
   688 {
   645     switch(param)
   689     switch(param)
   646     {
   690     {
   647     case ZSTD_c_format :
   691     case ZSTD_c_format :
   649         break;
   693         break;
   650     case ZSTD_c_compressionLevel :
   694     case ZSTD_c_compressionLevel :
   651         *value = CCtxParams->compressionLevel;
   695         *value = CCtxParams->compressionLevel;
   652         break;
   696         break;
   653     case ZSTD_c_windowLog :
   697     case ZSTD_c_windowLog :
   654         *value = CCtxParams->cParams.windowLog;
   698         *value = (int)CCtxParams->cParams.windowLog;
   655         break;
   699         break;
   656     case ZSTD_c_hashLog :
   700     case ZSTD_c_hashLog :
   657         *value = CCtxParams->cParams.hashLog;
   701         *value = (int)CCtxParams->cParams.hashLog;
   658         break;
   702         break;
   659     case ZSTD_c_chainLog :
   703     case ZSTD_c_chainLog :
   660         *value = CCtxParams->cParams.chainLog;
   704         *value = (int)CCtxParams->cParams.chainLog;
   661         break;
   705         break;
   662     case ZSTD_c_searchLog :
   706     case ZSTD_c_searchLog :
   663         *value = CCtxParams->cParams.searchLog;
   707         *value = CCtxParams->cParams.searchLog;
   664         break;
   708         break;
   665     case ZSTD_c_minMatch :
   709     case ZSTD_c_minMatch :
   684         *value = CCtxParams->forceWindow;
   728         *value = CCtxParams->forceWindow;
   685         break;
   729         break;
   686     case ZSTD_c_forceAttachDict :
   730     case ZSTD_c_forceAttachDict :
   687         *value = CCtxParams->attachDictPref;
   731         *value = CCtxParams->attachDictPref;
   688         break;
   732         break;
       
   733     case ZSTD_c_literalCompressionMode :
       
   734         *value = CCtxParams->literalCompressionMode;
       
   735         break;
   689     case ZSTD_c_nbWorkers :
   736     case ZSTD_c_nbWorkers :
   690 #ifndef ZSTD_MULTITHREAD
   737 #ifndef ZSTD_MULTITHREAD
   691         assert(CCtxParams->nbWorkers == 0);
   738         assert(CCtxParams->nbWorkers == 0);
   692 #endif
   739 #endif
   693         *value = CCtxParams->nbWorkers;
   740         *value = CCtxParams->nbWorkers;
   694         break;
   741         break;
   695     case ZSTD_c_jobSize :
   742     case ZSTD_c_jobSize :
   696 #ifndef ZSTD_MULTITHREAD
   743 #ifndef ZSTD_MULTITHREAD
   697         return ERROR(parameter_unsupported);
   744         RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
   698 #else
   745 #else
   699         assert(CCtxParams->jobSize <= INT_MAX);
   746         assert(CCtxParams->jobSize <= INT_MAX);
   700         *value = (int)CCtxParams->jobSize;
   747         *value = (int)CCtxParams->jobSize;
   701         break;
   748         break;
   702 #endif
   749 #endif
   703     case ZSTD_c_overlapLog :
   750     case ZSTD_c_overlapLog :
   704 #ifndef ZSTD_MULTITHREAD
   751 #ifndef ZSTD_MULTITHREAD
   705         return ERROR(parameter_unsupported);
   752         RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
   706 #else
   753 #else
   707         *value = CCtxParams->overlapLog;
   754         *value = CCtxParams->overlapLog;
   708         break;
   755         break;
   709 #endif
   756 #endif
   710     case ZSTD_c_rsyncable :
   757     case ZSTD_c_rsyncable :
   711 #ifndef ZSTD_MULTITHREAD
   758 #ifndef ZSTD_MULTITHREAD
   712         return ERROR(parameter_unsupported);
   759         RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
   713 #else
   760 #else
   714         *value = CCtxParams->rsyncable;
   761         *value = CCtxParams->rsyncable;
   715         break;
   762         break;
   716 #endif
   763 #endif
   717     case ZSTD_c_enableLongDistanceMatching :
   764     case ZSTD_c_enableLongDistanceMatching :
   727         *value = CCtxParams->ldmParams.bucketSizeLog;
   774         *value = CCtxParams->ldmParams.bucketSizeLog;
   728         break;
   775         break;
   729     case ZSTD_c_ldmHashRateLog :
   776     case ZSTD_c_ldmHashRateLog :
   730         *value = CCtxParams->ldmParams.hashRateLog;
   777         *value = CCtxParams->ldmParams.hashRateLog;
   731         break;
   778         break;
   732     default: return ERROR(parameter_unsupported);
   779     case ZSTD_c_targetCBlockSize :
       
   780         *value = (int)CCtxParams->targetCBlockSize;
       
   781         break;
       
   782     default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
   733     }
   783     }
   734     return 0;
   784     return 0;
   735 }
   785 }
   736 
   786 
   737 /** ZSTD_CCtx_setParametersUsingCCtxParams() :
   787 /** ZSTD_CCtx_setParametersUsingCCtxParams() :
   743  */
   793  */
   744 size_t ZSTD_CCtx_setParametersUsingCCtxParams(
   794 size_t ZSTD_CCtx_setParametersUsingCCtxParams(
   745         ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
   795         ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
   746 {
   796 {
   747     DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
   797     DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
   748     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   798     RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
   749     if (cctx->cdict) return ERROR(stage_wrong);
   799     RETURN_ERROR_IF(cctx->cdict, stage_wrong);
   750 
   800 
   751     cctx->requestedParams = *params;
   801     cctx->requestedParams = *params;
   752     return 0;
   802     return 0;
   753 }
   803 }
   754 
   804 
   755 ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
   805 ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
   756 {
   806 {
   757     DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %u bytes", (U32)pledgedSrcSize);
   807     DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %u bytes", (U32)pledgedSrcSize);
   758     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   808     RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
   759     cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
   809     cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
       
   810     return 0;
       
   811 }
       
   812 
       
   813 /**
       
   814  * Initializes the local dict using the requested parameters.
       
   815  * NOTE: This does not use the pledged src size, because it may be used for more
       
   816  * than one compression.
       
   817  */
       
   818 static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
       
   819 {
       
   820     ZSTD_localDict* const dl = &cctx->localDict;
       
   821     ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(
       
   822             &cctx->requestedParams, 0, dl->dictSize);
       
   823     if (dl->dict == NULL) {
       
   824         /* No local dictionary. */
       
   825         assert(dl->dictBuffer == NULL);
       
   826         assert(dl->cdict == NULL);
       
   827         assert(dl->dictSize == 0);
       
   828         return 0;
       
   829     }
       
   830     if (dl->cdict != NULL) {
       
   831         assert(cctx->cdict == dl->cdict);
       
   832         /* Local dictionary already initialized. */
       
   833         return 0;
       
   834     }
       
   835     assert(dl->dictSize > 0);
       
   836     assert(cctx->cdict == NULL);
       
   837     assert(cctx->prefixDict.dict == NULL);
       
   838 
       
   839     dl->cdict = ZSTD_createCDict_advanced(
       
   840             dl->dict,
       
   841             dl->dictSize,
       
   842             ZSTD_dlm_byRef,
       
   843             dl->dictContentType,
       
   844             cParams,
       
   845             cctx->customMem);
       
   846     RETURN_ERROR_IF(!dl->cdict, memory_allocation);
       
   847     cctx->cdict = dl->cdict;
   760     return 0;
   848     return 0;
   761 }
   849 }
   762 
   850 
   763 size_t ZSTD_CCtx_loadDictionary_advanced(
   851 size_t ZSTD_CCtx_loadDictionary_advanced(
   764         ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
   852         ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
   765         ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
   853         ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
   766 {
   854 {
   767     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   855     RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
   768     if (cctx->staticSize) return ERROR(memory_allocation);  /* no malloc for static CCtx */
   856     RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
       
   857                     "no malloc for static CCtx");
   769     DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
   858     DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
   770     ZSTD_freeCDict(cctx->cdictLocal);  /* in case one already exists */
   859     ZSTD_clearAllDicts(cctx);  /* in case one already exists */
   771     if (dict==NULL || dictSize==0) {   /* no dictionary mode */
   860     if (dict == NULL || dictSize == 0)  /* no dictionary mode */
   772         cctx->cdictLocal = NULL;
   861         return 0;
   773         cctx->cdict = NULL;
   862     if (dictLoadMethod == ZSTD_dlm_byRef) {
       
   863         cctx->localDict.dict = dict;
   774     } else {
   864     } else {
   775         ZSTD_compressionParameters const cParams =
   865         void* dictBuffer = ZSTD_malloc(dictSize, cctx->customMem);
   776                 ZSTD_getCParamsFromCCtxParams(&cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, dictSize);
   866         RETURN_ERROR_IF(!dictBuffer, memory_allocation);
   777         cctx->cdictLocal = ZSTD_createCDict_advanced(
   867         memcpy(dictBuffer, dict, dictSize);
   778                                 dict, dictSize,
   868         cctx->localDict.dictBuffer = dictBuffer;
   779                                 dictLoadMethod, dictContentType,
   869         cctx->localDict.dict = dictBuffer;
   780                                 cParams, cctx->customMem);
   870     }
   781         cctx->cdict = cctx->cdictLocal;
   871     cctx->localDict.dictSize = dictSize;
   782         if (cctx->cdictLocal == NULL)
   872     cctx->localDict.dictContentType = dictContentType;
   783             return ERROR(memory_allocation);
       
   784     }
       
   785     return 0;
   873     return 0;
   786 }
   874 }
   787 
   875 
   788 ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(
   876 ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(
   789       ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
   877       ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
   799 }
   887 }
   800 
   888 
   801 
   889 
   802 size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
   890 size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
   803 {
   891 {
   804     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   892     RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
       
   893     /* Free the existing local cdict (if any) to save memory. */
       
   894     ZSTD_clearAllDicts(cctx);
   805     cctx->cdict = cdict;
   895     cctx->cdict = cdict;
   806     memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));  /* exclusive */
       
   807     return 0;
   896     return 0;
   808 }
   897 }
   809 
   898 
   810 size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
   899 size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
   811 {
   900 {
   813 }
   902 }
   814 
   903 
   815 size_t ZSTD_CCtx_refPrefix_advanced(
   904 size_t ZSTD_CCtx_refPrefix_advanced(
   816         ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
   905         ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
   817 {
   906 {
   818     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   907     RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
   819     cctx->cdict = NULL;   /* prefix discards any prior cdict */
   908     ZSTD_clearAllDicts(cctx);
   820     cctx->prefixDict.dict = prefix;
   909     cctx->prefixDict.dict = prefix;
   821     cctx->prefixDict.dictSize = prefixSize;
   910     cctx->prefixDict.dictSize = prefixSize;
   822     cctx->prefixDict.dictContentType = dictContentType;
   911     cctx->prefixDict.dictContentType = dictContentType;
   823     return 0;
   912     return 0;
   824 }
   913 }
   832         cctx->streamStage = zcss_init;
   921         cctx->streamStage = zcss_init;
   833         cctx->pledgedSrcSizePlusOne = 0;
   922         cctx->pledgedSrcSizePlusOne = 0;
   834     }
   923     }
   835     if ( (reset == ZSTD_reset_parameters)
   924     if ( (reset == ZSTD_reset_parameters)
   836       || (reset == ZSTD_reset_session_and_parameters) ) {
   925       || (reset == ZSTD_reset_session_and_parameters) ) {
   837         if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   926         RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
   838         cctx->cdict = NULL;
   927         ZSTD_clearAllDicts(cctx);
   839         return ZSTD_CCtxParams_reset(&cctx->requestedParams);
   928         return ZSTD_CCtxParams_reset(&cctx->requestedParams);
   840     }
   929     }
   841     return 0;
   930     return 0;
   842 }
   931 }
   843 
   932 
   845 /** ZSTD_checkCParams() :
   934 /** ZSTD_checkCParams() :
   846     control CParam values remain within authorized range.
   935     control CParam values remain within authorized range.
   847     @return : 0, or an error code if one value is beyond authorized range */
   936     @return : 0, or an error code if one value is beyond authorized range */
   848 size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
   937 size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
   849 {
   938 {
   850     BOUNDCHECK(ZSTD_c_windowLog, cParams.windowLog);
   939     BOUNDCHECK(ZSTD_c_windowLog, (int)cParams.windowLog);
   851     BOUNDCHECK(ZSTD_c_chainLog,  cParams.chainLog);
   940     BOUNDCHECK(ZSTD_c_chainLog,  (int)cParams.chainLog);
   852     BOUNDCHECK(ZSTD_c_hashLog,   cParams.hashLog);
   941     BOUNDCHECK(ZSTD_c_hashLog,   (int)cParams.hashLog);
   853     BOUNDCHECK(ZSTD_c_searchLog, cParams.searchLog);
   942     BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog);
   854     BOUNDCHECK(ZSTD_c_minMatch,  cParams.minMatch);
   943     BOUNDCHECK(ZSTD_c_minMatch,  (int)cParams.minMatch);
   855     BOUNDCHECK(ZSTD_c_targetLength,cParams.targetLength);
   944     BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength);
   856     BOUNDCHECK(ZSTD_c_strategy,  cParams.strategy);
   945     BOUNDCHECK(ZSTD_c_strategy,  cParams.strategy);
   857     return 0;
   946     return 0;
   858 }
   947 }
   859 
   948 
   860 /** ZSTD_clampCParams() :
   949 /** ZSTD_clampCParams() :
   866 #   define CLAMP_TYPE(cParam, val, type) {                                \
   955 #   define CLAMP_TYPE(cParam, val, type) {                                \
   867         ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);         \
   956         ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);         \
   868         if ((int)val<bounds.lowerBound) val=(type)bounds.lowerBound;      \
   957         if ((int)val<bounds.lowerBound) val=(type)bounds.lowerBound;      \
   869         else if ((int)val>bounds.upperBound) val=(type)bounds.upperBound; \
   958         else if ((int)val>bounds.upperBound) val=(type)bounds.upperBound; \
   870     }
   959     }
   871 #   define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, int)
   960 #   define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned)
   872     CLAMP(ZSTD_c_windowLog, cParams.windowLog);
   961     CLAMP(ZSTD_c_windowLog, cParams.windowLog);
   873     CLAMP(ZSTD_c_chainLog,  cParams.chainLog);
   962     CLAMP(ZSTD_c_chainLog,  cParams.chainLog);
   874     CLAMP(ZSTD_c_hashLog,   cParams.hashLog);
   963     CLAMP(ZSTD_c_hashLog,   cParams.hashLog);
   875     CLAMP(ZSTD_c_searchLog, cParams.searchLog);
   964     CLAMP(ZSTD_c_searchLog, cParams.searchLog);
   876     CLAMP(ZSTD_c_minMatch,  cParams.minMatch);
   965     CLAMP(ZSTD_c_minMatch,  cParams.minMatch);
   886     U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
   975     U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
   887     return hashLog - btScale;
   976     return hashLog - btScale;
   888 }
   977 }
   889 
   978 
   890 /** ZSTD_adjustCParams_internal() :
   979 /** ZSTD_adjustCParams_internal() :
   891     optimize `cPar` for a given input (`srcSize` and `dictSize`).
   980  *  optimize `cPar` for a specified input (`srcSize` and `dictSize`).
   892     mostly downsizing to reduce memory consumption and initialization latency.
   981  *  mostly downsize to reduce memory consumption and initialization latency.
   893     Both `srcSize` and `dictSize` are optional (use 0 if unknown).
   982  * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
   894     Note : cPar is assumed validated. Use ZSTD_checkCParams() to ensure this condition. */
   983  *  note : for the time being, `srcSize==0` means "unknown" too, for compatibility with older convention.
       
   984  *  condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
   895 static ZSTD_compressionParameters
   985 static ZSTD_compressionParameters
   896 ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
   986 ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
   897                             unsigned long long srcSize,
   987                             unsigned long long srcSize,
   898                             size_t dictSize)
   988                             size_t dictSize)
   899 {
   989 {
   900     static const U64 minSrcSize = 513; /* (1<<9) + 1 */
   990     static const U64 minSrcSize = 513; /* (1<<9) + 1 */
   901     static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
   991     static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
   902     assert(ZSTD_checkCParams(cPar)==0);
   992     assert(ZSTD_checkCParams(cPar)==0);
   903 
   993 
   904     if (dictSize && (srcSize+1<2) /* srcSize unknown */ )
   994     if (dictSize && (srcSize+1<2) /* ZSTD_CONTENTSIZE_UNKNOWN and 0 mean "unknown" */ )
   905         srcSize = minSrcSize;  /* presumed small when there is a dictionary */
   995         srcSize = minSrcSize;  /* presumed small when there is a dictionary */
   906     else if (srcSize == 0)
   996     else if (srcSize == 0)
   907         srcSize = ZSTD_CONTENTSIZE_UNKNOWN;  /* 0 == unknown : presumed large */
   997         srcSize = ZSTD_CONTENTSIZE_UNKNOWN;  /* 0 == unknown : presumed large */
   908 
   998 
   909     /* resize windowLog if input is small enough, to use less memory */
   999     /* resize windowLog if input is small enough, to use less memory */
   920         if (cycleLog > cPar.windowLog)
  1010         if (cycleLog > cPar.windowLog)
   921             cPar.chainLog -= (cycleLog - cPar.windowLog);
  1011             cPar.chainLog -= (cycleLog - cPar.windowLog);
   922     }
  1012     }
   923 
  1013 
   924     if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN)
  1014     if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN)
   925         cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* required for frame header */
  1015         cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* minimum wlog required for valid frame header */
   926 
  1016 
   927     return cPar;
  1017     return cPar;
   928 }
  1018 }
   929 
  1019 
   930 ZSTD_compressionParameters
  1020 ZSTD_compressionParameters
   931 ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
  1021 ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
   932                    unsigned long long srcSize,
  1022                    unsigned long long srcSize,
   933                    size_t dictSize)
  1023                    size_t dictSize)
   934 {
  1024 {
   935     cPar = ZSTD_clampCParams(cPar);
  1025     cPar = ZSTD_clampCParams(cPar);   /* resulting cPar is necessarily valid (all parameters within range) */
   936     return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
  1026     return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
   937 }
  1027 }
   938 
  1028 
   939 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
  1029 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
   940         const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
  1030         const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
   971     return tableSpace + optSpace;
  1061     return tableSpace + optSpace;
   972 }
  1062 }
   973 
  1063 
   974 size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
  1064 size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
   975 {
  1065 {
   976     /* Estimate CCtx size is supported for single-threaded compression only. */
  1066     RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
   977     if (params->nbWorkers > 0) { return ERROR(GENERIC); }
       
   978     {   ZSTD_compressionParameters const cParams =
  1067     {   ZSTD_compressionParameters const cParams =
   979                 ZSTD_getCParamsFromCCtxParams(params, 0, 0);
  1068                 ZSTD_getCParamsFromCCtxParams(params, 0, 0);
   980         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
  1069         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
   981         U32    const divider = (cParams.minMatch==3) ? 3 : 4;
  1070         U32    const divider = (cParams.minMatch==3) ? 3 : 4;
   982         size_t const maxNbSeq = blockSize / divider;
  1071         size_t const maxNbSeq = blockSize / divider;
  1020     return memBudget;
  1109     return memBudget;
  1021 }
  1110 }
  1022 
  1111 
  1023 size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
  1112 size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
  1024 {
  1113 {
  1025     if (params->nbWorkers > 0) { return ERROR(GENERIC); }
  1114     RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
  1026     {   size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
  1115     {   ZSTD_compressionParameters const cParams =
  1027         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
  1116                 ZSTD_getCParamsFromCCtxParams(params, 0, 0);
  1028         size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
  1117         size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
       
  1118         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
       
  1119         size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
  1029         size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
  1120         size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
  1030         size_t const streamingSize = inBuffSize + outBuffSize;
  1121         size_t const streamingSize = inBuffSize + outBuffSize;
  1031 
  1122 
  1032         return CCtxSize + streamingSize;
  1123         return CCtxSize + streamingSize;
  1033     }
  1124     }
  1195     bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none;
  1286     bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none;
  1196     bs->entropy.fse.litlength_repeatMode = FSE_repeat_none;
  1287     bs->entropy.fse.litlength_repeatMode = FSE_repeat_none;
  1197 }
  1288 }
  1198 
  1289 
  1199 /*! ZSTD_invalidateMatchState()
  1290 /*! ZSTD_invalidateMatchState()
  1200  * Invalidate all the matches in the match finder tables.
  1291  *  Invalidate all the matches in the match finder tables.
  1201  * Requires nextSrc and base to be set (can be NULL).
  1292  *  Requires nextSrc and base to be set (can be NULL).
  1202  */
  1293  */
  1203 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
  1294 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
  1204 {
  1295 {
  1205     ZSTD_window_clear(&ms->window);
  1296     ZSTD_window_clear(&ms->window);
  1206 
  1297 
  1207     ms->nextToUpdate = ms->window.dictLimit;
  1298     ms->nextToUpdate = ms->window.dictLimit;
  1208     ms->nextToUpdate3 = ms->window.dictLimit;
       
  1209     ms->loadedDictEnd = 0;
  1299     ms->loadedDictEnd = 0;
  1210     ms->opt.litLengthSum = 0;  /* force reset of btopt stats */
  1300     ms->opt.litLengthSum = 0;  /* force reset of btopt stats */
  1211     ms->dictMatchState = NULL;
  1301     ms->dictMatchState = NULL;
  1212 }
  1302 }
  1213 
  1303 
  1240     return 0;
  1330     return 0;
  1241 }
  1331 }
  1242 
  1332 
  1243 typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
  1333 typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
  1244 
  1334 
       
  1335 typedef enum { ZSTD_resetTarget_CDict, ZSTD_resetTarget_CCtx } ZSTD_resetTarget_e;
       
  1336 
  1245 static void*
  1337 static void*
  1246 ZSTD_reset_matchState(ZSTD_matchState_t* ms,
  1338 ZSTD_reset_matchState(ZSTD_matchState_t* ms,
  1247                       void* ptr,
  1339                       void* ptr,
  1248                 const ZSTD_compressionParameters* cParams,
  1340                 const ZSTD_compressionParameters* cParams,
  1249                       ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
  1341                       ZSTD_compResetPolicy_e const crp, ZSTD_resetTarget_e const forWho)
  1250 {
  1342 {
  1251     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
  1343     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
  1252     size_t const hSize = ((size_t)1) << cParams->hashLog;
  1344     size_t const hSize = ((size_t)1) << cParams->hashLog;
  1253     U32    const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
  1345     U32    const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
  1254     size_t const h3Size = ((size_t)1) << hashLog3;
  1346     size_t const h3Size = ((size_t)1) << hashLog3;
  1255     size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
  1347     size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
  1256 
  1348 
  1257     assert(((size_t)ptr & 3) == 0);
  1349     assert(((size_t)ptr & 3) == 0);
  1258 
  1350 
  1262     ms->window.lowLimit = 1;     /* it ensures first and later CCtx usages compress the same */
  1354     ms->window.lowLimit = 1;     /* it ensures first and later CCtx usages compress the same */
  1263     ms->window.nextSrc = ms->window.base + 1;   /* see issue #1241 */
  1355     ms->window.nextSrc = ms->window.base + 1;   /* see issue #1241 */
  1264     ZSTD_invalidateMatchState(ms);
  1356     ZSTD_invalidateMatchState(ms);
  1265 
  1357 
  1266     /* opt parser space */
  1358     /* opt parser space */
  1267     if (forCCtx && (cParams->strategy >= ZSTD_btopt)) {
  1359     if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
  1268         DEBUGLOG(4, "reserving optimal parser space");
  1360         DEBUGLOG(4, "reserving optimal parser space");
  1269         ms->opt.litFreq = (unsigned*)ptr;
  1361         ms->opt.litFreq = (unsigned*)ptr;
  1270         ms->opt.litLengthFreq = ms->opt.litFreq + (1<<Litbits);
  1362         ms->opt.litLengthFreq = ms->opt.litFreq + (1<<Litbits);
  1271         ms->opt.matchLengthFreq = ms->opt.litLengthFreq + (MaxLL+1);
  1363         ms->opt.matchLengthFreq = ms->opt.litLengthFreq + (MaxLL+1);
  1272         ms->opt.offCodeFreq = ms->opt.matchLengthFreq + (MaxML+1);
  1364         ms->opt.offCodeFreq = ms->opt.matchLengthFreq + (MaxML+1);
  1290 
  1382 
  1291     assert(((size_t)ptr & 3) == 0);
  1383     assert(((size_t)ptr & 3) == 0);
  1292     return ptr;
  1384     return ptr;
  1293 }
  1385 }
  1294 
  1386 
       
  1387 /* ZSTD_indexTooCloseToMax() :
       
  1388  * minor optimization : prefer memset() rather than reduceIndex()
       
  1389  * which is measurably slow in some circumstances (reported for Visual Studio).
       
  1390  * Works when re-using a context for a lot of smallish inputs :
       
  1391  * if all inputs are smaller than ZSTD_INDEXOVERFLOW_MARGIN,
       
  1392  * memset() will be triggered before reduceIndex().
       
  1393  */
       
  1394 #define ZSTD_INDEXOVERFLOW_MARGIN (16 MB)
       
  1395 static int ZSTD_indexTooCloseToMax(ZSTD_window_t w)
       
  1396 {
       
  1397     return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN);
       
  1398 }
       
  1399 
  1295 #define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
  1400 #define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
  1296 #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128  /* when workspace is continuously too large
  1401 #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128  /* when workspace is continuously too large
  1297                                          * during at least this number of times,
  1402                                          * during at least this number of times,
  1298                                          * context's memory usage is considered wasteful,
  1403                                          * context's memory usage is considered wasteful,
  1299                                          * because it's sized to handle a worst case scenario which rarely happens.
  1404                                          * because it's sized to handle a worst case scenario which rarely happens.
  1301 
  1406 
  1302 /*! ZSTD_resetCCtx_internal() :
  1407 /*! ZSTD_resetCCtx_internal() :
  1303     note : `params` are assumed fully validated at this stage */
  1408     note : `params` are assumed fully validated at this stage */
  1304 static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
  1409 static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
  1305                                       ZSTD_CCtx_params params,
  1410                                       ZSTD_CCtx_params params,
  1306                                       U64 pledgedSrcSize,
  1411                                       U64 const pledgedSrcSize,
  1307                                       ZSTD_compResetPolicy_e const crp,
  1412                                       ZSTD_compResetPolicy_e const crp,
  1308                                       ZSTD_buffered_policy_e const zbuff)
  1413                                       ZSTD_buffered_policy_e const zbuff)
  1309 {
  1414 {
  1310     DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
  1415     DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
  1311                 (U32)pledgedSrcSize, params.cParams.windowLog);
  1416                 (U32)pledgedSrcSize, params.cParams.windowLog);
  1313 
  1418 
  1314     if (crp == ZSTDcrp_continue) {
  1419     if (crp == ZSTDcrp_continue) {
  1315         if (ZSTD_equivalentParams(zc->appliedParams, params,
  1420         if (ZSTD_equivalentParams(zc->appliedParams, params,
  1316                                   zc->inBuffSize,
  1421                                   zc->inBuffSize,
  1317                                   zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
  1422                                   zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
  1318                                   zbuff, pledgedSrcSize)) {
  1423                                   zbuff, pledgedSrcSize) ) {
  1319             DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
  1424             DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> consider continue mode");
  1320                         zc->appliedParams.cParams.windowLog, zc->blockSize);
       
  1321             zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0);   /* if it was too large, it still is */
  1425             zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0);   /* if it was too large, it still is */
  1322             if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION)
  1426             if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION) {
       
  1427                 DEBUGLOG(4, "continue mode confirmed (wLog1=%u, blockSize1=%zu)",
       
  1428                             zc->appliedParams.cParams.windowLog, zc->blockSize);
       
  1429                 if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
       
  1430                     /* prefer a reset, faster than a rescale */
       
  1431                     ZSTD_reset_matchState(&zc->blockState.matchState,
       
  1432                                            zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
       
  1433                                           &params.cParams,
       
  1434                                            crp, ZSTD_resetTarget_CCtx);
       
  1435                 }
  1323                 return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
  1436                 return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
  1324     }   }
  1437     }   }   }
  1325     DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
  1438     DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
  1326 
  1439 
  1327     if (params.ldmParams.enableLdm) {
  1440     if (params.ldmParams.enableLdm) {
  1328         /* Adjust long distance matching parameters */
  1441         /* Adjust long distance matching parameters */
  1329         ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
  1442         ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
  1362             DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
  1475             DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
  1363                         neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
  1476                         neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
  1364             DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
  1477             DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
  1365 
  1478 
  1366             if (workSpaceTooSmall || workSpaceWasteful) {
  1479             if (workSpaceTooSmall || workSpaceWasteful) {
  1367                 DEBUGLOG(4, "Need to resize workSpaceSize from %zuKB to %zuKB",
  1480                 DEBUGLOG(4, "Resize workSpaceSize from %zuKB to %zuKB",
  1368                             zc->workSpaceSize >> 10,
  1481                             zc->workSpaceSize >> 10,
  1369                             neededSpace >> 10);
  1482                             neededSpace >> 10);
  1370                 /* static cctx : no resize, error out */
  1483 
  1371                 if (zc->staticSize) return ERROR(memory_allocation);
  1484                 RETURN_ERROR_IF(zc->staticSize, memory_allocation, "static cctx : no resize");
  1372 
  1485 
  1373                 zc->workSpaceSize = 0;
  1486                 zc->workSpaceSize = 0;
  1374                 ZSTD_free(zc->workSpace, zc->customMem);
  1487                 ZSTD_free(zc->workSpace, zc->customMem);
  1375                 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
  1488                 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
  1376                 if (zc->workSpace == NULL) return ERROR(memory_allocation);
  1489                 RETURN_ERROR_IF(zc->workSpace == NULL, memory_allocation);
  1377                 zc->workSpaceSize = neededSpace;
  1490                 zc->workSpaceSize = neededSpace;
  1378                 zc->workSpaceOversizedDuration = 0;
  1491                 zc->workSpaceOversizedDuration = 0;
  1379 
  1492 
  1380                 /* Statically sized space.
  1493                 /* Statically sized space.
  1381                  * entropyWorkspace never moves,
  1494                  * entropyWorkspace never moves,
  1404         zc->stage = ZSTDcs_init;
  1517         zc->stage = ZSTDcs_init;
  1405         zc->dictID = 0;
  1518         zc->dictID = 0;
  1406 
  1519 
  1407         ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);
  1520         ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);
  1408 
  1521 
  1409         ptr = zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32;
  1522         ptr = ZSTD_reset_matchState(&zc->blockState.matchState,
       
  1523                                      zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
       
  1524                                     &params.cParams,
       
  1525                                      crp, ZSTD_resetTarget_CCtx);
  1410 
  1526 
  1411         /* ldm hash table */
  1527         /* ldm hash table */
  1412         /* initialize bucketOffsets table later for pointer alignment */
  1528         /* initialize bucketOffsets table later for pointer alignment */
  1413         if (params.ldmParams.enableLdm) {
  1529         if (params.ldmParams.enableLdm) {
  1414             size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
  1530             size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
  1421             zc->maxNbLdmSequences = maxNbLdmSeq;
  1537             zc->maxNbLdmSequences = maxNbLdmSeq;
  1422 
  1538 
  1423             memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
  1539             memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
  1424         }
  1540         }
  1425         assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
  1541         assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
  1426 
       
  1427         ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, &params.cParams, crp, /* forCCtx */ 1);
       
  1428 
  1542 
  1429         /* sequences storage */
  1543         /* sequences storage */
  1430         zc->seqStore.maxNbSeq = maxNbSeq;
  1544         zc->seqStore.maxNbSeq = maxNbSeq;
  1431         zc->seqStore.sequencesStart = (seqDef*)ptr;
  1545         zc->seqStore.sequencesStart = (seqDef*)ptr;
  1432         ptr = zc->seqStore.sequencesStart + maxNbSeq;
  1546         ptr = zc->seqStore.sequencesStart + maxNbSeq;
  1500         && params.attachDictPref != ZSTD_dictForceCopy
  1614         && params.attachDictPref != ZSTD_dictForceCopy
  1501         && !params.forceWindow; /* dictMatchState isn't correctly
  1615         && !params.forceWindow; /* dictMatchState isn't correctly
  1502                                  * handled in _enforceMaxDist */
  1616                                  * handled in _enforceMaxDist */
  1503 }
  1617 }
  1504 
  1618 
  1505 static size_t ZSTD_resetCCtx_byAttachingCDict(
  1619 static size_t
  1506     ZSTD_CCtx* cctx,
  1620 ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
  1507     const ZSTD_CDict* cdict,
  1621                         const ZSTD_CDict* cdict,
  1508     ZSTD_CCtx_params params,
  1622                         ZSTD_CCtx_params params,
  1509     U64 pledgedSrcSize,
  1623                         U64 pledgedSrcSize,
  1510     ZSTD_buffered_policy_e zbuff)
  1624                         ZSTD_buffered_policy_e zbuff)
  1511 {
  1625 {
  1512     {
  1626     {   const ZSTD_compressionParameters* const cdict_cParams = &cdict->matchState.cParams;
  1513         const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
       
  1514         unsigned const windowLog = params.cParams.windowLog;
  1627         unsigned const windowLog = params.cParams.windowLog;
  1515         assert(windowLog != 0);
  1628         assert(windowLog != 0);
  1516         /* Resize working context table params for input only, since the dict
  1629         /* Resize working context table params for input only, since the dict
  1517          * has its own tables. */
  1630          * has its own tables. */
  1518         params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
  1631         params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
  1520         ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  1633         ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  1521                                 ZSTDcrp_continue, zbuff);
  1634                                 ZSTDcrp_continue, zbuff);
  1522         assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
  1635         assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
  1523     }
  1636     }
  1524 
  1637 
  1525     {
  1638     {   const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
  1526         const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
       
  1527                                   - cdict->matchState.window.base);
  1639                                   - cdict->matchState.window.base);
  1528         const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit;
  1640         const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit;
  1529         if (cdictLen == 0) {
  1641         if (cdictLen == 0) {
  1530             /* don't even attach dictionaries with no contents */
  1642             /* don't even attach dictionaries with no contents */
  1531             DEBUGLOG(4, "skipping attaching empty dictionary");
  1643             DEBUGLOG(4, "skipping attaching empty dictionary");
  1538             if (cctx->blockState.matchState.window.dictLimit < cdictEnd) {
  1650             if (cctx->blockState.matchState.window.dictLimit < cdictEnd) {
  1539                 cctx->blockState.matchState.window.nextSrc =
  1651                 cctx->blockState.matchState.window.nextSrc =
  1540                     cctx->blockState.matchState.window.base + cdictEnd;
  1652                     cctx->blockState.matchState.window.base + cdictEnd;
  1541                 ZSTD_window_clear(&cctx->blockState.matchState.window);
  1653                 ZSTD_window_clear(&cctx->blockState.matchState.window);
  1542             }
  1654             }
       
  1655             /* loadedDictEnd is expressed within the referential of the active context */
  1543             cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
  1656             cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
  1544         }
  1657     }   }
  1545     }
       
  1546 
  1658 
  1547     cctx->dictID = cdict->dictID;
  1659     cctx->dictID = cdict->dictID;
  1548 
  1660 
  1549     /* copy block state */
  1661     /* copy block state */
  1550     memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
  1662     memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
  1594     /* copy dictionary offsets */
  1706     /* copy dictionary offsets */
  1595     {   ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
  1707     {   ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
  1596         ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
  1708         ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
  1597         dstMatchState->window       = srcMatchState->window;
  1709         dstMatchState->window       = srcMatchState->window;
  1598         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1710         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1599         dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
       
  1600         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1711         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1601     }
  1712     }
  1602 
  1713 
  1603     cctx->dictID = cdict->dictID;
  1714     cctx->dictID = cdict->dictID;
  1604 
  1715 
  1642                             ZSTD_frameParameters fParams,
  1753                             ZSTD_frameParameters fParams,
  1643                             U64 pledgedSrcSize,
  1754                             U64 pledgedSrcSize,
  1644                             ZSTD_buffered_policy_e zbuff)
  1755                             ZSTD_buffered_policy_e zbuff)
  1645 {
  1756 {
  1646     DEBUGLOG(5, "ZSTD_copyCCtx_internal");
  1757     DEBUGLOG(5, "ZSTD_copyCCtx_internal");
  1647     if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
  1758     RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong);
  1648 
  1759 
  1649     memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
  1760     memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
  1650     {   ZSTD_CCtx_params params = dstCCtx->requestedParams;
  1761     {   ZSTD_CCtx_params params = dstCCtx->requestedParams;
  1651         /* Copy only compression parameters related to tables. */
  1762         /* Copy only compression parameters related to tables. */
  1652         params.cParams = srcCCtx->appliedParams.cParams;
  1763         params.cParams = srcCCtx->appliedParams.cParams;
  1674     {
  1785     {
  1675         const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
  1786         const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
  1676         ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
  1787         ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
  1677         dstMatchState->window       = srcMatchState->window;
  1788         dstMatchState->window       = srcMatchState->window;
  1678         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1789         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1679         dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
       
  1680         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1790         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1681     }
  1791     }
  1682     dstCCtx->dictID = srcCCtx->dictID;
  1792     dstCCtx->dictID = srcCCtx->dictID;
  1683 
  1793 
  1684     /* copy block state */
  1794     /* copy block state */
  1744     ZSTD_reduceTable_internal(table, size, reducerValue, 1);
  1854     ZSTD_reduceTable_internal(table, size, reducerValue, 1);
  1745 }
  1855 }
  1746 
  1856 
  1747 /*! ZSTD_reduceIndex() :
  1857 /*! ZSTD_reduceIndex() :
  1748 *   rescale all indexes to avoid future overflow (indexes are U32) */
  1858 *   rescale all indexes to avoid future overflow (indexes are U32) */
  1749 static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
  1859 static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)
  1750 {
  1860 {
  1751     ZSTD_matchState_t* const ms = &zc->blockState.matchState;
  1861     {   U32 const hSize = (U32)1 << params->cParams.hashLog;
  1752     {   U32 const hSize = (U32)1 << zc->appliedParams.cParams.hashLog;
       
  1753         ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
  1862         ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
  1754     }
  1863     }
  1755 
  1864 
  1756     if (zc->appliedParams.cParams.strategy != ZSTD_fast) {
  1865     if (params->cParams.strategy != ZSTD_fast) {
  1757         U32 const chainSize = (U32)1 << zc->appliedParams.cParams.chainLog;
  1866         U32 const chainSize = (U32)1 << params->cParams.chainLog;
  1758         if (zc->appliedParams.cParams.strategy == ZSTD_btlazy2)
  1867         if (params->cParams.strategy == ZSTD_btlazy2)
  1759             ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue);
  1868             ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue);
  1760         else
  1869         else
  1761             ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue);
  1870             ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue);
  1762     }
  1871     }
  1763 
  1872 
  1775 /* See doc/zstd_compression_format.md for detailed format description */
  1884 /* See doc/zstd_compression_format.md for detailed format description */
  1776 
  1885 
  1777 static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
  1886 static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
  1778 {
  1887 {
  1779     U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
  1888     U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
  1780     if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
  1889     RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
       
  1890                     dstSize_tooSmall);
  1781     MEM_writeLE24(dst, cBlockHeader24);
  1891     MEM_writeLE24(dst, cBlockHeader24);
  1782     memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
  1892     memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
  1783     return ZSTD_blockHeaderSize + srcSize;
  1893     return ZSTD_blockHeaderSize + srcSize;
  1784 }
  1894 }
  1785 
       
  1786 static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
  1787 {
       
  1788     BYTE* const ostart = (BYTE* const)dst;
       
  1789     U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
       
  1790 
       
  1791     if (srcSize + flSize > dstCapacity) return ERROR(dstSize_tooSmall);
       
  1792 
       
  1793     switch(flSize)
       
  1794     {
       
  1795         case 1: /* 2 - 1 - 5 */
       
  1796             ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
       
  1797             break;
       
  1798         case 2: /* 2 - 2 - 12 */
       
  1799             MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
       
  1800             break;
       
  1801         case 3: /* 2 - 2 - 20 */
       
  1802             MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
       
  1803             break;
       
  1804         default:   /* not necessary : flSize is {1,2,3} */
       
  1805             assert(0);
       
  1806     }
       
  1807 
       
  1808     memcpy(ostart + flSize, src, srcSize);
       
  1809     return srcSize + flSize;
       
  1810 }
       
  1811 
       
  1812 static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
  1813 {
       
  1814     BYTE* const ostart = (BYTE* const)dst;
       
  1815     U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
       
  1816 
       
  1817     (void)dstCapacity;  /* dstCapacity already guaranteed to be >=4, hence large enough */
       
  1818 
       
  1819     switch(flSize)
       
  1820     {
       
  1821         case 1: /* 2 - 1 - 5 */
       
  1822             ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
       
  1823             break;
       
  1824         case 2: /* 2 - 2 - 12 */
       
  1825             MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
       
  1826             break;
       
  1827         case 3: /* 2 - 2 - 20 */
       
  1828             MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
       
  1829             break;
       
  1830         default:   /* not necessary : flSize is {1,2,3} */
       
  1831             assert(0);
       
  1832     }
       
  1833 
       
  1834     ostart[flSize] = *(const BYTE*)src;
       
  1835     return flSize+1;
       
  1836 }
       
  1837 
       
  1838 
       
  1839 /* ZSTD_minGain() :
       
  1840  * minimum compression required
       
  1841  * to generate a compress block or a compressed literals section.
       
  1842  * note : use same formula for both situations */
       
  1843 static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
       
  1844 {
       
  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));
       
  1848     return (srcSize >> minlog) + 2;
       
  1849 }
       
  1850 
       
  1851 static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
       
  1852                                      ZSTD_hufCTables_t* nextHuf,
       
  1853                                      ZSTD_strategy strategy, int disableLiteralCompression,
       
  1854                                      void* dst, size_t dstCapacity,
       
  1855                                const void* src, size_t srcSize,
       
  1856                                      void* workspace, size_t wkspSize,
       
  1857                                const int bmi2)
       
  1858 {
       
  1859     size_t const minGain = ZSTD_minGain(srcSize, strategy);
       
  1860     size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
       
  1861     BYTE*  const ostart = (BYTE*)dst;
       
  1862     U32 singleStream = srcSize < 256;
       
  1863     symbolEncodingType_e hType = set_compressed;
       
  1864     size_t cLitSize;
       
  1865 
       
  1866     DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
       
  1867                 disableLiteralCompression);
       
  1868 
       
  1869     /* Prepare nextEntropy assuming reusing the existing table */
       
  1870     memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
       
  1871 
       
  1872     if (disableLiteralCompression)
       
  1873         return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
       
  1874 
       
  1875     /* small ? don't even attempt compression (speed opt) */
       
  1876 #   define COMPRESS_LITERALS_SIZE_MIN 63
       
  1877     {   size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
       
  1878         if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
       
  1879     }
       
  1880 
       
  1881     if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
       
  1882     {   HUF_repeat repeat = prevHuf->repeatMode;
       
  1883         int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
       
  1884         if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
       
  1885         cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
       
  1886                                       workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
       
  1887                                 : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
       
  1888                                       workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
       
  1889         if (repeat != HUF_repeat_none) {
       
  1890             /* reused the existing table */
       
  1891             hType = set_repeat;
       
  1892         }
       
  1893     }
       
  1894 
       
  1895     if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
       
  1896         memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
       
  1897         return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
       
  1898     }
       
  1899     if (cLitSize==1) {
       
  1900         memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
       
  1901         return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
       
  1902     }
       
  1903 
       
  1904     if (hType == set_compressed) {
       
  1905         /* using a newly constructed table */
       
  1906         nextHuf->repeatMode = HUF_repeat_check;
       
  1907     }
       
  1908 
       
  1909     /* Build header */
       
  1910     switch(lhSize)
       
  1911     {
       
  1912     case 3: /* 2 - 2 - 10 - 10 */
       
  1913         {   U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
       
  1914             MEM_writeLE24(ostart, lhc);
       
  1915             break;
       
  1916         }
       
  1917     case 4: /* 2 - 2 - 14 - 14 */
       
  1918         {   U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
       
  1919             MEM_writeLE32(ostart, lhc);
       
  1920             break;
       
  1921         }
       
  1922     case 5: /* 2 - 2 - 18 - 18 */
       
  1923         {   U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
       
  1924             MEM_writeLE32(ostart, lhc);
       
  1925             ostart[4] = (BYTE)(cLitSize >> 10);
       
  1926             break;
       
  1927         }
       
  1928     default:  /* not possible : lhSize is {3,4,5} */
       
  1929         assert(0);
       
  1930     }
       
  1931     return lhSize+cLitSize;
       
  1932 }
       
  1933 
       
  1934 
  1895 
  1935 void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
  1896 void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
  1936 {
  1897 {
  1937     const seqDef* const sequences = seqStorePtr->sequencesStart;
  1898     const seqDef* const sequences = seqStorePtr->sequencesStart;
  1938     BYTE* const llCodeTable = seqStorePtr->llCode;
  1899     BYTE* const llCodeTable = seqStorePtr->llCode;
  1952         llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
  1913         llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
  1953     if (seqStorePtr->longLengthID==2)
  1914     if (seqStorePtr->longLengthID==2)
  1954         mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
  1915         mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
  1955 }
  1916 }
  1956 
  1917 
  1957 
  1918 static int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)
  1958 /**
  1919 {
  1959  * -log2(x / 256) lookup table for x in [0, 256).
  1920     switch (cctxParams->literalCompressionMode) {
  1960  * If x == 0: Return 0
  1921     case ZSTD_lcm_huffman:
  1961  * Else: Return floor(-log2(x / 256) * 256)
  1922         return 0;
  1962  */
  1923     case ZSTD_lcm_uncompressed:
  1963 static unsigned const kInverseProbabiltyLog256[256] = {
       
  1964     0,    2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
       
  1965     1130, 1100, 1073, 1047, 1024, 1001, 980,  960,  941,  923,  906,  889,
       
  1966     874,  859,  844,  830,  817,  804,  791,  779,  768,  756,  745,  734,
       
  1967     724,  714,  704,  694,  685,  676,  667,  658,  650,  642,  633,  626,
       
  1968     618,  610,  603,  595,  588,  581,  574,  567,  561,  554,  548,  542,
       
  1969     535,  529,  523,  517,  512,  506,  500,  495,  489,  484,  478,  473,
       
  1970     468,  463,  458,  453,  448,  443,  438,  434,  429,  424,  420,  415,
       
  1971     411,  407,  402,  398,  394,  390,  386,  382,  377,  373,  370,  366,
       
  1972     362,  358,  354,  350,  347,  343,  339,  336,  332,  329,  325,  322,
       
  1973     318,  315,  311,  308,  305,  302,  298,  295,  292,  289,  286,  282,
       
  1974     279,  276,  273,  270,  267,  264,  261,  258,  256,  253,  250,  247,
       
  1975     244,  241,  239,  236,  233,  230,  228,  225,  222,  220,  217,  215,
       
  1976     212,  209,  207,  204,  202,  199,  197,  194,  192,  190,  187,  185,
       
  1977     182,  180,  178,  175,  173,  171,  168,  166,  164,  162,  159,  157,
       
  1978     155,  153,  151,  149,  146,  144,  142,  140,  138,  136,  134,  132,
       
  1979     130,  128,  126,  123,  121,  119,  117,  115,  114,  112,  110,  108,
       
  1980     106,  104,  102,  100,  98,   96,   94,   93,   91,   89,   87,   85,
       
  1981     83,   82,   80,   78,   76,   74,   73,   71,   69,   67,   66,   64,
       
  1982     62,   61,   59,   57,   55,   54,   52,   50,   49,   47,   46,   44,
       
  1983     42,   41,   39,   37,   36,   34,   33,   31,   30,   28,   26,   25,
       
  1984     23,   22,   20,   19,   17,   16,   14,   13,   11,   10,   8,    7,
       
  1985     5,    4,    2,    1,
       
  1986 };
       
  1987 
       
  1988 
       
  1989 /**
       
  1990  * Returns the cost in bits of encoding the distribution described by count
       
  1991  * using the entropy bound.
       
  1992  */
       
  1993 static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
       
  1994 {
       
  1995     unsigned cost = 0;
       
  1996     unsigned s;
       
  1997     for (s = 0; s <= max; ++s) {
       
  1998         unsigned norm = (unsigned)((256 * count[s]) / total);
       
  1999         if (count[s] != 0 && norm == 0)
       
  2000             norm = 1;
       
  2001         assert(count[s] < total);
       
  2002         cost += count[s] * kInverseProbabiltyLog256[norm];
       
  2003     }
       
  2004     return cost >> 8;
       
  2005 }
       
  2006 
       
  2007 
       
  2008 /**
       
  2009  * Returns the cost in bits of encoding the distribution in count using the
       
  2010  * table described by norm. The max symbol support by norm is assumed >= max.
       
  2011  * norm must be valid for every symbol with non-zero probability in count.
       
  2012  */
       
  2013 static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
       
  2014                                     unsigned const* count, unsigned const max)
       
  2015 {
       
  2016     unsigned const shift = 8 - accuracyLog;
       
  2017     size_t cost = 0;
       
  2018     unsigned s;
       
  2019     assert(accuracyLog <= 8);
       
  2020     for (s = 0; s <= max; ++s) {
       
  2021         unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
       
  2022         unsigned const norm256 = normAcc << shift;
       
  2023         assert(norm256 > 0);
       
  2024         assert(norm256 < 256);
       
  2025         cost += count[s] * kInverseProbabiltyLog256[norm256];
       
  2026     }
       
  2027     return cost >> 8;
       
  2028 }
       
  2029 
       
  2030 
       
  2031 static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
       
  2032   void const* ptr = ctable;
       
  2033   U16 const* u16ptr = (U16 const*)ptr;
       
  2034   U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
       
  2035   return maxSymbolValue;
       
  2036 }
       
  2037 
       
  2038 
       
  2039 /**
       
  2040  * Returns the cost in bits of encoding the distribution in count using ctable.
       
  2041  * Returns an error if ctable cannot represent all the symbols in count.
       
  2042  */
       
  2043 static size_t ZSTD_fseBitCost(
       
  2044     FSE_CTable const* ctable,
       
  2045     unsigned const* count,
       
  2046     unsigned const max)
       
  2047 {
       
  2048     unsigned const kAccuracyLog = 8;
       
  2049     size_t cost = 0;
       
  2050     unsigned s;
       
  2051     FSE_CState_t cstate;
       
  2052     FSE_initCState(&cstate, ctable);
       
  2053     if (ZSTD_getFSEMaxSymbolValue(ctable) < max) {
       
  2054         DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u",
       
  2055                     ZSTD_getFSEMaxSymbolValue(ctable), max);
       
  2056         return ERROR(GENERIC);
       
  2057     }
       
  2058     for (s = 0; s <= max; ++s) {
       
  2059         unsigned const tableLog = cstate.stateLog;
       
  2060         unsigned const badCost = (tableLog + 1) << kAccuracyLog;
       
  2061         unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
       
  2062         if (count[s] == 0)
       
  2063             continue;
       
  2064         if (bitCost >= badCost) {
       
  2065             DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s);
       
  2066             return ERROR(GENERIC);
       
  2067         }
       
  2068         cost += count[s] * bitCost;
       
  2069     }
       
  2070     return cost >> kAccuracyLog;
       
  2071 }
       
  2072 
       
  2073 /**
       
  2074  * Returns the cost in bytes of encoding the normalized count header.
       
  2075  * Returns an error if any of the helper functions return an error.
       
  2076  */
       
  2077 static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
       
  2078                               size_t const nbSeq, unsigned const FSELog)
       
  2079 {
       
  2080     BYTE wksp[FSE_NCOUNTBOUND];
       
  2081     S16 norm[MaxSeq + 1];
       
  2082     const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
       
  2083     CHECK_F(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
       
  2084     return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
       
  2085 }
       
  2086 
       
  2087 
       
  2088 typedef enum {
       
  2089     ZSTD_defaultDisallowed = 0,
       
  2090     ZSTD_defaultAllowed = 1
       
  2091 } ZSTD_defaultPolicy_e;
       
  2092 
       
  2093 MEM_STATIC symbolEncodingType_e
       
  2094 ZSTD_selectEncodingType(
       
  2095         FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
       
  2096         size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
       
  2097         FSE_CTable const* prevCTable,
       
  2098         short const* defaultNorm, U32 defaultNormLog,
       
  2099         ZSTD_defaultPolicy_e const isDefaultAllowed,
       
  2100         ZSTD_strategy const strategy)
       
  2101 {
       
  2102     ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
       
  2103     if (mostFrequent == nbSeq) {
       
  2104         *repeatMode = FSE_repeat_none;
       
  2105         if (isDefaultAllowed && nbSeq <= 2) {
       
  2106             /* Prefer set_basic over set_rle when there are 2 or less symbols,
       
  2107              * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
       
  2108              * If basic encoding isn't possible, always choose RLE.
       
  2109              */
       
  2110             DEBUGLOG(5, "Selected set_basic");
       
  2111             return set_basic;
       
  2112         }
       
  2113         DEBUGLOG(5, "Selected set_rle");
       
  2114         return set_rle;
       
  2115     }
       
  2116     if (strategy < ZSTD_lazy) {
       
  2117         if (isDefaultAllowed) {
       
  2118             size_t const staticFse_nbSeq_max = 1000;
       
  2119             size_t const mult = 10 - strategy;
       
  2120             size_t const baseLog = 3;
       
  2121             size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog;  /* 28-36 for offset, 56-72 for lengths */
       
  2122             assert(defaultNormLog >= 5 && defaultNormLog <= 6);  /* xx_DEFAULTNORMLOG */
       
  2123             assert(mult <= 9 && mult >= 7);
       
  2124             if ( (*repeatMode == FSE_repeat_valid)
       
  2125               && (nbSeq < staticFse_nbSeq_max) ) {
       
  2126                 DEBUGLOG(5, "Selected set_repeat");
       
  2127                 return set_repeat;
       
  2128             }
       
  2129             if ( (nbSeq < dynamicFse_nbSeq_min)
       
  2130               || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
       
  2131                 DEBUGLOG(5, "Selected set_basic");
       
  2132                 /* The format allows default tables to be repeated, but it isn't useful.
       
  2133                  * When using simple heuristics to select encoding type, we don't want
       
  2134                  * to confuse these tables with dictionaries. When running more careful
       
  2135                  * analysis, we don't need to waste time checking both repeating tables
       
  2136                  * and default tables.
       
  2137                  */
       
  2138                 *repeatMode = FSE_repeat_none;
       
  2139                 return set_basic;
       
  2140             }
       
  2141         }
       
  2142     } else {
       
  2143         size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
       
  2144         size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
       
  2145         size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
       
  2146         size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
       
  2147 
       
  2148         if (isDefaultAllowed) {
       
  2149             assert(!ZSTD_isError(basicCost));
       
  2150             assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
       
  2151         }
       
  2152         assert(!ZSTD_isError(NCountCost));
       
  2153         assert(compressedCost < ERROR(maxCode));
       
  2154         DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
       
  2155                     (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);
       
  2156         if (basicCost <= repeatCost && basicCost <= compressedCost) {
       
  2157             DEBUGLOG(5, "Selected set_basic");
       
  2158             assert(isDefaultAllowed);
       
  2159             *repeatMode = FSE_repeat_none;
       
  2160             return set_basic;
       
  2161         }
       
  2162         if (repeatCost <= compressedCost) {
       
  2163             DEBUGLOG(5, "Selected set_repeat");
       
  2164             assert(!ZSTD_isError(repeatCost));
       
  2165             return set_repeat;
       
  2166         }
       
  2167         assert(compressedCost < basicCost && compressedCost < repeatCost);
       
  2168     }
       
  2169     DEBUGLOG(5, "Selected set_compressed");
       
  2170     *repeatMode = FSE_repeat_check;
       
  2171     return set_compressed;
       
  2172 }
       
  2173 
       
  2174 MEM_STATIC size_t
       
  2175 ZSTD_buildCTable(void* dst, size_t dstCapacity,
       
  2176                 FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
       
  2177                 unsigned* count, U32 max,
       
  2178                 const BYTE* codeTable, size_t nbSeq,
       
  2179                 const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
       
  2180                 const FSE_CTable* prevCTable, size_t prevCTableSize,
       
  2181                 void* workspace, size_t workspaceSize)
       
  2182 {
       
  2183     BYTE* op = (BYTE*)dst;
       
  2184     const BYTE* const oend = op + dstCapacity;
       
  2185     DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity);
       
  2186 
       
  2187     switch (type) {
       
  2188     case set_rle:
       
  2189         CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max));
       
  2190         if (dstCapacity==0) return ERROR(dstSize_tooSmall);
       
  2191         *op = codeTable[0];
       
  2192         return 1;
  1924         return 1;
  2193     case set_repeat:
  1925     default:
  2194         memcpy(nextCTable, prevCTable, prevCTableSize);
  1926         assert(0 /* impossible: pre-validated */);
  2195         return 0;
  1927         /* fall-through */
  2196     case set_basic:
  1928     case ZSTD_lcm_auto:
  2197         CHECK_F(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, workspace, workspaceSize));  /* note : could be pre-calculated */
  1929         return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
  2198         return 0;
  1930     }
  2199     case set_compressed: {
       
  2200         S16 norm[MaxSeq + 1];
       
  2201         size_t nbSeq_1 = nbSeq;
       
  2202         const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
       
  2203         if (count[codeTable[nbSeq-1]] > 1) {
       
  2204             count[codeTable[nbSeq-1]]--;
       
  2205             nbSeq_1--;
       
  2206         }
       
  2207         assert(nbSeq_1 > 1);
       
  2208         CHECK_F(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max));
       
  2209         {   size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog);   /* overflow protected */
       
  2210             if (FSE_isError(NCountSize)) return NCountSize;
       
  2211             CHECK_F(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, workspace, workspaceSize));
       
  2212             return NCountSize;
       
  2213         }
       
  2214     }
       
  2215     default: return assert(0), ERROR(GENERIC);
       
  2216     }
       
  2217 }
       
  2218 
       
  2219 FORCE_INLINE_TEMPLATE size_t
       
  2220 ZSTD_encodeSequences_body(
       
  2221             void* dst, size_t dstCapacity,
       
  2222             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
       
  2223             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
       
  2224             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
       
  2225             seqDef const* sequences, size_t nbSeq, int longOffsets)
       
  2226 {
       
  2227     BIT_CStream_t blockStream;
       
  2228     FSE_CState_t  stateMatchLength;
       
  2229     FSE_CState_t  stateOffsetBits;
       
  2230     FSE_CState_t  stateLitLength;
       
  2231 
       
  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);
       
  2236 
       
  2237     /* first symbols */
       
  2238     FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
       
  2239     FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);
       
  2240     FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);
       
  2241     BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
       
  2242     if (MEM_32bits()) BIT_flushBits(&blockStream);
       
  2243     BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
       
  2244     if (MEM_32bits()) BIT_flushBits(&blockStream);
       
  2245     if (longOffsets) {
       
  2246         U32 const ofBits = ofCodeTable[nbSeq-1];
       
  2247         int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
       
  2248         if (extraBits) {
       
  2249             BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
       
  2250             BIT_flushBits(&blockStream);
       
  2251         }
       
  2252         BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
       
  2253                     ofBits - extraBits);
       
  2254     } else {
       
  2255         BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
       
  2256     }
       
  2257     BIT_flushBits(&blockStream);
       
  2258 
       
  2259     {   size_t n;
       
  2260         for (n=nbSeq-2 ; n<nbSeq ; n--) {      /* intentional underflow */
       
  2261             BYTE const llCode = llCodeTable[n];
       
  2262             BYTE const ofCode = ofCodeTable[n];
       
  2263             BYTE const mlCode = mlCodeTable[n];
       
  2264             U32  const llBits = LL_bits[llCode];
       
  2265             U32  const ofBits = ofCode;
       
  2266             U32  const mlBits = ML_bits[mlCode];
       
  2267             DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
       
  2268                         (unsigned)sequences[n].litLength,
       
  2269                         (unsigned)sequences[n].matchLength + MINMATCH,
       
  2270                         (unsigned)sequences[n].offset);
       
  2271                                                                             /* 32b*/  /* 64b*/
       
  2272                                                                             /* (7)*/  /* (7)*/
       
  2273             FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode);       /* 15 */  /* 15 */
       
  2274             FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);      /* 24 */  /* 24 */
       
  2275             if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
       
  2276             FSE_encodeSymbol(&blockStream, &stateLitLength, llCode);        /* 16 */  /* 33 */
       
  2277             if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
       
  2278                 BIT_flushBits(&blockStream);                                /* (7)*/
       
  2279             BIT_addBits(&blockStream, sequences[n].litLength, llBits);
       
  2280             if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
       
  2281             BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
       
  2282             if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
       
  2283             if (longOffsets) {
       
  2284                 int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
       
  2285                 if (extraBits) {
       
  2286                     BIT_addBits(&blockStream, sequences[n].offset, extraBits);
       
  2287                     BIT_flushBits(&blockStream);                            /* (7)*/
       
  2288                 }
       
  2289                 BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
       
  2290                             ofBits - extraBits);                            /* 31 */
       
  2291             } else {
       
  2292                 BIT_addBits(&blockStream, sequences[n].offset, ofBits);     /* 31 */
       
  2293             }
       
  2294             BIT_flushBits(&blockStream);                                    /* (7)*/
       
  2295             DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
       
  2296     }   }
       
  2297 
       
  2298     DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
       
  2299     FSE_flushCState(&blockStream, &stateMatchLength);
       
  2300     DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
       
  2301     FSE_flushCState(&blockStream, &stateOffsetBits);
       
  2302     DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
       
  2303     FSE_flushCState(&blockStream, &stateLitLength);
       
  2304 
       
  2305     {   size_t const streamSize = BIT_closeCStream(&blockStream);
       
  2306         if (streamSize==0) return ERROR(dstSize_tooSmall);   /* not enough space */
       
  2307         return streamSize;
       
  2308     }
       
  2309 }
       
  2310 
       
  2311 static size_t
       
  2312 ZSTD_encodeSequences_default(
       
  2313             void* dst, size_t dstCapacity,
       
  2314             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
       
  2315             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
       
  2316             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
       
  2317             seqDef const* sequences, size_t nbSeq, int longOffsets)
       
  2318 {
       
  2319     return ZSTD_encodeSequences_body(dst, dstCapacity,
       
  2320                                     CTable_MatchLength, mlCodeTable,
       
  2321                                     CTable_OffsetBits, ofCodeTable,
       
  2322                                     CTable_LitLength, llCodeTable,
       
  2323                                     sequences, nbSeq, longOffsets);
       
  2324 }
       
  2325 
       
  2326 
       
  2327 #if DYNAMIC_BMI2
       
  2328 
       
  2329 static TARGET_ATTRIBUTE("bmi2") size_t
       
  2330 ZSTD_encodeSequences_bmi2(
       
  2331             void* dst, size_t dstCapacity,
       
  2332             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
       
  2333             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
       
  2334             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
       
  2335             seqDef const* sequences, size_t nbSeq, int longOffsets)
       
  2336 {
       
  2337     return ZSTD_encodeSequences_body(dst, dstCapacity,
       
  2338                                     CTable_MatchLength, mlCodeTable,
       
  2339                                     CTable_OffsetBits, ofCodeTable,
       
  2340                                     CTable_LitLength, llCodeTable,
       
  2341                                     sequences, nbSeq, longOffsets);
       
  2342 }
       
  2343 
       
  2344 #endif
       
  2345 
       
  2346 static size_t ZSTD_encodeSequences(
       
  2347             void* dst, size_t dstCapacity,
       
  2348             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
       
  2349             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
       
  2350             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
       
  2351             seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
       
  2352 {
       
  2353     DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity);
       
  2354 #if DYNAMIC_BMI2
       
  2355     if (bmi2) {
       
  2356         return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
       
  2357                                          CTable_MatchLength, mlCodeTable,
       
  2358                                          CTable_OffsetBits, ofCodeTable,
       
  2359                                          CTable_LitLength, llCodeTable,
       
  2360                                          sequences, nbSeq, longOffsets);
       
  2361     }
       
  2362 #endif
       
  2363     (void)bmi2;
       
  2364     return ZSTD_encodeSequences_default(dst, dstCapacity,
       
  2365                                         CTable_MatchLength, mlCodeTable,
       
  2366                                         CTable_OffsetBits, ofCodeTable,
       
  2367                                         CTable_LitLength, llCodeTable,
       
  2368                                         sequences, nbSeq, longOffsets);
       
  2369 }
  1931 }
  2370 
  1932 
  2371 /* ZSTD_compressSequences_internal():
  1933 /* ZSTD_compressSequences_internal():
  2372  * actually compresses both literals and sequences */
  1934  * actually compresses both literals and sequences */
  2373 MEM_STATIC size_t
  1935 MEM_STATIC size_t
  2391     const BYTE* const llCodeTable = seqStorePtr->llCode;
  1953     const BYTE* const llCodeTable = seqStorePtr->llCode;
  2392     const BYTE* const mlCodeTable = seqStorePtr->mlCode;
  1954     const BYTE* const mlCodeTable = seqStorePtr->mlCode;
  2393     BYTE* const ostart = (BYTE*)dst;
  1955     BYTE* const ostart = (BYTE*)dst;
  2394     BYTE* const oend = ostart + dstCapacity;
  1956     BYTE* const oend = ostart + dstCapacity;
  2395     BYTE* op = ostart;
  1957     BYTE* op = ostart;
  2396     size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
  1958     size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
  2397     BYTE* seqHead;
  1959     BYTE* seqHead;
  2398     BYTE* lastNCount = NULL;
  1960     BYTE* lastNCount = NULL;
  2399 
  1961 
       
  1962     DEBUGLOG(5, "ZSTD_compressSequences_internal (nbSeq=%zu)", nbSeq);
  2400     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
  1963     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
  2401     DEBUGLOG(5, "ZSTD_compressSequences_internal");
       
  2402 
  1964 
  2403     /* Compress literals */
  1965     /* Compress literals */
  2404     {   const BYTE* const literals = seqStorePtr->litStart;
  1966     {   const BYTE* const literals = seqStorePtr->litStart;
  2405         size_t const litSize = seqStorePtr->lit - literals;
  1967         size_t const litSize = (size_t)(seqStorePtr->lit - literals);
  2406         int const disableLiteralCompression = (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
       
  2407         size_t const cSize = ZSTD_compressLiterals(
  1968         size_t const cSize = ZSTD_compressLiterals(
  2408                                     &prevEntropy->huf, &nextEntropy->huf,
  1969                                     &prevEntropy->huf, &nextEntropy->huf,
  2409                                     cctxParams->cParams.strategy, disableLiteralCompression,
  1970                                     cctxParams->cParams.strategy,
       
  1971                                     ZSTD_disableLiteralsCompression(cctxParams),
  2410                                     op, dstCapacity,
  1972                                     op, dstCapacity,
  2411                                     literals, litSize,
  1973                                     literals, litSize,
  2412                                     workspace, wkspSize,
  1974                                     workspace, wkspSize,
  2413                                     bmi2);
  1975                                     bmi2);
  2414         if (ZSTD_isError(cSize))
  1976         FORWARD_IF_ERROR(cSize);
  2415           return cSize;
       
  2416         assert(cSize <= dstCapacity);
  1977         assert(cSize <= dstCapacity);
  2417         op += cSize;
  1978         op += cSize;
  2418     }
  1979     }
  2419 
  1980 
  2420     /* Sequences Header */
  1981     /* Sequences Header */
  2421     if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/) return ERROR(dstSize_tooSmall);
  1982     RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
       
  1983                     dstSize_tooSmall);
  2422     if (nbSeq < 0x7F)
  1984     if (nbSeq < 0x7F)
  2423         *op++ = (BYTE)nbSeq;
  1985         *op++ = (BYTE)nbSeq;
  2424     else if (nbSeq < LONGNBSEQ)
  1986     else if (nbSeq < LONGNBSEQ)
  2425         op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
  1987         op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
  2426     else
  1988     else
  2427         op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
  1989         op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
       
  1990     assert(op <= oend);
  2428     if (nbSeq==0) {
  1991     if (nbSeq==0) {
  2429         /* Copy the old tables over as if we repeated them */
  1992         /* Copy the old tables over as if we repeated them */
  2430         memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
  1993         memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
  2431         return op - ostart;
  1994         return (size_t)(op - ostart);
  2432     }
  1995     }
  2433 
  1996 
  2434     /* seqHead : flags for FSE encoding type */
  1997     /* seqHead : flags for FSE encoding type */
  2435     seqHead = op++;
  1998     seqHead = op++;
       
  1999     assert(op <= oend);
  2436 
  2000 
  2437     /* convert length/distances into codes */
  2001     /* convert length/distances into codes */
  2438     ZSTD_seqToCodes(seqStorePtr);
  2002     ZSTD_seqToCodes(seqStorePtr);
  2439     /* build CTable for Literal Lengths */
  2003     /* build CTable for Literal Lengths */
  2440     {   unsigned max = MaxLL;
  2004     {   unsigned max = MaxLL;
  2446                                         LLFSELog, prevEntropy->fse.litlengthCTable,
  2010                                         LLFSELog, prevEntropy->fse.litlengthCTable,
  2447                                         LL_defaultNorm, LL_defaultNormLog,
  2011                                         LL_defaultNorm, LL_defaultNormLog,
  2448                                         ZSTD_defaultAllowed, strategy);
  2012                                         ZSTD_defaultAllowed, strategy);
  2449         assert(set_basic < set_compressed && set_rle < set_compressed);
  2013         assert(set_basic < set_compressed && set_rle < set_compressed);
  2450         assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2014         assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2451         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
  2015         {   size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
  2452                                                     count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
  2016                                                     count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
  2453                                                     prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
  2017                                                     prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
  2454                                                     workspace, wkspSize);
  2018                                                     workspace, wkspSize);
  2455             if (ZSTD_isError(countSize)) return countSize;
  2019             FORWARD_IF_ERROR(countSize);
  2456             if (LLtype == set_compressed)
  2020             if (LLtype == set_compressed)
  2457                 lastNCount = op;
  2021                 lastNCount = op;
  2458             op += countSize;
  2022             op += countSize;
       
  2023             assert(op <= oend);
  2459     }   }
  2024     }   }
  2460     /* build CTable for Offsets */
  2025     /* build CTable for Offsets */
  2461     {   unsigned max = MaxOff;
  2026     {   unsigned max = MaxOff;
  2462         size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace, wkspSize);  /* can't fail */
  2027         size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace, wkspSize);  /* can't fail */
  2463         /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
  2028         /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
  2468                                         count, max, mostFrequent, nbSeq,
  2033                                         count, max, mostFrequent, nbSeq,
  2469                                         OffFSELog, prevEntropy->fse.offcodeCTable,
  2034                                         OffFSELog, prevEntropy->fse.offcodeCTable,
  2470                                         OF_defaultNorm, OF_defaultNormLog,
  2035                                         OF_defaultNorm, OF_defaultNormLog,
  2471                                         defaultPolicy, strategy);
  2036                                         defaultPolicy, strategy);
  2472         assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2037         assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2473         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
  2038         {   size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
  2474                                                     count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  2039                                                     count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  2475                                                     prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
  2040                                                     prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
  2476                                                     workspace, wkspSize);
  2041                                                     workspace, wkspSize);
  2477             if (ZSTD_isError(countSize)) return countSize;
  2042             FORWARD_IF_ERROR(countSize);
  2478             if (Offtype == set_compressed)
  2043             if (Offtype == set_compressed)
  2479                 lastNCount = op;
  2044                 lastNCount = op;
  2480             op += countSize;
  2045             op += countSize;
       
  2046             assert(op <= oend);
  2481     }   }
  2047     }   }
  2482     /* build CTable for MatchLengths */
  2048     /* build CTable for MatchLengths */
  2483     {   unsigned max = MaxML;
  2049     {   unsigned max = MaxML;
  2484         size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace, wkspSize);   /* can't fail */
  2050         size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace, wkspSize);   /* can't fail */
  2485         DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
  2051         DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
  2488                                         count, max, mostFrequent, nbSeq,
  2054                                         count, max, mostFrequent, nbSeq,
  2489                                         MLFSELog, prevEntropy->fse.matchlengthCTable,
  2055                                         MLFSELog, prevEntropy->fse.matchlengthCTable,
  2490                                         ML_defaultNorm, ML_defaultNormLog,
  2056                                         ML_defaultNorm, ML_defaultNormLog,
  2491                                         ZSTD_defaultAllowed, strategy);
  2057                                         ZSTD_defaultAllowed, strategy);
  2492         assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2058         assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  2493         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
  2059         {   size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
  2494                                                     count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
  2060                                                     count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
  2495                                                     prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
  2061                                                     prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
  2496                                                     workspace, wkspSize);
  2062                                                     workspace, wkspSize);
  2497             if (ZSTD_isError(countSize)) return countSize;
  2063             FORWARD_IF_ERROR(countSize);
  2498             if (MLtype == set_compressed)
  2064             if (MLtype == set_compressed)
  2499                 lastNCount = op;
  2065                 lastNCount = op;
  2500             op += countSize;
  2066             op += countSize;
       
  2067             assert(op <= oend);
  2501     }   }
  2068     }   }
  2502 
  2069 
  2503     *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
  2070     *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
  2504 
  2071 
  2505     {   size_t const bitstreamSize = ZSTD_encodeSequences(
  2072     {   size_t const bitstreamSize = ZSTD_encodeSequences(
  2506                                         op, oend - op,
  2073                                         op, (size_t)(oend - op),
  2507                                         CTable_MatchLength, mlCodeTable,
  2074                                         CTable_MatchLength, mlCodeTable,
  2508                                         CTable_OffsetBits, ofCodeTable,
  2075                                         CTable_OffsetBits, ofCodeTable,
  2509                                         CTable_LitLength, llCodeTable,
  2076                                         CTable_LitLength, llCodeTable,
  2510                                         sequences, nbSeq,
  2077                                         sequences, nbSeq,
  2511                                         longOffsets, bmi2);
  2078                                         longOffsets, bmi2);
  2512         if (ZSTD_isError(bitstreamSize)) return bitstreamSize;
  2079         FORWARD_IF_ERROR(bitstreamSize);
  2513         op += bitstreamSize;
  2080         op += bitstreamSize;
       
  2081         assert(op <= oend);
  2514         /* zstd versions <= 1.3.4 mistakenly report corruption when
  2082         /* zstd versions <= 1.3.4 mistakenly report corruption when
  2515          * FSE_readNCount() recieves a buffer < 4 bytes.
  2083          * FSE_readNCount() receives a buffer < 4 bytes.
  2516          * Fixed by https://github.com/facebook/zstd/pull/1146.
  2084          * Fixed by https://github.com/facebook/zstd/pull/1146.
  2517          * This can happen when the last set_compressed table present is 2
  2085          * This can happen when the last set_compressed table present is 2
  2518          * bytes and the bitstream is only one byte.
  2086          * bytes and the bitstream is only one byte.
  2519          * In this exceedingly rare case, we will simply emit an uncompressed
  2087          * In this exceedingly rare case, we will simply emit an uncompressed
  2520          * block, since it isn't worth optimizing.
  2088          * block, since it isn't worth optimizing.
  2527             return 0;
  2095             return 0;
  2528         }
  2096         }
  2529     }
  2097     }
  2530 
  2098 
  2531     DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart));
  2099     DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart));
  2532     return op - ostart;
  2100     return (size_t)(op - ostart);
  2533 }
  2101 }
  2534 
  2102 
  2535 MEM_STATIC size_t
  2103 MEM_STATIC size_t
  2536 ZSTD_compressSequences(seqStore_t* seqStorePtr,
  2104 ZSTD_compressSequences(seqStore_t* seqStorePtr,
  2537                        const ZSTD_entropyCTables_t* prevEntropy,
  2105                        const ZSTD_entropyCTables_t* prevEntropy,
  2550     /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
  2118     /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
  2551      * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
  2119      * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
  2552      */
  2120      */
  2553     if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
  2121     if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
  2554         return 0;  /* block not compressed */
  2122         return 0;  /* block not compressed */
  2555     if (ZSTD_isError(cSize)) return cSize;
  2123     FORWARD_IF_ERROR(cSize);
  2556 
  2124 
  2557     /* Check compressibility */
  2125     /* Check compressibility */
  2558     {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
  2126     {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
  2559         if (cSize >= maxCSize) return 0;  /* block not compressed */
  2127         if (cSize >= maxCSize) return 0;  /* block not compressed */
  2560     }
  2128     }
  2620     ssPtr->lit = ssPtr->litStart;
  2188     ssPtr->lit = ssPtr->litStart;
  2621     ssPtr->sequences = ssPtr->sequencesStart;
  2189     ssPtr->sequences = ssPtr->sequencesStart;
  2622     ssPtr->longLengthID = 0;
  2190     ssPtr->longLengthID = 0;
  2623 }
  2191 }
  2624 
  2192 
  2625 static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
  2193 typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e;
  2626                                         void* dst, size_t dstCapacity,
  2194 
  2627                                         const void* src, size_t srcSize)
  2195 static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
  2628 {
  2196 {
  2629     ZSTD_matchState_t* const ms = &zc->blockState.matchState;
  2197     ZSTD_matchState_t* const ms = &zc->blockState.matchState;
  2630     size_t cSize;
  2198     DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize);
  2631     DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
       
  2632                 (unsigned)dstCapacity, (unsigned)ms->window.dictLimit, (unsigned)ms->nextToUpdate);
       
  2633     assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
  2199     assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
  2634 
       
  2635     /* Assert that we have correctly flushed the ctx params into the ms's copy */
  2200     /* Assert that we have correctly flushed the ctx params into the ms's copy */
  2636     ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
  2201     ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
  2637 
       
  2638     if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
  2202     if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
  2639         ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
  2203         ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
  2640         cSize = 0;
  2204         return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */
  2641         goto out;  /* don't even attempt compression below a certain srcSize */
       
  2642     }
  2205     }
  2643     ZSTD_resetSeqStore(&(zc->seqStore));
  2206     ZSTD_resetSeqStore(&(zc->seqStore));
  2644     ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;   /* required for optimal parser to read stats from dictionary */
  2207     /* required for optimal parser to read stats from dictionary */
  2645 
  2208     ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;
       
  2209     /* tell the optimal parser how we expect to compress literals */
       
  2210     ms->opt.literalCompressionMode = zc->appliedParams.literalCompressionMode;
  2646     /* a gap between an attached dict and the current window is not safe,
  2211     /* a gap between an attached dict and the current window is not safe,
  2647      * they must remain adjacent,
  2212      * they must remain adjacent,
  2648      * and when that stops being the case, the dict must be unset */
  2213      * and when that stops being the case, the dict must be unset */
  2649     assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
  2214     assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
  2650 
  2215 
  2677             rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
  2242             rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
  2678 
  2243 
  2679             ldmSeqStore.seq = zc->ldmSequences;
  2244             ldmSeqStore.seq = zc->ldmSequences;
  2680             ldmSeqStore.capacity = zc->maxNbLdmSequences;
  2245             ldmSeqStore.capacity = zc->maxNbLdmSequences;
  2681             /* Updates ldmSeqStore.size */
  2246             /* Updates ldmSeqStore.size */
  2682             CHECK_F(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore,
  2247             FORWARD_IF_ERROR(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore,
  2683                                                &zc->appliedParams.ldmParams,
  2248                                                &zc->appliedParams.ldmParams,
  2684                                                src, srcSize));
  2249                                                src, srcSize));
  2685             /* Updates ldmSeqStore.pos */
  2250             /* Updates ldmSeqStore.pos */
  2686             lastLLSize =
  2251             lastLLSize =
  2687                 ZSTD_ldm_blockCompress(&ldmSeqStore,
  2252                 ZSTD_ldm_blockCompress(&ldmSeqStore,
  2694             lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
  2259             lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
  2695         }
  2260         }
  2696         {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
  2261         {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
  2697             ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
  2262             ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
  2698     }   }
  2263     }   }
       
  2264     return ZSTDbss_compress;
       
  2265 }
       
  2266 
       
  2267 static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
       
  2268                                         void* dst, size_t dstCapacity,
       
  2269                                         const void* src, size_t srcSize)
       
  2270 {
       
  2271     size_t cSize;
       
  2272     DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
       
  2273                 (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
       
  2274                 (unsigned)zc->blockState.matchState.nextToUpdate);
       
  2275 
       
  2276     {   const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
       
  2277         FORWARD_IF_ERROR(bss);
       
  2278         if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }
       
  2279     }
  2699 
  2280 
  2700     /* encode sequences and literals */
  2281     /* encode sequences and literals */
  2701     cSize = ZSTD_compressSequences(&zc->seqStore,
  2282     cSize = ZSTD_compressSequences(&zc->seqStore,
  2702             &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
  2283             &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
  2703             &zc->appliedParams,
  2284             &zc->appliedParams,
  2719      */
  2300      */
  2720     if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
  2301     if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
  2721         zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
  2302         zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
  2722 
  2303 
  2723     return cSize;
  2304     return cSize;
       
  2305 }
       
  2306 
       
  2307 
       
  2308 static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, void const* ip, void const* iend)
       
  2309 {
       
  2310     if (ZSTD_window_needOverflowCorrection(ms->window, iend)) {
       
  2311         U32 const maxDist = (U32)1 << params->cParams.windowLog;
       
  2312         U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy);
       
  2313         U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
       
  2314         ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
       
  2315         ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
       
  2316         ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
       
  2317         ZSTD_reduceIndex(ms, params, correction);
       
  2318         if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
       
  2319         else ms->nextToUpdate -= correction;
       
  2320         /* invalidate dictionaries on overflow correction */
       
  2321         ms->loadedDictEnd = 0;
       
  2322         ms->dictMatchState = NULL;
       
  2323     }
  2724 }
  2324 }
  2725 
  2325 
  2726 
  2326 
  2727 /*! ZSTD_compress_frameChunk() :
  2327 /*! ZSTD_compress_frameChunk() :
  2728 *   Compress a chunk of data into one or multiple blocks.
  2328 *   Compress a chunk of data into one or multiple blocks.
  2740     size_t remaining = srcSize;
  2340     size_t remaining = srcSize;
  2741     const BYTE* ip = (const BYTE*)src;
  2341     const BYTE* ip = (const BYTE*)src;
  2742     BYTE* const ostart = (BYTE*)dst;
  2342     BYTE* const ostart = (BYTE*)dst;
  2743     BYTE* op = ostart;
  2343     BYTE* op = ostart;
  2744     U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
  2344     U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
  2745     assert(cctx->appliedParams.cParams.windowLog <= 31);
  2345     assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
  2746 
  2346 
  2747     DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
  2347     DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
  2748     if (cctx->appliedParams.fParams.checksumFlag && srcSize)
  2348     if (cctx->appliedParams.fParams.checksumFlag && srcSize)
  2749         XXH64_update(&cctx->xxhState, src, srcSize);
  2349         XXH64_update(&cctx->xxhState, src, srcSize);
  2750 
  2350 
  2751     while (remaining) {
  2351     while (remaining) {
  2752         ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2352         ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2753         U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
  2353         U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
  2754 
  2354 
  2755         if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE)
  2355         RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE,
  2756             return ERROR(dstSize_tooSmall);   /* not enough space to store compressed block */
  2356                         dstSize_tooSmall,
       
  2357                         "not enough space to store compressed block");
  2757         if (remaining < blockSize) blockSize = remaining;
  2358         if (remaining < blockSize) blockSize = remaining;
  2758 
  2359 
  2759         if (ZSTD_window_needOverflowCorrection(ms->window, ip + blockSize)) {
  2360         ZSTD_overflowCorrectIfNeeded(ms, &cctx->appliedParams, ip, ip + blockSize);
  2760             U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
  2361         ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
  2761             U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
  2362 
  2762             ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
  2363         /* Ensure hash/chain table insertion resumes no sooner than lowlimit */
  2763             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
       
  2764             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
       
  2765             ZSTD_reduceIndex(cctx, correction);
       
  2766             if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
       
  2767             else ms->nextToUpdate -= correction;
       
  2768             ms->loadedDictEnd = 0;
       
  2769             ms->dictMatchState = NULL;
       
  2770         }
       
  2771         ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
       
  2772         if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
  2364         if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
  2773 
  2365 
  2774         {   size_t cSize = ZSTD_compressBlock_internal(cctx,
  2366         {   size_t cSize = ZSTD_compressBlock_internal(cctx,
  2775                                 op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
  2367                                 op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
  2776                                 ip, blockSize);
  2368                                 ip, blockSize);
  2777             if (ZSTD_isError(cSize)) return cSize;
  2369             FORWARD_IF_ERROR(cSize);
  2778 
  2370 
  2779             if (cSize == 0) {  /* block is not compressible */
  2371             if (cSize == 0) {  /* block is not compressible */
  2780                 cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
  2372                 cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
  2781                 if (ZSTD_isError(cSize)) return cSize;
  2373                 FORWARD_IF_ERROR(cSize);
  2782             } else {
  2374             } else {
  2783                 U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
  2375                 U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
  2784                 MEM_writeLE24(op, cBlockHeader24);
  2376                 MEM_writeLE24(op, cBlockHeader24);
  2785                 cSize += ZSTD_blockHeaderSize;
  2377                 cSize += ZSTD_blockHeaderSize;
  2786             }
  2378             }
  2794             DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u",
  2386             DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u",
  2795                         (unsigned)cSize);
  2387                         (unsigned)cSize);
  2796     }   }
  2388     }   }
  2797 
  2389 
  2798     if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
  2390     if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
  2799     return op-ostart;
  2391     return (size_t)(op-ostart);
  2800 }
  2392 }
  2801 
  2393 
  2802 
  2394 
  2803 static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
  2395 static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
  2804                                     ZSTD_CCtx_params params, U64 pledgedSrcSize, U32 dictID)
  2396                                     ZSTD_CCtx_params params, U64 pledgedSrcSize, U32 dictID)
  2809     U32   const windowSize = (U32)1 << params.cParams.windowLog;
  2401     U32   const windowSize = (U32)1 << params.cParams.windowLog;
  2810     U32   const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
  2402     U32   const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
  2811     BYTE  const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
  2403     BYTE  const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
  2812     U32   const fcsCode = params.fParams.contentSizeFlag ?
  2404     U32   const fcsCode = params.fParams.contentSizeFlag ?
  2813                      (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */
  2405                      (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */
  2814     BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
  2406     BYTE  const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
  2815     size_t pos=0;
  2407     size_t pos=0;
  2816 
  2408 
  2817     assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
  2409     assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
  2818     if (dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX) return ERROR(dstSize_tooSmall);
  2410     RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall);
  2819     DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
  2411     DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
  2820                 !params.fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
  2412                 !params.fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
  2821 
  2413 
  2822     if (params.format == ZSTD_f_zstd1) {
  2414     if (params.format == ZSTD_f_zstd1) {
  2823         MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
  2415         MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
  2824         pos = 4;
  2416         pos = 4;
  2825     }
  2417     }
  2826     op[pos++] = frameHeaderDecriptionByte;
  2418     op[pos++] = frameHeaderDescriptionByte;
  2827     if (!singleSegment) op[pos++] = windowLogByte;
  2419     if (!singleSegment) op[pos++] = windowLogByte;
  2828     switch(dictIDSizeCode)
  2420     switch(dictIDSizeCode)
  2829     {
  2421     {
  2830         default:  assert(0); /* impossible */
  2422         default:  assert(0); /* impossible */
  2831         case 0 : break;
  2423         case 0 : break;
  2845 }
  2437 }
  2846 
  2438 
  2847 /* ZSTD_writeLastEmptyBlock() :
  2439 /* ZSTD_writeLastEmptyBlock() :
  2848  * output an empty Block with end-of-frame mark to complete a frame
  2440  * output an empty Block with end-of-frame mark to complete a frame
  2849  * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))
  2441  * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))
  2850  *           or an error code if `dstCapcity` is too small (<ZSTD_blockHeaderSize)
  2442  *           or an error code if `dstCapacity` is too small (<ZSTD_blockHeaderSize)
  2851  */
  2443  */
  2852 size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
  2444 size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
  2853 {
  2445 {
  2854     if (dstCapacity < ZSTD_blockHeaderSize) return ERROR(dstSize_tooSmall);
  2446     RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall);
  2855     {   U32 const cBlockHeader24 = 1 /*lastBlock*/ + (((U32)bt_raw)<<1);  /* 0 size */
  2447     {   U32 const cBlockHeader24 = 1 /*lastBlock*/ + (((U32)bt_raw)<<1);  /* 0 size */
  2856         MEM_writeLE24(dst, cBlockHeader24);
  2448         MEM_writeLE24(dst, cBlockHeader24);
  2857         return ZSTD_blockHeaderSize;
  2449         return ZSTD_blockHeaderSize;
  2858     }
  2450     }
  2859 }
  2451 }
  2860 
  2452 
  2861 size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq)
  2453 size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq)
  2862 {
  2454 {
  2863     if (cctx->stage != ZSTDcs_init)
  2455     RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong);
  2864         return ERROR(stage_wrong);
  2456     RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm,
  2865     if (cctx->appliedParams.ldmParams.enableLdm)
  2457                     parameter_unsupported);
  2866         return ERROR(parameter_unsupported);
       
  2867     cctx->externSeqStore.seq = seq;
  2458     cctx->externSeqStore.seq = seq;
  2868     cctx->externSeqStore.size = nbSeq;
  2459     cctx->externSeqStore.size = nbSeq;
  2869     cctx->externSeqStore.capacity = nbSeq;
  2460     cctx->externSeqStore.capacity = nbSeq;
  2870     cctx->externSeqStore.pos = 0;
  2461     cctx->externSeqStore.pos = 0;
  2871     return 0;
  2462     return 0;
  2880     ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2471     ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2881     size_t fhSize = 0;
  2472     size_t fhSize = 0;
  2882 
  2473 
  2883     DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
  2474     DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
  2884                 cctx->stage, (unsigned)srcSize);
  2475                 cctx->stage, (unsigned)srcSize);
  2885     if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
  2476     RETURN_ERROR_IF(cctx->stage==ZSTDcs_created, stage_wrong,
       
  2477                     "missing init (ZSTD_compressBegin)");
  2886 
  2478 
  2887     if (frame && (cctx->stage==ZSTDcs_init)) {
  2479     if (frame && (cctx->stage==ZSTDcs_init)) {
  2888         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
  2480         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
  2889                                        cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
  2481                                        cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
  2890         if (ZSTD_isError(fhSize)) return fhSize;
  2482         FORWARD_IF_ERROR(fhSize);
       
  2483         assert(fhSize <= dstCapacity);
  2891         dstCapacity -= fhSize;
  2484         dstCapacity -= fhSize;
  2892         dst = (char*)dst + fhSize;
  2485         dst = (char*)dst + fhSize;
  2893         cctx->stage = ZSTDcs_ongoing;
  2486         cctx->stage = ZSTDcs_ongoing;
  2894     }
  2487     }
  2895 
  2488 
  2902         ZSTD_window_update(&cctx->ldmState.window, src, srcSize);
  2495         ZSTD_window_update(&cctx->ldmState.window, src, srcSize);
  2903     }
  2496     }
  2904 
  2497 
  2905     if (!frame) {
  2498     if (!frame) {
  2906         /* overflow check and correction for block mode */
  2499         /* overflow check and correction for block mode */
  2907         if (ZSTD_window_needOverflowCorrection(ms->window, (const char*)src + srcSize)) {
  2500         ZSTD_overflowCorrectIfNeeded(ms, &cctx->appliedParams, src, (BYTE const*)src + srcSize);
  2908             U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
       
  2909             U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, 1 << cctx->appliedParams.cParams.windowLog, src);
       
  2910             ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
       
  2911             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
       
  2912             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
       
  2913             ZSTD_reduceIndex(cctx, correction);
       
  2914             if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
       
  2915             else ms->nextToUpdate -= correction;
       
  2916             ms->loadedDictEnd = 0;
       
  2917             ms->dictMatchState = NULL;
       
  2918         }
       
  2919     }
  2501     }
  2920 
  2502 
  2921     DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
  2503     DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
  2922     {   size_t const cSize = frame ?
  2504     {   size_t const cSize = frame ?
  2923                              ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
  2505                              ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
  2924                              ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
  2506                              ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
  2925         if (ZSTD_isError(cSize)) return cSize;
  2507         FORWARD_IF_ERROR(cSize);
  2926         cctx->consumedSrcSize += srcSize;
  2508         cctx->consumedSrcSize += srcSize;
  2927         cctx->producedCSize += (cSize + fhSize);
  2509         cctx->producedCSize += (cSize + fhSize);
  2928         assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
  2510         assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
  2929         if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  2511         if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  2930             ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  2512             ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  2931             if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
  2513             RETURN_ERROR_IF(
  2932                 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
  2514                 cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne,
  2933                     (unsigned)cctx->pledgedSrcSizePlusOne-1, (unsigned)cctx->consumedSrcSize);
  2515                 srcSize_wrong,
  2934                 return ERROR(srcSize_wrong);
  2516                 "error : pledgedSrcSize = %u, while realSrcSize >= %u",
  2935             }
  2517                 (unsigned)cctx->pledgedSrcSizePlusOne-1,
       
  2518                 (unsigned)cctx->consumedSrcSize);
  2936         }
  2519         }
  2937         return cSize + fhSize;
  2520         return cSize + fhSize;
  2938     }
  2521     }
  2939 }
  2522 }
  2940 
  2523 
  2954     return MIN (ZSTD_BLOCKSIZE_MAX, (U32)1 << cParams.windowLog);
  2537     return MIN (ZSTD_BLOCKSIZE_MAX, (U32)1 << cParams.windowLog);
  2955 }
  2538 }
  2956 
  2539 
  2957 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
  2540 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
  2958 {
  2541 {
  2959     size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
  2542     DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize);
  2960     if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
  2543     { size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
       
  2544       RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong); }
  2961 
  2545 
  2962     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
  2546     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
  2963 }
  2547 }
  2964 
  2548 
  2965 /*! ZSTD_loadDictionaryContent() :
  2549 /*! ZSTD_loadDictionaryContent() :
  2968 static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
  2552 static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
  2969                                          ZSTD_CCtx_params const* params,
  2553                                          ZSTD_CCtx_params const* params,
  2970                                          const void* src, size_t srcSize,
  2554                                          const void* src, size_t srcSize,
  2971                                          ZSTD_dictTableLoadMethod_e dtlm)
  2555                                          ZSTD_dictTableLoadMethod_e dtlm)
  2972 {
  2556 {
  2973     const BYTE* const ip = (const BYTE*) src;
  2557     const BYTE* ip = (const BYTE*) src;
  2974     const BYTE* const iend = ip + srcSize;
  2558     const BYTE* const iend = ip + srcSize;
  2975 
  2559 
  2976     ZSTD_window_update(&ms->window, src, srcSize);
  2560     ZSTD_window_update(&ms->window, src, srcSize);
  2977     ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
  2561     ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
  2978 
  2562 
  2979     /* Assert that we the ms params match the params we're being given */
  2563     /* Assert that we the ms params match the params we're being given */
  2980     ZSTD_assertEqualCParams(params->cParams, ms->cParams);
  2564     ZSTD_assertEqualCParams(params->cParams, ms->cParams);
  2981 
  2565 
  2982     if (srcSize <= HASH_READ_SIZE) return 0;
  2566     if (srcSize <= HASH_READ_SIZE) return 0;
  2983 
  2567 
  2984     switch(params->cParams.strategy)
  2568     while (iend - ip > HASH_READ_SIZE) {
  2985     {
  2569         size_t const remaining = (size_t)(iend - ip);
  2986     case ZSTD_fast:
  2570         size_t const chunk = MIN(remaining, ZSTD_CHUNKSIZE_MAX);
  2987         ZSTD_fillHashTable(ms, iend, dtlm);
  2571         const BYTE* const ichunk = ip + chunk;
  2988         break;
  2572 
  2989     case ZSTD_dfast:
  2573         ZSTD_overflowCorrectIfNeeded(ms, params, ip, ichunk);
  2990         ZSTD_fillDoubleHashTable(ms, iend, dtlm);
  2574 
  2991         break;
  2575         switch(params->cParams.strategy)
  2992 
  2576         {
  2993     case ZSTD_greedy:
  2577         case ZSTD_fast:
  2994     case ZSTD_lazy:
  2578             ZSTD_fillHashTable(ms, ichunk, dtlm);
  2995     case ZSTD_lazy2:
  2579             break;
  2996         if (srcSize >= HASH_READ_SIZE)
  2580         case ZSTD_dfast:
  2997             ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE);
  2581             ZSTD_fillDoubleHashTable(ms, ichunk, dtlm);
  2998         break;
  2582             break;
  2999 
  2583 
  3000     case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */
  2584         case ZSTD_greedy:
  3001     case ZSTD_btopt:
  2585         case ZSTD_lazy:
  3002     case ZSTD_btultra:
  2586         case ZSTD_lazy2:
  3003     case ZSTD_btultra2:
  2587             if (chunk >= HASH_READ_SIZE)
  3004         if (srcSize >= HASH_READ_SIZE)
  2588                 ZSTD_insertAndFindFirstIndex(ms, ichunk-HASH_READ_SIZE);
  3005             ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
  2589             break;
  3006         break;
  2590 
  3007 
  2591         case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */
  3008     default:
  2592         case ZSTD_btopt:
  3009         assert(0);  /* not possible : not a valid strategy id */
  2593         case ZSTD_btultra:
       
  2594         case ZSTD_btultra2:
       
  2595             if (chunk >= HASH_READ_SIZE)
       
  2596                 ZSTD_updateTree(ms, ichunk-HASH_READ_SIZE, ichunk);
       
  2597             break;
       
  2598 
       
  2599         default:
       
  2600             assert(0);  /* not possible : not a valid strategy id */
       
  2601         }
       
  2602 
       
  2603         ip = ichunk;
  3010     }
  2604     }
  3011 
  2605 
  3012     ms->nextToUpdate = (U32)(iend - ms->window.base);
  2606     ms->nextToUpdate = (U32)(iend - ms->window.base);
  3013     return 0;
  2607     return 0;
  3014 }
  2608 }
  3018    when FSE encoding.  Refuse dictionaries that assign zero probability to symbols
  2612    when FSE encoding.  Refuse dictionaries that assign zero probability to symbols
  3019    that we may encounter during compression.
  2613    that we may encounter during compression.
  3020    NOTE: This behavior is not standard and could be improved in the future. */
  2614    NOTE: This behavior is not standard and could be improved in the future. */
  3021 static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
  2615 static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
  3022     U32 s;
  2616     U32 s;
  3023     if (dictMaxSymbolValue < maxSymbolValue) return ERROR(dictionary_corrupted);
  2617     RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted);
  3024     for (s = 0; s <= maxSymbolValue; ++s) {
  2618     for (s = 0; s <= maxSymbolValue; ++s) {
  3025         if (normalizedCounter[s] == 0) return ERROR(dictionary_corrupted);
  2619         RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted);
  3026     }
  2620     }
  3027     return 0;
  2621     return 0;
  3028 }
  2622 }
  3029 
  2623 
  3030 
  2624 
  3058     dictID = params->fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
  2652     dictID = params->fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
  3059     dictPtr += 4;
  2653     dictPtr += 4;
  3060 
  2654 
  3061     {   unsigned maxSymbolValue = 255;
  2655     {   unsigned maxSymbolValue = 255;
  3062         size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
  2656         size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
  3063         if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
  2657         RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted);
  3064         if (maxSymbolValue < 255) return ERROR(dictionary_corrupted);
  2658         RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted);
  3065         dictPtr += hufHeaderSize;
  2659         dictPtr += hufHeaderSize;
  3066     }
  2660     }
  3067 
  2661 
  3068     {   unsigned offcodeLog;
  2662     {   unsigned offcodeLog;
  3069         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
  2663         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
  3070         if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
  2664         RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);
  3071         if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
  2665         RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);
  3072         /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
  2666         /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
  3073         /* fill all offset symbols to avoid garbage at end of table */
  2667         /* fill all offset symbols to avoid garbage at end of table */
  3074         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.offcodeCTable,
  2668         RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
  3075                                     offcodeNCount, MaxOff, offcodeLog,
  2669                 bs->entropy.fse.offcodeCTable,
  3076                                     workspace, HUF_WORKSPACE_SIZE),
  2670                 offcodeNCount, MaxOff, offcodeLog,
  3077                  dictionary_corrupted);
  2671                 workspace, HUF_WORKSPACE_SIZE)),
       
  2672             dictionary_corrupted);
  3078         dictPtr += offcodeHeaderSize;
  2673         dictPtr += offcodeHeaderSize;
  3079     }
  2674     }
  3080 
  2675 
  3081     {   short matchlengthNCount[MaxML+1];
  2676     {   short matchlengthNCount[MaxML+1];
  3082         unsigned matchlengthMaxValue = MaxML, matchlengthLog;
  2677         unsigned matchlengthMaxValue = MaxML, matchlengthLog;
  3083         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
  2678         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
  3084         if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2679         RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);
  3085         if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
  2680         RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);
  3086         /* Every match length code must have non-zero probability */
  2681         /* Every match length code must have non-zero probability */
  3087         CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
  2682         FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
  3088         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.matchlengthCTable,
  2683         RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
  3089                                     matchlengthNCount, matchlengthMaxValue, matchlengthLog,
  2684                 bs->entropy.fse.matchlengthCTable,
  3090                                     workspace, HUF_WORKSPACE_SIZE),
  2685                 matchlengthNCount, matchlengthMaxValue, matchlengthLog,
  3091                  dictionary_corrupted);
  2686                 workspace, HUF_WORKSPACE_SIZE)),
       
  2687             dictionary_corrupted);
  3092         dictPtr += matchlengthHeaderSize;
  2688         dictPtr += matchlengthHeaderSize;
  3093     }
  2689     }
  3094 
  2690 
  3095     {   short litlengthNCount[MaxLL+1];
  2691     {   short litlengthNCount[MaxLL+1];
  3096         unsigned litlengthMaxValue = MaxLL, litlengthLog;
  2692         unsigned litlengthMaxValue = MaxLL, litlengthLog;
  3097         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
  2693         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
  3098         if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2694         RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);
  3099         if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
  2695         RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);
  3100         /* Every literal length code must have non-zero probability */
  2696         /* Every literal length code must have non-zero probability */
  3101         CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
  2697         FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
  3102         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.litlengthCTable,
  2698         RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
  3103                                     litlengthNCount, litlengthMaxValue, litlengthLog,
  2699                 bs->entropy.fse.litlengthCTable,
  3104                                     workspace, HUF_WORKSPACE_SIZE),
  2700                 litlengthNCount, litlengthMaxValue, litlengthLog,
  3105                  dictionary_corrupted);
  2701                 workspace, HUF_WORKSPACE_SIZE)),
       
  2702             dictionary_corrupted);
  3106         dictPtr += litlengthHeaderSize;
  2703         dictPtr += litlengthHeaderSize;
  3107     }
  2704     }
  3108 
  2705 
  3109     if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
  2706     RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);
  3110     bs->rep[0] = MEM_readLE32(dictPtr+0);
  2707     bs->rep[0] = MEM_readLE32(dictPtr+0);
  3111     bs->rep[1] = MEM_readLE32(dictPtr+4);
  2708     bs->rep[1] = MEM_readLE32(dictPtr+4);
  3112     bs->rep[2] = MEM_readLE32(dictPtr+8);
  2709     bs->rep[2] = MEM_readLE32(dictPtr+8);
  3113     dictPtr += 12;
  2710     dictPtr += 12;
  3114 
  2711 
  3117         if (dictContentSize <= ((U32)-1) - 128 KB) {
  2714         if (dictContentSize <= ((U32)-1) - 128 KB) {
  3118             U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
  2715             U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
  3119             offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
  2716             offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
  3120         }
  2717         }
  3121         /* All offset values <= dictContentSize + 128 KB must be representable */
  2718         /* All offset values <= dictContentSize + 128 KB must be representable */
  3122         CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
  2719         FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
  3123         /* All repCodes must be <= dictContentSize and != 0*/
  2720         /* All repCodes must be <= dictContentSize and != 0*/
  3124         {   U32 u;
  2721         {   U32 u;
  3125             for (u=0; u<3; u++) {
  2722             for (u=0; u<3; u++) {
  3126                 if (bs->rep[u] == 0) return ERROR(dictionary_corrupted);
  2723                 RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted);
  3127                 if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
  2724                 RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted);
  3128         }   }
  2725         }   }
  3129 
  2726 
  3130         bs->entropy.huf.repeatMode = HUF_repeat_valid;
  2727         bs->entropy.huf.repeatMode = HUF_repeat_valid;
  3131         bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
  2728         bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
  3132         bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
  2729         bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
  3133         bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
  2730         bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
  3134         CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize, dtlm));
  2731         FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize, dtlm));
  3135         return dictID;
  2732         return dictID;
  3136     }
  2733     }
  3137 }
  2734 }
  3138 
  2735 
  3139 /** ZSTD_compress_insertDictionary() :
  2736 /** ZSTD_compress_insertDictionary() :
  3159     if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
  2756     if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
  3160         if (dictContentType == ZSTD_dct_auto) {
  2757         if (dictContentType == ZSTD_dct_auto) {
  3161             DEBUGLOG(4, "raw content dictionary detected");
  2758             DEBUGLOG(4, "raw content dictionary detected");
  3162             return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
  2759             return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
  3163         }
  2760         }
  3164         if (dictContentType == ZSTD_dct_fullDict)
  2761         RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
  3165             return ERROR(dictionary_wrong);
       
  3166         assert(0);   /* impossible */
  2762         assert(0);   /* impossible */
  3167     }
  2763     }
  3168 
  2764 
  3169     /* dict as full zstd dictionary */
  2765     /* dict as full zstd dictionary */
  3170     return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, dtlm, workspace);
  2766     return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, dtlm, workspace);
  3187 
  2783 
  3188     if (cdict && cdict->dictContentSize>0) {
  2784     if (cdict && cdict->dictContentSize>0) {
  3189         return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
  2785         return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
  3190     }
  2786     }
  3191 
  2787 
  3192     CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  2788     FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  3193                                      ZSTDcrp_continue, zbuff) );
  2789                                      ZSTDcrp_continue, zbuff) );
  3194     {
  2790     {   size_t const dictID = ZSTD_compress_insertDictionary(
  3195         size_t const dictID = ZSTD_compress_insertDictionary(
       
  3196                 cctx->blockState.prevCBlock, &cctx->blockState.matchState,
  2791                 cctx->blockState.prevCBlock, &cctx->blockState.matchState,
  3197                 &params, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace);
  2792                 &params, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace);
  3198         if (ZSTD_isError(dictID)) return dictID;
  2793         FORWARD_IF_ERROR(dictID);
  3199         assert(dictID <= (size_t)(U32)-1);
  2794         assert(dictID <= UINT_MAX);
  3200         cctx->dictID = (U32)dictID;
  2795         cctx->dictID = (U32)dictID;
  3201     }
  2796     }
  3202     return 0;
  2797     return 0;
  3203 }
  2798 }
  3204 
  2799 
  3210                                     ZSTD_CCtx_params params,
  2805                                     ZSTD_CCtx_params params,
  3211                                     unsigned long long pledgedSrcSize)
  2806                                     unsigned long long pledgedSrcSize)
  3212 {
  2807 {
  3213     DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog);
  2808     DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog);
  3214     /* compression parameters verification and optimization */
  2809     /* compression parameters verification and optimization */
  3215     CHECK_F( ZSTD_checkCParams(params.cParams) );
  2810     FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
  3216     return ZSTD_compressBegin_internal(cctx,
  2811     return ZSTD_compressBegin_internal(cctx,
  3217                                        dict, dictSize, dictContentType, dtlm,
  2812                                        dict, dictSize, dictContentType, dtlm,
  3218                                        cdict,
  2813                                        cdict,
  3219                                        params, pledgedSrcSize,
  2814                                        params, pledgedSrcSize,
  3220                                        ZSTDb_not_buffered);
  2815                                        ZSTDb_not_buffered);
  3258     BYTE* const ostart = (BYTE*)dst;
  2853     BYTE* const ostart = (BYTE*)dst;
  3259     BYTE* op = ostart;
  2854     BYTE* op = ostart;
  3260     size_t fhSize = 0;
  2855     size_t fhSize = 0;
  3261 
  2856 
  3262     DEBUGLOG(4, "ZSTD_writeEpilogue");
  2857     DEBUGLOG(4, "ZSTD_writeEpilogue");
  3263     if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong);  /* init missing */
  2858     RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, "init missing");
  3264 
  2859 
  3265     /* special case : empty frame */
  2860     /* special case : empty frame */
  3266     if (cctx->stage == ZSTDcs_init) {
  2861     if (cctx->stage == ZSTDcs_init) {
  3267         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, 0, 0);
  2862         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, 0, 0);
  3268         if (ZSTD_isError(fhSize)) return fhSize;
  2863         FORWARD_IF_ERROR(fhSize);
  3269         dstCapacity -= fhSize;
  2864         dstCapacity -= fhSize;
  3270         op += fhSize;
  2865         op += fhSize;
  3271         cctx->stage = ZSTDcs_ongoing;
  2866         cctx->stage = ZSTDcs_ongoing;
  3272     }
  2867     }
  3273 
  2868 
  3274     if (cctx->stage != ZSTDcs_ending) {
  2869     if (cctx->stage != ZSTDcs_ending) {
  3275         /* write one last empty block, make it the "last" block */
  2870         /* write one last empty block, make it the "last" block */
  3276         U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
  2871         U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
  3277         if (dstCapacity<4) return ERROR(dstSize_tooSmall);
  2872         RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);
  3278         MEM_writeLE32(op, cBlockHeader24);
  2873         MEM_writeLE32(op, cBlockHeader24);
  3279         op += ZSTD_blockHeaderSize;
  2874         op += ZSTD_blockHeaderSize;
  3280         dstCapacity -= ZSTD_blockHeaderSize;
  2875         dstCapacity -= ZSTD_blockHeaderSize;
  3281     }
  2876     }
  3282 
  2877 
  3283     if (cctx->appliedParams.fParams.checksumFlag) {
  2878     if (cctx->appliedParams.fParams.checksumFlag) {
  3284         U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
  2879         U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
  3285         if (dstCapacity<4) return ERROR(dstSize_tooSmall);
  2880         RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);
  3286         DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum);
  2881         DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum);
  3287         MEM_writeLE32(op, checksum);
  2882         MEM_writeLE32(op, checksum);
  3288         op += 4;
  2883         op += 4;
  3289     }
  2884     }
  3290 
  2885 
  3298 {
  2893 {
  3299     size_t endResult;
  2894     size_t endResult;
  3300     size_t const cSize = ZSTD_compressContinue_internal(cctx,
  2895     size_t const cSize = ZSTD_compressContinue_internal(cctx,
  3301                                 dst, dstCapacity, src, srcSize,
  2896                                 dst, dstCapacity, src, srcSize,
  3302                                 1 /* frame mode */, 1 /* last chunk */);
  2897                                 1 /* frame mode */, 1 /* last chunk */);
  3303     if (ZSTD_isError(cSize)) return cSize;
  2898     FORWARD_IF_ERROR(cSize);
  3304     endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
  2899     endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
  3305     if (ZSTD_isError(endResult)) return endResult;
  2900     FORWARD_IF_ERROR(endResult);
  3306     assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
  2901     assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
  3307     if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  2902     if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
  3308         ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  2903         ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  3309         DEBUGLOG(4, "end of frame : controlling src size");
  2904         DEBUGLOG(4, "end of frame : controlling src size");
  3310         if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) {
  2905         RETURN_ERROR_IF(
  3311             DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u",
  2906             cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1,
  3312                 (unsigned)cctx->pledgedSrcSizePlusOne-1, (unsigned)cctx->consumedSrcSize);
  2907             srcSize_wrong,
  3313             return ERROR(srcSize_wrong);
  2908              "error : pledgedSrcSize = %u, while realSrcSize = %u",
  3314     }   }
  2909             (unsigned)cctx->pledgedSrcSizePlusOne-1,
       
  2910             (unsigned)cctx->consumedSrcSize);
       
  2911     }
  3315     return cSize + endResult;
  2912     return cSize + endResult;
  3316 }
  2913 }
  3317 
  2914 
  3318 
  2915 
  3319 static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
  2916 static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
  3337                          const void* src, size_t srcSize,
  2934                          const void* src, size_t srcSize,
  3338                          const void* dict,size_t dictSize,
  2935                          const void* dict,size_t dictSize,
  3339                                ZSTD_parameters params)
  2936                                ZSTD_parameters params)
  3340 {
  2937 {
  3341     DEBUGLOG(4, "ZSTD_compress_advanced");
  2938     DEBUGLOG(4, "ZSTD_compress_advanced");
  3342     CHECK_F(ZSTD_checkCParams(params.cParams));
  2939     FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams));
  3343     return ZSTD_compress_internal(cctx,
  2940     return ZSTD_compress_internal(cctx,
  3344                                   dst, dstCapacity,
  2941                                   dst, dstCapacity,
  3345                                   src, srcSize,
  2942                                   src, srcSize,
  3346                                   dict, dictSize,
  2943                                   dict, dictSize,
  3347                                   params);
  2944                                   params);
  3354         const void* src, size_t srcSize,
  2951         const void* src, size_t srcSize,
  3355         const void* dict,size_t dictSize,
  2952         const void* dict,size_t dictSize,
  3356         ZSTD_CCtx_params params)
  2953         ZSTD_CCtx_params params)
  3357 {
  2954 {
  3358     DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
  2955     DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
  3359     CHECK_F( ZSTD_compressBegin_internal(cctx,
  2956     FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
  3360                          dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  2957                          dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  3361                          params, srcSize, ZSTDb_not_buffered) );
  2958                          params, srcSize, ZSTDb_not_buffered) );
  3362     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  2959     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  3363 }
  2960 }
  3364 
  2961 
  3438         cdict->dictContent = dictBuffer;
  3035         cdict->dictContent = dictBuffer;
  3439     } else {
  3036     } else {
  3440         void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem);
  3037         void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem);
  3441         cdict->dictBuffer = internalBuffer;
  3038         cdict->dictBuffer = internalBuffer;
  3442         cdict->dictContent = internalBuffer;
  3039         cdict->dictContent = internalBuffer;
  3443         if (!internalBuffer) return ERROR(memory_allocation);
  3040         RETURN_ERROR_IF(!internalBuffer, memory_allocation);
  3444         memcpy(internalBuffer, dictBuffer, dictSize);
  3041         memcpy(internalBuffer, dictBuffer, dictSize);
  3445     }
  3042     }
  3446     cdict->dictContentSize = dictSize;
  3043     cdict->dictContentSize = dictSize;
  3447 
  3044 
  3448     /* Reset the state to no dictionary */
  3045     /* Reset the state to no dictionary */
  3449     ZSTD_reset_compressedBlockState(&cdict->cBlockState);
  3046     ZSTD_reset_compressedBlockState(&cdict->cBlockState);
  3450     {   void* const end = ZSTD_reset_matchState(
  3047     {   void* const end = ZSTD_reset_matchState(&cdict->matchState,
  3451                 &cdict->matchState,
  3048                             (U32*)cdict->workspace + HUF_WORKSPACE_SIZE_U32,
  3452                 (U32*)cdict->workspace + HUF_WORKSPACE_SIZE_U32,
  3049                             &cParams,
  3453                 &cParams, ZSTDcrp_continue, /* forCCtx */ 0);
  3050                              ZSTDcrp_continue, ZSTD_resetTarget_CDict);
  3454         assert(end == (char*)cdict->workspace + cdict->workspaceSize);
  3051         assert(end == (char*)cdict->workspace + cdict->workspaceSize);
  3455         (void)end;
  3052         (void)end;
  3456     }
  3053     }
  3457     /* (Maybe) load the dictionary
  3054     /* (Maybe) load the dictionary
  3458      * Skips loading the dictionary if it is <= 8 bytes.
  3055      * Skips loading the dictionary if it is <= 8 bytes.
  3464         params.cParams = cParams;
  3061         params.cParams = cParams;
  3465         {   size_t const dictID = ZSTD_compress_insertDictionary(
  3062         {   size_t const dictID = ZSTD_compress_insertDictionary(
  3466                     &cdict->cBlockState, &cdict->matchState, &params,
  3063                     &cdict->cBlockState, &cdict->matchState, &params,
  3467                     cdict->dictContent, cdict->dictContentSize,
  3064                     cdict->dictContent, cdict->dictContentSize,
  3468                     dictContentType, ZSTD_dtlm_full, cdict->workspace);
  3065                     dictContentType, ZSTD_dtlm_full, cdict->workspace);
  3469             if (ZSTD_isError(dictID)) return dictID;
  3066             FORWARD_IF_ERROR(dictID);
  3470             assert(dictID <= (size_t)(U32)-1);
  3067             assert(dictID <= (size_t)(U32)-1);
  3471             cdict->dictID = (U32)dictID;
  3068             cdict->dictID = (U32)dictID;
  3472         }
  3069         }
  3473     }
  3070     }
  3474 
  3071 
  3594 size_t ZSTD_compressBegin_usingCDict_advanced(
  3191 size_t ZSTD_compressBegin_usingCDict_advanced(
  3595     ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
  3192     ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
  3596     ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
  3193     ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
  3597 {
  3194 {
  3598     DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
  3195     DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
  3599     if (cdict==NULL) return ERROR(dictionary_wrong);
  3196     RETURN_ERROR_IF(cdict==NULL, dictionary_wrong);
  3600     {   ZSTD_CCtx_params params = cctx->requestedParams;
  3197     {   ZSTD_CCtx_params params = cctx->requestedParams;
  3601         params.cParams = ZSTD_getCParamsFromCDict(cdict);
  3198         params.cParams = ZSTD_getCParamsFromCDict(cdict);
  3602         /* Increase window log to fit the entire dictionary and source if the
  3199         /* Increase window log to fit the entire dictionary and source if the
  3603          * source size is known. Limit the increase to 19, which is the
  3200          * source size is known. Limit the increase to 19, which is the
  3604          * window log for compression level 1 with the largest source size.
  3201          * window log for compression level 1 with the largest source size.
  3630 size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
  3227 size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
  3631                                 void* dst, size_t dstCapacity,
  3228                                 void* dst, size_t dstCapacity,
  3632                                 const void* src, size_t srcSize,
  3229                                 const void* src, size_t srcSize,
  3633                                 const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
  3230                                 const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
  3634 {
  3231 {
  3635     CHECK_F (ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize));   /* will check if cdict != NULL */
  3232     FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize));   /* will check if cdict != NULL */
  3636     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  3233     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  3637 }
  3234 }
  3638 
  3235 
  3639 /*! ZSTD_compress_usingCDict() :
  3236 /*! ZSTD_compress_usingCDict() :
  3640  *  Compression using a digested Dictionary.
  3237  *  Compression using a digested Dictionary.
  3698     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
  3295     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
  3699     /* params are supposed to be fully validated at this point */
  3296     /* params are supposed to be fully validated at this point */
  3700     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  3297     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  3701     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3298     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3702 
  3299 
  3703     CHECK_F( ZSTD_compressBegin_internal(cctx,
  3300     FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
  3704                                          dict, dictSize, dictContentType, ZSTD_dtlm_fast,
  3301                                          dict, dictSize, dictContentType, ZSTD_dtlm_fast,
  3705                                          cdict,
  3302                                          cdict,
  3706                                          params, pledgedSrcSize,
  3303                                          params, pledgedSrcSize,
  3707                                          ZSTDb_buffered) );
  3304                                          ZSTDb_buffered) );
  3708 
  3305 
  3716     return 0;   /* ready to go */
  3313     return 0;   /* ready to go */
  3717 }
  3314 }
  3718 
  3315 
  3719 /* ZSTD_resetCStream():
  3316 /* ZSTD_resetCStream():
  3720  * pledgedSrcSize == 0 means "unknown" */
  3317  * pledgedSrcSize == 0 means "unknown" */
  3721 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
  3318 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss)
  3722 {
  3319 {
  3723     ZSTD_CCtx_params params = zcs->requestedParams;
  3320     /* temporary : 0 interpreted as "unknown" during transition period.
       
  3321      * Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN.
       
  3322      * 0 will be interpreted as "empty" in the future.
       
  3323      */
       
  3324     U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
  3724     DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (unsigned)pledgedSrcSize);
  3325     DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (unsigned)pledgedSrcSize);
  3725     if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
  3326     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
  3726     params.fParams.contentSizeFlag = 1;
  3327     FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
  3727     return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
  3328     return 0;
  3728 }
  3329 }
  3729 
  3330 
  3730 /*! ZSTD_initCStream_internal() :
  3331 /*! ZSTD_initCStream_internal() :
  3731  *  Note : for lib/compress only. Used by zstdmt_compress.c.
  3332  *  Note : for lib/compress only. Used by zstdmt_compress.c.
  3732  *  Assumption 1 : params are valid
  3333  *  Assumption 1 : params are valid
  3734 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
  3335 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
  3735                     const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
  3336                     const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
  3736                     ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
  3337                     ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
  3737 {
  3338 {
  3738     DEBUGLOG(4, "ZSTD_initCStream_internal");
  3339     DEBUGLOG(4, "ZSTD_initCStream_internal");
  3739     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
  3340     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
       
  3341     FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
  3740     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  3342     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
       
  3343     zcs->requestedParams = params;
  3741     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3344     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3742 
  3345     if (dict) {
  3743     if (dict && dictSize >= 8) {
  3346         FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
  3744         DEBUGLOG(4, "loading dictionary of size %u", (unsigned)dictSize);
       
  3745         if (zcs->staticSize) {   /* static CCtx : never uses malloc */
       
  3746             /* incompatible with internal cdict creation */
       
  3747             return ERROR(memory_allocation);
       
  3748         }
       
  3749         ZSTD_freeCDict(zcs->cdictLocal);
       
  3750         zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
       
  3751                                             ZSTD_dlm_byCopy, ZSTD_dct_auto,
       
  3752                                             params.cParams, zcs->customMem);
       
  3753         zcs->cdict = zcs->cdictLocal;
       
  3754         if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
       
  3755     } else {
  3347     } else {
  3756         if (cdict) {
  3348         /* Dictionary is cleared if !cdict */
  3757             params.cParams = ZSTD_getCParamsFromCDict(cdict);  /* cParams are enforced from cdict; it includes windowLog */
  3349         FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
  3758         }
  3350     }
  3759         ZSTD_freeCDict(zcs->cdictLocal);
  3351     return 0;
  3760         zcs->cdictLocal = NULL;
       
  3761         zcs->cdict = cdict;
       
  3762     }
       
  3763 
       
  3764     return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
       
  3765 }
  3352 }
  3766 
  3353 
  3767 /* ZSTD_initCStream_usingCDict_advanced() :
  3354 /* ZSTD_initCStream_usingCDict_advanced() :
  3768  * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
  3355  * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
  3769 size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
  3356 size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
  3770                                             const ZSTD_CDict* cdict,
  3357                                             const ZSTD_CDict* cdict,
  3771                                             ZSTD_frameParameters fParams,
  3358                                             ZSTD_frameParameters fParams,
  3772                                             unsigned long long pledgedSrcSize)
  3359                                             unsigned long long pledgedSrcSize)
  3773 {
  3360 {
  3774     DEBUGLOG(4, "ZSTD_initCStream_usingCDict_advanced");
  3361     DEBUGLOG(4, "ZSTD_initCStream_usingCDict_advanced");
  3775     if (!cdict) return ERROR(dictionary_wrong); /* cannot handle NULL cdict (does not know what to do) */
  3362     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
  3776     {   ZSTD_CCtx_params params = zcs->requestedParams;
  3363     FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
  3777         params.cParams = ZSTD_getCParamsFromCDict(cdict);
  3364     zcs->requestedParams.fParams = fParams;
  3778         params.fParams = fParams;
  3365     FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
  3779         return ZSTD_initCStream_internal(zcs,
  3366     return 0;
  3780                                 NULL, 0, cdict,
       
  3781                                 params, pledgedSrcSize);
       
  3782     }
       
  3783 }
  3367 }
  3784 
  3368 
  3785 /* note : cdict must outlive compression session */
  3369 /* note : cdict must outlive compression session */
  3786 size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
  3370 size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
  3787 {
  3371 {
  3788     ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */, 0 /* checksum */, 0 /* hideDictID */ };
       
  3789     DEBUGLOG(4, "ZSTD_initCStream_usingCDict");
  3372     DEBUGLOG(4, "ZSTD_initCStream_usingCDict");
  3790     return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN);  /* note : will check that cdict != NULL */
  3373     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
       
  3374     FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
       
  3375     return 0;
  3791 }
  3376 }
  3792 
  3377 
  3793 
  3378 
  3794 /* ZSTD_initCStream_advanced() :
  3379 /* ZSTD_initCStream_advanced() :
  3795  * pledgedSrcSize must be exact.
  3380  * pledgedSrcSize must be exact.
  3796  * if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
  3381  * if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
  3797  * dict is loaded with default parameters ZSTD_dm_auto and ZSTD_dlm_byCopy. */
  3382  * dict is loaded with default parameters ZSTD_dm_auto and ZSTD_dlm_byCopy. */
  3798 size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
  3383 size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
  3799                                  const void* dict, size_t dictSize,
  3384                                  const void* dict, size_t dictSize,
  3800                                  ZSTD_parameters params, unsigned long long pledgedSrcSize)
  3385                                  ZSTD_parameters params, unsigned long long pss)
  3801 {
  3386 {
  3802     DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u",
  3387     /* for compatibility with older programs relying on this behavior.
  3803                 (unsigned)pledgedSrcSize, params.fParams.contentSizeFlag);
  3388      * Users should now specify ZSTD_CONTENTSIZE_UNKNOWN.
  3804     CHECK_F( ZSTD_checkCParams(params.cParams) );
  3389      * 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. */
  3390      */
       
  3391     U64 const pledgedSrcSize = (pss==0 && params.fParams.contentSizeFlag==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
       
  3392     DEBUGLOG(4, "ZSTD_initCStream_advanced");
       
  3393     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
       
  3394     FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
       
  3395     FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
  3806     zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
  3396     zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
  3807     return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, zcs->requestedParams, pledgedSrcSize);
  3397     FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
       
  3398     return 0;
  3808 }
  3399 }
  3809 
  3400 
  3810 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
  3401 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
  3811 {
  3402 {
  3812     ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel);
  3403     DEBUGLOG(4, "ZSTD_initCStream_usingDict");
  3813     return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, zcs->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN);
  3404     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
       
  3405     FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
       
  3406     FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
       
  3407     return 0;
  3814 }
  3408 }
  3815 
  3409 
  3816 size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)
  3410 size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)
  3817 {
  3411 {
  3818     U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;  /* temporary : 0 interpreted as "unknown" during transition period. Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN. `0` will be interpreted as "empty" in the future */
  3412     /* temporary : 0 interpreted as "unknown" during transition period.
  3819     ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel);
  3413      * Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN.
  3820     return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, zcs->requestedParams, pledgedSrcSize);
  3414      * 0 will be interpreted as "empty" in the future.
       
  3415      */
       
  3416     U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
       
  3417     DEBUGLOG(4, "ZSTD_initCStream_srcSize");
       
  3418     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
       
  3419     FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );
       
  3420     FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
       
  3421     FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
       
  3422     return 0;
  3821 }
  3423 }
  3822 
  3424 
  3823 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
  3425 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
  3824 {
  3426 {
  3825     DEBUGLOG(4, "ZSTD_initCStream");
  3427     DEBUGLOG(4, "ZSTD_initCStream");
  3826     return ZSTD_initCStream_srcSize(zcs, compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN);
  3428     FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
       
  3429     FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );
       
  3430     FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
       
  3431     return 0;
  3827 }
  3432 }
  3828 
  3433 
  3829 /*======   Compression   ======*/
  3434 /*======   Compression   ======*/
  3830 
  3435 
  3831 static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
  3436 static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
  3845 
  3450 
  3846 /** ZSTD_compressStream_generic():
  3451 /** ZSTD_compressStream_generic():
  3847  *  internal function for all *compressStream*() variants
  3452  *  internal function for all *compressStream*() variants
  3848  *  non-static, because can be called from zstdmt_compress.c
  3453  *  non-static, because can be called from zstdmt_compress.c
  3849  * @return : hint size for next input */
  3454  * @return : hint size for next input */
  3850 size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
  3455 static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
  3851                                    ZSTD_outBuffer* output,
  3456                                           ZSTD_outBuffer* output,
  3852                                    ZSTD_inBuffer* input,
  3457                                           ZSTD_inBuffer* input,
  3853                                    ZSTD_EndDirective const flushMode)
  3458                                           ZSTD_EndDirective const flushMode)
  3854 {
  3459 {
  3855     const char* const istart = (const char*)input->src;
  3460     const char* const istart = (const char*)input->src;
  3856     const char* const iend = istart + input->size;
  3461     const char* const iend = istart + input->size;
  3857     const char* ip = istart + input->pos;
  3462     const char* ip = istart + input->pos;
  3858     char* const ostart = (char*)output->dst;
  3463     char* const ostart = (char*)output->dst;
  3871 
  3476 
  3872     while (someMoreWork) {
  3477     while (someMoreWork) {
  3873         switch(zcs->streamStage)
  3478         switch(zcs->streamStage)
  3874         {
  3479         {
  3875         case zcss_init:
  3480         case zcss_init:
  3876             /* call ZSTD_initCStream() first ! */
  3481             RETURN_ERROR(init_missing, "call ZSTD_initCStream() first!");
  3877             return ERROR(init_missing);
       
  3878 
  3482 
  3879         case zcss_load:
  3483         case zcss_load:
  3880             if ( (flushMode == ZSTD_e_end)
  3484             if ( (flushMode == ZSTD_e_end)
  3881               && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip))  /* enough dstCapacity */
  3485               && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip))  /* enough dstCapacity */
  3882               && (zcs->inBuffPos == 0) ) {
  3486               && (zcs->inBuffPos == 0) ) {
  3883                 /* shortcut to compression pass directly into output buffer */
  3487                 /* shortcut to compression pass directly into output buffer */
  3884                 size_t const cSize = ZSTD_compressEnd(zcs,
  3488                 size_t const cSize = ZSTD_compressEnd(zcs,
  3885                                                 op, oend-op, ip, iend-ip);
  3489                                                 op, oend-op, ip, iend-ip);
  3886                 DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
  3490                 DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
  3887                 if (ZSTD_isError(cSize)) return cSize;
  3491                 FORWARD_IF_ERROR(cSize);
  3888                 ip = iend;
  3492                 ip = iend;
  3889                 op += cSize;
  3493                 op += cSize;
  3890                 zcs->frameEnded = 1;
  3494                 zcs->frameEnded = 1;
  3891                 ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
  3495                 ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
  3892                 someMoreWork = 0; break;
  3496                 someMoreWork = 0; break;
  3923                 cSize = lastBlock ?
  3527                 cSize = lastBlock ?
  3924                         ZSTD_compressEnd(zcs, cDst, oSize,
  3528                         ZSTD_compressEnd(zcs, cDst, oSize,
  3925                                     zcs->inBuff + zcs->inToCompress, iSize) :
  3529                                     zcs->inBuff + zcs->inToCompress, iSize) :
  3926                         ZSTD_compressContinue(zcs, cDst, oSize,
  3530                         ZSTD_compressContinue(zcs, cDst, oSize,
  3927                                     zcs->inBuff + zcs->inToCompress, iSize);
  3531                                     zcs->inBuff + zcs->inToCompress, iSize);
  3928                 if (ZSTD_isError(cSize)) return cSize;
  3532                 FORWARD_IF_ERROR(cSize);
  3929                 zcs->frameEnded = lastBlock;
  3533                 zcs->frameEnded = lastBlock;
  3930                 /* prepare next block */
  3534                 /* prepare next block */
  3931                 zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
  3535                 zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
  3932                 if (zcs->inBuffTarget > zcs->inBuffSize)
  3536                 if (zcs->inBuffTarget > zcs->inBuffSize)
  3933                     zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
  3537                     zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
  3951             }
  3555             }
  3952 	    /* fall-through */
  3556 	    /* fall-through */
  3953         case zcss_flush:
  3557         case zcss_flush:
  3954             DEBUGLOG(5, "flush stage");
  3558             DEBUGLOG(5, "flush stage");
  3955             {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
  3559             {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
  3956                 size_t const flushed = ZSTD_limitCopy(op, oend-op,
  3560                 size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op),
  3957                             zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
  3561                             zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
  3958                 DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
  3562                 DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
  3959                             (unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);
  3563                             (unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);
  3960                 op += flushed;
  3564                 op += flushed;
  3961                 zcs->outBuffFlushedSize += flushed;
  3565                 zcs->outBuffFlushedSize += flushed;
  3999 
  3603 
  4000 }
  3604 }
  4001 
  3605 
  4002 size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
  3606 size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
  4003 {
  3607 {
  4004     CHECK_F( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) );
  3608     FORWARD_IF_ERROR( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) );
  4005     return ZSTD_nextInputSizeHint_MTorST(zcs);
  3609     return ZSTD_nextInputSizeHint_MTorST(zcs);
  4006 }
  3610 }
  4007 
  3611 
  4008 
  3612 
  4009 size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
  3613 size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
  4011                              ZSTD_inBuffer* input,
  3615                              ZSTD_inBuffer* input,
  4012                              ZSTD_EndDirective endOp)
  3616                              ZSTD_EndDirective endOp)
  4013 {
  3617 {
  4014     DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
  3618     DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
  4015     /* check conditions */
  3619     /* check conditions */
  4016     if (output->pos > output->size) return ERROR(GENERIC);
  3620     RETURN_ERROR_IF(output->pos > output->size, GENERIC);
  4017     if (input->pos  > input->size)  return ERROR(GENERIC);
  3621     RETURN_ERROR_IF(input->pos  > input->size, GENERIC);
  4018     assert(cctx!=NULL);
  3622     assert(cctx!=NULL);
  4019 
  3623 
  4020     /* transparent initialization stage */
  3624     /* transparent initialization stage */
  4021     if (cctx->streamStage == zcss_init) {
  3625     if (cctx->streamStage == zcss_init) {
  4022         ZSTD_CCtx_params params = cctx->requestedParams;
  3626         ZSTD_CCtx_params params = cctx->requestedParams;
  4023         ZSTD_prefixDict const prefixDict = cctx->prefixDict;
  3627         ZSTD_prefixDict const prefixDict = cctx->prefixDict;
       
  3628         FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) ); /* Init the local dict if present. */
  4024         memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));   /* single usage */
  3629         memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));   /* single usage */
  4025         assert(prefixDict.dict==NULL || cctx->cdict==NULL);    /* only one can be set */
  3630         assert(prefixDict.dict==NULL || cctx->cdict==NULL);    /* only one can be set */
  4026         DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
  3631         DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
  4027         if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */
  3632         if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */
  4028         params.cParams = ZSTD_getCParamsFromCCtxParams(
  3633         params.cParams = ZSTD_getCParamsFromCCtxParams(
  4037             /* mt context creation */
  3642             /* mt context creation */
  4038             if (cctx->mtctx == NULL) {
  3643             if (cctx->mtctx == NULL) {
  4039                 DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
  3644                 DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
  4040                             params.nbWorkers);
  3645                             params.nbWorkers);
  4041                 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
  3646                 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
  4042                 if (cctx->mtctx == NULL) return ERROR(memory_allocation);
  3647                 RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation);
  4043             }
  3648             }
  4044             /* mt compression */
  3649             /* mt compression */
  4045             DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
  3650             DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
  4046             CHECK_F( ZSTDMT_initCStream_internal(
  3651             FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(
  4047                         cctx->mtctx,
  3652                         cctx->mtctx,
  4048                         prefixDict.dict, prefixDict.dictSize, ZSTD_dct_rawContent,
  3653                         prefixDict.dict, prefixDict.dictSize, ZSTD_dct_rawContent,
  4049                         cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
  3654                         cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
  4050             cctx->streamStage = zcss_load;
  3655             cctx->streamStage = zcss_load;
  4051             cctx->appliedParams.nbWorkers = params.nbWorkers;
  3656             cctx->appliedParams.nbWorkers = params.nbWorkers;
  4052         } else
  3657         } else
  4053 #endif
  3658 #endif
  4054         {   CHECK_F( ZSTD_resetCStream_internal(cctx,
  3659         {   FORWARD_IF_ERROR( ZSTD_resetCStream_internal(cctx,
  4055                             prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
  3660                             prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
  4056                             cctx->cdict,
  3661                             cctx->cdict,
  4057                             params, cctx->pledgedSrcSizePlusOne-1) );
  3662                             params, cctx->pledgedSrcSizePlusOne-1) );
  4058             assert(cctx->streamStage == zcss_load);
  3663             assert(cctx->streamStage == zcss_load);
  4059             assert(cctx->appliedParams.nbWorkers == 0);
  3664             assert(cctx->appliedParams.nbWorkers == 0);
  4061     /* end of transparent initialization stage */
  3666     /* end of transparent initialization stage */
  4062 
  3667 
  4063     /* compression stage */
  3668     /* compression stage */
  4064 #ifdef ZSTD_MULTITHREAD
  3669 #ifdef ZSTD_MULTITHREAD
  4065     if (cctx->appliedParams.nbWorkers > 0) {
  3670     if (cctx->appliedParams.nbWorkers > 0) {
       
  3671         int const forceMaxProgress = (endOp == ZSTD_e_flush || endOp == ZSTD_e_end);
       
  3672         size_t flushMin;
       
  3673         assert(forceMaxProgress || endOp == ZSTD_e_continue /* Protection for a new flush type */);
  4066         if (cctx->cParamsChanged) {
  3674         if (cctx->cParamsChanged) {
  4067             ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams);
  3675             ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams);
  4068             cctx->cParamsChanged = 0;
  3676             cctx->cParamsChanged = 0;
  4069         }
  3677         }
  4070         {   size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
  3678         do {
       
  3679             flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
  4071             if ( ZSTD_isError(flushMin)
  3680             if ( ZSTD_isError(flushMin)
  4072               || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
  3681               || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
  4073                 ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
  3682                 ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
  4074             }
  3683             }
  4075             DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
  3684             FORWARD_IF_ERROR(flushMin);
  4076             return flushMin;
  3685         } while (forceMaxProgress && flushMin != 0 && output->pos < output->size);
  4077     }   }
  3686         DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
       
  3687         /* Either we don't require maximum forward progress, we've finished the
       
  3688          * flush, or we are out of output space.
       
  3689          */
       
  3690         assert(!forceMaxProgress || flushMin == 0 || output->pos == output->size);
       
  3691         return flushMin;
       
  3692     }
  4078 #endif
  3693 #endif
  4079     CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
  3694     FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) );
  4080     DEBUGLOG(5, "completed ZSTD_compressStream2");
  3695     DEBUGLOG(5, "completed ZSTD_compressStream2");
  4081     return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
  3696     return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
  4082 }
  3697 }
  4083 
  3698 
  4084 size_t ZSTD_compressStream2_simpleArgs (
  3699 size_t ZSTD_compressStream2_simpleArgs (
  4105         size_t iPos = 0;
  3720         size_t iPos = 0;
  4106         size_t const result = ZSTD_compressStream2_simpleArgs(cctx,
  3721         size_t const result = ZSTD_compressStream2_simpleArgs(cctx,
  4107                                         dst, dstCapacity, &oPos,
  3722                                         dst, dstCapacity, &oPos,
  4108                                         src, srcSize, &iPos,
  3723                                         src, srcSize, &iPos,
  4109                                         ZSTD_e_end);
  3724                                         ZSTD_e_end);
  4110         if (ZSTD_isError(result)) return result;
  3725         FORWARD_IF_ERROR(result);
  4111         if (result != 0) {  /* compression not completed, due to lack of output space */
  3726         if (result != 0) {  /* compression not completed, due to lack of output space */
  4112             assert(oPos == dstCapacity);
  3727             assert(oPos == dstCapacity);
  4113             return ERROR(dstSize_tooSmall);
  3728             RETURN_ERROR(dstSize_tooSmall);
  4114         }
  3729         }
  4115         assert(iPos == srcSize);   /* all input is expected consumed */
  3730         assert(iPos == srcSize);   /* all input is expected consumed */
  4116         return oPos;
  3731         return oPos;
  4117     }
  3732     }
  4118 }
  3733 }
  4130 
  3745 
  4131 size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
  3746 size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
  4132 {
  3747 {
  4133     ZSTD_inBuffer input = { NULL, 0, 0 };
  3748     ZSTD_inBuffer input = { NULL, 0, 0 };
  4134     size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
  3749     size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
  4135     CHECK_F( remainingToFlush );
  3750     FORWARD_IF_ERROR( remainingToFlush );
  4136     if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush;   /* minimal estimation */
  3751     if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush;   /* minimal estimation */
  4137     /* single thread mode : attempt to calculate remaining to flush more precisely */
  3752     /* single thread mode : attempt to calculate remaining to flush more precisely */
  4138     {   size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
  3753     {   size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
  4139         size_t const checksumSize = zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4;
  3754         size_t const checksumSize = (size_t)(zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4);
  4140         size_t const toFlush = remainingToFlush + lastBlockSize + checksumSize;
  3755         size_t const toFlush = remainingToFlush + lastBlockSize + checksumSize;
  4141         DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (unsigned)toFlush);
  3756         DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (unsigned)toFlush);
  4142         return toFlush;
  3757         return toFlush;
  4143     }
  3758     }
  4144 }
  3759 }
  4149 #define ZSTD_MAX_CLEVEL     22
  3764 #define ZSTD_MAX_CLEVEL     22
  4150 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
  3765 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
  4151 int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }
  3766 int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }
  4152 
  3767 
  4153 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
  3768 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
  4154 {   /* "default" - guarantees a monotonically increasing memory budget */
  3769 {   /* "default" - for any srcSize > 256 KB */
  4155     /* W,  C,  H,  S,  L, TL, strat */
  3770     /* W,  C,  H,  S,  L, TL, strat */
  4156     { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */
  3771     { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */
  4157     { 19, 13, 14,  1,  7,  0, ZSTD_fast    },  /* level  1 */
  3772     { 19, 13, 14,  1,  7,  0, ZSTD_fast    },  /* level  1 */
  4158     { 20, 15, 16,  1,  6,  0, ZSTD_fast    },  /* level  2 */
  3773     { 20, 15, 16,  1,  6,  0, ZSTD_fast    },  /* level  2 */
  4159     { 21, 16, 17,  1,  5,  1, ZSTD_dfast   },  /* level  3 */
  3774     { 21, 16, 17,  1,  5,  1, ZSTD_dfast   },  /* level  3 */
  4256     { 14, 15, 15, 10,  3,999, ZSTD_btultra2},  /* level 22.*/
  3871     { 14, 15, 15, 10,  3,999, ZSTD_btultra2},  /* level 22.*/
  4257 },
  3872 },
  4258 };
  3873 };
  4259 
  3874 
  4260 /*! ZSTD_getCParams() :
  3875 /*! ZSTD_getCParams() :
  4261 *  @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
  3876  * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
  4262 *   Size values are optional, provide 0 if not known or unused */
  3877  *  Size values are optional, provide 0 if not known or unused */
  4263 ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
  3878 ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
  4264 {
  3879 {
  4265     size_t const addedSize = srcSizeHint ? 0 : 500;
  3880     size_t const addedSize = srcSizeHint ? 0 : 500;
  4266     U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : (U64)-1;
  3881     U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : ZSTD_CONTENTSIZE_UNKNOWN;  /* intentional overflow for srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN */
  4267     U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);   /* intentional underflow for srcSizeHint == 0 */
  3882     U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
  4268     int row = compressionLevel;
  3883     int row = compressionLevel;
  4269     DEBUGLOG(5, "ZSTD_getCParams (cLevel=%i)", compressionLevel);
  3884     DEBUGLOG(5, "ZSTD_getCParams (cLevel=%i)", compressionLevel);
  4270     if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT;   /* 0 == default */
  3885     if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT;   /* 0 == default */
  4271     if (compressionLevel < 0) row = 0;   /* entry 0 is baseline for fast mode */
  3886     if (compressionLevel < 0) row = 0;   /* entry 0 is baseline for fast mode */
  4272     if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
  3887     if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
  4273     {   ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
  3888     {   ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
  4274         if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel);   /* acceleration factor */
  3889         if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel);   /* acceleration factor */
  4275         return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);
  3890         return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);               /* refine parameters based on srcSize & dictSize */
  4276     }
  3891     }
  4277 }
  3892 }
  4278 
  3893 
  4279 /*! ZSTD_getParams() :
  3894 /*! ZSTD_getParams() :
  4280 *   same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
  3895  *  same idea as ZSTD_getCParams()
  4281 *   All fields of `ZSTD_frameParameters` are set to default (0) */
  3896  * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
       
  3897  *  Fields of `ZSTD_frameParameters` are set to default values */
  4282 ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
  3898 ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
  4283     ZSTD_parameters params;
  3899     ZSTD_parameters params;
  4284     ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);
  3900     ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);
  4285     DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
  3901     DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
  4286     memset(&params, 0, sizeof(params));
  3902     memset(&params, 0, sizeof(params));