contrib/python-zstandard/zstd/compress/zstd_compress.c
changeset 40121 73fef626dae3
parent 37495 b1fb341d8a61
child 42070 675775c33ab6
equal deleted inserted replaced
40120:89742f1fa6cb 40121:73fef626dae3
     6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
     6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
     7  * in the COPYING file in the root directory of this source tree).
     7  * in the COPYING file in the root directory of this source tree).
     8  * You may select, at your option, one of the above-listed licenses.
     8  * You may select, at your option, one of the above-listed licenses.
     9  */
     9  */
    10 
    10 
    11 
       
    12 /*-*************************************
       
    13 *  Tuning parameters
       
    14 ***************************************/
       
    15 #ifndef ZSTD_CLEVEL_DEFAULT
       
    16 #  define ZSTD_CLEVEL_DEFAULT 3
       
    17 #endif
       
    18 
       
    19 
       
    20 /*-*************************************
    11 /*-*************************************
    21 *  Dependencies
    12 *  Dependencies
    22 ***************************************/
    13 ***************************************/
    23 #include <string.h>         /* memset */
    14 #include <string.h>         /* memset */
    24 #include "cpu.h"
    15 #include "cpu.h"
    25 #include "mem.h"
    16 #include "mem.h"
       
    17 #include "hist.h"           /* HIST_countFast_wksp */
    26 #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
    18 #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
    27 #include "fse.h"
    19 #include "fse.h"
    28 #define HUF_STATIC_LINKING_ONLY
    20 #define HUF_STATIC_LINKING_ONLY
    29 #include "huf.h"
    21 #include "huf.h"
    30 #include "zstd_compress_internal.h"
    22 #include "zstd_compress_internal.h"
    52     size_t dictContentSize;
    44     size_t dictContentSize;
    53     void* workspace;
    45     void* workspace;
    54     size_t workspaceSize;
    46     size_t workspaceSize;
    55     ZSTD_matchState_t matchState;
    47     ZSTD_matchState_t matchState;
    56     ZSTD_compressedBlockState_t cBlockState;
    48     ZSTD_compressedBlockState_t cBlockState;
    57     ZSTD_compressionParameters cParams;
       
    58     ZSTD_customMem customMem;
    49     ZSTD_customMem customMem;
    59     U32 dictID;
    50     U32 dictID;
    60 };  /* typedef'd to ZSTD_CDict within "zstd.h" */
    51 };  /* typedef'd to ZSTD_CDict within "zstd.h" */
    61 
    52 
    62 ZSTD_CCtx* ZSTD_createCCtx(void)
    53 ZSTD_CCtx* ZSTD_createCCtx(void)
    63 {
    54 {
    64     return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);
    55     return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);
    65 }
    56 }
    66 
    57 
       
    58 static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)
       
    59 {
       
    60     assert(cctx != NULL);
       
    61     memset(cctx, 0, sizeof(*cctx));
       
    62     cctx->customMem = memManager;
       
    63     cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
       
    64     {   size_t const err = ZSTD_CCtx_resetParameters(cctx);
       
    65         assert(!ZSTD_isError(err));
       
    66         (void)err;
       
    67     }
       
    68 }
       
    69 
    67 ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
    70 ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
    68 {
    71 {
    69     ZSTD_STATIC_ASSERT(zcss_init==0);
    72     ZSTD_STATIC_ASSERT(zcss_init==0);
    70     ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
    73     ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
    71     if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
    74     if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
    72     {   ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_calloc(sizeof(ZSTD_CCtx), customMem);
    75     {   ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
    73         if (!cctx) return NULL;
    76         if (!cctx) return NULL;
    74         cctx->customMem = customMem;
    77         ZSTD_initCCtx(cctx, customMem);
    75         cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;
       
    76         cctx->requestedParams.fParams.contentSizeFlag = 1;
       
    77         cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
       
    78         return cctx;
    78         return cctx;
    79     }
    79     }
    80 }
    80 }
    81 
    81 
    82 ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
    82 ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
   100     }
   100     }
   101     cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
   101     cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
   102     return cctx;
   102     return cctx;
   103 }
   103 }
   104 
   104 
   105 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
   105 static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
   106 {
   106 {
   107     if (cctx==NULL) return 0;   /* support free on NULL */
   107     assert(cctx != NULL);
   108     if (cctx->staticSize) return ERROR(memory_allocation);   /* not compatible with static CCtx */
   108     assert(cctx->staticSize == 0);
   109     ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
   109     ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
   110     ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL;
   110     ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL;
   111 #ifdef ZSTD_MULTITHREAD
   111 #ifdef ZSTD_MULTITHREAD
   112     ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
   112     ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
   113 #endif
   113 #endif
       
   114 }
       
   115 
       
   116 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
       
   117 {
       
   118     if (cctx==NULL) return 0;   /* support free on NULL */
       
   119     if (cctx->staticSize) return ERROR(memory_allocation);   /* not compatible with static CCtx */
       
   120     ZSTD_freeCCtxContent(cctx);
   114     ZSTD_free(cctx, cctx->customMem);
   121     ZSTD_free(cctx, cctx->customMem);
   115     return 0;   /* reserved as a potential error code in the future */
   122     return 0;
   116 }
   123 }
   117 
   124 
   118 
   125 
   119 static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
   126 static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
   120 {
   127 {
   140     return ZSTD_sizeof_CCtx(zcs);  /* same object */
   147     return ZSTD_sizeof_CCtx(zcs);  /* same object */
   141 }
   148 }
   142 
   149 
   143 /* private API call, for dictBuilder only */
   150 /* private API call, for dictBuilder only */
   144 const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
   151 const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
   145 
       
   146 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
       
   147         const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
       
   148 {
       
   149     ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
       
   150     if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
       
   151     if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
       
   152     if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
       
   153     if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
       
   154     if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
       
   155     if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
       
   156     if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
       
   157     if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
       
   158     return cParams;
       
   159 }
       
   160 
   152 
   161 static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
   153 static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
   162         ZSTD_compressionParameters cParams)
   154         ZSTD_compressionParameters cParams)
   163 {
   155 {
   164     ZSTD_CCtx_params cctxParams;
   156     ZSTD_CCtx_params cctxParams;
   249     case ZSTD_p_chainLog:
   241     case ZSTD_p_chainLog:
   250     case ZSTD_p_searchLog:
   242     case ZSTD_p_searchLog:
   251     case ZSTD_p_minMatch:
   243     case ZSTD_p_minMatch:
   252     case ZSTD_p_targetLength:
   244     case ZSTD_p_targetLength:
   253     case ZSTD_p_compressionStrategy:
   245     case ZSTD_p_compressionStrategy:
   254     case ZSTD_p_compressLiterals:
       
   255         return 1;
   246         return 1;
   256 
   247 
   257     case ZSTD_p_format:
   248     case ZSTD_p_format:
   258     case ZSTD_p_windowLog:
   249     case ZSTD_p_windowLog:
   259     case ZSTD_p_contentSizeFlag:
   250     case ZSTD_p_contentSizeFlag:
   266     case ZSTD_p_enableLongDistanceMatching:
   257     case ZSTD_p_enableLongDistanceMatching:
   267     case ZSTD_p_ldmHashLog:
   258     case ZSTD_p_ldmHashLog:
   268     case ZSTD_p_ldmMinMatch:
   259     case ZSTD_p_ldmMinMatch:
   269     case ZSTD_p_ldmBucketSizeLog:
   260     case ZSTD_p_ldmBucketSizeLog:
   270     case ZSTD_p_ldmHashEveryLog:
   261     case ZSTD_p_ldmHashEveryLog:
       
   262     case ZSTD_p_forceAttachDict:
   271     default:
   263     default:
   272         return 0;
   264         return 0;
   273     }
   265     }
   274 }
   266 }
   275 
   267 
   300     case ZSTD_p_targetLength:
   292     case ZSTD_p_targetLength:
   301     case ZSTD_p_compressionStrategy:
   293     case ZSTD_p_compressionStrategy:
   302         if (cctx->cdict) return ERROR(stage_wrong);
   294         if (cctx->cdict) return ERROR(stage_wrong);
   303         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   295         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   304 
   296 
   305     case ZSTD_p_compressLiterals:
       
   306     case ZSTD_p_contentSizeFlag:
   297     case ZSTD_p_contentSizeFlag:
   307     case ZSTD_p_checksumFlag:
   298     case ZSTD_p_checksumFlag:
   308     case ZSTD_p_dictIDFlag:
   299     case ZSTD_p_dictIDFlag:
   309         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   300         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   310 
   301 
   311     case ZSTD_p_forceMaxWindow :  /* Force back-references to remain < windowSize,
   302     case ZSTD_p_forceMaxWindow :  /* Force back-references to remain < windowSize,
   312                                    * even when referencing into Dictionary content.
   303                                    * even when referencing into Dictionary content.
   313                                    * default : 0 when using a CDict, 1 when using a Prefix */
   304                                    * default : 0 when using a CDict, 1 when using a Prefix */
       
   305         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
       
   306 
       
   307     case ZSTD_p_forceAttachDict:
   314         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   308         return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
   315 
   309 
   316     case ZSTD_p_nbWorkers:
   310     case ZSTD_p_nbWorkers:
   317         if ((value>0) && cctx->staticSize) {
   311         if ((value>0) && cctx->staticSize) {
   318             return ERROR(parameter_unsupported);  /* MT not compatible with static alloc */
   312             return ERROR(parameter_unsupported);  /* MT not compatible with static alloc */
   349 
   343 
   350     case ZSTD_p_compressionLevel : {
   344     case ZSTD_p_compressionLevel : {
   351         int cLevel = (int)value;  /* cast expected to restore negative sign */
   345         int cLevel = (int)value;  /* cast expected to restore negative sign */
   352         if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
   346         if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
   353         if (cLevel) {  /* 0 : does not change current level */
   347         if (cLevel) {  /* 0 : does not change current level */
   354             CCtxParams->disableLiteralCompression = (cLevel<0);  /* negative levels disable huffman */
       
   355             CCtxParams->compressionLevel = cLevel;
   348             CCtxParams->compressionLevel = cLevel;
   356         }
   349         }
   357         if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
   350         if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
   358         return 0;  /* return type (size_t) cannot represent negative values */
   351         return 0;  /* return type (size_t) cannot represent negative values */
   359     }
   352     }
   397         if (value>0)   /* 0 => use default */
   390         if (value>0)   /* 0 => use default */
   398             CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
   391             CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
   399         CCtxParams->cParams.strategy = (ZSTD_strategy)value;
   392         CCtxParams->cParams.strategy = (ZSTD_strategy)value;
   400         return (size_t)CCtxParams->cParams.strategy;
   393         return (size_t)CCtxParams->cParams.strategy;
   401 
   394 
   402     case ZSTD_p_compressLiterals:
       
   403         CCtxParams->disableLiteralCompression = !value;
       
   404         return !CCtxParams->disableLiteralCompression;
       
   405 
       
   406     case ZSTD_p_contentSizeFlag :
   395     case ZSTD_p_contentSizeFlag :
   407         /* Content size written in frame header _when known_ (default:1) */
   396         /* Content size written in frame header _when known_ (default:1) */
   408         DEBUGLOG(4, "set content size flag = %u", (value>0));
   397         DEBUGLOG(4, "set content size flag = %u", (value>0));
   409         CCtxParams->fParams.contentSizeFlag = value > 0;
   398         CCtxParams->fParams.contentSizeFlag = value > 0;
   410         return CCtxParams->fParams.contentSizeFlag;
   399         return CCtxParams->fParams.contentSizeFlag;
   420         return !CCtxParams->fParams.noDictIDFlag;
   409         return !CCtxParams->fParams.noDictIDFlag;
   421 
   410 
   422     case ZSTD_p_forceMaxWindow :
   411     case ZSTD_p_forceMaxWindow :
   423         CCtxParams->forceWindow = (value > 0);
   412         CCtxParams->forceWindow = (value > 0);
   424         return CCtxParams->forceWindow;
   413         return CCtxParams->forceWindow;
       
   414 
       
   415     case ZSTD_p_forceAttachDict :
       
   416         CCtxParams->attachDictPref = value ?
       
   417                                     (value > 0 ? ZSTD_dictForceAttach : ZSTD_dictForceCopy) :
       
   418                                      ZSTD_dictDefaultAttach;
       
   419         return CCtxParams->attachDictPref;
   425 
   420 
   426     case ZSTD_p_nbWorkers :
   421     case ZSTD_p_nbWorkers :
   427 #ifndef ZSTD_MULTITHREAD
   422 #ifndef ZSTD_MULTITHREAD
   428         if (value>0) return ERROR(parameter_unsupported);
   423         if (value>0) return ERROR(parameter_unsupported);
   429         return 0;
   424         return 0;
   473         CCtxParams->ldmParams.hashEveryLog = value;
   468         CCtxParams->ldmParams.hashEveryLog = value;
   474         return CCtxParams->ldmParams.hashEveryLog;
   469         return CCtxParams->ldmParams.hashEveryLog;
   475 
   470 
   476     default: return ERROR(parameter_unsupported);
   471     default: return ERROR(parameter_unsupported);
   477     }
   472     }
       
   473 }
       
   474 
       
   475 size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned* value)
       
   476 {
       
   477     return ZSTD_CCtxParam_getParameter(&cctx->requestedParams, param, value);
       
   478 }
       
   479 
       
   480 size_t ZSTD_CCtxParam_getParameter(
       
   481         ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, unsigned* value)
       
   482 {
       
   483     switch(param)
       
   484     {
       
   485     case ZSTD_p_format :
       
   486         *value = CCtxParams->format;
       
   487         break;
       
   488     case ZSTD_p_compressionLevel :
       
   489         *value = CCtxParams->compressionLevel;
       
   490         break;
       
   491     case ZSTD_p_windowLog :
       
   492         *value = CCtxParams->cParams.windowLog;
       
   493         break;
       
   494     case ZSTD_p_hashLog :
       
   495         *value = CCtxParams->cParams.hashLog;
       
   496         break;
       
   497     case ZSTD_p_chainLog :
       
   498         *value = CCtxParams->cParams.chainLog;
       
   499         break;
       
   500     case ZSTD_p_searchLog :
       
   501         *value = CCtxParams->cParams.searchLog;
       
   502         break;
       
   503     case ZSTD_p_minMatch :
       
   504         *value = CCtxParams->cParams.searchLength;
       
   505         break;
       
   506     case ZSTD_p_targetLength :
       
   507         *value = CCtxParams->cParams.targetLength;
       
   508         break;
       
   509     case ZSTD_p_compressionStrategy :
       
   510         *value = (unsigned)CCtxParams->cParams.strategy;
       
   511         break;
       
   512     case ZSTD_p_contentSizeFlag :
       
   513         *value = CCtxParams->fParams.contentSizeFlag;
       
   514         break;
       
   515     case ZSTD_p_checksumFlag :
       
   516         *value = CCtxParams->fParams.checksumFlag;
       
   517         break;
       
   518     case ZSTD_p_dictIDFlag :
       
   519         *value = !CCtxParams->fParams.noDictIDFlag;
       
   520         break;
       
   521     case ZSTD_p_forceMaxWindow :
       
   522         *value = CCtxParams->forceWindow;
       
   523         break;
       
   524     case ZSTD_p_forceAttachDict :
       
   525         *value = CCtxParams->attachDictPref;
       
   526         break;
       
   527     case ZSTD_p_nbWorkers :
       
   528 #ifndef ZSTD_MULTITHREAD
       
   529         assert(CCtxParams->nbWorkers == 0);
       
   530 #endif
       
   531         *value = CCtxParams->nbWorkers;
       
   532         break;
       
   533     case ZSTD_p_jobSize :
       
   534 #ifndef ZSTD_MULTITHREAD
       
   535         return ERROR(parameter_unsupported);
       
   536 #else
       
   537         *value = CCtxParams->jobSize;
       
   538         break;
       
   539 #endif
       
   540     case ZSTD_p_overlapSizeLog :
       
   541 #ifndef ZSTD_MULTITHREAD
       
   542         return ERROR(parameter_unsupported);
       
   543 #else
       
   544         *value = CCtxParams->overlapSizeLog;
       
   545         break;
       
   546 #endif
       
   547     case ZSTD_p_enableLongDistanceMatching :
       
   548         *value = CCtxParams->ldmParams.enableLdm;
       
   549         break;
       
   550     case ZSTD_p_ldmHashLog :
       
   551         *value = CCtxParams->ldmParams.hashLog;
       
   552         break;
       
   553     case ZSTD_p_ldmMinMatch :
       
   554         *value = CCtxParams->ldmParams.minMatchLength;
       
   555         break;
       
   556     case ZSTD_p_ldmBucketSizeLog :
       
   557         *value = CCtxParams->ldmParams.bucketSizeLog;
       
   558         break;
       
   559     case ZSTD_p_ldmHashEveryLog :
       
   560         *value = CCtxParams->ldmParams.hashEveryLog;
       
   561         break;
       
   562     default: return ERROR(parameter_unsupported);
       
   563     }
       
   564     return 0;
   478 }
   565 }
   479 
   566 
   480 /** ZSTD_CCtx_setParametersUsingCCtxParams() :
   567 /** ZSTD_CCtx_setParametersUsingCCtxParams() :
   481  *  just applies `params` into `cctx`
   568  *  just applies `params` into `cctx`
   482  *  no action is performed, parameters are merely stored.
   569  *  no action is performed, parameters are merely stored.
   485  *    In which case, new parameters will be applied on the fly, starting with next compression job.
   572  *    In which case, new parameters will be applied on the fly, starting with next compression job.
   486  */
   573  */
   487 size_t ZSTD_CCtx_setParametersUsingCCtxParams(
   574 size_t ZSTD_CCtx_setParametersUsingCCtxParams(
   488         ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
   575         ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
   489 {
   576 {
       
   577     DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
   490     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   578     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   491     if (cctx->cdict) return ERROR(stage_wrong);
   579     if (cctx->cdict) return ERROR(stage_wrong);
   492 
   580 
   493     cctx->requestedParams = *params;
   581     cctx->requestedParams = *params;
   494     return 0;
   582     return 0;
   563     cctx->prefixDict.dictSize = prefixSize;
   651     cctx->prefixDict.dictSize = prefixSize;
   564     cctx->prefixDict.dictContentType = dictContentType;
   652     cctx->prefixDict.dictContentType = dictContentType;
   565     return 0;
   653     return 0;
   566 }
   654 }
   567 
   655 
   568 static void ZSTD_startNewCompression(ZSTD_CCtx* cctx)
       
   569 {
       
   570     cctx->streamStage = zcss_init;
       
   571     cctx->pledgedSrcSizePlusOne = 0;
       
   572 }
       
   573 
       
   574 /*! ZSTD_CCtx_reset() :
   656 /*! ZSTD_CCtx_reset() :
   575  *  Also dumps dictionary */
   657  *  Also dumps dictionary */
   576 void ZSTD_CCtx_reset(ZSTD_CCtx* cctx)
   658 void ZSTD_CCtx_reset(ZSTD_CCtx* cctx)
   577 {
   659 {
   578     ZSTD_startNewCompression(cctx);
   660     cctx->streamStage = zcss_init;
       
   661     cctx->pledgedSrcSizePlusOne = 0;
       
   662 }
       
   663 
       
   664 size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx)
       
   665 {
       
   666     if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
   579     cctx->cdict = NULL;
   667     cctx->cdict = NULL;
       
   668     return ZSTD_CCtxParams_reset(&cctx->requestedParams);
   580 }
   669 }
   581 
   670 
   582 /** ZSTD_checkCParams() :
   671 /** ZSTD_checkCParams() :
   583     control CParam values remain within authorized range.
   672     control CParam values remain within authorized range.
   584     @return : 0, or an error code if one value is beyond authorized range */
   673     @return : 0, or an error code if one value is beyond authorized range */
   587     CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
   676     CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
   588     CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
   677     CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
   589     CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   678     CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   590     CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
   679     CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
   591     CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
   680     CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
   592     if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN)
   681     ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0);
   593         return ERROR(parameter_unsupported);
   682     if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX)
       
   683         return ERROR(parameter_outOfBound);
   594     if ((U32)(cParams.strategy) > (U32)ZSTD_btultra)
   684     if ((U32)(cParams.strategy) > (U32)ZSTD_btultra)
   595         return ERROR(parameter_unsupported);
   685         return ERROR(parameter_unsupported);
   596     return 0;
   686     return 0;
   597 }
   687 }
   598 
   688 
   599 /** ZSTD_clampCParams() :
   689 /** ZSTD_clampCParams() :
   600  *  make CParam values within valid range.
   690  *  make CParam values within valid range.
   601  *  @return : valid CParams */
   691  *  @return : valid CParams */
   602 static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters cParams)
   692 static ZSTD_compressionParameters
       
   693 ZSTD_clampCParams(ZSTD_compressionParameters cParams)
   603 {
   694 {
   604 #   define CLAMP(val,min,max) {      \
   695 #   define CLAMP(val,min,max) {      \
   605         if (val<min) val=min;        \
   696         if (val<min) val=min;        \
   606         else if (val>max) val=max;   \
   697         else if (val>max) val=max;   \
   607     }
   698     }
   608     CLAMP(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
   699     CLAMP(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
   609     CLAMP(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
   700     CLAMP(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
   610     CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   701     CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
   611     CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
   702     CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
   612     CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
   703     CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
   613     if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN) cParams.targetLength = ZSTD_TARGETLENGTH_MIN;
   704     ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0);
   614     if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) cParams.strategy = ZSTD_btultra;
   705     if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX)
       
   706         cParams.targetLength = ZSTD_TARGETLENGTH_MAX;
       
   707     CLAMP(cParams.strategy, ZSTD_fast, ZSTD_btultra);
   615     return cParams;
   708     return cParams;
   616 }
   709 }
   617 
   710 
   618 /** ZSTD_cycleLog() :
   711 /** ZSTD_cycleLog() :
   619  *  condition for correct operation : hashLog > 1 */
   712  *  condition for correct operation : hashLog > 1 */
   625 
   718 
   626 /** ZSTD_adjustCParams_internal() :
   719 /** ZSTD_adjustCParams_internal() :
   627     optimize `cPar` for a given input (`srcSize` and `dictSize`).
   720     optimize `cPar` for a given input (`srcSize` and `dictSize`).
   628     mostly downsizing to reduce memory consumption and initialization latency.
   721     mostly downsizing to reduce memory consumption and initialization latency.
   629     Both `srcSize` and `dictSize` are optional (use 0 if unknown).
   722     Both `srcSize` and `dictSize` are optional (use 0 if unknown).
   630     Note : cPar is considered validated at this stage. Use ZSTD_checkCParams() to ensure that condition. */
   723     Note : cPar is assumed validated. Use ZSTD_checkCParams() to ensure this condition. */
   631 ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
   724 static ZSTD_compressionParameters
       
   725 ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
       
   726                             unsigned long long srcSize,
       
   727                             size_t dictSize)
   632 {
   728 {
   633     static const U64 minSrcSize = 513; /* (1<<9) + 1 */
   729     static const U64 minSrcSize = 513; /* (1<<9) + 1 */
   634     static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
   730     static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
   635     assert(ZSTD_checkCParams(cPar)==0);
   731     assert(ZSTD_checkCParams(cPar)==0);
   636 
   732 
   646         static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN;
   742         static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN;
   647         U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN :
   743         U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN :
   648                             ZSTD_highbit32(tSize-1) + 1;
   744                             ZSTD_highbit32(tSize-1) + 1;
   649         if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
   745         if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
   650     }
   746     }
   651     if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
   747     if (cPar.hashLog > cPar.windowLog+1) cPar.hashLog = cPar.windowLog+1;
   652     {   U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
   748     {   U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
   653         if (cycleLog > cPar.windowLog)
   749         if (cycleLog > cPar.windowLog)
   654             cPar.chainLog -= (cycleLog - cPar.windowLog);
   750             cPar.chainLog -= (cycleLog - cPar.windowLog);
   655     }
   751     }
   656 
   752 
   658         cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* required for frame header */
   754         cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* required for frame header */
   659 
   755 
   660     return cPar;
   756     return cPar;
   661 }
   757 }
   662 
   758 
   663 ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
   759 ZSTD_compressionParameters
       
   760 ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
       
   761                    unsigned long long srcSize,
       
   762                    size_t dictSize)
   664 {
   763 {
   665     cPar = ZSTD_clampCParams(cPar);
   764     cPar = ZSTD_clampCParams(cPar);
   666     return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
   765     return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
   667 }
   766 }
   668 
   767 
   669 static size_t ZSTD_sizeof_matchState(ZSTD_compressionParameters const* cParams, const U32 forCCtx)
   768 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
       
   769         const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
       
   770 {
       
   771     ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
       
   772     if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
       
   773     if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
       
   774     if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
       
   775     if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
       
   776     if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
       
   777     if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
       
   778     if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
       
   779     if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
       
   780     assert(!ZSTD_checkCParams(cParams));
       
   781     return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
       
   782 }
       
   783 
       
   784 static size_t
       
   785 ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
       
   786                        const U32 forCCtx)
   670 {
   787 {
   671     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
   788     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
   672     size_t const hSize = ((size_t)1) << cParams->hashLog;
   789     size_t const hSize = ((size_t)1) << cParams->hashLog;
   673     U32    const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
   790     U32    const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
   674     size_t const h3Size = ((size_t)1) << hashLog3;
   791     size_t const h3Size = ((size_t)1) << hashLog3;
   691     {   ZSTD_compressionParameters const cParams =
   808     {   ZSTD_compressionParameters const cParams =
   692                 ZSTD_getCParamsFromCCtxParams(params, 0, 0);
   809                 ZSTD_getCParamsFromCCtxParams(params, 0, 0);
   693         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
   810         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
   694         U32    const divider = (cParams.searchLength==3) ? 3 : 4;
   811         U32    const divider = (cParams.searchLength==3) ? 3 : 4;
   695         size_t const maxNbSeq = blockSize / divider;
   812         size_t const maxNbSeq = blockSize / divider;
   696         size_t const tokenSpace = blockSize + 11*maxNbSeq;
   813         size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
   697         size_t const entropySpace = HUF_WORKSPACE_SIZE;
   814         size_t const entropySpace = HUF_WORKSPACE_SIZE;
   698         size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
   815         size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
   699         size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
   816         size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
   700 
   817 
   701         size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);
   818         size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);
   750 {
   867 {
   751     ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
   868     ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
   752     return ZSTD_estimateCStreamSize_usingCCtxParams(&params);
   869     return ZSTD_estimateCStreamSize_usingCCtxParams(&params);
   753 }
   870 }
   754 
   871 
   755 static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) {
   872 static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
       
   873 {
   756     ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
   874     ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
   757     return ZSTD_estimateCStreamSize_usingCParams(cParams);
   875     return ZSTD_estimateCStreamSize_usingCParams(cParams);
   758 }
   876 }
   759 
   877 
   760 size_t ZSTD_estimateCStreamSize(int compressionLevel) {
   878 size_t ZSTD_estimateCStreamSize(int compressionLevel)
       
   879 {
   761     int level;
   880     int level;
   762     size_t memBudget = 0;
   881     size_t memBudget = 0;
   763     for (level=1; level<=compressionLevel; level++) {
   882     for (level=1; level<=compressionLevel; level++) {
   764         size_t const newMB = ZSTD_estimateCStreamSize_internal(level);
   883         size_t const newMB = ZSTD_estimateCStreamSize_internal(level);
   765         if (newMB > memBudget) memBudget = newMB;
   884         if (newMB > memBudget) memBudget = newMB;
   784         if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress);
   903         if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress);
   785         assert(buffered <= ZSTD_BLOCKSIZE_MAX);
   904         assert(buffered <= ZSTD_BLOCKSIZE_MAX);
   786         fp.ingested = cctx->consumedSrcSize + buffered;
   905         fp.ingested = cctx->consumedSrcSize + buffered;
   787         fp.consumed = cctx->consumedSrcSize;
   906         fp.consumed = cctx->consumedSrcSize;
   788         fp.produced = cctx->producedCSize;
   907         fp.produced = cctx->producedCSize;
       
   908         fp.flushed  = cctx->producedCSize;   /* simplified; some data might still be left within streaming output buffer */
       
   909         fp.currentJobID = 0;
       
   910         fp.nbActiveWorkers = 0;
   789         return fp;
   911         return fp;
   790 }   }
   912 }   }
       
   913 
       
   914 /*! ZSTD_toFlushNow()
       
   915  *  Only useful for multithreading scenarios currently (nbWorkers >= 1).
       
   916  */
       
   917 size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx)
       
   918 {
       
   919 #ifdef ZSTD_MULTITHREAD
       
   920     if (cctx->appliedParams.nbWorkers > 0) {
       
   921         return ZSTDMT_toFlushNow(cctx->mtctx);
       
   922     }
       
   923 #endif
       
   924     (void)cctx;
       
   925     return 0;   /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */
       
   926 }
       
   927 
   791 
   928 
   792 
   929 
   793 static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
   930 static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
   794                                   ZSTD_compressionParameters cParams2)
   931                                   ZSTD_compressionParameters cParams2)
   795 {
   932 {
   796     return (cParams1.hashLog  == cParams2.hashLog)
   933     return (cParams1.hashLog  == cParams2.hashLog)
   797          & (cParams1.chainLog == cParams2.chainLog)
   934          & (cParams1.chainLog == cParams2.chainLog)
   798          & (cParams1.strategy == cParams2.strategy)   /* opt parser space */
   935          & (cParams1.strategy == cParams2.strategy)   /* opt parser space */
   799          & ((cParams1.searchLength==3) == (cParams2.searchLength==3));  /* hashlog3 space */
   936          & ((cParams1.searchLength==3) == (cParams2.searchLength==3));  /* hashlog3 space */
       
   937 }
       
   938 
       
   939 static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
       
   940                                     ZSTD_compressionParameters cParams2)
       
   941 {
       
   942     (void)cParams1;
       
   943     (void)cParams2;
       
   944     assert(cParams1.windowLog    == cParams2.windowLog);
       
   945     assert(cParams1.chainLog     == cParams2.chainLog);
       
   946     assert(cParams1.hashLog      == cParams2.hashLog);
       
   947     assert(cParams1.searchLog    == cParams2.searchLog);
       
   948     assert(cParams1.searchLength == cParams2.searchLength);
       
   949     assert(cParams1.targetLength == cParams2.targetLength);
       
   950     assert(cParams1.strategy     == cParams2.strategy);
   800 }
   951 }
   801 
   952 
   802 /** The parameters are equivalent if ldm is not enabled in both sets or
   953 /** The parameters are equivalent if ldm is not enabled in both sets or
   803  *  all the parameters are equivalent. */
   954  *  all the parameters are equivalent. */
   804 static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
   955 static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
   815 typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
   966 typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
   816 
   967 
   817 /* ZSTD_sufficientBuff() :
   968 /* ZSTD_sufficientBuff() :
   818  * check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
   969  * check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
   819  * Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
   970  * Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
   820 static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t blockSize1,
   971 static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t maxNbSeq1,
       
   972                             size_t maxNbLit1,
   821                             ZSTD_buffered_policy_e buffPol2,
   973                             ZSTD_buffered_policy_e buffPol2,
   822                             ZSTD_compressionParameters cParams2,
   974                             ZSTD_compressionParameters cParams2,
   823                             U64 pledgedSrcSize)
   975                             U64 pledgedSrcSize)
   824 {
   976 {
   825     size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
   977     size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
   826     size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
   978     size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
       
   979     size_t const maxNbSeq2 = blockSize2 / ((cParams2.searchLength == 3) ? 3 : 4);
       
   980     size_t const maxNbLit2 = blockSize2;
   827     size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
   981     size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
   828     DEBUGLOG(4, "ZSTD_sufficientBuff: is windowSize2=%u <= wlog1=%u",
   982     DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u",
   829                 (U32)windowSize2, cParams2.windowLog);
   983                 (U32)neededBufferSize2, (U32)bufferSize1);
   830     DEBUGLOG(4, "ZSTD_sufficientBuff: is blockSize2=%u <= blockSize1=%u",
   984     DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u",
   831                 (U32)blockSize2, (U32)blockSize1);
   985                 (U32)maxNbSeq2, (U32)maxNbSeq1);
   832     return (blockSize2 <= blockSize1) /* seqStore space depends on blockSize */
   986     DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbLit2=%u <= maxNbLit1=%u",
       
   987                 (U32)maxNbLit2, (U32)maxNbLit1);
       
   988     return (maxNbLit2 <= maxNbLit1)
       
   989          & (maxNbSeq2 <= maxNbSeq1)
   833          & (neededBufferSize2 <= bufferSize1);
   990          & (neededBufferSize2 <= bufferSize1);
   834 }
   991 }
   835 
   992 
   836 /** Equivalence for resetCCtx purposes */
   993 /** Equivalence for resetCCtx purposes */
   837 static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
   994 static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
   838                                  ZSTD_CCtx_params params2,
   995                                  ZSTD_CCtx_params params2,
   839                                  size_t buffSize1, size_t blockSize1,
   996                                  size_t buffSize1,
       
   997                                  size_t maxNbSeq1, size_t maxNbLit1,
   840                                  ZSTD_buffered_policy_e buffPol2,
   998                                  ZSTD_buffered_policy_e buffPol2,
   841                                  U64 pledgedSrcSize)
   999                                  U64 pledgedSrcSize)
   842 {
  1000 {
   843     DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
  1001     DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
   844     return ZSTD_equivalentCParams(params1.cParams, params2.cParams) &&
  1002     if (!ZSTD_equivalentCParams(params1.cParams, params2.cParams)) {
   845            ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams) &&
  1003       DEBUGLOG(4, "ZSTD_equivalentCParams() == 0");
   846            ZSTD_sufficientBuff(buffSize1, blockSize1, buffPol2, params2.cParams, pledgedSrcSize);
  1004       return 0;
       
  1005     }
       
  1006     if (!ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams)) {
       
  1007       DEBUGLOG(4, "ZSTD_equivalentLdmParams() == 0");
       
  1008       return 0;
       
  1009     }
       
  1010     if (!ZSTD_sufficientBuff(buffSize1, maxNbSeq1, maxNbLit1, buffPol2,
       
  1011                              params2.cParams, pledgedSrcSize)) {
       
  1012       DEBUGLOG(4, "ZSTD_sufficientBuff() == 0");
       
  1013       return 0;
       
  1014     }
       
  1015     return 1;
   847 }
  1016 }
   848 
  1017 
   849 static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
  1018 static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
   850 {
  1019 {
   851     int i;
  1020     int i;
   852     for (i = 0; i < ZSTD_REP_NUM; ++i)
  1021     for (i = 0; i < ZSTD_REP_NUM; ++i)
   853         bs->rep[i] = repStartValue[i];
  1022         bs->rep[i] = repStartValue[i];
   854     bs->entropy.hufCTable_repeatMode = HUF_repeat_none;
  1023     bs->entropy.huf.repeatMode = HUF_repeat_none;
   855     bs->entropy.offcode_repeatMode = FSE_repeat_none;
  1024     bs->entropy.fse.offcode_repeatMode = FSE_repeat_none;
   856     bs->entropy.matchlength_repeatMode = FSE_repeat_none;
  1025     bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none;
   857     bs->entropy.litlength_repeatMode = FSE_repeat_none;
  1026     bs->entropy.fse.litlength_repeatMode = FSE_repeat_none;
   858 }
  1027 }
   859 
  1028 
   860 /*! ZSTD_invalidateMatchState()
  1029 /*! ZSTD_invalidateMatchState()
   861  * Invalidate all the matches in the match finder tables.
  1030  * Invalidate all the matches in the match finder tables.
   862  * Requires nextSrc and base to be set (can be NULL).
  1031  * Requires nextSrc and base to be set (can be NULL).
   864 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
  1033 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
   865 {
  1034 {
   866     ZSTD_window_clear(&ms->window);
  1035     ZSTD_window_clear(&ms->window);
   867 
  1036 
   868     ms->nextToUpdate = ms->window.dictLimit + 1;
  1037     ms->nextToUpdate = ms->window.dictLimit + 1;
       
  1038     ms->nextToUpdate3 = ms->window.dictLimit + 1;
   869     ms->loadedDictEnd = 0;
  1039     ms->loadedDictEnd = 0;
   870     ms->opt.litLengthSum = 0;  /* force reset of btopt stats */
  1040     ms->opt.litLengthSum = 0;  /* force reset of btopt stats */
       
  1041     ms->dictMatchState = NULL;
   871 }
  1042 }
   872 
  1043 
   873 /*! ZSTD_continueCCtx() :
  1044 /*! ZSTD_continueCCtx() :
   874  *  reuse CCtx without reset (note : requires no dictionary) */
  1045  *  reuse CCtx without reset (note : requires no dictionary) */
   875 static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize)
  1046 static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize)
   878     size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
  1049     size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
   879     DEBUGLOG(4, "ZSTD_continueCCtx: re-use context in place");
  1050     DEBUGLOG(4, "ZSTD_continueCCtx: re-use context in place");
   880 
  1051 
   881     cctx->blockSize = blockSize;   /* previous block size could be different even for same windowLog, due to pledgedSrcSize */
  1052     cctx->blockSize = blockSize;   /* previous block size could be different even for same windowLog, due to pledgedSrcSize */
   882     cctx->appliedParams = params;
  1053     cctx->appliedParams = params;
       
  1054     cctx->blockState.matchState.cParams = params.cParams;
   883     cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
  1055     cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
   884     cctx->consumedSrcSize = 0;
  1056     cctx->consumedSrcSize = 0;
   885     cctx->producedCSize = 0;
  1057     cctx->producedCSize = 0;
   886     if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
  1058     if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
   887         cctx->appliedParams.fParams.contentSizeFlag = 0;
  1059         cctx->appliedParams.fParams.contentSizeFlag = 0;
   898     return 0;
  1070     return 0;
   899 }
  1071 }
   900 
  1072 
   901 typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
  1073 typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
   902 
  1074 
   903 static void* ZSTD_reset_matchState(ZSTD_matchState_t* ms, void* ptr, ZSTD_compressionParameters const* cParams, ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
  1075 static void*
       
  1076 ZSTD_reset_matchState(ZSTD_matchState_t* ms,
       
  1077                       void* ptr,
       
  1078                 const ZSTD_compressionParameters* cParams,
       
  1079                       ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
   904 {
  1080 {
   905     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
  1081     size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
   906     size_t const hSize = ((size_t)1) << cParams->hashLog;
  1082     size_t const hSize = ((size_t)1) << cParams->hashLog;
   907     U32    const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
  1083     U32    const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
   908     size_t const h3Size = ((size_t)1) << hashLog3;
  1084     size_t const h3Size = ((size_t)1) << hashLog3;
   910 
  1086 
   911     assert(((size_t)ptr & 3) == 0);
  1087     assert(((size_t)ptr & 3) == 0);
   912 
  1088 
   913     ms->hashLog3 = hashLog3;
  1089     ms->hashLog3 = hashLog3;
   914     memset(&ms->window, 0, sizeof(ms->window));
  1090     memset(&ms->window, 0, sizeof(ms->window));
       
  1091     ms->window.dictLimit = 1;    /* start from 1, so that 1st position is valid */
       
  1092     ms->window.lowLimit = 1;     /* it ensures first and later CCtx usages compress the same */
       
  1093     ms->window.nextSrc = ms->window.base + 1;   /* see issue #1241 */
   915     ZSTD_invalidateMatchState(ms);
  1094     ZSTD_invalidateMatchState(ms);
   916 
  1095 
   917     /* opt parser space */
  1096     /* opt parser space */
   918     if (forCCtx && ((cParams->strategy == ZSTD_btopt) | (cParams->strategy == ZSTD_btultra))) {
  1097     if (forCCtx && ((cParams->strategy == ZSTD_btopt) | (cParams->strategy == ZSTD_btultra))) {
   919         DEBUGLOG(4, "reserving optimal parser space");
  1098         DEBUGLOG(4, "reserving optimal parser space");
   935     ms->hashTable = (U32*)(ptr);
  1114     ms->hashTable = (U32*)(ptr);
   936     ms->chainTable = ms->hashTable + hSize;
  1115     ms->chainTable = ms->hashTable + hSize;
   937     ms->hashTable3 = ms->chainTable + chainSize;
  1116     ms->hashTable3 = ms->chainTable + chainSize;
   938     ptr = ms->hashTable3 + h3Size;
  1117     ptr = ms->hashTable3 + h3Size;
   939 
  1118 
       
  1119     ms->cParams = *cParams;
       
  1120 
   940     assert(((size_t)ptr & 3) == 0);
  1121     assert(((size_t)ptr & 3) == 0);
   941     return ptr;
  1122     return ptr;
   942 }
  1123 }
       
  1124 
       
  1125 #define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
       
  1126 #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128  /* when workspace is continuously too large
       
  1127                                          * during at least this number of times,
       
  1128                                          * context's memory usage is considered wasteful,
       
  1129                                          * because it's sized to handle a worst case scenario which rarely happens.
       
  1130                                          * In which case, resize it down to free some memory */
   943 
  1131 
   944 /*! ZSTD_resetCCtx_internal() :
  1132 /*! ZSTD_resetCCtx_internal() :
   945     note : `params` are assumed fully validated at this stage */
  1133     note : `params` are assumed fully validated at this stage */
   946 static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
  1134 static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
   947                                       ZSTD_CCtx_params params, U64 pledgedSrcSize,
  1135                                       ZSTD_CCtx_params params,
       
  1136                                       U64 pledgedSrcSize,
   948                                       ZSTD_compResetPolicy_e const crp,
  1137                                       ZSTD_compResetPolicy_e const crp,
   949                                       ZSTD_buffered_policy_e const zbuff)
  1138                                       ZSTD_buffered_policy_e const zbuff)
   950 {
  1139 {
   951     DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
  1140     DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
   952                 (U32)pledgedSrcSize, params.cParams.windowLog);
  1141                 (U32)pledgedSrcSize, params.cParams.windowLog);
   953     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  1142     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
   954 
  1143 
   955     if (crp == ZSTDcrp_continue) {
  1144     if (crp == ZSTDcrp_continue) {
   956         if (ZSTD_equivalentParams(zc->appliedParams, params,
  1145         if (ZSTD_equivalentParams(zc->appliedParams, params,
   957                                 zc->inBuffSize, zc->blockSize,
  1146                                   zc->inBuffSize,
   958                                 zbuff, pledgedSrcSize)) {
  1147                                   zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
   959             DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%u)",
  1148                                   zbuff, pledgedSrcSize)) {
   960                         zc->appliedParams.cParams.windowLog, (U32)zc->blockSize);
  1149             DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
   961             return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
  1150                         zc->appliedParams.cParams.windowLog, zc->blockSize);
       
  1151             zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0);   /* if it was too large, it still is */
       
  1152             if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION)
       
  1153                 return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
   962     }   }
  1154     }   }
   963     DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
  1155     DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
   964 
  1156 
   965     if (params.ldmParams.enableLdm) {
  1157     if (params.ldmParams.enableLdm) {
   966         /* Adjust long distance matching parameters */
  1158         /* Adjust long distance matching parameters */
   967         params.ldmParams.windowLog = params.cParams.windowLog;
       
   968         ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
  1159         ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
   969         assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
  1160         assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
   970         assert(params.ldmParams.hashEveryLog < 32);
  1161         assert(params.ldmParams.hashEveryLog < 32);
   971         zc->ldmState.hashPower =
  1162         zc->ldmState.hashPower = ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
   972                 ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
       
   973     }
  1163     }
   974 
  1164 
   975     {   size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
  1165     {   size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
   976         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
  1166         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
   977         U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
  1167         U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
   978         size_t const maxNbSeq = blockSize / divider;
  1168         size_t const maxNbSeq = blockSize / divider;
   979         size_t const tokenSpace = blockSize + 11*maxNbSeq;
  1169         size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
   980         size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
  1170         size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
   981         size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
  1171         size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
   982         size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);
  1172         size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);
   983         size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
  1173         size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
   984         void* ptr;
  1174         void* ptr;   /* used to partition workSpace */
   985 
  1175 
   986         /* Check if workSpace is large enough, alloc a new one if needed */
  1176         /* Check if workSpace is large enough, alloc a new one if needed */
   987         {   size_t const entropySpace = HUF_WORKSPACE_SIZE;
  1177         {   size_t const entropySpace = HUF_WORKSPACE_SIZE;
   988             size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
  1178             size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
   989             size_t const bufferSpace = buffInSize + buffOutSize;
  1179             size_t const bufferSpace = buffInSize + buffOutSize;
   991             size_t const ldmSeqSpace = maxNbLdmSeq * sizeof(rawSeq);
  1181             size_t const ldmSeqSpace = maxNbLdmSeq * sizeof(rawSeq);
   992 
  1182 
   993             size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace +
  1183             size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace +
   994                                        ldmSeqSpace + matchStateSize + tokenSpace +
  1184                                        ldmSeqSpace + matchStateSize + tokenSpace +
   995                                        bufferSpace;
  1185                                        bufferSpace;
   996             DEBUGLOG(4, "Need %uKB workspace, including %uKB for match state, and %uKB for buffers",
  1186 
   997                         (U32)(neededSpace>>10), (U32)(matchStateSize>>10), (U32)(bufferSpace>>10));
  1187             int const workSpaceTooSmall = zc->workSpaceSize < neededSpace;
   998             DEBUGLOG(4, "windowSize: %u - blockSize: %u", (U32)windowSize, (U32)blockSize);
  1188             int const workSpaceTooLarge = zc->workSpaceSize > ZSTD_WORKSPACETOOLARGE_FACTOR * neededSpace;
   999 
  1189             int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION);
  1000             if (zc->workSpaceSize < neededSpace) {  /* too small : resize */
  1190             zc->workSpaceOversizedDuration = workSpaceTooLarge ? zc->workSpaceOversizedDuration+1 : 0;
  1001                 DEBUGLOG(4, "Need to update workSpaceSize from %uK to %uK",
  1191 
  1002                             (unsigned)(zc->workSpaceSize>>10),
  1192             DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
  1003                             (unsigned)(neededSpace>>10));
  1193                         neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
       
  1194             DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
       
  1195 
       
  1196             if (workSpaceTooSmall || workSpaceWasteful) {
       
  1197                 DEBUGLOG(4, "Need to resize workSpaceSize from %zuKB to %zuKB",
       
  1198                             zc->workSpaceSize >> 10,
       
  1199                             neededSpace >> 10);
  1004                 /* static cctx : no resize, error out */
  1200                 /* static cctx : no resize, error out */
  1005                 if (zc->staticSize) return ERROR(memory_allocation);
  1201                 if (zc->staticSize) return ERROR(memory_allocation);
  1006 
  1202 
  1007                 zc->workSpaceSize = 0;
  1203                 zc->workSpaceSize = 0;
  1008                 ZSTD_free(zc->workSpace, zc->customMem);
  1204                 ZSTD_free(zc->workSpace, zc->customMem);
  1009                 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
  1205                 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
  1010                 if (zc->workSpace == NULL) return ERROR(memory_allocation);
  1206                 if (zc->workSpace == NULL) return ERROR(memory_allocation);
  1011                 zc->workSpaceSize = neededSpace;
  1207                 zc->workSpaceSize = neededSpace;
  1012                 ptr = zc->workSpace;
  1208                 zc->workSpaceOversizedDuration = 0;
  1013 
  1209 
  1014                 /* Statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
  1210                 /* Statically sized space.
       
  1211                  * entropyWorkspace never moves,
       
  1212                  * though prev/next block swap places */
  1015                 assert(((size_t)zc->workSpace & 3) == 0);   /* ensure correct alignment */
  1213                 assert(((size_t)zc->workSpace & 3) == 0);   /* ensure correct alignment */
  1016                 assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t));
  1214                 assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t));
  1017                 zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace;
  1215                 zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace;
  1018                 zc->blockState.nextCBlock = zc->blockState.prevCBlock + 1;
  1216                 zc->blockState.nextCBlock = zc->blockState.prevCBlock + 1;
  1019                 ptr = zc->blockState.nextCBlock + 1;
  1217                 ptr = zc->blockState.nextCBlock + 1;
  1020                 zc->entropyWorkspace = (U32*)ptr;
  1218                 zc->entropyWorkspace = (U32*)ptr;
  1021         }   }
  1219         }   }
  1022 
  1220 
  1023         /* init params */
  1221         /* init params */
  1024         zc->appliedParams = params;
  1222         zc->appliedParams = params;
       
  1223         zc->blockState.matchState.cParams = params.cParams;
  1025         zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
  1224         zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
  1026         zc->consumedSrcSize = 0;
  1225         zc->consumedSrcSize = 0;
  1027         zc->producedCSize = 0;
  1226         zc->producedCSize = 0;
  1028         if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
  1227         if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
  1029             zc->appliedParams.fParams.contentSizeFlag = 0;
  1228             zc->appliedParams.fParams.contentSizeFlag = 0;
  1056         assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
  1255         assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
  1057 
  1256 
  1058         ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, &params.cParams, crp, /* forCCtx */ 1);
  1257         ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, &params.cParams, crp, /* forCCtx */ 1);
  1059 
  1258 
  1060         /* sequences storage */
  1259         /* sequences storage */
       
  1260         zc->seqStore.maxNbSeq = maxNbSeq;
  1061         zc->seqStore.sequencesStart = (seqDef*)ptr;
  1261         zc->seqStore.sequencesStart = (seqDef*)ptr;
  1062         ptr = zc->seqStore.sequencesStart + maxNbSeq;
  1262         ptr = zc->seqStore.sequencesStart + maxNbSeq;
  1063         zc->seqStore.llCode = (BYTE*) ptr;
  1263         zc->seqStore.llCode = (BYTE*) ptr;
  1064         zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
  1264         zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
  1065         zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
  1265         zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
  1066         zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
  1266         zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
  1067         ptr = zc->seqStore.litStart + blockSize;
  1267         /* ZSTD_wildcopy() is used to copy into the literals buffer,
       
  1268          * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.
       
  1269          */
       
  1270         zc->seqStore.maxNbLit = blockSize;
       
  1271         ptr = zc->seqStore.litStart + blockSize + WILDCOPY_OVERLENGTH;
  1068 
  1272 
  1069         /* ldm bucketOffsets table */
  1273         /* ldm bucketOffsets table */
  1070         if (params.ldmParams.enableLdm) {
  1274         if (params.ldmParams.enableLdm) {
  1071             size_t const ldmBucketSize =
  1275             size_t const ldmBucketSize =
  1072                   ((size_t)1) << (params.ldmParams.hashLog -
  1276                   ((size_t)1) << (params.ldmParams.hashLog -
  1096     int i;
  1300     int i;
  1097     for (i=0; i<ZSTD_REP_NUM; i++) cctx->blockState.prevCBlock->rep[i] = 0;
  1301     for (i=0; i<ZSTD_REP_NUM; i++) cctx->blockState.prevCBlock->rep[i] = 0;
  1098     assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window));
  1302     assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window));
  1099 }
  1303 }
  1100 
  1304 
  1101 static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
  1305 /* These are the approximate sizes for each strategy past which copying the
       
  1306  * dictionary tables into the working context is faster than using them
       
  1307  * in-place.
       
  1308  */
       
  1309 static const size_t attachDictSizeCutoffs[(unsigned)ZSTD_btultra+1] = {
       
  1310     8 KB, /* unused */
       
  1311     8 KB, /* ZSTD_fast */
       
  1312     16 KB, /* ZSTD_dfast */
       
  1313     32 KB, /* ZSTD_greedy */
       
  1314     32 KB, /* ZSTD_lazy */
       
  1315     32 KB, /* ZSTD_lazy2 */
       
  1316     32 KB, /* ZSTD_btlazy2 */
       
  1317     32 KB, /* ZSTD_btopt */
       
  1318     8 KB /* ZSTD_btultra */
       
  1319 };
       
  1320 
       
  1321 static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
       
  1322                                  ZSTD_CCtx_params params,
       
  1323                                  U64 pledgedSrcSize)
       
  1324 {
       
  1325     size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];
       
  1326     return ( pledgedSrcSize <= cutoff
       
  1327           || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
       
  1328           || params.attachDictPref == ZSTD_dictForceAttach )
       
  1329         && params.attachDictPref != ZSTD_dictForceCopy
       
  1330         && !params.forceWindow; /* dictMatchState isn't correctly
       
  1331                                  * handled in _enforceMaxDist */
       
  1332 }
       
  1333 
       
  1334 static size_t ZSTD_resetCCtx_byAttachingCDict(
       
  1335     ZSTD_CCtx* cctx,
       
  1336     const ZSTD_CDict* cdict,
       
  1337     ZSTD_CCtx_params params,
       
  1338     U64 pledgedSrcSize,
       
  1339     ZSTD_buffered_policy_e zbuff)
       
  1340 {
       
  1341     {
       
  1342         const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
       
  1343         unsigned const windowLog = params.cParams.windowLog;
       
  1344         assert(windowLog != 0);
       
  1345         /* Resize working context table params for input only, since the dict
       
  1346          * has its own tables. */
       
  1347         params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
       
  1348         params.cParams.windowLog = windowLog;
       
  1349         ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
       
  1350                                 ZSTDcrp_continue, zbuff);
       
  1351         assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
       
  1352     }
       
  1353 
       
  1354     {
       
  1355         const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
       
  1356                                   - cdict->matchState.window.base);
       
  1357         const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit;
       
  1358         if (cdictLen == 0) {
       
  1359             /* don't even attach dictionaries with no contents */
       
  1360             DEBUGLOG(4, "skipping attaching empty dictionary");
       
  1361         } else {
       
  1362             DEBUGLOG(4, "attaching dictionary into context");
       
  1363             cctx->blockState.matchState.dictMatchState = &cdict->matchState;
       
  1364 
       
  1365             /* prep working match state so dict matches never have negative indices
       
  1366              * when they are translated to the working context's index space. */
       
  1367             if (cctx->blockState.matchState.window.dictLimit < cdictEnd) {
       
  1368                 cctx->blockState.matchState.window.nextSrc =
       
  1369                     cctx->blockState.matchState.window.base + cdictEnd;
       
  1370                 ZSTD_window_clear(&cctx->blockState.matchState.window);
       
  1371             }
       
  1372             cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
       
  1373         }
       
  1374     }
       
  1375 
       
  1376     cctx->dictID = cdict->dictID;
       
  1377 
       
  1378     /* copy block state */
       
  1379     memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
       
  1380 
       
  1381     return 0;
       
  1382 }
       
  1383 
       
  1384 static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
  1102                             const ZSTD_CDict* cdict,
  1385                             const ZSTD_CDict* cdict,
  1103                             unsigned windowLog,
  1386                             ZSTD_CCtx_params params,
  1104                             ZSTD_frameParameters fParams,
       
  1105                             U64 pledgedSrcSize,
  1387                             U64 pledgedSrcSize,
  1106                             ZSTD_buffered_policy_e zbuff)
  1388                             ZSTD_buffered_policy_e zbuff)
  1107 {
  1389 {
  1108     {   ZSTD_CCtx_params params = cctx->requestedParams;
  1390     const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
       
  1391 
       
  1392     DEBUGLOG(4, "copying dictionary into context");
       
  1393 
       
  1394     {   unsigned const windowLog = params.cParams.windowLog;
       
  1395         assert(windowLog != 0);
  1109         /* Copy only compression parameters related to tables. */
  1396         /* Copy only compression parameters related to tables. */
  1110         params.cParams = cdict->cParams;
  1397         params.cParams = *cdict_cParams;
  1111         if (windowLog) params.cParams.windowLog = windowLog;
  1398         params.cParams.windowLog = windowLog;
  1112         params.fParams = fParams;
       
  1113         ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  1399         ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  1114                                 ZSTDcrp_noMemset, zbuff);
  1400                                 ZSTDcrp_noMemset, zbuff);
  1115         assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy);
  1401         assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
  1116         assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog);
  1402         assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
  1117         assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog);
  1403         assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);
  1118     }
  1404     }
  1119 
  1405 
  1120     /* copy tables */
  1406     /* copy tables */
  1121     {   size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog);
  1407     {   size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);
  1122         size_t const hSize =  (size_t)1 << cdict->cParams.hashLog;
  1408         size_t const hSize =  (size_t)1 << cdict_cParams->hashLog;
  1123         size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
  1409         size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
  1124         assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize);  /* chainTable must follow hashTable */
  1410         assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize);  /* chainTable must follow hashTable */
  1125         assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
  1411         assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
  1126         assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize);  /* chainTable must follow hashTable */
  1412         assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize);  /* chainTable must follow hashTable */
  1127         assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
  1413         assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
  1128         memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace);   /* presumes all tables follow each other */
  1414         memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace);   /* presumes all tables follow each other */
  1129     }
  1415     }
       
  1416 
  1130     /* Zero the hashTable3, since the cdict never fills it */
  1417     /* Zero the hashTable3, since the cdict never fills it */
  1131     {   size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
  1418     {   size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
  1132         assert(cdict->matchState.hashLog3 == 0);
  1419         assert(cdict->matchState.hashLog3 == 0);
  1133         memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
  1420         memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
  1134     }
  1421     }
  1135 
  1422 
  1136     /* copy dictionary offsets */
  1423     /* copy dictionary offsets */
  1137     {
  1424     {   ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
  1138         ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
       
  1139         ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
  1425         ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
  1140         dstMatchState->window       = srcMatchState->window;
  1426         dstMatchState->window       = srcMatchState->window;
  1141         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1427         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1142         dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
  1428         dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
  1143         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1429         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1144     }
  1430     }
       
  1431 
  1145     cctx->dictID = cdict->dictID;
  1432     cctx->dictID = cdict->dictID;
  1146 
  1433 
  1147     /* copy block state */
  1434     /* copy block state */
  1148     memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
  1435     memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
  1149 
  1436 
  1150     return 0;
  1437     return 0;
       
  1438 }
       
  1439 
       
  1440 /* We have a choice between copying the dictionary context into the working
       
  1441  * context, or referencing the dictionary context from the working context
       
  1442  * in-place. We decide here which strategy to use. */
       
  1443 static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
       
  1444                             const ZSTD_CDict* cdict,
       
  1445                             ZSTD_CCtx_params params,
       
  1446                             U64 pledgedSrcSize,
       
  1447                             ZSTD_buffered_policy_e zbuff)
       
  1448 {
       
  1449 
       
  1450     DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
       
  1451 
       
  1452     if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {
       
  1453         return ZSTD_resetCCtx_byAttachingCDict(
       
  1454             cctx, cdict, params, pledgedSrcSize, zbuff);
       
  1455     } else {
       
  1456         return ZSTD_resetCCtx_byCopyingCDict(
       
  1457             cctx, cdict, params, pledgedSrcSize, zbuff);
       
  1458     }
  1151 }
  1459 }
  1152 
  1460 
  1153 /*! ZSTD_copyCCtx_internal() :
  1461 /*! ZSTD_copyCCtx_internal() :
  1154  *  Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
  1462  *  Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
  1155  *  Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
  1463  *  Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
  1190         memcpy(dstCCtx->blockState.matchState.hashTable, srcCCtx->blockState.matchState.hashTable, tableSpace);   /* presumes all tables follow each other */
  1498         memcpy(dstCCtx->blockState.matchState.hashTable, srcCCtx->blockState.matchState.hashTable, tableSpace);   /* presumes all tables follow each other */
  1191     }
  1499     }
  1192 
  1500 
  1193     /* copy dictionary offsets */
  1501     /* copy dictionary offsets */
  1194     {
  1502     {
  1195         ZSTD_matchState_t const* srcMatchState = &srcCCtx->blockState.matchState;
  1503         const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
  1196         ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
  1504         ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
  1197         dstMatchState->window       = srcMatchState->window;
  1505         dstMatchState->window       = srcMatchState->window;
  1198         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1506         dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
  1199         dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
  1507         dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
  1200         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1508         dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
  1292 *  Block entropic compression
  1600 *  Block entropic compression
  1293 *********************************************************/
  1601 *********************************************************/
  1294 
  1602 
  1295 /* See doc/zstd_compression_format.md for detailed format description */
  1603 /* See doc/zstd_compression_format.md for detailed format description */
  1296 
  1604 
  1297 size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
  1605 static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
  1298 {
  1606 {
       
  1607     U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
  1299     if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
  1608     if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
       
  1609     MEM_writeLE24(dst, cBlockHeader24);
  1300     memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
  1610     memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
  1301     MEM_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
  1611     return ZSTD_blockHeaderSize + srcSize;
  1302     return ZSTD_blockHeaderSize+srcSize;
  1612 }
  1303 }
       
  1304 
       
  1305 
  1613 
  1306 static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
  1614 static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
  1307 {
  1615 {
  1308     BYTE* const ostart = (BYTE* const)dst;
  1616     BYTE* const ostart = (BYTE* const)dst;
  1309     U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
  1617     U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
  1354     ostart[flSize] = *(const BYTE*)src;
  1662     ostart[flSize] = *(const BYTE*)src;
  1355     return flSize+1;
  1663     return flSize+1;
  1356 }
  1664 }
  1357 
  1665 
  1358 
  1666 
  1359 static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; }
  1667 /* ZSTD_minGain() :
  1360 
  1668  * minimum compression required
  1361 static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t const* prevEntropy,
  1669  * to generate a compress block or a compressed literals section.
  1362                                      ZSTD_entropyCTables_t* nextEntropy,
  1670  * note : use same formula for both situations */
       
  1671 static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
       
  1672 {
       
  1673     U32 const minlog = (strat==ZSTD_btultra) ? 7 : 6;
       
  1674     return (srcSize >> minlog) + 2;
       
  1675 }
       
  1676 
       
  1677 static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
       
  1678                                      ZSTD_hufCTables_t* nextHuf,
  1363                                      ZSTD_strategy strategy, int disableLiteralCompression,
  1679                                      ZSTD_strategy strategy, int disableLiteralCompression,
  1364                                      void* dst, size_t dstCapacity,
  1680                                      void* dst, size_t dstCapacity,
  1365                                const void* src, size_t srcSize,
  1681                                const void* src, size_t srcSize,
  1366                                      U32* workspace, const int bmi2)
  1682                                      U32* workspace, const int bmi2)
  1367 {
  1683 {
  1368     size_t const minGain = ZSTD_minGain(srcSize);
  1684     size_t const minGain = ZSTD_minGain(srcSize, strategy);
  1369     size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
  1685     size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
  1370     BYTE*  const ostart = (BYTE*)dst;
  1686     BYTE*  const ostart = (BYTE*)dst;
  1371     U32 singleStream = srcSize < 256;
  1687     U32 singleStream = srcSize < 256;
  1372     symbolEncodingType_e hType = set_compressed;
  1688     symbolEncodingType_e hType = set_compressed;
  1373     size_t cLitSize;
  1689     size_t cLitSize;
  1374 
  1690 
  1375     DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
  1691     DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
  1376                 disableLiteralCompression);
  1692                 disableLiteralCompression);
  1377 
  1693 
  1378     /* Prepare nextEntropy assuming reusing the existing table */
  1694     /* Prepare nextEntropy assuming reusing the existing table */
  1379     nextEntropy->hufCTable_repeatMode = prevEntropy->hufCTable_repeatMode;
  1695     memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
  1380     memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable,
       
  1381            sizeof(prevEntropy->hufCTable));
       
  1382 
  1696 
  1383     if (disableLiteralCompression)
  1697     if (disableLiteralCompression)
  1384         return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
  1698         return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
  1385 
  1699 
  1386     /* small ? don't even attempt compression (speed opt) */
  1700     /* small ? don't even attempt compression (speed opt) */
  1387 #   define COMPRESS_LITERALS_SIZE_MIN 63
  1701 #   define COMPRESS_LITERALS_SIZE_MIN 63
  1388     {   size_t const minLitSize = (prevEntropy->hufCTable_repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
  1702     {   size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
  1389         if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
  1703         if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
  1390     }
  1704     }
  1391 
  1705 
  1392     if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
  1706     if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
  1393     {   HUF_repeat repeat = prevEntropy->hufCTable_repeatMode;
  1707     {   HUF_repeat repeat = prevHuf->repeatMode;
  1394         int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
  1708         int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
  1395         if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
  1709         if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
  1396         cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1710         cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1397                                       workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextEntropy->hufCTable, &repeat, preferRepeat, bmi2)
  1711                                       workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
  1398                                 : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1712                                 : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
  1399                                       workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextEntropy->hufCTable, &repeat, preferRepeat, bmi2);
  1713                                       workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
  1400         if (repeat != HUF_repeat_none) {
  1714         if (repeat != HUF_repeat_none) {
  1401             /* reused the existing table */
  1715             /* reused the existing table */
  1402             hType = set_repeat;
  1716             hType = set_repeat;
  1403         }
  1717         }
  1404     }
  1718     }
  1405 
  1719 
  1406     if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
  1720     if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
  1407         memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable, sizeof(prevEntropy->hufCTable));
  1721         memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
  1408         return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
  1722         return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
  1409     }
  1723     }
  1410     if (cLitSize==1) {
  1724     if (cLitSize==1) {
  1411         memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable, sizeof(prevEntropy->hufCTable));
  1725         memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
  1412         return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
  1726         return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
  1413     }
  1727     }
  1414 
  1728 
  1415     if (hType == set_compressed) {
  1729     if (hType == set_compressed) {
  1416         /* using a newly constructed table */
  1730         /* using a newly constructed table */
  1417         nextEntropy->hufCTable_repeatMode = HUF_repeat_check;
  1731         nextHuf->repeatMode = HUF_repeat_check;
  1418     }
  1732     }
  1419 
  1733 
  1420     /* Build header */
  1734     /* Build header */
  1421     switch(lhSize)
  1735     switch(lhSize)
  1422     {
  1736     {
  1449     BYTE* const llCodeTable = seqStorePtr->llCode;
  1763     BYTE* const llCodeTable = seqStorePtr->llCode;
  1450     BYTE* const ofCodeTable = seqStorePtr->ofCode;
  1764     BYTE* const ofCodeTable = seqStorePtr->ofCode;
  1451     BYTE* const mlCodeTable = seqStorePtr->mlCode;
  1765     BYTE* const mlCodeTable = seqStorePtr->mlCode;
  1452     U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
  1766     U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
  1453     U32 u;
  1767     U32 u;
       
  1768     assert(nbSeq <= seqStorePtr->maxNbSeq);
  1454     for (u=0; u<nbSeq; u++) {
  1769     for (u=0; u<nbSeq; u++) {
  1455         U32 const llv = sequences[u].litLength;
  1770         U32 const llv = sequences[u].litLength;
  1456         U32 const mlv = sequences[u].matchLength;
  1771         U32 const mlv = sequences[u].matchLength;
  1457         llCodeTable[u] = (BYTE)ZSTD_LLcode(llv);
  1772         llCodeTable[u] = (BYTE)ZSTD_LLcode(llv);
  1458         ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
  1773         ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
  1462         llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
  1777         llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
  1463     if (seqStorePtr->longLengthID==2)
  1778     if (seqStorePtr->longLengthID==2)
  1464         mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
  1779         mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
  1465 }
  1780 }
  1466 
  1781 
       
  1782 
       
  1783 /**
       
  1784  * -log2(x / 256) lookup table for x in [0, 256).
       
  1785  * If x == 0: Return 0
       
  1786  * Else: Return floor(-log2(x / 256) * 256)
       
  1787  */
       
  1788 static unsigned const kInverseProbabiltyLog256[256] = {
       
  1789     0,    2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
       
  1790     1130, 1100, 1073, 1047, 1024, 1001, 980,  960,  941,  923,  906,  889,
       
  1791     874,  859,  844,  830,  817,  804,  791,  779,  768,  756,  745,  734,
       
  1792     724,  714,  704,  694,  685,  676,  667,  658,  650,  642,  633,  626,
       
  1793     618,  610,  603,  595,  588,  581,  574,  567,  561,  554,  548,  542,
       
  1794     535,  529,  523,  517,  512,  506,  500,  495,  489,  484,  478,  473,
       
  1795     468,  463,  458,  453,  448,  443,  438,  434,  429,  424,  420,  415,
       
  1796     411,  407,  402,  398,  394,  390,  386,  382,  377,  373,  370,  366,
       
  1797     362,  358,  354,  350,  347,  343,  339,  336,  332,  329,  325,  322,
       
  1798     318,  315,  311,  308,  305,  302,  298,  295,  292,  289,  286,  282,
       
  1799     279,  276,  273,  270,  267,  264,  261,  258,  256,  253,  250,  247,
       
  1800     244,  241,  239,  236,  233,  230,  228,  225,  222,  220,  217,  215,
       
  1801     212,  209,  207,  204,  202,  199,  197,  194,  192,  190,  187,  185,
       
  1802     182,  180,  178,  175,  173,  171,  168,  166,  164,  162,  159,  157,
       
  1803     155,  153,  151,  149,  146,  144,  142,  140,  138,  136,  134,  132,
       
  1804     130,  128,  126,  123,  121,  119,  117,  115,  114,  112,  110,  108,
       
  1805     106,  104,  102,  100,  98,   96,   94,   93,   91,   89,   87,   85,
       
  1806     83,   82,   80,   78,   76,   74,   73,   71,   69,   67,   66,   64,
       
  1807     62,   61,   59,   57,   55,   54,   52,   50,   49,   47,   46,   44,
       
  1808     42,   41,   39,   37,   36,   34,   33,   31,   30,   28,   26,   25,
       
  1809     23,   22,   20,   19,   17,   16,   14,   13,   11,   10,   8,    7,
       
  1810     5,    4,    2,    1,
       
  1811 };
       
  1812 
       
  1813 
       
  1814 /**
       
  1815  * Returns the cost in bits of encoding the distribution described by count
       
  1816  * using the entropy bound.
       
  1817  */
       
  1818 static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
       
  1819 {
       
  1820     unsigned cost = 0;
       
  1821     unsigned s;
       
  1822     for (s = 0; s <= max; ++s) {
       
  1823         unsigned norm = (unsigned)((256 * count[s]) / total);
       
  1824         if (count[s] != 0 && norm == 0)
       
  1825             norm = 1;
       
  1826         assert(count[s] < total);
       
  1827         cost += count[s] * kInverseProbabiltyLog256[norm];
       
  1828     }
       
  1829     return cost >> 8;
       
  1830 }
       
  1831 
       
  1832 
       
  1833 /**
       
  1834  * Returns the cost in bits of encoding the distribution in count using the
       
  1835  * table described by norm. The max symbol support by norm is assumed >= max.
       
  1836  * norm must be valid for every symbol with non-zero probability in count.
       
  1837  */
       
  1838 static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
       
  1839                                     unsigned const* count, unsigned const max)
       
  1840 {
       
  1841     unsigned const shift = 8 - accuracyLog;
       
  1842     size_t cost = 0;
       
  1843     unsigned s;
       
  1844     assert(accuracyLog <= 8);
       
  1845     for (s = 0; s <= max; ++s) {
       
  1846         unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
       
  1847         unsigned const norm256 = normAcc << shift;
       
  1848         assert(norm256 > 0);
       
  1849         assert(norm256 < 256);
       
  1850         cost += count[s] * kInverseProbabiltyLog256[norm256];
       
  1851     }
       
  1852     return cost >> 8;
       
  1853 }
       
  1854 
       
  1855 
       
  1856 static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
       
  1857   void const* ptr = ctable;
       
  1858   U16 const* u16ptr = (U16 const*)ptr;
       
  1859   U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
       
  1860   return maxSymbolValue;
       
  1861 }
       
  1862 
       
  1863 
       
  1864 /**
       
  1865  * Returns the cost in bits of encoding the distribution in count using ctable.
       
  1866  * Returns an error if ctable cannot represent all the symbols in count.
       
  1867  */
       
  1868 static size_t ZSTD_fseBitCost(
       
  1869     FSE_CTable const* ctable,
       
  1870     unsigned const* count,
       
  1871     unsigned const max)
       
  1872 {
       
  1873     unsigned const kAccuracyLog = 8;
       
  1874     size_t cost = 0;
       
  1875     unsigned s;
       
  1876     FSE_CState_t cstate;
       
  1877     FSE_initCState(&cstate, ctable);
       
  1878     if (ZSTD_getFSEMaxSymbolValue(ctable) < max) {
       
  1879         DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u",
       
  1880                     ZSTD_getFSEMaxSymbolValue(ctable), max);
       
  1881         return ERROR(GENERIC);
       
  1882     }
       
  1883     for (s = 0; s <= max; ++s) {
       
  1884         unsigned const tableLog = cstate.stateLog;
       
  1885         unsigned const badCost = (tableLog + 1) << kAccuracyLog;
       
  1886         unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
       
  1887         if (count[s] == 0)
       
  1888             continue;
       
  1889         if (bitCost >= badCost) {
       
  1890             DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s);
       
  1891             return ERROR(GENERIC);
       
  1892         }
       
  1893         cost += count[s] * bitCost;
       
  1894     }
       
  1895     return cost >> kAccuracyLog;
       
  1896 }
       
  1897 
       
  1898 /**
       
  1899  * Returns the cost in bytes of encoding the normalized count header.
       
  1900  * Returns an error if any of the helper functions return an error.
       
  1901  */
       
  1902 static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
       
  1903                               size_t const nbSeq, unsigned const FSELog)
       
  1904 {
       
  1905     BYTE wksp[FSE_NCOUNTBOUND];
       
  1906     S16 norm[MaxSeq + 1];
       
  1907     const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
       
  1908     CHECK_F(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
       
  1909     return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
       
  1910 }
       
  1911 
       
  1912 
  1467 typedef enum {
  1913 typedef enum {
  1468     ZSTD_defaultDisallowed = 0,
  1914     ZSTD_defaultDisallowed = 0,
  1469     ZSTD_defaultAllowed = 1
  1915     ZSTD_defaultAllowed = 1
  1470 } ZSTD_defaultPolicy_e;
  1916 } ZSTD_defaultPolicy_e;
  1471 
  1917 
  1472 MEM_STATIC
  1918 MEM_STATIC symbolEncodingType_e
  1473 symbolEncodingType_e ZSTD_selectEncodingType(
  1919 ZSTD_selectEncodingType(
  1474         FSE_repeat* repeatMode, size_t const mostFrequent, size_t nbSeq,
  1920         FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
  1475         U32 defaultNormLog, ZSTD_defaultPolicy_e const isDefaultAllowed)
  1921         size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
  1476 {
  1922         FSE_CTable const* prevCTable,
  1477 #define MIN_SEQ_FOR_DYNAMIC_FSE   64
  1923         short const* defaultNorm, U32 defaultNormLog,
  1478 #define MAX_SEQ_FOR_STATIC_FSE  1000
  1924         ZSTD_defaultPolicy_e const isDefaultAllowed,
       
  1925         ZSTD_strategy const strategy)
       
  1926 {
  1479     ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
  1927     ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
  1480     if ((mostFrequent == nbSeq) && (!isDefaultAllowed || nbSeq > 2)) {
  1928     if (mostFrequent == nbSeq) {
       
  1929         *repeatMode = FSE_repeat_none;
       
  1930         if (isDefaultAllowed && nbSeq <= 2) {
       
  1931             /* Prefer set_basic over set_rle when there are 2 or less symbols,
       
  1932              * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
       
  1933              * If basic encoding isn't possible, always choose RLE.
       
  1934              */
       
  1935             DEBUGLOG(5, "Selected set_basic");
       
  1936             return set_basic;
       
  1937         }
  1481         DEBUGLOG(5, "Selected set_rle");
  1938         DEBUGLOG(5, "Selected set_rle");
  1482         /* Prefer set_basic over set_rle when there are 2 or less symbols,
       
  1483          * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
       
  1484          * If basic encoding isn't possible, always choose RLE.
       
  1485          */
       
  1486         *repeatMode = FSE_repeat_check;
       
  1487         return set_rle;
  1939         return set_rle;
  1488     }
  1940     }
  1489     if ( isDefaultAllowed
  1941     if (strategy < ZSTD_lazy) {
  1490       && (*repeatMode == FSE_repeat_valid) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
  1942         if (isDefaultAllowed) {
  1491         DEBUGLOG(5, "Selected set_repeat");
  1943             size_t const staticFse_nbSeq_max = 1000;
  1492         return set_repeat;
  1944             size_t const mult = 10 - strategy;
  1493     }
  1945             size_t const baseLog = 3;
  1494     if ( isDefaultAllowed
  1946             size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog;  /* 28-36 for offset, 56-72 for lengths */
  1495       && ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (defaultNormLog-1)))) ) {
  1947             assert(defaultNormLog >= 5 && defaultNormLog <= 6);  /* xx_DEFAULTNORMLOG */
  1496         DEBUGLOG(5, "Selected set_basic");
  1948             assert(mult <= 9 && mult >= 7);
  1497         /* The format allows default tables to be repeated, but it isn't useful.
  1949             if ( (*repeatMode == FSE_repeat_valid)
  1498          * When using simple heuristics to select encoding type, we don't want
  1950               && (nbSeq < staticFse_nbSeq_max) ) {
  1499          * to confuse these tables with dictionaries. When running more careful
  1951                 DEBUGLOG(5, "Selected set_repeat");
  1500          * analysis, we don't need to waste time checking both repeating tables
  1952                 return set_repeat;
  1501          * and default tables.
  1953             }
  1502          */
  1954             if ( (nbSeq < dynamicFse_nbSeq_min)
  1503         *repeatMode = FSE_repeat_none;
  1955               || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
  1504         return set_basic;
  1956                 DEBUGLOG(5, "Selected set_basic");
       
  1957                 /* The format allows default tables to be repeated, but it isn't useful.
       
  1958                  * When using simple heuristics to select encoding type, we don't want
       
  1959                  * to confuse these tables with dictionaries. When running more careful
       
  1960                  * analysis, we don't need to waste time checking both repeating tables
       
  1961                  * and default tables.
       
  1962                  */
       
  1963                 *repeatMode = FSE_repeat_none;
       
  1964                 return set_basic;
       
  1965             }
       
  1966         }
       
  1967     } else {
       
  1968         size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
       
  1969         size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
       
  1970         size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
       
  1971         size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
       
  1972 
       
  1973         if (isDefaultAllowed) {
       
  1974             assert(!ZSTD_isError(basicCost));
       
  1975             assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
       
  1976         }
       
  1977         assert(!ZSTD_isError(NCountCost));
       
  1978         assert(compressedCost < ERROR(maxCode));
       
  1979         DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
       
  1980                     (U32)basicCost, (U32)repeatCost, (U32)compressedCost);
       
  1981         if (basicCost <= repeatCost && basicCost <= compressedCost) {
       
  1982             DEBUGLOG(5, "Selected set_basic");
       
  1983             assert(isDefaultAllowed);
       
  1984             *repeatMode = FSE_repeat_none;
       
  1985             return set_basic;
       
  1986         }
       
  1987         if (repeatCost <= compressedCost) {
       
  1988             DEBUGLOG(5, "Selected set_repeat");
       
  1989             assert(!ZSTD_isError(repeatCost));
       
  1990             return set_repeat;
       
  1991         }
       
  1992         assert(compressedCost < basicCost && compressedCost < repeatCost);
  1505     }
  1993     }
  1506     DEBUGLOG(5, "Selected set_compressed");
  1994     DEBUGLOG(5, "Selected set_compressed");
  1507     *repeatMode = FSE_repeat_check;
  1995     *repeatMode = FSE_repeat_check;
  1508     return set_compressed;
  1996     return set_compressed;
  1509 }
  1997 }
  1510 
  1998 
  1511 MEM_STATIC
  1999 MEM_STATIC size_t
  1512 size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
  2000 ZSTD_buildCTable(void* dst, size_t dstCapacity,
  1513         FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
  2001                 FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
  1514         U32* count, U32 max,
  2002                 U32* count, U32 max,
  1515         BYTE const* codeTable, size_t nbSeq,
  2003                 const BYTE* codeTable, size_t nbSeq,
  1516         S16 const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
  2004                 const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
  1517         FSE_CTable const* prevCTable, size_t prevCTableSize,
  2005                 const FSE_CTable* prevCTable, size_t prevCTableSize,
  1518         void* workspace, size_t workspaceSize)
  2006                 void* workspace, size_t workspaceSize)
  1519 {
  2007 {
  1520     BYTE* op = (BYTE*)dst;
  2008     BYTE* op = (BYTE*)dst;
  1521     BYTE const* const oend = op + dstCapacity;
  2009     const BYTE* const oend = op + dstCapacity;
  1522 
  2010 
  1523     switch (type) {
  2011     switch (type) {
  1524     case set_rle:
  2012     case set_rle:
  1525         *op = codeTable[0];
  2013         *op = codeTable[0];
  1526         CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max));
  2014         CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max));
  1672                                     sequences, nbSeq, longOffsets);
  2160                                     sequences, nbSeq, longOffsets);
  1673 }
  2161 }
  1674 
  2162 
  1675 #endif
  2163 #endif
  1676 
  2164 
  1677 size_t ZSTD_encodeSequences(
  2165 static size_t ZSTD_encodeSequences(
  1678             void* dst, size_t dstCapacity,
  2166             void* dst, size_t dstCapacity,
  1679             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
  2167             FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
  1680             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
  2168             FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
  1681             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
  2169             FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
  1682             seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
  2170             seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
  1704                               ZSTD_CCtx_params const* cctxParams,
  2192                               ZSTD_CCtx_params const* cctxParams,
  1705                               void* dst, size_t dstCapacity, U32* workspace,
  2193                               void* dst, size_t dstCapacity, U32* workspace,
  1706                               const int bmi2)
  2194                               const int bmi2)
  1707 {
  2195 {
  1708     const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
  2196     const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
       
  2197     ZSTD_strategy const strategy = cctxParams->cParams.strategy;
  1709     U32 count[MaxSeq+1];
  2198     U32 count[MaxSeq+1];
  1710     FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
  2199     FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
  1711     FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
  2200     FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
  1712     FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
  2201     FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
  1713     U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
  2202     U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
  1714     const seqDef* const sequences = seqStorePtr->sequencesStart;
  2203     const seqDef* const sequences = seqStorePtr->sequencesStart;
  1715     const BYTE* const ofCodeTable = seqStorePtr->ofCode;
  2204     const BYTE* const ofCodeTable = seqStorePtr->ofCode;
  1716     const BYTE* const llCodeTable = seqStorePtr->llCode;
  2205     const BYTE* const llCodeTable = seqStorePtr->llCode;
  1717     const BYTE* const mlCodeTable = seqStorePtr->mlCode;
  2206     const BYTE* const mlCodeTable = seqStorePtr->mlCode;
  1718     BYTE* const ostart = (BYTE*)dst;
  2207     BYTE* const ostart = (BYTE*)dst;
  1719     BYTE* const oend = ostart + dstCapacity;
  2208     BYTE* const oend = ostart + dstCapacity;
  1720     BYTE* op = ostart;
  2209     BYTE* op = ostart;
  1721     size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
  2210     size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
  1722     BYTE* seqHead;
  2211     BYTE* seqHead;
       
  2212     BYTE* lastNCount = NULL;
  1723 
  2213 
  1724     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
  2214     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
  1725 
  2215 
  1726     /* Compress literals */
  2216     /* Compress literals */
  1727     {   const BYTE* const literals = seqStorePtr->litStart;
  2217     {   const BYTE* const literals = seqStorePtr->litStart;
  1728         size_t const litSize = seqStorePtr->lit - literals;
  2218         size_t const litSize = seqStorePtr->lit - literals;
       
  2219         int const disableLiteralCompression = (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
  1729         size_t const cSize = ZSTD_compressLiterals(
  2220         size_t const cSize = ZSTD_compressLiterals(
  1730                                     prevEntropy, nextEntropy,
  2221                                     &prevEntropy->huf, &nextEntropy->huf,
  1731                                     cctxParams->cParams.strategy, cctxParams->disableLiteralCompression,
  2222                                     cctxParams->cParams.strategy, disableLiteralCompression,
  1732                                     op, dstCapacity,
  2223                                     op, dstCapacity,
  1733                                     literals, litSize,
  2224                                     literals, litSize,
  1734                                     workspace, bmi2);
  2225                                     workspace, bmi2);
  1735         if (ZSTD_isError(cSize))
  2226         if (ZSTD_isError(cSize))
  1736           return cSize;
  2227           return cSize;
  1745     else if (nbSeq < LONGNBSEQ)
  2236     else if (nbSeq < LONGNBSEQ)
  1746         op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
  2237         op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
  1747     else
  2238     else
  1748         op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
  2239         op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
  1749     if (nbSeq==0) {
  2240     if (nbSeq==0) {
  1750       memcpy(nextEntropy->litlengthCTable, prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable));
  2241         /* Copy the old tables over as if we repeated them */
  1751       nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
  2242         memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
  1752       memcpy(nextEntropy->offcodeCTable, prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable));
  2243         return op - ostart;
  1753       nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
       
  1754       memcpy(nextEntropy->matchlengthCTable, prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable));
       
  1755       nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
       
  1756       return op - ostart;
       
  1757     }
  2244     }
  1758 
  2245 
  1759     /* seqHead : flags for FSE encoding type */
  2246     /* seqHead : flags for FSE encoding type */
  1760     seqHead = op++;
  2247     seqHead = op++;
  1761 
  2248 
  1762     /* convert length/distances into codes */
  2249     /* convert length/distances into codes */
  1763     ZSTD_seqToCodes(seqStorePtr);
  2250     ZSTD_seqToCodes(seqStorePtr);
  1764     /* build CTable for Literal Lengths */
  2251     /* build CTable for Literal Lengths */
  1765     {   U32 max = MaxLL;
  2252     {   U32 max = MaxLL;
  1766         size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace);
  2253         size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace);   /* can't fail */
  1767         DEBUGLOG(5, "Building LL table");
  2254         DEBUGLOG(5, "Building LL table");
  1768         nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
  2255         nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
  1769         LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, mostFrequent, nbSeq, LL_defaultNormLog, ZSTD_defaultAllowed);
  2256         LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode, count, max, mostFrequent, nbSeq, LLFSELog, prevEntropy->fse.litlengthCTable, LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultAllowed, strategy);
       
  2257         assert(set_basic < set_compressed && set_rle < set_compressed);
       
  2258         assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  1770         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
  2259         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
  1771                     count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
  2260                                                     count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
  1772                     prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable),
  2261                                                     prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
  1773                     workspace, HUF_WORKSPACE_SIZE);
  2262                                                     workspace, HUF_WORKSPACE_SIZE);
  1774             if (ZSTD_isError(countSize)) return countSize;
  2263             if (ZSTD_isError(countSize)) return countSize;
       
  2264             if (LLtype == set_compressed)
       
  2265                 lastNCount = op;
  1775             op += countSize;
  2266             op += countSize;
  1776     }   }
  2267     }   }
  1777     /* build CTable for Offsets */
  2268     /* build CTable for Offsets */
  1778     {   U32 max = MaxOff;
  2269     {   U32 max = MaxOff;
  1779         size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace);
  2270         size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace);  /* can't fail */
  1780         /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
  2271         /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
  1781         ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
  2272         ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
  1782         DEBUGLOG(5, "Building OF table");
  2273         DEBUGLOG(5, "Building OF table");
  1783         nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
  2274         nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode;
  1784         Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, mostFrequent, nbSeq, OF_defaultNormLog, defaultPolicy);
  2275         Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode, count, max, mostFrequent, nbSeq, OffFSELog, prevEntropy->fse.offcodeCTable, OF_defaultNorm, OF_defaultNormLog, defaultPolicy, strategy);
       
  2276         assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  1785         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
  2277         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
  1786                     count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  2278                                                     count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  1787                     prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable),
  2279                                                     prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
  1788                     workspace, HUF_WORKSPACE_SIZE);
  2280                                                     workspace, HUF_WORKSPACE_SIZE);
  1789             if (ZSTD_isError(countSize)) return countSize;
  2281             if (ZSTD_isError(countSize)) return countSize;
       
  2282             if (Offtype == set_compressed)
       
  2283                 lastNCount = op;
  1790             op += countSize;
  2284             op += countSize;
  1791     }   }
  2285     }   }
  1792     /* build CTable for MatchLengths */
  2286     /* build CTable for MatchLengths */
  1793     {   U32 max = MaxML;
  2287     {   U32 max = MaxML;
  1794         size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace);
  2288         size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace);   /* can't fail */
  1795         DEBUGLOG(5, "Building ML table");
  2289         DEBUGLOG(5, "Building ML table");
  1796         nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
  2290         nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
  1797         MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, mostFrequent, nbSeq, ML_defaultNormLog, ZSTD_defaultAllowed);
  2291         MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode, count, max, mostFrequent, nbSeq, MLFSELog, prevEntropy->fse.matchlengthCTable, ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultAllowed, strategy);
       
  2292         assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  1798         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
  2293         {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
  1799                     count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
  2294                                                     count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
  1800                     prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable),
  2295                                                     prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
  1801                     workspace, HUF_WORKSPACE_SIZE);
  2296                                                     workspace, HUF_WORKSPACE_SIZE);
  1802             if (ZSTD_isError(countSize)) return countSize;
  2297             if (ZSTD_isError(countSize)) return countSize;
       
  2298             if (MLtype == set_compressed)
       
  2299                 lastNCount = op;
  1803             op += countSize;
  2300             op += countSize;
  1804     }   }
  2301     }   }
  1805 
  2302 
  1806     *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
  2303     *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
  1807 
  2304 
  1812                                         CTable_LitLength, llCodeTable,
  2309                                         CTable_LitLength, llCodeTable,
  1813                                         sequences, nbSeq,
  2310                                         sequences, nbSeq,
  1814                                         longOffsets, bmi2);
  2311                                         longOffsets, bmi2);
  1815         if (ZSTD_isError(bitstreamSize)) return bitstreamSize;
  2312         if (ZSTD_isError(bitstreamSize)) return bitstreamSize;
  1816         op += bitstreamSize;
  2313         op += bitstreamSize;
       
  2314         /* zstd versions <= 1.3.4 mistakenly report corruption when
       
  2315          * FSE_readNCount() recieves a buffer < 4 bytes.
       
  2316          * Fixed by https://github.com/facebook/zstd/pull/1146.
       
  2317          * This can happen when the last set_compressed table present is 2
       
  2318          * bytes and the bitstream is only one byte.
       
  2319          * In this exceedingly rare case, we will simply emit an uncompressed
       
  2320          * block, since it isn't worth optimizing.
       
  2321          */
       
  2322         if (lastNCount && (op - lastNCount) < 4) {
       
  2323             /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
       
  2324             assert(op - lastNCount == 3);
       
  2325             DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
       
  2326                         "emitting an uncompressed block.");
       
  2327             return 0;
       
  2328         }
  1817     }
  2329     }
  1818 
  2330 
  1819     return op - ostart;
  2331     return op - ostart;
  1820 }
  2332 }
  1821 
  2333 
  1822 MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
  2334 MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
  1823                               ZSTD_entropyCTables_t const* prevEntropy,
  2335                         const ZSTD_entropyCTables_t* prevEntropy,
  1824                               ZSTD_entropyCTables_t* nextEntropy,
  2336                               ZSTD_entropyCTables_t* nextEntropy,
  1825                               ZSTD_CCtx_params const* cctxParams,
  2337                         const ZSTD_CCtx_params* cctxParams,
  1826                               void* dst, size_t dstCapacity,
  2338                               void* dst, size_t dstCapacity,
  1827                               size_t srcSize, U32* workspace, int bmi2)
  2339                               size_t srcSize, U32* workspace, int bmi2)
  1828 {
  2340 {
  1829     size_t const cSize = ZSTD_compressSequences_internal(
  2341     size_t const cSize = ZSTD_compressSequences_internal(
  1830             seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity,
  2342             seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity,
  1831             workspace, bmi2);
  2343             workspace, bmi2);
       
  2344     if (cSize == 0) return 0;
  1832     /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
  2345     /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
  1833      * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
  2346      * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
  1834      */
  2347      */
  1835     if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
  2348     if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
  1836         return 0;  /* block not compressed */
  2349         return 0;  /* block not compressed */
  1837     if (ZSTD_isError(cSize)) return cSize;
  2350     if (ZSTD_isError(cSize)) return cSize;
  1838 
  2351 
  1839     /* Check compressibility */
  2352     /* Check compressibility */
  1840     {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize);  /* note : fixed formula, maybe should depend on compression level, or strategy */
  2353     {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
  1841         if (cSize >= maxCSize) return 0;  /* block not compressed */
  2354         if (cSize >= maxCSize) return 0;  /* block not compressed */
  1842     }
  2355     }
  1843 
       
  1844     /* We check that dictionaries have offset codes available for the first
       
  1845      * block. After the first block, the offcode table might not have large
       
  1846      * enough codes to represent the offsets in the data.
       
  1847      */
       
  1848     if (nextEntropy->offcode_repeatMode == FSE_repeat_valid)
       
  1849         nextEntropy->offcode_repeatMode = FSE_repeat_check;
       
  1850 
  2356 
  1851     return cSize;
  2357     return cSize;
  1852 }
  2358 }
  1853 
  2359 
  1854 /* ZSTD_selectBlockCompressor() :
  2360 /* ZSTD_selectBlockCompressor() :
  1855  * Not static, but internal use only (used by long distance matcher)
  2361  * Not static, but internal use only (used by long distance matcher)
  1856  * assumption : strat is a valid strategy */
  2362  * assumption : strat is a valid strategy */
  1857 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
  2363 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
  1858 {
  2364 {
  1859     static const ZSTD_blockCompressor blockCompressor[2][(unsigned)ZSTD_btultra+1] = {
  2365     static const ZSTD_blockCompressor blockCompressor[3][(unsigned)ZSTD_btultra+1] = {
  1860         { ZSTD_compressBlock_fast  /* default for 0 */,
  2366         { ZSTD_compressBlock_fast  /* default for 0 */,
  1861           ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy,
  2367           ZSTD_compressBlock_fast,
  1862           ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2,
  2368           ZSTD_compressBlock_doubleFast,
  1863           ZSTD_compressBlock_btopt, ZSTD_compressBlock_btultra },
  2369           ZSTD_compressBlock_greedy,
       
  2370           ZSTD_compressBlock_lazy,
       
  2371           ZSTD_compressBlock_lazy2,
       
  2372           ZSTD_compressBlock_btlazy2,
       
  2373           ZSTD_compressBlock_btopt,
       
  2374           ZSTD_compressBlock_btultra },
  1864         { ZSTD_compressBlock_fast_extDict  /* default for 0 */,
  2375         { ZSTD_compressBlock_fast_extDict  /* default for 0 */,
  1865           ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict,
  2376           ZSTD_compressBlock_fast_extDict,
  1866           ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict,
  2377           ZSTD_compressBlock_doubleFast_extDict,
  1867           ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btultra_extDict }
  2378           ZSTD_compressBlock_greedy_extDict,
       
  2379           ZSTD_compressBlock_lazy_extDict,
       
  2380           ZSTD_compressBlock_lazy2_extDict,
       
  2381           ZSTD_compressBlock_btlazy2_extDict,
       
  2382           ZSTD_compressBlock_btopt_extDict,
       
  2383           ZSTD_compressBlock_btultra_extDict },
       
  2384         { ZSTD_compressBlock_fast_dictMatchState  /* default for 0 */,
       
  2385           ZSTD_compressBlock_fast_dictMatchState,
       
  2386           ZSTD_compressBlock_doubleFast_dictMatchState,
       
  2387           ZSTD_compressBlock_greedy_dictMatchState,
       
  2388           ZSTD_compressBlock_lazy_dictMatchState,
       
  2389           ZSTD_compressBlock_lazy2_dictMatchState,
       
  2390           ZSTD_compressBlock_btlazy2_dictMatchState,
       
  2391           ZSTD_compressBlock_btopt_dictMatchState,
       
  2392           ZSTD_compressBlock_btultra_dictMatchState }
  1868     };
  2393     };
       
  2394     ZSTD_blockCompressor selectedCompressor;
  1869     ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
  2395     ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
  1870 
  2396 
  1871     assert((U32)strat >= (U32)ZSTD_fast);
  2397     assert((U32)strat >= (U32)ZSTD_fast);
  1872     assert((U32)strat <= (U32)ZSTD_btultra);
  2398     assert((U32)strat <= (U32)ZSTD_btultra);
  1873     return blockCompressor[extDict!=0][(U32)strat];
  2399     selectedCompressor = blockCompressor[(int)dictMode][(U32)strat];
       
  2400     assert(selectedCompressor != NULL);
       
  2401     return selectedCompressor;
  1874 }
  2402 }
  1875 
  2403 
  1876 static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
  2404 static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
  1877                                    const BYTE* anchor, size_t lastLLSize)
  2405                                    const BYTE* anchor, size_t lastLLSize)
  1878 {
  2406 {
  1879     memcpy(seqStorePtr->lit, anchor, lastLLSize);
  2407     memcpy(seqStorePtr->lit, anchor, lastLLSize);
  1880     seqStorePtr->lit += lastLLSize;
  2408     seqStorePtr->lit += lastLLSize;
  1881 }
  2409 }
  1882 
  2410 
  1883 static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
  2411 void ZSTD_resetSeqStore(seqStore_t* ssPtr)
  1884 {
  2412 {
  1885     ssPtr->lit = ssPtr->litStart;
  2413     ssPtr->lit = ssPtr->litStart;
  1886     ssPtr->sequences = ssPtr->sequencesStart;
  2414     ssPtr->sequences = ssPtr->sequencesStart;
  1887     ssPtr->longLengthID = 0;
  2415     ssPtr->longLengthID = 0;
  1888 }
  2416 }
  1890 static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
  2418 static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
  1891                                         void* dst, size_t dstCapacity,
  2419                                         void* dst, size_t dstCapacity,
  1892                                         const void* src, size_t srcSize)
  2420                                         const void* src, size_t srcSize)
  1893 {
  2421 {
  1894     ZSTD_matchState_t* const ms = &zc->blockState.matchState;
  2422     ZSTD_matchState_t* const ms = &zc->blockState.matchState;
  1895     DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
  2423     size_t cSize;
  1896                 (U32)dstCapacity, ms->window.dictLimit, ms->nextToUpdate);
  2424     DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%zu, dictLimit=%u, nextToUpdate=%u)",
       
  2425                 dstCapacity, ms->window.dictLimit, ms->nextToUpdate);
       
  2426     assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
       
  2427 
       
  2428     /* Assert that we have correctly flushed the ctx params into the ms's copy */
       
  2429     ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
       
  2430 
  1897     if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
  2431     if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
  1898         ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength);
  2432         ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength);
  1899         return 0;   /* don't even attempt compression below a certain srcSize */
  2433         cSize = 0;
       
  2434         goto out;  /* don't even attempt compression below a certain srcSize */
  1900     }
  2435     }
  1901     ZSTD_resetSeqStore(&(zc->seqStore));
  2436     ZSTD_resetSeqStore(&(zc->seqStore));
       
  2437     ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;   /* required for optimal parser to read stats from dictionary */
       
  2438 
       
  2439     /* a gap between an attached dict and the current window is not safe,
       
  2440      * they must remain adjacent, and when that stops being the case, the dict
       
  2441      * must be unset */
       
  2442     assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
  1902 
  2443 
  1903     /* limited update after a very long match */
  2444     /* limited update after a very long match */
  1904     {   const BYTE* const base = ms->window.base;
  2445     {   const BYTE* const base = ms->window.base;
  1905         const BYTE* const istart = (const BYTE*)src;
  2446         const BYTE* const istart = (const BYTE*)src;
  1906         const U32 current = (U32)(istart-base);
  2447         const U32 current = (U32)(istart-base);
       
  2448         if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1));   /* ensure no overflow */
  1907         if (current > ms->nextToUpdate + 384)
  2449         if (current > ms->nextToUpdate + 384)
  1908             ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384));
  2450             ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384));
  1909     }
  2451     }
  1910 
  2452 
  1911     /* select and store sequences */
  2453     /* select and store sequences */
  1912     {   U32 const extDict = ZSTD_window_hasExtDict(ms->window);
  2454     {   ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms);
  1913         size_t lastLLSize;
  2455         size_t lastLLSize;
  1914         {   int i;
  2456         {   int i;
  1915             for (i = 0; i < ZSTD_REP_NUM; ++i)
  2457             for (i = 0; i < ZSTD_REP_NUM; ++i)
  1916                 zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i];
  2458                 zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i];
  1917         }
  2459         }
  1920             /* Updates ldmSeqStore.pos */
  2462             /* Updates ldmSeqStore.pos */
  1921             lastLLSize =
  2463             lastLLSize =
  1922                 ZSTD_ldm_blockCompress(&zc->externSeqStore,
  2464                 ZSTD_ldm_blockCompress(&zc->externSeqStore,
  1923                                        ms, &zc->seqStore,
  2465                                        ms, &zc->seqStore,
  1924                                        zc->blockState.nextCBlock->rep,
  2466                                        zc->blockState.nextCBlock->rep,
  1925                                        &zc->appliedParams.cParams,
  2467                                        src, srcSize);
  1926                                        src, srcSize, extDict);
       
  1927             assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
  2468             assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
  1928         } else if (zc->appliedParams.ldmParams.enableLdm) {
  2469         } else if (zc->appliedParams.ldmParams.enableLdm) {
  1929             rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
  2470             rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
  1930 
  2471 
  1931             ldmSeqStore.seq = zc->ldmSequences;
  2472             ldmSeqStore.seq = zc->ldmSequences;
  1937             /* Updates ldmSeqStore.pos */
  2478             /* Updates ldmSeqStore.pos */
  1938             lastLLSize =
  2479             lastLLSize =
  1939                 ZSTD_ldm_blockCompress(&ldmSeqStore,
  2480                 ZSTD_ldm_blockCompress(&ldmSeqStore,
  1940                                        ms, &zc->seqStore,
  2481                                        ms, &zc->seqStore,
  1941                                        zc->blockState.nextCBlock->rep,
  2482                                        zc->blockState.nextCBlock->rep,
  1942                                        &zc->appliedParams.cParams,
  2483                                        src, srcSize);
  1943                                        src, srcSize, extDict);
       
  1944             assert(ldmSeqStore.pos == ldmSeqStore.size);
  2484             assert(ldmSeqStore.pos == ldmSeqStore.size);
  1945         } else {   /* not long range mode */
  2485         } else {   /* not long range mode */
  1946             ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, extDict);
  2486             ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);
  1947             lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, &zc->appliedParams.cParams, src, srcSize);
  2487             lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
  1948         }
  2488         }
  1949         {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
  2489         {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
  1950             ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
  2490             ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
  1951     }   }
  2491     }   }
  1952 
  2492 
  1953     /* encode sequences and literals */
  2493     /* encode sequences and literals */
  1954     {   size_t const cSize = ZSTD_compressSequences(&zc->seqStore,
  2494     cSize = ZSTD_compressSequences(&zc->seqStore,
  1955                                 &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
  2495             &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
  1956                                 &zc->appliedParams,
  2496             &zc->appliedParams,
  1957                                 dst, dstCapacity,
  2497             dst, dstCapacity,
  1958                                 srcSize, zc->entropyWorkspace, zc->bmi2);
  2498             srcSize, zc->entropyWorkspace, zc->bmi2);
  1959         if (ZSTD_isError(cSize) || cSize == 0) return cSize;
  2499 
  1960         /* confirm repcodes and entropy tables */
  2500 out:
  1961         {   ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
  2501     if (!ZSTD_isError(cSize) && cSize != 0) {
  1962             zc->blockState.prevCBlock = zc->blockState.nextCBlock;
  2502         /* confirm repcodes and entropy tables when emitting a compressed block */
  1963             zc->blockState.nextCBlock = tmp;
  2503         ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
  1964         }
  2504         zc->blockState.prevCBlock = zc->blockState.nextCBlock;
  1965         return cSize;
  2505         zc->blockState.nextCBlock = tmp;
  1966     }
  2506     }
       
  2507     /* We check that dictionaries have offset codes available for the first
       
  2508      * block. After the first block, the offcode table might not have large
       
  2509      * enough codes to represent the offsets in the data.
       
  2510      */
       
  2511     if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
       
  2512         zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
       
  2513 
       
  2514     return cSize;
  1967 }
  2515 }
  1968 
  2516 
  1969 
  2517 
  1970 /*! ZSTD_compress_frameChunk() :
  2518 /*! ZSTD_compress_frameChunk() :
  1971 *   Compress a chunk of data into one or multiple blocks.
  2519 *   Compress a chunk of data into one or multiple blocks.
  2003             U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
  2551             U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
  2004             U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
  2552             U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
  2005             ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
  2553             ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
  2006             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
  2554             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
  2007             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
  2555             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
  2008 
       
  2009             ZSTD_reduceIndex(cctx, correction);
  2556             ZSTD_reduceIndex(cctx, correction);
  2010             if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
  2557             if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
  2011             else ms->nextToUpdate -= correction;
  2558             else ms->nextToUpdate -= correction;
  2012             ms->loadedDictEnd = 0;
  2559             ms->loadedDictEnd = 0;
       
  2560             ms->dictMatchState = NULL;
  2013         }
  2561         }
  2014         ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd);
  2562         ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
  2015         if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
  2563         if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
  2016 
  2564 
  2017         {   size_t cSize = ZSTD_compressBlock_internal(cctx,
  2565         {   size_t cSize = ZSTD_compressBlock_internal(cctx,
  2018                                 op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
  2566                                 op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
  2019                                 ip, blockSize);
  2567                                 ip, blockSize);
  2020             if (ZSTD_isError(cSize)) return cSize;
  2568             if (ZSTD_isError(cSize)) return cSize;
  2021 
  2569 
  2022             if (cSize == 0) {  /* block is not compressible */
  2570             if (cSize == 0) {  /* block is not compressible */
  2023                 U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
  2571                 cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
  2024                 if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
  2572                 if (ZSTD_isError(cSize)) return cSize;
  2025                 MEM_writeLE32(op, cBlockHeader24);   /* 4th byte will be overwritten */
       
  2026                 memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
       
  2027                 cSize = ZSTD_blockHeaderSize + blockSize;
       
  2028             } else {
  2573             } else {
  2029                 U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
  2574                 U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
  2030                 MEM_writeLE24(op, cBlockHeader24);
  2575                 MEM_writeLE24(op, cBlockHeader24);
  2031                 cSize += ZSTD_blockHeaderSize;
  2576                 cSize += ZSTD_blockHeaderSize;
  2032             }
  2577             }
  2058     U32   const fcsCode = params.fParams.contentSizeFlag ?
  2603     U32   const fcsCode = params.fParams.contentSizeFlag ?
  2059                      (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */
  2604                      (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */
  2060     BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
  2605     BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
  2061     size_t pos=0;
  2606     size_t pos=0;
  2062 
  2607 
       
  2608     assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
  2063     if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
  2609     if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
  2064     DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
  2610     DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
  2065                 !params.fParams.noDictIDFlag, dictID,  dictIDSizeCode);
  2611                 !params.fParams.noDictIDFlag, dictID,  dictIDSizeCode);
  2066 
  2612 
  2067     if (params.format == ZSTD_f_zstd1) {
  2613     if (params.format == ZSTD_f_zstd1) {
  2120 static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
  2666 static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
  2121                               void* dst, size_t dstCapacity,
  2667                               void* dst, size_t dstCapacity,
  2122                         const void* src, size_t srcSize,
  2668                         const void* src, size_t srcSize,
  2123                                U32 frame, U32 lastFrameChunk)
  2669                                U32 frame, U32 lastFrameChunk)
  2124 {
  2670 {
  2125     ZSTD_matchState_t* ms = &cctx->blockState.matchState;
  2671     ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
  2126     size_t fhSize = 0;
  2672     size_t fhSize = 0;
  2127 
  2673 
  2128     DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
  2674     DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
  2129                 cctx->stage, (U32)srcSize);
  2675                 cctx->stage, (U32)srcSize);
  2130     if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
  2676     if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
  2141     if (!srcSize) return fhSize;  /* do not generate an empty block if no input */
  2687     if (!srcSize) return fhSize;  /* do not generate an empty block if no input */
  2142 
  2688 
  2143     if (!ZSTD_window_update(&ms->window, src, srcSize)) {
  2689     if (!ZSTD_window_update(&ms->window, src, srcSize)) {
  2144         ms->nextToUpdate = ms->window.dictLimit;
  2690         ms->nextToUpdate = ms->window.dictLimit;
  2145     }
  2691     }
  2146     if (cctx->appliedParams.ldmParams.enableLdm)
  2692     if (cctx->appliedParams.ldmParams.enableLdm) {
  2147         ZSTD_window_update(&cctx->ldmState.window, src, srcSize);
  2693         ZSTD_window_update(&cctx->ldmState.window, src, srcSize);
       
  2694     }
       
  2695 
       
  2696     if (!frame) {
       
  2697         /* overflow check and correction for block mode */
       
  2698         if (ZSTD_window_needOverflowCorrection(ms->window, (const char*)src + srcSize)) {
       
  2699             U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
       
  2700             U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, 1 << cctx->appliedParams.cParams.windowLog, src);
       
  2701             ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
       
  2702             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
       
  2703             ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
       
  2704             ZSTD_reduceIndex(cctx, correction);
       
  2705             if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
       
  2706             else ms->nextToUpdate -= correction;
       
  2707             ms->loadedDictEnd = 0;
       
  2708             ms->dictMatchState = NULL;
       
  2709         }
       
  2710     }
  2148 
  2711 
  2149     DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize);
  2712     DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize);
  2150     {   size_t const cSize = frame ?
  2713     {   size_t const cSize = frame ?
  2151                              ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
  2714                              ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
  2152                              ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
  2715                              ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
  2153         if (ZSTD_isError(cSize)) return cSize;
  2716         if (ZSTD_isError(cSize)) return cSize;
  2154         cctx->consumedSrcSize += srcSize;
  2717         cctx->consumedSrcSize += srcSize;
  2155         cctx->producedCSize += (cSize + fhSize);
  2718         cctx->producedCSize += (cSize + fhSize);
  2156         if (cctx->appliedParams.fParams.contentSizeFlag) {  /* control src size */
  2719         assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
       
  2720         if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
       
  2721             ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  2157             if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
  2722             if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
  2158                 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
  2723                 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
  2159                     (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
  2724                     (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
  2160                 return ERROR(srcSize_wrong);
  2725                 return ERROR(srcSize_wrong);
  2161             }
  2726             }
  2182 
  2747 
  2183 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
  2748 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
  2184 {
  2749 {
  2185     size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
  2750     size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
  2186     if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
  2751     if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
       
  2752 
  2187     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
  2753     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
  2188 }
  2754 }
  2189 
  2755 
  2190 /*! ZSTD_loadDictionaryContent() :
  2756 /*! ZSTD_loadDictionaryContent() :
  2191  *  @return : 0, or an error code
  2757  *  @return : 0, or an error code
  2192  */
  2758  */
  2193 static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const void* src, size_t srcSize)
  2759 static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
       
  2760                                          ZSTD_CCtx_params const* params,
       
  2761                                          const void* src, size_t srcSize,
       
  2762                                          ZSTD_dictTableLoadMethod_e dtlm)
  2194 {
  2763 {
  2195     const BYTE* const ip = (const BYTE*) src;
  2764     const BYTE* const ip = (const BYTE*) src;
  2196     const BYTE* const iend = ip + srcSize;
  2765     const BYTE* const iend = ip + srcSize;
  2197     ZSTD_compressionParameters const* cParams = &params->cParams;
       
  2198 
  2766 
  2199     ZSTD_window_update(&ms->window, src, srcSize);
  2767     ZSTD_window_update(&ms->window, src, srcSize);
  2200     ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
  2768     ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
       
  2769 
       
  2770     /* Assert that we the ms params match the params we're being given */
       
  2771     ZSTD_assertEqualCParams(params->cParams, ms->cParams);
  2201 
  2772 
  2202     if (srcSize <= HASH_READ_SIZE) return 0;
  2773     if (srcSize <= HASH_READ_SIZE) return 0;
  2203 
  2774 
  2204     switch(params->cParams.strategy)
  2775     switch(params->cParams.strategy)
  2205     {
  2776     {
  2206     case ZSTD_fast:
  2777     case ZSTD_fast:
  2207         ZSTD_fillHashTable(ms, cParams, iend);
  2778         ZSTD_fillHashTable(ms, iend, dtlm);
  2208         break;
  2779         break;
  2209     case ZSTD_dfast:
  2780     case ZSTD_dfast:
  2210         ZSTD_fillDoubleHashTable(ms, cParams, iend);
  2781         ZSTD_fillDoubleHashTable(ms, iend, dtlm);
  2211         break;
  2782         break;
  2212 
  2783 
  2213     case ZSTD_greedy:
  2784     case ZSTD_greedy:
  2214     case ZSTD_lazy:
  2785     case ZSTD_lazy:
  2215     case ZSTD_lazy2:
  2786     case ZSTD_lazy2:
  2216         if (srcSize >= HASH_READ_SIZE)
  2787         if (srcSize >= HASH_READ_SIZE)
  2217             ZSTD_insertAndFindFirstIndex(ms, cParams, iend-HASH_READ_SIZE);
  2788             ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE);
  2218         break;
  2789         break;
  2219 
  2790 
  2220     case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */
  2791     case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */
  2221     case ZSTD_btopt:
  2792     case ZSTD_btopt:
  2222     case ZSTD_btultra:
  2793     case ZSTD_btultra:
  2223         if (srcSize >= HASH_READ_SIZE)
  2794         if (srcSize >= HASH_READ_SIZE)
  2224             ZSTD_updateTree(ms, cParams, iend-HASH_READ_SIZE, iend);
  2795             ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
  2225         break;
  2796         break;
  2226 
  2797 
  2227     default:
  2798     default:
  2228         assert(0);  /* not possible : not a valid strategy id */
  2799         assert(0);  /* not possible : not a valid strategy id */
  2229     }
  2800     }
  2254 /*! ZSTD_loadZstdDictionary() :
  2825 /*! ZSTD_loadZstdDictionary() :
  2255  * @return : dictID, or an error code
  2826  * @return : dictID, or an error code
  2256  *  assumptions : magic number supposed already checked
  2827  *  assumptions : magic number supposed already checked
  2257  *                dictSize supposed > 8
  2828  *                dictSize supposed > 8
  2258  */
  2829  */
  2259 static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const void* dict, size_t dictSize, void* workspace)
  2830 static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
       
  2831                                       ZSTD_matchState_t* ms,
       
  2832                                       ZSTD_CCtx_params const* params,
       
  2833                                       const void* dict, size_t dictSize,
       
  2834                                       ZSTD_dictTableLoadMethod_e dtlm,
       
  2835                                       void* workspace)
  2260 {
  2836 {
  2261     const BYTE* dictPtr = (const BYTE*)dict;
  2837     const BYTE* dictPtr = (const BYTE*)dict;
  2262     const BYTE* const dictEnd = dictPtr + dictSize;
  2838     const BYTE* const dictEnd = dictPtr + dictSize;
  2263     short offcodeNCount[MaxOff+1];
  2839     short offcodeNCount[MaxOff+1];
  2264     unsigned offcodeMaxValue = MaxOff;
  2840     unsigned offcodeMaxValue = MaxOff;
  2265     size_t dictID;
  2841     size_t dictID;
  2266 
  2842 
  2267     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
  2843     ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
       
  2844     assert(dictSize > 8);
       
  2845     assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
  2268 
  2846 
  2269     dictPtr += 4;   /* skip magic number */
  2847     dictPtr += 4;   /* skip magic number */
  2270     dictID = params->fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
  2848     dictID = params->fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
  2271     dictPtr += 4;
  2849     dictPtr += 4;
  2272 
  2850 
  2273     {   unsigned maxSymbolValue = 255;
  2851     {   unsigned maxSymbolValue = 255;
  2274         size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.hufCTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
  2852         size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
  2275         if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
  2853         if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
  2276         if (maxSymbolValue < 255) return ERROR(dictionary_corrupted);
  2854         if (maxSymbolValue < 255) return ERROR(dictionary_corrupted);
  2277         dictPtr += hufHeaderSize;
  2855         dictPtr += hufHeaderSize;
  2278     }
  2856     }
  2279 
  2857 
  2280     {   unsigned offcodeLog;
  2858     {   unsigned offcodeLog;
  2281         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
  2859         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
  2282         if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
  2860         if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
  2283         if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
  2861         if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
  2284         /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
  2862         /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
  2285         CHECK_E( FSE_buildCTable_wksp(bs->entropy.offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, workspace, HUF_WORKSPACE_SIZE),
  2863         /* fill all offset symbols to avoid garbage at end of table */
       
  2864         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.offcodeCTable, offcodeNCount, MaxOff, offcodeLog, workspace, HUF_WORKSPACE_SIZE),
  2286                  dictionary_corrupted);
  2865                  dictionary_corrupted);
  2287         dictPtr += offcodeHeaderSize;
  2866         dictPtr += offcodeHeaderSize;
  2288     }
  2867     }
  2289 
  2868 
  2290     {   short matchlengthNCount[MaxML+1];
  2869     {   short matchlengthNCount[MaxML+1];
  2292         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
  2871         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
  2293         if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2872         if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2294         if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
  2873         if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
  2295         /* Every match length code must have non-zero probability */
  2874         /* Every match length code must have non-zero probability */
  2296         CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
  2875         CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
  2297         CHECK_E( FSE_buildCTable_wksp(bs->entropy.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
  2876         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
  2298                  dictionary_corrupted);
  2877                  dictionary_corrupted);
  2299         dictPtr += matchlengthHeaderSize;
  2878         dictPtr += matchlengthHeaderSize;
  2300     }
  2879     }
  2301 
  2880 
  2302     {   short litlengthNCount[MaxLL+1];
  2881     {   short litlengthNCount[MaxLL+1];
  2304         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
  2883         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
  2305         if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2884         if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
  2306         if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
  2885         if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
  2307         /* Every literal length code must have non-zero probability */
  2886         /* Every literal length code must have non-zero probability */
  2308         CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
  2887         CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
  2309         CHECK_E( FSE_buildCTable_wksp(bs->entropy.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
  2888         CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
  2310                  dictionary_corrupted);
  2889                  dictionary_corrupted);
  2311         dictPtr += litlengthHeaderSize;
  2890         dictPtr += litlengthHeaderSize;
  2312     }
  2891     }
  2313 
  2892 
  2314     if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
  2893     if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
  2330             for (u=0; u<3; u++) {
  2909             for (u=0; u<3; u++) {
  2331                 if (bs->rep[u] == 0) return ERROR(dictionary_corrupted);
  2910                 if (bs->rep[u] == 0) return ERROR(dictionary_corrupted);
  2332                 if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
  2911                 if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
  2333         }   }
  2912         }   }
  2334 
  2913 
  2335         bs->entropy.hufCTable_repeatMode = HUF_repeat_valid;
  2914         bs->entropy.huf.repeatMode = HUF_repeat_valid;
  2336         bs->entropy.offcode_repeatMode = FSE_repeat_valid;
  2915         bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
  2337         bs->entropy.matchlength_repeatMode = FSE_repeat_valid;
  2916         bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
  2338         bs->entropy.litlength_repeatMode = FSE_repeat_valid;
  2917         bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
  2339         CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize));
  2918         CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize, dtlm));
  2340         return dictID;
  2919         return dictID;
  2341     }
  2920     }
  2342 }
  2921 }
  2343 
  2922 
  2344 /** ZSTD_compress_insertDictionary() :
  2923 /** ZSTD_compress_insertDictionary() :
  2345 *   @return : dictID, or an error code */
  2924 *   @return : dictID, or an error code */
  2346 static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matchState_t* ms,
  2925 static size_t
  2347                                              ZSTD_CCtx_params const* params,
  2926 ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
  2348                                        const void* dict, size_t dictSize,
  2927                                ZSTD_matchState_t* ms,
  2349                                              ZSTD_dictContentType_e dictContentType,
  2928                          const ZSTD_CCtx_params* params,
  2350                                              void* workspace)
  2929                          const void* dict, size_t dictSize,
       
  2930                                ZSTD_dictContentType_e dictContentType,
       
  2931                                ZSTD_dictTableLoadMethod_e dtlm,
       
  2932                                void* workspace)
  2351 {
  2933 {
  2352     DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
  2934     DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
  2353     if ((dict==NULL) || (dictSize<=8)) return 0;
  2935     if ((dict==NULL) || (dictSize<=8)) return 0;
  2354 
  2936 
  2355     ZSTD_reset_compressedBlockState(bs);
  2937     ZSTD_reset_compressedBlockState(bs);
  2356 
  2938 
  2357     /* dict restricted modes */
  2939     /* dict restricted modes */
  2358     if (dictContentType == ZSTD_dct_rawContent)
  2940     if (dictContentType == ZSTD_dct_rawContent)
  2359         return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
  2941         return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
  2360 
  2942 
  2361     if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
  2943     if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
  2362         if (dictContentType == ZSTD_dct_auto) {
  2944         if (dictContentType == ZSTD_dct_auto) {
  2363             DEBUGLOG(4, "raw content dictionary detected");
  2945             DEBUGLOG(4, "raw content dictionary detected");
  2364             return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
  2946             return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
  2365         }
  2947         }
  2366         if (dictContentType == ZSTD_dct_fullDict)
  2948         if (dictContentType == ZSTD_dct_fullDict)
  2367             return ERROR(dictionary_wrong);
  2949             return ERROR(dictionary_wrong);
  2368         assert(0);   /* impossible */
  2950         assert(0);   /* impossible */
  2369     }
  2951     }
  2370 
  2952 
  2371     /* dict as full zstd dictionary */
  2953     /* dict as full zstd dictionary */
  2372     return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, workspace);
  2954     return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, dtlm, workspace);
  2373 }
  2955 }
  2374 
  2956 
  2375 /*! ZSTD_compressBegin_internal() :
  2957 /*! ZSTD_compressBegin_internal() :
  2376  * @return : 0, or an error code */
  2958  * @return : 0, or an error code */
  2377 size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
  2959 static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
  2378                              const void* dict, size_t dictSize,
  2960                                     const void* dict, size_t dictSize,
  2379                              ZSTD_dictContentType_e dictContentType,
  2961                                     ZSTD_dictContentType_e dictContentType,
  2380                              const ZSTD_CDict* cdict,
  2962                                     ZSTD_dictTableLoadMethod_e dtlm,
  2381                              ZSTD_CCtx_params params, U64 pledgedSrcSize,
  2963                                     const ZSTD_CDict* cdict,
  2382                              ZSTD_buffered_policy_e zbuff)
  2964                                     ZSTD_CCtx_params params, U64 pledgedSrcSize,
       
  2965                                     ZSTD_buffered_policy_e zbuff)
  2383 {
  2966 {
  2384     DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params.cParams.windowLog);
  2967     DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params.cParams.windowLog);
  2385     /* params are supposed to be fully validated at this point */
  2968     /* params are supposed to be fully validated at this point */
  2386     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  2969     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  2387     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  2970     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  2388 
  2971 
  2389     if (cdict && cdict->dictContentSize>0) {
  2972     if (cdict && cdict->dictContentSize>0) {
  2390         cctx->requestedParams = params;
  2973         return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
  2391         return ZSTD_resetCCtx_usingCDict(cctx, cdict, params.cParams.windowLog,
       
  2392                                          params.fParams, pledgedSrcSize, zbuff);
       
  2393     }
  2974     }
  2394 
  2975 
  2395     CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  2976     CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
  2396                                      ZSTDcrp_continue, zbuff) );
  2977                                      ZSTDcrp_continue, zbuff) );
  2397     {
  2978     {
  2398         size_t const dictID = ZSTD_compress_insertDictionary(
  2979         size_t const dictID = ZSTD_compress_insertDictionary(
  2399                 cctx->blockState.prevCBlock, &cctx->blockState.matchState,
  2980                 cctx->blockState.prevCBlock, &cctx->blockState.matchState,
  2400                 &params, dict, dictSize, dictContentType, cctx->entropyWorkspace);
  2981                 &params, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace);
  2401         if (ZSTD_isError(dictID)) return dictID;
  2982         if (ZSTD_isError(dictID)) return dictID;
  2402         assert(dictID <= (size_t)(U32)-1);
  2983         assert(dictID <= (size_t)(U32)-1);
  2403         cctx->dictID = (U32)dictID;
  2984         cctx->dictID = (U32)dictID;
  2404     }
  2985     }
  2405     return 0;
  2986     return 0;
  2406 }
  2987 }
  2407 
  2988 
  2408 size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
  2989 size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
  2409                                     const void* dict, size_t dictSize,
  2990                                     const void* dict, size_t dictSize,
  2410                                     ZSTD_dictContentType_e dictContentType,
  2991                                     ZSTD_dictContentType_e dictContentType,
       
  2992                                     ZSTD_dictTableLoadMethod_e dtlm,
  2411                                     const ZSTD_CDict* cdict,
  2993                                     const ZSTD_CDict* cdict,
  2412                                     ZSTD_CCtx_params params,
  2994                                     ZSTD_CCtx_params params,
  2413                                     unsigned long long pledgedSrcSize)
  2995                                     unsigned long long pledgedSrcSize)
  2414 {
  2996 {
  2415     DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog);
  2997     DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog);
  2416     /* compression parameters verification and optimization */
  2998     /* compression parameters verification and optimization */
  2417     CHECK_F( ZSTD_checkCParams(params.cParams) );
  2999     CHECK_F( ZSTD_checkCParams(params.cParams) );
  2418     return ZSTD_compressBegin_internal(cctx,
  3000     return ZSTD_compressBegin_internal(cctx,
  2419                                        dict, dictSize, dictContentType,
  3001                                        dict, dictSize, dictContentType, dtlm,
  2420                                        cdict,
  3002                                        cdict,
  2421                                        params, pledgedSrcSize,
  3003                                        params, pledgedSrcSize,
  2422                                        ZSTDb_not_buffered);
  3004                                        ZSTDb_not_buffered);
  2423 }
  3005 }
  2424 
  3006 
  2429                                    ZSTD_parameters params, unsigned long long pledgedSrcSize)
  3011                                    ZSTD_parameters params, unsigned long long pledgedSrcSize)
  2430 {
  3012 {
  2431     ZSTD_CCtx_params const cctxParams =
  3013     ZSTD_CCtx_params const cctxParams =
  2432             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  3014             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  2433     return ZSTD_compressBegin_advanced_internal(cctx,
  3015     return ZSTD_compressBegin_advanced_internal(cctx,
  2434                                             dict, dictSize, ZSTD_dct_auto,
  3016                                             dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
  2435                                             NULL /*cdict*/,
  3017                                             NULL /*cdict*/,
  2436                                             cctxParams, pledgedSrcSize);
  3018                                             cctxParams, pledgedSrcSize);
  2437 }
  3019 }
  2438 
  3020 
  2439 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
  3021 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
  2440 {
  3022 {
  2441     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
  3023     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
  2442     ZSTD_CCtx_params const cctxParams =
  3024     ZSTD_CCtx_params const cctxParams =
  2443             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  3025             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  2444     DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize);
  3026     DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize);
  2445     return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL,
  3027     return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  2446                                        cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
  3028                                        cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
  2447 }
  3029 }
  2448 
  3030 
  2449 size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
  3031 size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
  2450 {
  3032 {
  2503                                 dst, dstCapacity, src, srcSize,
  3085                                 dst, dstCapacity, src, srcSize,
  2504                                 1 /* frame mode */, 1 /* last chunk */);
  3086                                 1 /* frame mode */, 1 /* last chunk */);
  2505     if (ZSTD_isError(cSize)) return cSize;
  3087     if (ZSTD_isError(cSize)) return cSize;
  2506     endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
  3088     endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
  2507     if (ZSTD_isError(endResult)) return endResult;
  3089     if (ZSTD_isError(endResult)) return endResult;
  2508     if (cctx->appliedParams.fParams.contentSizeFlag) {  /* control src size */
  3090     assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
       
  3091     if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
       
  3092         ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
  2509         DEBUGLOG(4, "end of frame : controlling src size");
  3093         DEBUGLOG(4, "end of frame : controlling src size");
  2510         if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) {
  3094         if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) {
  2511             DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u",
  3095             DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u",
  2512                 (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
  3096                 (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
  2513             return ERROR(srcSize_wrong);
  3097             return ERROR(srcSize_wrong);
  2515     return cSize + endResult;
  3099     return cSize + endResult;
  2516 }
  3100 }
  2517 
  3101 
  2518 
  3102 
  2519 static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
  3103 static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
       
  3104                                       void* dst, size_t dstCapacity,
       
  3105                                 const void* src, size_t srcSize,
       
  3106                                 const void* dict,size_t dictSize,
       
  3107                                       ZSTD_parameters params)
       
  3108 {
       
  3109     ZSTD_CCtx_params const cctxParams =
       
  3110             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
       
  3111     DEBUGLOG(4, "ZSTD_compress_internal");
       
  3112     return ZSTD_compress_advanced_internal(cctx,
       
  3113                                            dst, dstCapacity,
       
  3114                                            src, srcSize,
       
  3115                                            dict, dictSize,
       
  3116                                            cctxParams);
       
  3117 }
       
  3118 
       
  3119 size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
  2520                                void* dst, size_t dstCapacity,
  3120                                void* dst, size_t dstCapacity,
  2521                          const void* src, size_t srcSize,
  3121                          const void* src, size_t srcSize,
  2522                          const void* dict,size_t dictSize,
  3122                          const void* dict,size_t dictSize,
  2523                                ZSTD_parameters params)
  3123                                ZSTD_parameters params)
  2524 {
  3124 {
  2525     ZSTD_CCtx_params const cctxParams =
       
  2526             ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
       
  2527     DEBUGLOG(4, "ZSTD_compress_internal");
       
  2528     return ZSTD_compress_advanced_internal(cctx,
       
  2529                                           dst, dstCapacity,
       
  2530                                           src, srcSize,
       
  2531                                           dict, dictSize,
       
  2532                                           cctxParams);
       
  2533 }
       
  2534 
       
  2535 size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
       
  2536                                void* dst, size_t dstCapacity,
       
  2537                          const void* src, size_t srcSize,
       
  2538                          const void* dict,size_t dictSize,
       
  2539                                ZSTD_parameters params)
       
  2540 {
       
  2541     DEBUGLOG(4, "ZSTD_compress_advanced");
  3125     DEBUGLOG(4, "ZSTD_compress_advanced");
  2542     CHECK_F(ZSTD_checkCParams(params.cParams));
  3126     CHECK_F(ZSTD_checkCParams(params.cParams));
  2543     return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
  3127     return ZSTD_compress_internal(cctx,
       
  3128                                   dst, dstCapacity,
       
  3129                                   src, srcSize,
       
  3130                                   dict, dictSize,
       
  3131                                   params);
  2544 }
  3132 }
  2545 
  3133 
  2546 /* Internal */
  3134 /* Internal */
  2547 size_t ZSTD_compress_advanced_internal(
  3135 size_t ZSTD_compress_advanced_internal(
  2548         ZSTD_CCtx* cctx,
  3136         ZSTD_CCtx* cctx,
  2549         void* dst, size_t dstCapacity,
  3137         void* dst, size_t dstCapacity,
  2550         const void* src, size_t srcSize,
  3138         const void* src, size_t srcSize,
  2551         const void* dict,size_t dictSize,
  3139         const void* dict,size_t dictSize,
  2552         ZSTD_CCtx_params params)
  3140         ZSTD_CCtx_params params)
  2553 {
  3141 {
  2554     DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)",
  3142     DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (U32)srcSize);
  2555                 (U32)srcSize);
  3143     CHECK_F( ZSTD_compressBegin_internal(cctx,
  2556     CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL,
  3144                          dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
  2557                                          params, srcSize, ZSTDb_not_buffered) );
  3145                          params, srcSize, ZSTDb_not_buffered) );
  2558     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  3146     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
  2559 }
  3147 }
  2560 
  3148 
  2561 size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
  3149 size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
  2562                                const void* dict, size_t dictSize, int compressionLevel)
  3150                                void* dst, size_t dstCapacity,
  2563 {
  3151                          const void* src, size_t srcSize,
  2564     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize ? srcSize : 1, dict ? dictSize : 0);
  3152                          const void* dict, size_t dictSize,
       
  3153                                int compressionLevel)
       
  3154 {
       
  3155     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);
  2565     ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  3156     ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
  2566     assert(params.fParams.contentSizeFlag == 1);
  3157     assert(params.fParams.contentSizeFlag == 1);
  2567     ZSTD_CCtxParam_setParameter(&cctxParams, ZSTD_p_compressLiterals, compressionLevel>=0);
       
  2568     return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams);
  3158     return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams);
  2569 }
  3159 }
  2570 
  3160 
  2571 size_t ZSTD_compressCCtx (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
  3161 size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
       
  3162                          void* dst, size_t dstCapacity,
       
  3163                    const void* src, size_t srcSize,
       
  3164                          int compressionLevel)
  2572 {
  3165 {
  2573     DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize);
  3166     DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize);
       
  3167     assert(cctx != NULL);
  2574     return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
  3168     return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
  2575 }
  3169 }
  2576 
  3170 
  2577 size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
  3171 size_t ZSTD_compress(void* dst, size_t dstCapacity,
       
  3172                const void* src, size_t srcSize,
       
  3173                      int compressionLevel)
  2578 {
  3174 {
  2579     size_t result;
  3175     size_t result;
  2580     ZSTD_CCtx ctxBody;
  3176     ZSTD_CCtx ctxBody;
  2581     memset(&ctxBody, 0, sizeof(ctxBody));
  3177     ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem);
  2582     ctxBody.customMem = ZSTD_defaultCMem;
       
  2583     result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
  3178     result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
  2584     ZSTD_free(ctxBody.workSpace, ZSTD_defaultCMem);  /* can't free ctxBody itself, as it's on stack; free only heap content */
  3179     ZSTD_freeCCtxContent(&ctxBody);   /* can't free ctxBody itself, as it's on stack; free only heap content */
  2585     return result;
  3180     return result;
  2586 }
  3181 }
  2587 
  3182 
  2588 
  3183 
  2589 /* =====  Dictionary API  ===== */
  3184 /* =====  Dictionary API  ===== */
  2617               const void* dictBuffer, size_t dictSize,
  3212               const void* dictBuffer, size_t dictSize,
  2618                     ZSTD_dictLoadMethod_e dictLoadMethod,
  3213                     ZSTD_dictLoadMethod_e dictLoadMethod,
  2619                     ZSTD_dictContentType_e dictContentType,
  3214                     ZSTD_dictContentType_e dictContentType,
  2620                     ZSTD_compressionParameters cParams)
  3215                     ZSTD_compressionParameters cParams)
  2621 {
  3216 {
  2622     DEBUGLOG(3, "ZSTD_initCDict_internal, dictContentType %u", (U32)dictContentType);
  3217     DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (U32)dictContentType);
  2623     assert(!ZSTD_checkCParams(cParams));
  3218     assert(!ZSTD_checkCParams(cParams));
  2624     cdict->cParams = cParams;
  3219     cdict->matchState.cParams = cParams;
  2625     if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
  3220     if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
  2626         cdict->dictBuffer = NULL;
  3221         cdict->dictBuffer = NULL;
  2627         cdict->dictContent = dictBuffer;
  3222         cdict->dictContent = dictBuffer;
  2628     } else {
  3223     } else {
  2629         void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem);
  3224         void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem);
  2652         params.fParams.contentSizeFlag = 1;
  3247         params.fParams.contentSizeFlag = 1;
  2653         params.cParams = cParams;
  3248         params.cParams = cParams;
  2654         {   size_t const dictID = ZSTD_compress_insertDictionary(
  3249         {   size_t const dictID = ZSTD_compress_insertDictionary(
  2655                     &cdict->cBlockState, &cdict->matchState, &params,
  3250                     &cdict->cBlockState, &cdict->matchState, &params,
  2656                     cdict->dictContent, cdict->dictContentSize,
  3251                     cdict->dictContent, cdict->dictContentSize,
  2657                     dictContentType, cdict->workspace);
  3252                     dictContentType, ZSTD_dtlm_full, cdict->workspace);
  2658             if (ZSTD_isError(dictID)) return dictID;
  3253             if (ZSTD_isError(dictID)) return dictID;
  2659             assert(dictID <= (size_t)(U32)-1);
  3254             assert(dictID <= (size_t)(U32)-1);
  2660             cdict->dictID = (U32)dictID;
  3255             cdict->dictID = (U32)dictID;
  2661         }
  3256         }
  2662     }
  3257     }
  2773 }
  3368 }
  2774 
  3369 
  2775 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)
  3370 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)
  2776 {
  3371 {
  2777     assert(cdict != NULL);
  3372     assert(cdict != NULL);
  2778     return cdict->cParams;
  3373     return cdict->matchState.cParams;
  2779 }
  3374 }
  2780 
  3375 
  2781 /* ZSTD_compressBegin_usingCDict_advanced() :
  3376 /* ZSTD_compressBegin_usingCDict_advanced() :
  2782  * cdict must be != NULL */
  3377  * cdict must be != NULL */
  2783 size_t ZSTD_compressBegin_usingCDict_advanced(
  3378 size_t ZSTD_compressBegin_usingCDict_advanced(
  2797             U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1;
  3392             U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1;
  2798             params.cParams.windowLog = MAX(params.cParams.windowLog, limitedSrcLog);
  3393             params.cParams.windowLog = MAX(params.cParams.windowLog, limitedSrcLog);
  2799         }
  3394         }
  2800         params.fParams = fParams;
  3395         params.fParams = fParams;
  2801         return ZSTD_compressBegin_internal(cctx,
  3396         return ZSTD_compressBegin_internal(cctx,
  2802                                            NULL, 0, ZSTD_dct_auto,
  3397                                            NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
  2803                                            cdict,
  3398                                            cdict,
  2804                                            params, pledgedSrcSize,
  3399                                            params, pledgedSrcSize,
  2805                                            ZSTDb_not_buffered);
  3400                                            ZSTDb_not_buffered);
  2806     }
  3401     }
  2807 }
  3402 }
  2811  * if pledgedSrcSize>0, it will enable contentSizeFlag */
  3406  * if pledgedSrcSize>0, it will enable contentSizeFlag */
  2812 size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
  3407 size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
  2813 {
  3408 {
  2814     ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
  3409     ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
  2815     DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
  3410     DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
  2816     return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, 0);
  3411     return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN);
  2817 }
  3412 }
  2818 
  3413 
  2819 size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
  3414 size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
  2820                                 void* dst, size_t dstCapacity,
  3415                                 void* dst, size_t dstCapacity,
  2821                                 const void* src, size_t srcSize,
  3416                                 const void* src, size_t srcSize,
  2878 }
  3473 }
  2879 
  3474 
  2880 static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
  3475 static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
  2881                     const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType,
  3476                     const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType,
  2882                     const ZSTD_CDict* const cdict,
  3477                     const ZSTD_CDict* const cdict,
  2883                     ZSTD_CCtx_params const params, unsigned long long const pledgedSrcSize)
  3478                     ZSTD_CCtx_params params, unsigned long long const pledgedSrcSize)
  2884 {
  3479 {
  2885     DEBUGLOG(4, "ZSTD_resetCStream_internal (disableLiteralCompression=%i)",
  3480     DEBUGLOG(4, "ZSTD_resetCStream_internal");
  2886                 params.disableLiteralCompression);
  3481     /* Finalize the compression parameters */
       
  3482     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
  2887     /* params are supposed to be fully validated at this point */
  3483     /* params are supposed to be fully validated at this point */
  2888     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  3484     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  2889     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3485     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  2890 
  3486 
  2891     CHECK_F( ZSTD_compressBegin_internal(cctx,
  3487     CHECK_F( ZSTD_compressBegin_internal(cctx,
  2892                                          dict, dictSize, dictContentType,
  3488                                          dict, dictSize, dictContentType, ZSTD_dtlm_fast,
  2893                                          cdict,
  3489                                          cdict,
  2894                                          params, pledgedSrcSize,
  3490                                          params, pledgedSrcSize,
  2895                                          ZSTDb_buffered) );
  3491                                          ZSTDb_buffered) );
  2896 
  3492 
  2897     cctx->inToCompress = 0;
  3493     cctx->inToCompress = 0;
  2910 {
  3506 {
  2911     ZSTD_CCtx_params params = zcs->requestedParams;
  3507     ZSTD_CCtx_params params = zcs->requestedParams;
  2912     DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize);
  3508     DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize);
  2913     if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
  3509     if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
  2914     params.fParams.contentSizeFlag = 1;
  3510     params.fParams.contentSizeFlag = 1;
  2915     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, 0);
       
  2916     return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
  3511     return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
  2917 }
  3512 }
  2918 
  3513 
  2919 /*! ZSTD_initCStream_internal() :
  3514 /*! ZSTD_initCStream_internal() :
  2920  *  Note : for lib/compress only. Used by zstdmt_compress.c.
  3515  *  Note : for lib/compress only. Used by zstdmt_compress.c.
  2923 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
  3518 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
  2924                     const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
  3519                     const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
  2925                     ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
  3520                     ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
  2926 {
  3521 {
  2927     DEBUGLOG(4, "ZSTD_initCStream_internal");
  3522     DEBUGLOG(4, "ZSTD_initCStream_internal");
       
  3523     params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
  2928     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  3524     assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
  2929     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  3525     assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
  2930 
  3526 
  2931     if (dict && dictSize >= 8) {
  3527     if (dict && dictSize >= 8) {
  2932         DEBUGLOG(4, "loading dictionary of size %u", (U32)dictSize);
  3528         DEBUGLOG(4, "loading dictionary of size %u", (U32)dictSize);
  2989 {
  3585 {
  2990     DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u",
  3586     DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u",
  2991                 (U32)pledgedSrcSize, params.fParams.contentSizeFlag);
  3587                 (U32)pledgedSrcSize, params.fParams.contentSizeFlag);
  2992     CHECK_F( ZSTD_checkCParams(params.cParams) );
  3588     CHECK_F( ZSTD_checkCParams(params.cParams) );
  2993     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. */
  3589     if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;  /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */
  2994     {   ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
  3590     zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
  2995         return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, cctxParams, pledgedSrcSize);
  3591     return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, zcs->requestedParams, pledgedSrcSize);
  2996     }
       
  2997 }
  3592 }
  2998 
  3593 
  2999 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
  3594 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
  3000 {
  3595 {
  3001     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
  3596     ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel);
  3002     ZSTD_CCtx_params const cctxParams =
  3597     return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, zcs->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN);
  3003             ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
       
  3004     return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN);
       
  3005 }
  3598 }
  3006 
  3599 
  3007 size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)
  3600 size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)
  3008 {
  3601 {
  3009     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 */
  3602     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 */
  3010     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
  3603     ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel);
  3011     ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
  3604     return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, zcs->requestedParams, pledgedSrcSize);
  3012     return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, pledgedSrcSize);
       
  3013 }
  3605 }
  3014 
  3606 
  3015 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
  3607 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
  3016 {
  3608 {
  3017     DEBUGLOG(4, "ZSTD_initCStream");
  3609     DEBUGLOG(4, "ZSTD_initCStream");
  3071                 DEBUGLOG(4, "ZSTD_compressEnd : %u", (U32)cSize);
  3663                 DEBUGLOG(4, "ZSTD_compressEnd : %u", (U32)cSize);
  3072                 if (ZSTD_isError(cSize)) return cSize;
  3664                 if (ZSTD_isError(cSize)) return cSize;
  3073                 ip = iend;
  3665                 ip = iend;
  3074                 op += cSize;
  3666                 op += cSize;
  3075                 zcs->frameEnded = 1;
  3667                 zcs->frameEnded = 1;
  3076                 ZSTD_startNewCompression(zcs);
  3668                 ZSTD_CCtx_reset(zcs);
  3077                 someMoreWork = 0; break;
  3669                 someMoreWork = 0; break;
  3078             }
  3670             }
  3079             /* complete loading into inBuffer */
  3671             /* complete loading into inBuffer */
  3080             {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
  3672             {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
  3081                 size_t const loaded = ZSTD_limitCopy(
  3673                 size_t const loaded = ZSTD_limitCopy(
  3124                 if (cDst == op) {  /* no need to flush */
  3716                 if (cDst == op) {  /* no need to flush */
  3125                     op += cSize;
  3717                     op += cSize;
  3126                     if (zcs->frameEnded) {
  3718                     if (zcs->frameEnded) {
  3127                         DEBUGLOG(5, "Frame completed directly in outBuffer");
  3719                         DEBUGLOG(5, "Frame completed directly in outBuffer");
  3128                         someMoreWork = 0;
  3720                         someMoreWork = 0;
  3129                         ZSTD_startNewCompression(zcs);
  3721                         ZSTD_CCtx_reset(zcs);
  3130                     }
  3722                     }
  3131                     break;
  3723                     break;
  3132                 }
  3724                 }
  3133                 zcs->outBuffContentSize = cSize;
  3725                 zcs->outBuffContentSize = cSize;
  3134                 zcs->outBuffFlushedSize = 0;
  3726                 zcs->outBuffFlushedSize = 0;
  3152                 }
  3744                 }
  3153                 zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
  3745                 zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
  3154                 if (zcs->frameEnded) {
  3746                 if (zcs->frameEnded) {
  3155                     DEBUGLOG(5, "Frame completed on flush");
  3747                     DEBUGLOG(5, "Frame completed on flush");
  3156                     someMoreWork = 0;
  3748                     someMoreWork = 0;
  3157                     ZSTD_startNewCompression(zcs);
  3749                     ZSTD_CCtx_reset(zcs);
  3158                     break;
  3750                     break;
  3159                 }
  3751                 }
  3160                 zcs->streamStage = zcss_load;
  3752                 zcs->streamStage = zcss_load;
  3161                 break;
  3753                 break;
  3162             }
  3754             }
  3205         DEBUGLOG(4, "ZSTD_compress_generic : transparent init stage");
  3797         DEBUGLOG(4, "ZSTD_compress_generic : transparent init stage");
  3206         if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */
  3798         if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */
  3207         params.cParams = ZSTD_getCParamsFromCCtxParams(
  3799         params.cParams = ZSTD_getCParamsFromCCtxParams(
  3208                 &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
  3800                 &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
  3209 
  3801 
       
  3802 
  3210 #ifdef ZSTD_MULTITHREAD
  3803 #ifdef ZSTD_MULTITHREAD
  3211         if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
  3804         if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
  3212             params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
  3805             params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
  3213         }
  3806         }
  3214         if (params.nbWorkers > 0) {
  3807         if (params.nbWorkers > 0) {
  3215             /* mt context creation */
  3808             /* mt context creation */
  3216             if (cctx->mtctx == NULL || (params.nbWorkers != ZSTDMT_getNbWorkers(cctx->mtctx))) {
  3809             if (cctx->mtctx == NULL) {
  3217                 DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u",
  3810                 DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u",
  3218                             params.nbWorkers);
  3811                             params.nbWorkers);
  3219                 if (cctx->mtctx != NULL)
       
  3220                     DEBUGLOG(4, "ZSTD_compress_generic: previous nbWorkers was %u",
       
  3221                                 ZSTDMT_getNbWorkers(cctx->mtctx));
       
  3222                 ZSTDMT_freeCCtx(cctx->mtctx);
       
  3223                 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
  3812                 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
  3224                 if (cctx->mtctx == NULL) return ERROR(memory_allocation);
  3813                 if (cctx->mtctx == NULL) return ERROR(memory_allocation);
  3225             }
  3814             }
  3226             /* mt compression */
  3815             /* mt compression */
  3227             DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
  3816             DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
  3249             cctx->cParamsChanged = 0;
  3838             cctx->cParamsChanged = 0;
  3250         }
  3839         }
  3251         {   size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
  3840         {   size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
  3252             if ( ZSTD_isError(flushMin)
  3841             if ( ZSTD_isError(flushMin)
  3253               || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
  3842               || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
  3254                 ZSTD_startNewCompression(cctx);
  3843                 ZSTD_CCtx_reset(cctx);
  3255             }
  3844             }
       
  3845             DEBUGLOG(5, "completed ZSTD_compress_generic delegating to ZSTDMT_compressStream_generic");
  3256             return flushMin;
  3846             return flushMin;
  3257     }   }
  3847     }   }
  3258 #endif
  3848 #endif
  3259     CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
  3849     CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
  3260     DEBUGLOG(5, "completed ZSTD_compress_generic");
  3850     DEBUGLOG(5, "completed ZSTD_compress_generic");
  3306 
  3896 
  3307 /*-=====  Pre-defined compression levels  =====-*/
  3897 /*-=====  Pre-defined compression levels  =====-*/
  3308 
  3898 
  3309 #define ZSTD_MAX_CLEVEL     22
  3899 #define ZSTD_MAX_CLEVEL     22
  3310 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
  3900 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
       
  3901 int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }
  3311 
  3902 
  3312 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
  3903 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
  3313 {   /* "default" - guarantees a monotonically increasing memory budget */
  3904 {   /* "default" - guarantees a monotonically increasing memory budget */
  3314     /* W,  C,  H,  S,  L, TL, strat */
  3905     /* W,  C,  H,  S,  L, TL, strat */
  3315     { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */
  3906     { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */
  3316     { 19, 13, 14,  1,  7,  1, ZSTD_fast    },  /* level  1 */
  3907     { 19, 13, 14,  1,  7,  0, ZSTD_fast    },  /* level  1 */
  3317     { 19, 15, 16,  1,  6,  1, ZSTD_fast    },  /* level  2 */
  3908     { 19, 15, 16,  1,  6,  0, ZSTD_fast    },  /* level  2 */
  3318     { 20, 16, 17,  1,  5,  8, ZSTD_dfast   },  /* level  3 */
  3909     { 20, 16, 17,  1,  5,  1, ZSTD_dfast   },  /* level  3 */
  3319     { 20, 17, 18,  1,  5,  8, ZSTD_dfast   },  /* level  4 */
  3910     { 20, 18, 18,  1,  5,  1, ZSTD_dfast   },  /* level  4 */
  3320     { 20, 17, 18,  2,  5, 16, ZSTD_greedy  },  /* level  5 */
  3911     { 20, 18, 18,  2,  5,  2, ZSTD_greedy  },  /* level  5 */
  3321     { 21, 17, 19,  2,  5, 16, ZSTD_lazy    },  /* level  6 */
  3912     { 21, 18, 19,  2,  5,  4, ZSTD_lazy    },  /* level  6 */
  3322     { 21, 18, 19,  3,  5, 16, ZSTD_lazy    },  /* level  7 */
  3913     { 21, 18, 19,  3,  5,  8, ZSTD_lazy2   },  /* level  7 */
  3323     { 21, 18, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
  3914     { 21, 19, 19,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
  3324     { 21, 19, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  9 */
  3915     { 21, 19, 20,  4,  5, 16, ZSTD_lazy2   },  /* level  9 */
  3325     { 21, 19, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
  3916     { 21, 20, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
  3326     { 22, 20, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
  3917     { 21, 21, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
  3327     { 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
  3918     { 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
  3328     { 22, 21, 22,  4,  5, 32, ZSTD_btlazy2 },  /* level 13 */
  3919     { 22, 21, 22,  4,  5, 32, ZSTD_btlazy2 },  /* level 13 */
  3329     { 22, 21, 22,  5,  5, 32, ZSTD_btlazy2 },  /* level 14 */
  3920     { 22, 21, 22,  5,  5, 32, ZSTD_btlazy2 },  /* level 14 */
  3330     { 22, 22, 22,  6,  5, 32, ZSTD_btlazy2 },  /* level 15 */
  3921     { 22, 22, 22,  6,  5, 32, ZSTD_btlazy2 },  /* level 15 */
  3331     { 22, 21, 22,  4,  5, 48, ZSTD_btopt   },  /* level 16 */
  3922     { 22, 21, 22,  4,  5, 48, ZSTD_btopt   },  /* level 16 */
  3332     { 23, 22, 22,  4,  4, 48, ZSTD_btopt   },  /* level 17 */
  3923     { 23, 22, 22,  4,  4, 64, ZSTD_btopt   },  /* level 17 */
  3333     { 23, 22, 22,  5,  3, 64, ZSTD_btopt   },  /* level 18 */
  3924     { 23, 23, 22,  6,  3,256, ZSTD_btopt   },  /* level 18 */
  3334     { 23, 23, 22,  7,  3,128, ZSTD_btopt   },  /* level 19 */
  3925     { 23, 24, 22,  7,  3,256, ZSTD_btultra },  /* level 19 */
  3335     { 25, 25, 23,  7,  3,128, ZSTD_btultra },  /* level 20 */
  3926     { 25, 25, 23,  7,  3,256, ZSTD_btultra },  /* level 20 */
  3336     { 26, 26, 24,  7,  3,256, ZSTD_btultra },  /* level 21 */
  3927     { 26, 26, 24,  7,  3,512, ZSTD_btultra },  /* level 21 */
  3337     { 27, 27, 25,  9,  3,512, ZSTD_btultra },  /* level 22 */
  3928     { 27, 27, 25,  9,  3,999, ZSTD_btultra },  /* level 22 */
  3338 },
  3929 },
  3339 {   /* for srcSize <= 256 KB */
  3930 {   /* for srcSize <= 256 KB */
  3340     /* W,  C,  H,  S,  L,  T, strat */
  3931     /* W,  C,  H,  S,  L,  T, strat */
  3341     { 18, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3932     { 18, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3342     { 18, 13, 14,  1,  6,  1, ZSTD_fast    },  /* level  1 */
  3933     { 18, 13, 14,  1,  6,  0, ZSTD_fast    },  /* level  1 */
  3343     { 18, 14, 13,  1,  5,  8, ZSTD_dfast   },  /* level  2 */
  3934     { 18, 14, 14,  1,  5,  1, ZSTD_dfast   },  /* level  2 */
  3344     { 18, 16, 15,  1,  5,  8, ZSTD_dfast   },  /* level  3 */
  3935     { 18, 16, 16,  1,  4,  1, ZSTD_dfast   },  /* level  3 */
  3345     { 18, 15, 17,  1,  5,  8, ZSTD_greedy  },  /* level  4.*/
  3936     { 18, 16, 17,  2,  5,  2, ZSTD_greedy  },  /* level  4.*/
  3346     { 18, 16, 17,  4,  5,  8, ZSTD_greedy  },  /* level  5.*/
  3937     { 18, 18, 18,  3,  5,  2, ZSTD_greedy  },  /* level  5.*/
  3347     { 18, 16, 17,  3,  5,  8, ZSTD_lazy    },  /* level  6.*/
  3938     { 18, 18, 19,  3,  5,  4, ZSTD_lazy    },  /* level  6.*/
  3348     { 18, 17, 17,  4,  4,  8, ZSTD_lazy    },  /* level  7 */
  3939     { 18, 18, 19,  4,  4,  4, ZSTD_lazy    },  /* level  7 */
  3349     { 18, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  3940     { 18, 18, 19,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  3350     { 18, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  3941     { 18, 18, 19,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  3351     { 18, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  3942     { 18, 18, 19,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  3352     { 18, 18, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 11.*/
  3943     { 18, 18, 19,  5,  4, 16, ZSTD_btlazy2 },  /* level 11.*/
  3353     { 18, 18, 17,  5,  4,  8, ZSTD_btlazy2 },  /* level 12.*/
  3944     { 18, 19, 19,  6,  4, 16, ZSTD_btlazy2 },  /* level 12.*/
  3354     { 18, 19, 17,  7,  4,  8, ZSTD_btlazy2 },  /* level 13 */
  3945     { 18, 19, 19,  8,  4, 16, ZSTD_btlazy2 },  /* level 13 */
  3355     { 18, 18, 18,  4,  4, 16, ZSTD_btopt   },  /* level 14.*/
  3946     { 18, 18, 19,  4,  4, 24, ZSTD_btopt   },  /* level 14.*/
  3356     { 18, 18, 18,  4,  3, 16, ZSTD_btopt   },  /* level 15.*/
  3947     { 18, 18, 19,  4,  3, 24, ZSTD_btopt   },  /* level 15.*/
  3357     { 18, 19, 18,  6,  3, 32, ZSTD_btopt   },  /* level 16.*/
  3948     { 18, 19, 19,  6,  3, 64, ZSTD_btopt   },  /* level 16.*/
  3358     { 18, 19, 18,  8,  3, 64, ZSTD_btopt   },  /* level 17.*/
  3949     { 18, 19, 19,  8,  3,128, ZSTD_btopt   },  /* level 17.*/
  3359     { 18, 19, 18,  9,  3,128, ZSTD_btopt   },  /* level 18.*/
  3950     { 18, 19, 19, 10,  3,256, ZSTD_btopt   },  /* level 18.*/
  3360     { 18, 19, 18, 10,  3,256, ZSTD_btopt   },  /* level 19.*/
  3951     { 18, 19, 19, 10,  3,256, ZSTD_btultra },  /* level 19.*/
  3361     { 18, 19, 18, 11,  3,512, ZSTD_btultra },  /* level 20.*/
  3952     { 18, 19, 19, 11,  3,512, ZSTD_btultra },  /* level 20.*/
  3362     { 18, 19, 18, 12,  3,512, ZSTD_btultra },  /* level 21.*/
  3953     { 18, 19, 19, 12,  3,512, ZSTD_btultra },  /* level 21.*/
  3363     { 18, 19, 18, 13,  3,512, ZSTD_btultra },  /* level 22.*/
  3954     { 18, 19, 19, 13,  3,999, ZSTD_btultra },  /* level 22.*/
  3364 },
  3955 },
  3365 {   /* for srcSize <= 128 KB */
  3956 {   /* for srcSize <= 128 KB */
  3366     /* W,  C,  H,  S,  L,  T, strat */
  3957     /* W,  C,  H,  S,  L,  T, strat */
  3367     { 17, 12, 12,  1,  5,  1, ZSTD_fast    },  /* level  0 - not used */
  3958     { 17, 12, 12,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3368     { 17, 12, 13,  1,  6,  1, ZSTD_fast    },  /* level  1 */
  3959     { 17, 12, 13,  1,  6,  0, ZSTD_fast    },  /* level  1 */
  3369     { 17, 13, 16,  1,  5,  1, ZSTD_fast    },  /* level  2 */
  3960     { 17, 13, 15,  1,  5,  0, ZSTD_fast    },  /* level  2 */
  3370     { 17, 16, 16,  2,  5,  8, ZSTD_dfast   },  /* level  3 */
  3961     { 17, 15, 16,  2,  5,  1, ZSTD_dfast   },  /* level  3 */
  3371     { 17, 13, 15,  3,  4,  8, ZSTD_greedy  },  /* level  4 */
  3962     { 17, 17, 17,  2,  4,  1, ZSTD_dfast   },  /* level  4 */
  3372     { 17, 15, 17,  4,  4,  8, ZSTD_greedy  },  /* level  5 */
  3963     { 17, 16, 17,  3,  4,  2, ZSTD_greedy  },  /* level  5 */
  3373     { 17, 16, 17,  3,  4,  8, ZSTD_lazy    },  /* level  6 */
  3964     { 17, 17, 17,  3,  4,  4, ZSTD_lazy    },  /* level  6 */
  3374     { 17, 15, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  7 */
  3965     { 17, 17, 17,  3,  4,  8, ZSTD_lazy2   },  /* level  7 */
  3375     { 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  3966     { 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
  3376     { 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  3967     { 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
  3377     { 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  3968     { 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
  3378     { 17, 17, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 11 */
  3969     { 17, 17, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 11 */
  3379     { 17, 17, 17,  8,  4,  8, ZSTD_lazy2   },  /* level 12 */
  3970     { 17, 18, 17,  6,  4, 16, ZSTD_btlazy2 },  /* level 12 */
  3380     { 17, 18, 17,  6,  4,  8, ZSTD_btlazy2 },  /* level 13.*/
  3971     { 17, 18, 17,  8,  4, 16, ZSTD_btlazy2 },  /* level 13.*/
  3381     { 17, 17, 17,  7,  3,  8, ZSTD_btopt   },  /* level 14.*/
  3972     { 17, 18, 17,  4,  4, 32, ZSTD_btopt   },  /* level 14.*/
  3382     { 17, 17, 17,  7,  3, 16, ZSTD_btopt   },  /* level 15.*/
  3973     { 17, 18, 17,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
  3383     { 17, 18, 17,  7,  3, 32, ZSTD_btopt   },  /* level 16.*/
  3974     { 17, 18, 17,  7,  3,128, ZSTD_btopt   },  /* level 16.*/
  3384     { 17, 18, 17,  7,  3, 64, ZSTD_btopt   },  /* level 17.*/
  3975     { 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 17.*/
  3385     { 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 18.*/
  3976     { 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 18.*/
  3386     { 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 19.*/
  3977     { 17, 18, 17,  8,  3,256, ZSTD_btultra },  /* level 19.*/
  3387     { 17, 18, 17,  9,  3,256, ZSTD_btultra },  /* level 20.*/
  3978     { 17, 18, 17,  9,  3,256, ZSTD_btultra },  /* level 20.*/
  3388     { 17, 18, 17, 10,  3,256, ZSTD_btultra },  /* level 21.*/
  3979     { 17, 18, 17, 10,  3,256, ZSTD_btultra },  /* level 21.*/
  3389     { 17, 18, 17, 11,  3,512, ZSTD_btultra },  /* level 22.*/
  3980     { 17, 18, 17, 11,  3,512, ZSTD_btultra },  /* level 22.*/
  3390 },
  3981 },
  3391 {   /* for srcSize <= 16 KB */
  3982 {   /* for srcSize <= 16 KB */
  3392     /* W,  C,  H,  S,  L,  T, strat */
  3983     /* W,  C,  H,  S,  L,  T, strat */
  3393     { 14, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3984     { 14, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
  3394     { 14, 14, 14,  1,  6,  1, ZSTD_fast    },  /* level  1 */
  3985     { 14, 14, 15,  1,  5,  0, ZSTD_fast    },  /* level  1 */
  3395     { 14, 14, 14,  1,  4,  1, ZSTD_fast    },  /* level  2 */
  3986     { 14, 14, 15,  1,  4,  0, ZSTD_fast    },  /* level  2 */
  3396     { 14, 14, 14,  1,  4,  6, ZSTD_dfast   },  /* level  3.*/
  3987     { 14, 14, 14,  2,  4,  1, ZSTD_dfast   },  /* level  3.*/
  3397     { 14, 14, 14,  4,  4,  6, ZSTD_greedy  },  /* level  4.*/
  3988     { 14, 14, 14,  4,  4,  2, ZSTD_greedy  },  /* level  4.*/
  3398     { 14, 14, 14,  3,  4,  6, ZSTD_lazy    },  /* level  5.*/
  3989     { 14, 14, 14,  3,  4,  4, ZSTD_lazy    },  /* level  5.*/
  3399     { 14, 14, 14,  4,  4,  6, ZSTD_lazy2   },  /* level  6 */
  3990     { 14, 14, 14,  4,  4,  8, ZSTD_lazy2   },  /* level  6 */
  3400     { 14, 14, 14,  5,  4,  6, ZSTD_lazy2   },  /* level  7 */
  3991     { 14, 14, 14,  6,  4,  8, ZSTD_lazy2   },  /* level  7 */
  3401     { 14, 14, 14,  6,  4,  6, ZSTD_lazy2   },  /* level  8.*/
  3992     { 14, 14, 14,  8,  4,  8, ZSTD_lazy2   },  /* level  8.*/
  3402     { 14, 15, 14,  6,  4,  6, ZSTD_btlazy2 },  /* level  9.*/
  3993     { 14, 15, 14,  5,  4,  8, ZSTD_btlazy2 },  /* level  9.*/
  3403     { 14, 15, 14,  3,  3,  6, ZSTD_btopt   },  /* level 10.*/
  3994     { 14, 15, 14,  9,  4,  8, ZSTD_btlazy2 },  /* level 10.*/
  3404     { 14, 15, 14,  6,  3,  8, ZSTD_btopt   },  /* level 11.*/
  3995     { 14, 15, 14,  3,  4, 12, ZSTD_btopt   },  /* level 11.*/
  3405     { 14, 15, 14,  6,  3, 16, ZSTD_btopt   },  /* level 12.*/
  3996     { 14, 15, 14,  6,  3, 16, ZSTD_btopt   },  /* level 12.*/
  3406     { 14, 15, 14,  6,  3, 24, ZSTD_btopt   },  /* level 13.*/
  3997     { 14, 15, 14,  6,  3, 24, ZSTD_btopt   },  /* level 13.*/
  3407     { 14, 15, 15,  6,  3, 48, ZSTD_btopt   },  /* level 14.*/
  3998     { 14, 15, 15,  6,  3, 48, ZSTD_btopt   },  /* level 14.*/
  3408     { 14, 15, 15,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
  3999     { 14, 15, 15,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
  3409     { 14, 15, 15,  6,  3, 96, ZSTD_btopt   },  /* level 16.*/
  4000     { 14, 15, 15,  6,  3, 96, ZSTD_btopt   },  /* level 16.*/
  3410     { 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
  4001     { 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
  3411     { 14, 15, 15,  6,  3,256, ZSTD_btopt   },  /* level 18.*/
  4002     { 14, 15, 15,  8,  3,256, ZSTD_btopt   },  /* level 18.*/
  3412     { 14, 15, 15,  7,  3,256, ZSTD_btopt   },  /* level 19.*/
  4003     { 14, 15, 15,  6,  3,256, ZSTD_btultra },  /* level 19.*/
  3413     { 14, 15, 15,  8,  3,256, ZSTD_btultra },  /* level 20.*/
  4004     { 14, 15, 15,  8,  3,256, ZSTD_btultra },  /* level 20.*/
  3414     { 14, 15, 15,  9,  3,256, ZSTD_btultra },  /* level 21.*/
  4005     { 14, 15, 15,  9,  3,256, ZSTD_btultra },  /* level 21.*/
  3415     { 14, 15, 15, 10,  3,256, ZSTD_btultra },  /* level 22.*/
  4006     { 14, 15, 15, 10,  3,512, ZSTD_btultra },  /* level 22.*/
  3416 },
  4007 },
  3417 };
  4008 };
  3418 
  4009 
  3419 /*! ZSTD_getCParams() :
  4010 /*! ZSTD_getCParams() :
  3420 *  @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
  4011 *  @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.