extzstd 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +28 -14
 - data/contrib/zstd/CHANGELOG +114 -56
 - data/contrib/zstd/CONTRIBUTING.md +14 -0
 - data/contrib/zstd/Makefile +37 -31
 - data/contrib/zstd/README.md +6 -0
 - data/contrib/zstd/appveyor.yml +4 -1
 - data/contrib/zstd/lib/Makefile +231 -134
 - data/contrib/zstd/lib/README.md +28 -0
 - data/contrib/zstd/lib/common/bitstream.h +24 -15
 - data/contrib/zstd/lib/common/compiler.h +116 -3
 - data/contrib/zstd/lib/common/cpu.h +0 -2
 - data/contrib/zstd/lib/common/debug.h +11 -18
 - data/contrib/zstd/lib/common/entropy_common.c +188 -42
 - data/contrib/zstd/lib/common/error_private.c +1 -0
 - data/contrib/zstd/lib/common/error_private.h +1 -1
 - data/contrib/zstd/lib/common/fse.h +38 -11
 - data/contrib/zstd/lib/common/fse_decompress.c +123 -16
 - data/contrib/zstd/lib/common/huf.h +26 -5
 - data/contrib/zstd/lib/common/mem.h +66 -93
 - data/contrib/zstd/lib/common/pool.c +22 -16
 - data/contrib/zstd/lib/common/pool.h +1 -1
 - data/contrib/zstd/lib/common/threading.c +6 -5
 - data/contrib/zstd/lib/common/xxhash.c +18 -56
 - data/contrib/zstd/lib/common/xxhash.h +1 -1
 - data/contrib/zstd/lib/common/zstd_common.c +9 -9
 - data/contrib/zstd/lib/common/zstd_deps.h +111 -0
 - data/contrib/zstd/lib/common/zstd_errors.h +1 -0
 - data/contrib/zstd/lib/common/zstd_internal.h +89 -58
 - data/contrib/zstd/lib/compress/fse_compress.c +30 -23
 - data/contrib/zstd/lib/compress/hist.c +26 -28
 - data/contrib/zstd/lib/compress/hist.h +1 -1
 - data/contrib/zstd/lib/compress/huf_compress.c +210 -95
 - data/contrib/zstd/lib/compress/zstd_compress.c +1339 -409
 - data/contrib/zstd/lib/compress/zstd_compress_internal.h +119 -41
 - data/contrib/zstd/lib/compress/zstd_compress_literals.c +4 -4
 - data/contrib/zstd/lib/compress/zstd_compress_sequences.c +17 -3
 - data/contrib/zstd/lib/compress/zstd_compress_superblock.c +23 -19
 - data/contrib/zstd/lib/compress/zstd_cwksp.h +60 -24
 - data/contrib/zstd/lib/compress/zstd_double_fast.c +22 -22
 - data/contrib/zstd/lib/compress/zstd_fast.c +19 -19
 - data/contrib/zstd/lib/compress/zstd_lazy.c +351 -77
 - data/contrib/zstd/lib/compress/zstd_lazy.h +20 -0
 - data/contrib/zstd/lib/compress/zstd_ldm.c +59 -18
 - data/contrib/zstd/lib/compress/zstd_ldm.h +6 -0
 - data/contrib/zstd/lib/compress/zstd_opt.c +190 -45
 - data/contrib/zstd/lib/compress/zstdmt_compress.c +74 -406
 - data/contrib/zstd/lib/compress/zstdmt_compress.h +26 -108
 - data/contrib/zstd/lib/decompress/huf_decompress.c +302 -200
 - data/contrib/zstd/lib/decompress/zstd_ddict.c +8 -8
 - data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
 - data/contrib/zstd/lib/decompress/zstd_decompress.c +125 -80
 - data/contrib/zstd/lib/decompress/zstd_decompress_block.c +145 -37
 - data/contrib/zstd/lib/decompress/zstd_decompress_block.h +5 -2
 - data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +11 -10
 - data/contrib/zstd/lib/dictBuilder/cover.c +29 -20
 - data/contrib/zstd/lib/dictBuilder/cover.h +1 -1
 - data/contrib/zstd/lib/dictBuilder/fastcover.c +20 -19
 - data/contrib/zstd/lib/dictBuilder/zdict.c +15 -16
 - data/contrib/zstd/lib/dictBuilder/zdict.h +1 -1
 - data/contrib/zstd/lib/legacy/zstd_v01.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v02.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v03.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v04.c +6 -2
 - data/contrib/zstd/lib/legacy/zstd_v05.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v06.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v07.c +5 -1
 - data/contrib/zstd/lib/libzstd.pc.in +3 -3
 - data/contrib/zstd/lib/zstd.h +348 -47
 - data/ext/extzstd.c +6 -0
 - data/ext/extzstd.h +6 -0
 - data/gemstub.rb +3 -21
 - data/lib/extzstd.rb +0 -2
 - data/lib/extzstd/version.rb +6 -1
 - data/test/test_basic.rb +0 -5
 - metadata +5 -4
 
| 
         @@ -11,8 +11,7 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
            /*-*************************************
         
     | 
| 
       12 
12 
     | 
    
         
             
            *  Dependencies
         
     | 
| 
       13 
13 
     | 
    
         
             
            ***************************************/
         
     | 
| 
       14 
     | 
    
         
            -
            #include  
     | 
| 
       15 
     | 
    
         
            -
            #include <string.h>         /* memset */
         
     | 
| 
      
 14 
     | 
    
         
            +
            #include "../common/zstd_deps.h"  /* INT_MAX, ZSTD_memset, ZSTD_memcpy */
         
     | 
| 
       16 
15 
     | 
    
         
             
            #include "../common/cpu.h"
         
     | 
| 
       17 
16 
     | 
    
         
             
            #include "../common/mem.h"
         
     | 
| 
       18 
17 
     | 
    
         
             
            #include "hist.h"           /* HIST_countFast_wksp */
         
     | 
| 
         @@ -30,6 +29,19 @@ 
     | 
|
| 
       30 
29 
     | 
    
         
             
            #include "zstd_ldm.h"
         
     | 
| 
       31 
30 
     | 
    
         
             
            #include "zstd_compress_superblock.h"
         
     | 
| 
       32 
31 
     | 
    
         | 
| 
      
 32 
     | 
    
         
            +
            /* ***************************************************************
         
     | 
| 
      
 33 
     | 
    
         
            +
            *  Tuning parameters
         
     | 
| 
      
 34 
     | 
    
         
            +
            *****************************************************************/
         
     | 
| 
      
 35 
     | 
    
         
            +
            /*!
         
     | 
| 
      
 36 
     | 
    
         
            +
             * COMPRESS_HEAPMODE :
         
     | 
| 
      
 37 
     | 
    
         
            +
             * Select how default decompression function ZSTD_compress() allocates its context,
         
     | 
| 
      
 38 
     | 
    
         
            +
             * on stack (0, default), or into heap (1).
         
     | 
| 
      
 39 
     | 
    
         
            +
             * Note that functions with explicit context such as ZSTD_compressCCtx() are unaffected.
         
     | 
| 
      
 40 
     | 
    
         
            +
             */
         
     | 
| 
      
 41 
     | 
    
         
            +
            #ifndef ZSTD_COMPRESS_HEAPMODE
         
     | 
| 
      
 42 
     | 
    
         
            +
            #  define ZSTD_COMPRESS_HEAPMODE 0
         
     | 
| 
      
 43 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       33 
45 
     | 
    
         | 
| 
       34 
46 
     | 
    
         
             
            /*-*************************************
         
     | 
| 
       35 
47 
     | 
    
         
             
            *  Helper functions
         
     | 
| 
         @@ -52,6 +64,7 @@ size_t ZSTD_compressBound(size_t srcSize) { 
     | 
|
| 
       52 
64 
     | 
    
         
             
            struct ZSTD_CDict_s {
         
     | 
| 
       53 
65 
     | 
    
         
             
                const void* dictContent;
         
     | 
| 
       54 
66 
     | 
    
         
             
                size_t dictContentSize;
         
     | 
| 
      
 67 
     | 
    
         
            +
                ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */
         
     | 
| 
       55 
68 
     | 
    
         
             
                U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
         
     | 
| 
       56 
69 
     | 
    
         
             
                ZSTD_cwksp workspace;
         
     | 
| 
       57 
70 
     | 
    
         
             
                ZSTD_matchState_t matchState;
         
     | 
| 
         @@ -69,7 +82,7 @@ ZSTD_CCtx* ZSTD_createCCtx(void) 
     | 
|
| 
       69 
82 
     | 
    
         
             
            static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)
         
     | 
| 
       70 
83 
     | 
    
         
             
            {
         
     | 
| 
       71 
84 
     | 
    
         
             
                assert(cctx != NULL);
         
     | 
| 
       72 
     | 
    
         
            -
                 
     | 
| 
      
 85 
     | 
    
         
            +
                ZSTD_memset(cctx, 0, sizeof(*cctx));
         
     | 
| 
       73 
86 
     | 
    
         
             
                cctx->customMem = memManager;
         
     | 
| 
       74 
87 
     | 
    
         
             
                cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
         
     | 
| 
       75 
88 
     | 
    
         
             
                {   size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters);
         
     | 
| 
         @@ -82,8 +95,8 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) 
     | 
|
| 
       82 
95 
     | 
    
         
             
            {
         
     | 
| 
       83 
96 
     | 
    
         
             
                ZSTD_STATIC_ASSERT(zcss_init==0);
         
     | 
| 
       84 
97 
     | 
    
         
             
                ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
         
     | 
| 
       85 
     | 
    
         
            -
                if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
         
     | 
| 
       86 
     | 
    
         
            -
                {   ZSTD_CCtx* const cctx = (ZSTD_CCtx*) 
     | 
| 
      
 98 
     | 
    
         
            +
                if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
         
     | 
| 
      
 99 
     | 
    
         
            +
                {   ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_customMalloc(sizeof(ZSTD_CCtx), customMem);
         
     | 
| 
       87 
100 
     | 
    
         
             
                    if (!cctx) return NULL;
         
     | 
| 
       88 
101 
     | 
    
         
             
                    ZSTD_initCCtx(cctx, customMem);
         
     | 
| 
       89 
102 
     | 
    
         
             
                    return cctx;
         
     | 
| 
         @@ -96,20 +109,20 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) 
     | 
|
| 
       96 
109 
     | 
    
         
             
                ZSTD_CCtx* cctx;
         
     | 
| 
       97 
110 
     | 
    
         
             
                if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL;  /* minimum size */
         
     | 
| 
       98 
111 
     | 
    
         
             
                if ((size_t)workspace & 7) return NULL;  /* must be 8-aligned */
         
     | 
| 
       99 
     | 
    
         
            -
                ZSTD_cwksp_init(&ws, workspace, workspaceSize);
         
     | 
| 
      
 112 
     | 
    
         
            +
                ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc);
         
     | 
| 
       100 
113 
     | 
    
         | 
| 
       101 
114 
     | 
    
         
             
                cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
         
     | 
| 
       102 
115 
     | 
    
         
             
                if (cctx == NULL) return NULL;
         
     | 
| 
       103 
116 
     | 
    
         | 
| 
       104 
     | 
    
         
            -
                 
     | 
| 
      
 117 
     | 
    
         
            +
                ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx));
         
     | 
| 
       105 
118 
     | 
    
         
             
                ZSTD_cwksp_move(&cctx->workspace, &ws);
         
     | 
| 
       106 
119 
     | 
    
         
             
                cctx->staticSize = workspaceSize;
         
     | 
| 
       107 
120 
     | 
    
         | 
| 
       108 
121 
     | 
    
         
             
                /* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
         
     | 
| 
       109 
     | 
    
         
            -
                if (!ZSTD_cwksp_check_available(&cctx->workspace,  
     | 
| 
      
 122 
     | 
    
         
            +
                if (!ZSTD_cwksp_check_available(&cctx->workspace, ENTROPY_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
         
     | 
| 
       110 
123 
     | 
    
         
             
                cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
         
     | 
| 
       111 
124 
     | 
    
         
             
                cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
         
     | 
| 
       112 
     | 
    
         
            -
                cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace,  
     | 
| 
      
 125 
     | 
    
         
            +
                cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, ENTROPY_WORKSPACE_SIZE);
         
     | 
| 
       113 
126 
     | 
    
         
             
                cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
         
     | 
| 
       114 
127 
     | 
    
         
             
                return cctx;
         
     | 
| 
       115 
128 
     | 
    
         
             
            }
         
     | 
| 
         @@ -119,10 +132,10 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) 
     | 
|
| 
       119 
132 
     | 
    
         
             
             */
         
     | 
| 
       120 
133 
     | 
    
         
             
            static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx)
         
     | 
| 
       121 
134 
     | 
    
         
             
            {
         
     | 
| 
       122 
     | 
    
         
            -
                 
     | 
| 
      
 135 
     | 
    
         
            +
                ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem);
         
     | 
| 
       123 
136 
     | 
    
         
             
                ZSTD_freeCDict(cctx->localDict.cdict);
         
     | 
| 
       124 
     | 
    
         
            -
                 
     | 
| 
       125 
     | 
    
         
            -
                 
     | 
| 
      
 137 
     | 
    
         
            +
                ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict));
         
     | 
| 
      
 138 
     | 
    
         
            +
                ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));
         
     | 
| 
       126 
139 
     | 
    
         
             
                cctx->cdict = NULL;
         
     | 
| 
       127 
140 
     | 
    
         
             
            }
         
     | 
| 
       128 
141 
     | 
    
         | 
| 
         @@ -153,7 +166,7 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) 
     | 
|
| 
       153 
166 
     | 
    
         
             
                    int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx);
         
     | 
| 
       154 
167 
     | 
    
         
             
                    ZSTD_freeCCtxContent(cctx);
         
     | 
| 
       155 
168 
     | 
    
         
             
                    if (!cctxInWorkspace) {
         
     | 
| 
       156 
     | 
    
         
            -
                         
     | 
| 
      
 169 
     | 
    
         
            +
                        ZSTD_customFree(cctx, cctx->customMem);
         
     | 
| 
       157 
170 
     | 
    
         
             
                    }
         
     | 
| 
       158 
171 
     | 
    
         
             
                }
         
     | 
| 
       159 
172 
     | 
    
         
             
                return 0;
         
     | 
| 
         @@ -189,15 +202,32 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs) 
     | 
|
| 
       189 
202 
     | 
    
         
             
            /* private API call, for dictBuilder only */
         
     | 
| 
       190 
203 
     | 
    
         
             
            const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
         
     | 
| 
       191 
204 
     | 
    
         | 
| 
      
 205 
     | 
    
         
            +
            /* Returns 1 if compression parameters are such that we should
         
     | 
| 
      
 206 
     | 
    
         
            +
             * enable long distance matching (wlog >= 27, strategy >= btopt).
         
     | 
| 
      
 207 
     | 
    
         
            +
             * Returns 0 otherwise.
         
     | 
| 
      
 208 
     | 
    
         
            +
             */
         
     | 
| 
      
 209 
     | 
    
         
            +
            static U32 ZSTD_CParams_shouldEnableLdm(const ZSTD_compressionParameters* const cParams) {
         
     | 
| 
      
 210 
     | 
    
         
            +
                return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27;
         
     | 
| 
      
 211 
     | 
    
         
            +
            }
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
       192 
213 
     | 
    
         
             
            static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
         
     | 
| 
       193 
214 
     | 
    
         
             
                    ZSTD_compressionParameters cParams)
         
     | 
| 
       194 
215 
     | 
    
         
             
            {
         
     | 
| 
       195 
216 
     | 
    
         
             
                ZSTD_CCtx_params cctxParams;
         
     | 
| 
       196 
     | 
    
         
            -
                 
     | 
| 
      
 217 
     | 
    
         
            +
                /* should not matter, as all cParams are presumed properly defined */
         
     | 
| 
      
 218 
     | 
    
         
            +
                ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT);
         
     | 
| 
       197 
219 
     | 
    
         
             
                cctxParams.cParams = cParams;
         
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
                if (ZSTD_CParams_shouldEnableLdm(&cParams)) {
         
     | 
| 
      
 222 
     | 
    
         
            +
                    DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including LDM into cctx params");
         
     | 
| 
      
 223 
     | 
    
         
            +
                    cctxParams.ldmParams.enableLdm = 1;
         
     | 
| 
      
 224 
     | 
    
         
            +
                    /* LDM is enabled by default for optimal parser and window size >= 128MB */
         
     | 
| 
      
 225 
     | 
    
         
            +
                    ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams);
         
     | 
| 
      
 226 
     | 
    
         
            +
                    assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog);
         
     | 
| 
      
 227 
     | 
    
         
            +
                    assert(cctxParams.ldmParams.hashRateLog < 32);
         
     | 
| 
      
 228 
     | 
    
         
            +
                }
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
       199 
230 
     | 
    
         
             
                assert(!ZSTD_checkCParams(cParams));
         
     | 
| 
       200 
     | 
    
         
            -
                cctxParams.fParams.contentSizeFlag = 1;
         
     | 
| 
       201 
231 
     | 
    
         
             
                return cctxParams;
         
     | 
| 
       202 
232 
     | 
    
         
             
            }
         
     | 
| 
       203 
233 
     | 
    
         | 
| 
         @@ -205,13 +235,12 @@ static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced( 
     | 
|
| 
       205 
235 
     | 
    
         
             
                    ZSTD_customMem customMem)
         
     | 
| 
       206 
236 
     | 
    
         
             
            {
         
     | 
| 
       207 
237 
     | 
    
         
             
                ZSTD_CCtx_params* params;
         
     | 
| 
       208 
     | 
    
         
            -
                if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
         
     | 
| 
       209 
     | 
    
         
            -
                params = (ZSTD_CCtx_params*) 
     | 
| 
      
 238 
     | 
    
         
            +
                if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
         
     | 
| 
      
 239 
     | 
    
         
            +
                params = (ZSTD_CCtx_params*)ZSTD_customCalloc(
         
     | 
| 
       210 
240 
     | 
    
         
             
                        sizeof(ZSTD_CCtx_params), customMem);
         
     | 
| 
       211 
241 
     | 
    
         
             
                if (!params) { return NULL; }
         
     | 
| 
      
 242 
     | 
    
         
            +
                ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);
         
     | 
| 
       212 
243 
     | 
    
         
             
                params->customMem = customMem;
         
     | 
| 
       213 
     | 
    
         
            -
                params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
         
     | 
| 
       214 
     | 
    
         
            -
                params->fParams.contentSizeFlag = 1;
         
     | 
| 
       215 
244 
     | 
    
         
             
                return params;
         
     | 
| 
       216 
245 
     | 
    
         
             
            }
         
     | 
| 
       217 
246 
     | 
    
         | 
| 
         @@ -223,7 +252,7 @@ ZSTD_CCtx_params* ZSTD_createCCtxParams(void) 
     | 
|
| 
       223 
252 
     | 
    
         
             
            size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
         
     | 
| 
       224 
253 
     | 
    
         
             
            {
         
     | 
| 
       225 
254 
     | 
    
         
             
                if (params == NULL) { return 0; }
         
     | 
| 
       226 
     | 
    
         
            -
                 
     | 
| 
      
 255 
     | 
    
         
            +
                ZSTD_customFree(params, params->customMem);
         
     | 
| 
       227 
256 
     | 
    
         
             
                return 0;
         
     | 
| 
       228 
257 
     | 
    
         
             
            }
         
     | 
| 
       229 
258 
     | 
    
         | 
| 
         @@ -234,7 +263,7 @@ size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params) 
     | 
|
| 
       234 
263 
     | 
    
         | 
| 
       235 
264 
     | 
    
         
             
            size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
         
     | 
| 
       236 
265 
     | 
    
         
             
                RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
         
     | 
| 
       237 
     | 
    
         
            -
                 
     | 
| 
      
 266 
     | 
    
         
            +
                ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
         
     | 
| 
       238 
267 
     | 
    
         
             
                cctxParams->compressionLevel = compressionLevel;
         
     | 
| 
       239 
268 
     | 
    
         
             
                cctxParams->fParams.contentSizeFlag = 1;
         
     | 
| 
       240 
269 
     | 
    
         
             
                return 0;
         
     | 
| 
         @@ -244,7 +273,7 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete 
     | 
|
| 
       244 
273 
     | 
    
         
             
            {
         
     | 
| 
       245 
274 
     | 
    
         
             
                RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
         
     | 
| 
       246 
275 
     | 
    
         
             
                FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
         
     | 
| 
       247 
     | 
    
         
            -
                 
     | 
| 
      
 276 
     | 
    
         
            +
                ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
         
     | 
| 
       248 
277 
     | 
    
         
             
                assert(!ZSTD_checkCParams(params.cParams));
         
     | 
| 
       249 
278 
     | 
    
         
             
                cctxParams->cParams = params.cParams;
         
     | 
| 
       250 
279 
     | 
    
         
             
                cctxParams->fParams = params.fParams;
         
     | 
| 
         @@ -354,6 +383,11 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) 
     | 
|
| 
       354 
383 
     | 
    
         
             
            #endif
         
     | 
| 
       355 
384 
     | 
    
         
             
                    return bounds;
         
     | 
| 
       356 
385 
     | 
    
         | 
| 
      
 386 
     | 
    
         
            +
                case ZSTD_c_enableDedicatedDictSearch:
         
     | 
| 
      
 387 
     | 
    
         
            +
                    bounds.lowerBound = 0;
         
     | 
| 
      
 388 
     | 
    
         
            +
                    bounds.upperBound = 1;
         
     | 
| 
      
 389 
     | 
    
         
            +
                    return bounds;
         
     | 
| 
      
 390 
     | 
    
         
            +
             
     | 
| 
       357 
391 
     | 
    
         
             
                case ZSTD_c_enableLongDistanceMatching:
         
     | 
| 
       358 
392 
     | 
    
         
             
                    bounds.lowerBound = 0;
         
     | 
| 
       359 
393 
     | 
    
         
             
                    bounds.upperBound = 1;
         
     | 
| 
         @@ -397,7 +431,7 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) 
     | 
|
| 
       397 
431 
     | 
    
         
             
                    return bounds;
         
     | 
| 
       398 
432 
     | 
    
         | 
| 
       399 
433 
     | 
    
         
             
                case ZSTD_c_forceAttachDict:
         
     | 
| 
       400 
     | 
    
         
            -
                    ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach <  
     | 
| 
      
 434 
     | 
    
         
            +
                    ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad);
         
     | 
| 
       401 
435 
     | 
    
         
             
                    bounds.lowerBound = ZSTD_dictDefaultAttach;
         
     | 
| 
       402 
436 
     | 
    
         
             
                    bounds.upperBound = ZSTD_dictForceLoad;       /* note : how to ensure at compile time that this is the highest value enum ? */
         
     | 
| 
       403 
437 
     | 
    
         
             
                    return bounds;
         
     | 
| 
         @@ -418,6 +452,22 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) 
     | 
|
| 
       418 
452 
     | 
    
         
             
                    bounds.upperBound = ZSTD_SRCSIZEHINT_MAX;
         
     | 
| 
       419 
453 
     | 
    
         
             
                    return bounds;
         
     | 
| 
       420 
454 
     | 
    
         | 
| 
      
 455 
     | 
    
         
            +
                case ZSTD_c_stableInBuffer:
         
     | 
| 
      
 456 
     | 
    
         
            +
                case ZSTD_c_stableOutBuffer:
         
     | 
| 
      
 457 
     | 
    
         
            +
                    bounds.lowerBound = (int)ZSTD_bm_buffered;
         
     | 
| 
      
 458 
     | 
    
         
            +
                    bounds.upperBound = (int)ZSTD_bm_stable;
         
     | 
| 
      
 459 
     | 
    
         
            +
                    return bounds;
         
     | 
| 
      
 460 
     | 
    
         
            +
             
     | 
| 
      
 461 
     | 
    
         
            +
                case ZSTD_c_blockDelimiters:
         
     | 
| 
      
 462 
     | 
    
         
            +
                    bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters;
         
     | 
| 
      
 463 
     | 
    
         
            +
                    bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters;
         
     | 
| 
      
 464 
     | 
    
         
            +
                    return bounds;
         
     | 
| 
      
 465 
     | 
    
         
            +
             
     | 
| 
      
 466 
     | 
    
         
            +
                case ZSTD_c_validateSequences:
         
     | 
| 
      
 467 
     | 
    
         
            +
                    bounds.lowerBound = 0;
         
     | 
| 
      
 468 
     | 
    
         
            +
                    bounds.upperBound = 1;
         
     | 
| 
      
 469 
     | 
    
         
            +
                    return bounds;
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
       421 
471 
     | 
    
         
             
                default:
         
     | 
| 
       422 
472 
     | 
    
         
             
                    bounds.error = ERROR(parameter_unsupported);
         
     | 
| 
       423 
473 
     | 
    
         
             
                    return bounds;
         
     | 
| 
         @@ -465,6 +515,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) 
     | 
|
| 
       465 
515 
     | 
    
         
             
                case ZSTD_c_jobSize:
         
     | 
| 
       466 
516 
     | 
    
         
             
                case ZSTD_c_overlapLog:
         
     | 
| 
       467 
517 
     | 
    
         
             
                case ZSTD_c_rsyncable:
         
     | 
| 
      
 518 
     | 
    
         
            +
                case ZSTD_c_enableDedicatedDictSearch:
         
     | 
| 
       468 
519 
     | 
    
         
             
                case ZSTD_c_enableLongDistanceMatching:
         
     | 
| 
       469 
520 
     | 
    
         
             
                case ZSTD_c_ldmHashLog:
         
     | 
| 
       470 
521 
     | 
    
         
             
                case ZSTD_c_ldmMinMatch:
         
     | 
| 
         @@ -474,6 +525,10 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) 
     | 
|
| 
       474 
525 
     | 
    
         
             
                case ZSTD_c_literalCompressionMode:
         
     | 
| 
       475 
526 
     | 
    
         
             
                case ZSTD_c_targetCBlockSize:
         
     | 
| 
       476 
527 
     | 
    
         
             
                case ZSTD_c_srcSizeHint:
         
     | 
| 
      
 528 
     | 
    
         
            +
                case ZSTD_c_stableInBuffer:
         
     | 
| 
      
 529 
     | 
    
         
            +
                case ZSTD_c_stableOutBuffer:
         
     | 
| 
      
 530 
     | 
    
         
            +
                case ZSTD_c_blockDelimiters:
         
     | 
| 
      
 531 
     | 
    
         
            +
                case ZSTD_c_validateSequences:
         
     | 
| 
       477 
532 
     | 
    
         
             
                default:
         
     | 
| 
       478 
533 
     | 
    
         
             
                    return 0;
         
     | 
| 
       479 
534 
     | 
    
         
             
                }
         
     | 
| 
         @@ -515,12 +570,17 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) 
     | 
|
| 
       515 
570 
     | 
    
         
             
                case ZSTD_c_jobSize:
         
     | 
| 
       516 
571 
     | 
    
         
             
                case ZSTD_c_overlapLog:
         
     | 
| 
       517 
572 
     | 
    
         
             
                case ZSTD_c_rsyncable:
         
     | 
| 
      
 573 
     | 
    
         
            +
                case ZSTD_c_enableDedicatedDictSearch:
         
     | 
| 
       518 
574 
     | 
    
         
             
                case ZSTD_c_enableLongDistanceMatching:
         
     | 
| 
       519 
575 
     | 
    
         
             
                case ZSTD_c_ldmHashLog:
         
     | 
| 
       520 
576 
     | 
    
         
             
                case ZSTD_c_ldmMinMatch:
         
     | 
| 
       521 
577 
     | 
    
         
             
                case ZSTD_c_ldmBucketSizeLog:
         
     | 
| 
       522 
578 
     | 
    
         
             
                case ZSTD_c_targetCBlockSize:
         
     | 
| 
       523 
579 
     | 
    
         
             
                case ZSTD_c_srcSizeHint:
         
     | 
| 
      
 580 
     | 
    
         
            +
                case ZSTD_c_stableInBuffer:
         
     | 
| 
      
 581 
     | 
    
         
            +
                case ZSTD_c_stableOutBuffer:
         
     | 
| 
      
 582 
     | 
    
         
            +
                case ZSTD_c_blockDelimiters:
         
     | 
| 
      
 583 
     | 
    
         
            +
                case ZSTD_c_validateSequences:
         
     | 
| 
       524 
584 
     | 
    
         
             
                    break;
         
     | 
| 
       525 
585 
     | 
    
         | 
| 
       526 
586 
     | 
    
         
             
                default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
         
     | 
| 
         @@ -541,9 +601,10 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, 
     | 
|
| 
       541 
601 
     | 
    
         | 
| 
       542 
602 
     | 
    
         
             
                case ZSTD_c_compressionLevel : {
         
     | 
| 
       543 
603 
     | 
    
         
             
                    FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
         
     | 
| 
       544 
     | 
    
         
            -
                    if (value 
     | 
| 
      
 604 
     | 
    
         
            +
                    if (value == 0)
         
     | 
| 
      
 605 
     | 
    
         
            +
                        CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
         
     | 
| 
      
 606 
     | 
    
         
            +
                    else
         
     | 
| 
       545 
607 
     | 
    
         
             
                        CCtxParams->compressionLevel = value;
         
     | 
| 
       546 
     | 
    
         
            -
                    }
         
     | 
| 
       547 
608 
     | 
    
         
             
                    if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel;
         
     | 
| 
       548 
609 
     | 
    
         
             
                    return 0;  /* return type (size_t) cannot represent negative values */
         
     | 
| 
       549 
610 
     | 
    
         
             
                }
         
     | 
| 
         @@ -667,6 +728,10 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, 
     | 
|
| 
       667 
728 
     | 
    
         
             
                    return CCtxParams->rsyncable;
         
     | 
| 
       668 
729 
     | 
    
         
             
            #endif
         
     | 
| 
       669 
730 
     | 
    
         | 
| 
      
 731 
     | 
    
         
            +
                case ZSTD_c_enableDedicatedDictSearch :
         
     | 
| 
      
 732 
     | 
    
         
            +
                    CCtxParams->enableDedicatedDictSearch = (value!=0);
         
     | 
| 
      
 733 
     | 
    
         
            +
                    return CCtxParams->enableDedicatedDictSearch;
         
     | 
| 
      
 734 
     | 
    
         
            +
             
     | 
| 
       670 
735 
     | 
    
         
             
                case ZSTD_c_enableLongDistanceMatching :
         
     | 
| 
       671 
736 
     | 
    
         
             
                    CCtxParams->ldmParams.enableLdm = (value!=0);
         
     | 
| 
       672 
737 
     | 
    
         
             
                    return CCtxParams->ldmParams.enableLdm;
         
     | 
| 
         @@ -707,6 +772,26 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, 
     | 
|
| 
       707 
772 
     | 
    
         
             
                    CCtxParams->srcSizeHint = value;
         
     | 
| 
       708 
773 
     | 
    
         
             
                    return CCtxParams->srcSizeHint;
         
     | 
| 
       709 
774 
     | 
    
         | 
| 
      
 775 
     | 
    
         
            +
                case ZSTD_c_stableInBuffer:
         
     | 
| 
      
 776 
     | 
    
         
            +
                    BOUNDCHECK(ZSTD_c_stableInBuffer, value);
         
     | 
| 
      
 777 
     | 
    
         
            +
                    CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value;
         
     | 
| 
      
 778 
     | 
    
         
            +
                    return CCtxParams->inBufferMode;
         
     | 
| 
      
 779 
     | 
    
         
            +
             
     | 
| 
      
 780 
     | 
    
         
            +
                case ZSTD_c_stableOutBuffer:
         
     | 
| 
      
 781 
     | 
    
         
            +
                    BOUNDCHECK(ZSTD_c_stableOutBuffer, value);
         
     | 
| 
      
 782 
     | 
    
         
            +
                    CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value;
         
     | 
| 
      
 783 
     | 
    
         
            +
                    return CCtxParams->outBufferMode;
         
     | 
| 
      
 784 
     | 
    
         
            +
             
     | 
| 
      
 785 
     | 
    
         
            +
                case ZSTD_c_blockDelimiters:
         
     | 
| 
      
 786 
     | 
    
         
            +
                    BOUNDCHECK(ZSTD_c_blockDelimiters, value);
         
     | 
| 
      
 787 
     | 
    
         
            +
                    CCtxParams->blockDelimiters = (ZSTD_sequenceFormat_e)value;
         
     | 
| 
      
 788 
     | 
    
         
            +
                    return CCtxParams->blockDelimiters;
         
     | 
| 
      
 789 
     | 
    
         
            +
             
     | 
| 
      
 790 
     | 
    
         
            +
                case ZSTD_c_validateSequences:
         
     | 
| 
      
 791 
     | 
    
         
            +
                    BOUNDCHECK(ZSTD_c_validateSequences, value);
         
     | 
| 
      
 792 
     | 
    
         
            +
                    CCtxParams->validateSequences = value;
         
     | 
| 
      
 793 
     | 
    
         
            +
                    return CCtxParams->validateSequences;
         
     | 
| 
      
 794 
     | 
    
         
            +
             
     | 
| 
       710 
795 
     | 
    
         
             
                default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
         
     | 
| 
       711 
796 
     | 
    
         
             
                }
         
     | 
| 
       712 
797 
     | 
    
         
             
            }
         
     | 
| 
         @@ -794,6 +879,9 @@ size_t ZSTD_CCtxParams_getParameter( 
     | 
|
| 
       794 
879 
     | 
    
         
             
                    *value = CCtxParams->rsyncable;
         
     | 
| 
       795 
880 
     | 
    
         
             
                    break;
         
     | 
| 
       796 
881 
     | 
    
         
             
            #endif
         
     | 
| 
      
 882 
     | 
    
         
            +
                case ZSTD_c_enableDedicatedDictSearch :
         
     | 
| 
      
 883 
     | 
    
         
            +
                    *value = CCtxParams->enableDedicatedDictSearch;
         
     | 
| 
      
 884 
     | 
    
         
            +
                    break;
         
     | 
| 
       797 
885 
     | 
    
         
             
                case ZSTD_c_enableLongDistanceMatching :
         
     | 
| 
       798 
886 
     | 
    
         
             
                    *value = CCtxParams->ldmParams.enableLdm;
         
     | 
| 
       799 
887 
     | 
    
         
             
                    break;
         
     | 
| 
         @@ -815,6 +903,18 @@ size_t ZSTD_CCtxParams_getParameter( 
     | 
|
| 
       815 
903 
     | 
    
         
             
                case ZSTD_c_srcSizeHint :
         
     | 
| 
       816 
904 
     | 
    
         
             
                    *value = (int)CCtxParams->srcSizeHint;
         
     | 
| 
       817 
905 
     | 
    
         
             
                    break;
         
     | 
| 
      
 906 
     | 
    
         
            +
                case ZSTD_c_stableInBuffer :
         
     | 
| 
      
 907 
     | 
    
         
            +
                    *value = (int)CCtxParams->inBufferMode;
         
     | 
| 
      
 908 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 909 
     | 
    
         
            +
                case ZSTD_c_stableOutBuffer :
         
     | 
| 
      
 910 
     | 
    
         
            +
                    *value = (int)CCtxParams->outBufferMode;
         
     | 
| 
      
 911 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 912 
     | 
    
         
            +
                case ZSTD_c_blockDelimiters :
         
     | 
| 
      
 913 
     | 
    
         
            +
                    *value = (int)CCtxParams->blockDelimiters;
         
     | 
| 
      
 914 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 915 
     | 
    
         
            +
                case ZSTD_c_validateSequences :
         
     | 
| 
      
 916 
     | 
    
         
            +
                    *value = (int)CCtxParams->validateSequences;
         
     | 
| 
      
 917 
     | 
    
         
            +
                    break;
         
     | 
| 
       818 
918 
     | 
    
         
             
                default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
         
     | 
| 
       819 
919 
     | 
    
         
             
                }
         
     | 
| 
       820 
920 
     | 
    
         
             
                return 0;
         
     | 
| 
         @@ -850,6 +950,14 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo 
     | 
|
| 
       850 
950 
     | 
    
         
             
                return 0;
         
     | 
| 
       851 
951 
     | 
    
         
             
            }
         
     | 
| 
       852 
952 
     | 
    
         | 
| 
      
 953 
     | 
    
         
            +
            static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(
         
     | 
| 
      
 954 
     | 
    
         
            +
                    int const compressionLevel,
         
     | 
| 
      
 955 
     | 
    
         
            +
                    size_t const dictSize);
         
     | 
| 
      
 956 
     | 
    
         
            +
            static int ZSTD_dedicatedDictSearch_isSupported(
         
     | 
| 
      
 957 
     | 
    
         
            +
                    const ZSTD_compressionParameters* cParams);
         
     | 
| 
      
 958 
     | 
    
         
            +
            static void ZSTD_dedicatedDictSearch_revertCParams(
         
     | 
| 
      
 959 
     | 
    
         
            +
                    ZSTD_compressionParameters* cParams);
         
     | 
| 
      
 960 
     | 
    
         
            +
             
     | 
| 
       853 
961 
     | 
    
         
             
            /**
         
     | 
| 
       854 
962 
     | 
    
         
             
             * Initializes the local dict using the requested parameters.
         
     | 
| 
       855 
963 
     | 
    
         
             
             * NOTE: This does not use the pledged src size, because it may be used for more
         
     | 
| 
         @@ -858,8 +966,6 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo 
     | 
|
| 
       858 
966 
     | 
    
         
             
            static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
         
     | 
| 
       859 
967 
     | 
    
         
             
            {
         
     | 
| 
       860 
968 
     | 
    
         
             
                ZSTD_localDict* const dl = &cctx->localDict;
         
     | 
| 
       861 
     | 
    
         
            -
                ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(
         
     | 
| 
       862 
     | 
    
         
            -
                        &cctx->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN, dl->dictSize);
         
     | 
| 
       863 
969 
     | 
    
         
             
                if (dl->dict == NULL) {
         
     | 
| 
       864 
970 
     | 
    
         
             
                    /* No local dictionary. */
         
     | 
| 
       865 
971 
     | 
    
         
             
                    assert(dl->dictBuffer == NULL);
         
     | 
| 
         @@ -876,12 +982,12 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx) 
     | 
|
| 
       876 
982 
     | 
    
         
             
                assert(cctx->cdict == NULL);
         
     | 
| 
       877 
983 
     | 
    
         
             
                assert(cctx->prefixDict.dict == NULL);
         
     | 
| 
       878 
984 
     | 
    
         | 
| 
       879 
     | 
    
         
            -
                dl->cdict =  
     | 
| 
      
 985 
     | 
    
         
            +
                dl->cdict = ZSTD_createCDict_advanced2(
         
     | 
| 
       880 
986 
     | 
    
         
             
                        dl->dict,
         
     | 
| 
       881 
987 
     | 
    
         
             
                        dl->dictSize,
         
     | 
| 
       882 
988 
     | 
    
         
             
                        ZSTD_dlm_byRef,
         
     | 
| 
       883 
989 
     | 
    
         
             
                        dl->dictContentType,
         
     | 
| 
       884 
     | 
    
         
            -
                         
     | 
| 
      
 990 
     | 
    
         
            +
                        &cctx->requestedParams,
         
     | 
| 
       885 
991 
     | 
    
         
             
                        cctx->customMem);
         
     | 
| 
       886 
992 
     | 
    
         
             
                RETURN_ERROR_IF(!dl->cdict, memory_allocation, "ZSTD_createCDict_advanced failed");
         
     | 
| 
       887 
993 
     | 
    
         
             
                cctx->cdict = dl->cdict;
         
     | 
| 
         @@ -894,8 +1000,6 @@ size_t ZSTD_CCtx_loadDictionary_advanced( 
     | 
|
| 
       894 
1000 
     | 
    
         
             
            {
         
     | 
| 
       895 
1001 
     | 
    
         
             
                RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
         
     | 
| 
       896 
1002 
     | 
    
         
             
                                "Can't load a dictionary when ctx is not in init stage.");
         
     | 
| 
       897 
     | 
    
         
            -
                RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
         
     | 
| 
       898 
     | 
    
         
            -
                                "no malloc for static CCtx");
         
     | 
| 
       899 
1003 
     | 
    
         
             
                DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
         
     | 
| 
       900 
1004 
     | 
    
         
             
                ZSTD_clearAllDicts(cctx);  /* in case one already exists */
         
     | 
| 
       901 
1005 
     | 
    
         
             
                if (dict == NULL || dictSize == 0)  /* no dictionary mode */
         
     | 
| 
         @@ -903,9 +1007,12 @@ size_t ZSTD_CCtx_loadDictionary_advanced( 
     | 
|
| 
       903 
1007 
     | 
    
         
             
                if (dictLoadMethod == ZSTD_dlm_byRef) {
         
     | 
| 
       904 
1008 
     | 
    
         
             
                    cctx->localDict.dict = dict;
         
     | 
| 
       905 
1009 
     | 
    
         
             
                } else {
         
     | 
| 
       906 
     | 
    
         
            -
                    void* dictBuffer 
     | 
| 
      
 1010 
     | 
    
         
            +
                    void* dictBuffer;
         
     | 
| 
      
 1011 
     | 
    
         
            +
                    RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
         
     | 
| 
      
 1012 
     | 
    
         
            +
                                    "no malloc for static CCtx");
         
     | 
| 
      
 1013 
     | 
    
         
            +
                    dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem);
         
     | 
| 
       907 
1014 
     | 
    
         
             
                    RETURN_ERROR_IF(!dictBuffer, memory_allocation, "NULL pointer!");
         
     | 
| 
       908 
     | 
    
         
            -
                     
     | 
| 
      
 1015 
     | 
    
         
            +
                    ZSTD_memcpy(dictBuffer, dict, dictSize);
         
     | 
| 
       909 
1016 
     | 
    
         
             
                    cctx->localDict.dictBuffer = dictBuffer;
         
     | 
| 
       910 
1017 
     | 
    
         
             
                    cctx->localDict.dict = dictBuffer;
         
     | 
| 
       911 
1018 
     | 
    
         
             
                }
         
     | 
| 
         @@ -938,6 +1045,14 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) 
     | 
|
| 
       938 
1045 
     | 
    
         
             
                return 0;
         
     | 
| 
       939 
1046 
     | 
    
         
             
            }
         
     | 
| 
       940 
1047 
     | 
    
         | 
| 
      
 1048 
     | 
    
         
            +
            size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool)
         
     | 
| 
      
 1049 
     | 
    
         
            +
            {
         
     | 
| 
      
 1050 
     | 
    
         
            +
                RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
         
     | 
| 
      
 1051 
     | 
    
         
            +
                                "Can't ref a pool when ctx not in init stage.");
         
     | 
| 
      
 1052 
     | 
    
         
            +
                cctx->pool = pool;
         
     | 
| 
      
 1053 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 1054 
     | 
    
         
            +
            }
         
     | 
| 
      
 1055 
     | 
    
         
            +
             
     | 
| 
       941 
1056 
     | 
    
         
             
            size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
         
     | 
| 
       942 
1057 
     | 
    
         
             
            {
         
     | 
| 
       943 
1058 
     | 
    
         
             
                return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent);
         
     | 
| 
         @@ -1022,24 +1137,73 @@ U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) 
     | 
|
| 
       1022 
1137 
     | 
    
         
             
                return hashLog - btScale;
         
     | 
| 
       1023 
1138 
     | 
    
         
             
            }
         
     | 
| 
       1024 
1139 
     | 
    
         | 
| 
      
 1140 
     | 
    
         
            +
            /** ZSTD_dictAndWindowLog() :
         
     | 
| 
      
 1141 
     | 
    
         
            +
             * Returns an adjusted window log that is large enough to fit the source and the dictionary.
         
     | 
| 
      
 1142 
     | 
    
         
            +
             * The zstd format says that the entire dictionary is valid if one byte of the dictionary
         
     | 
| 
      
 1143 
     | 
    
         
            +
             * is within the window. So the hashLog and chainLog should be large enough to reference both
         
     | 
| 
      
 1144 
     | 
    
         
            +
             * the dictionary and the window. So we must use this adjusted dictAndWindowLog when downsizing
         
     | 
| 
      
 1145 
     | 
    
         
            +
             * the hashLog and windowLog.
         
     | 
| 
      
 1146 
     | 
    
         
            +
             * NOTE: srcSize must not be ZSTD_CONTENTSIZE_UNKNOWN.
         
     | 
| 
      
 1147 
     | 
    
         
            +
             */
         
     | 
| 
      
 1148 
     | 
    
         
            +
            static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize)
         
     | 
| 
      
 1149 
     | 
    
         
            +
            {
         
     | 
| 
      
 1150 
     | 
    
         
            +
                const U64 maxWindowSize = 1ULL << ZSTD_WINDOWLOG_MAX;
         
     | 
| 
      
 1151 
     | 
    
         
            +
                /* No dictionary ==> No change */
         
     | 
| 
      
 1152 
     | 
    
         
            +
                if (dictSize == 0) {
         
     | 
| 
      
 1153 
     | 
    
         
            +
                    return windowLog;
         
     | 
| 
      
 1154 
     | 
    
         
            +
                }
         
     | 
| 
      
 1155 
     | 
    
         
            +
                assert(windowLog <= ZSTD_WINDOWLOG_MAX);
         
     | 
| 
      
 1156 
     | 
    
         
            +
                assert(srcSize != ZSTD_CONTENTSIZE_UNKNOWN); /* Handled in ZSTD_adjustCParams_internal() */
         
     | 
| 
      
 1157 
     | 
    
         
            +
                {
         
     | 
| 
      
 1158 
     | 
    
         
            +
                    U64 const windowSize = 1ULL << windowLog;
         
     | 
| 
      
 1159 
     | 
    
         
            +
                    U64 const dictAndWindowSize = dictSize + windowSize;
         
     | 
| 
      
 1160 
     | 
    
         
            +
                    /* If the window size is already large enough to fit both the source and the dictionary
         
     | 
| 
      
 1161 
     | 
    
         
            +
                     * then just use the window size. Otherwise adjust so that it fits the dictionary and
         
     | 
| 
      
 1162 
     | 
    
         
            +
                     * the window.
         
     | 
| 
      
 1163 
     | 
    
         
            +
                     */
         
     | 
| 
      
 1164 
     | 
    
         
            +
                    if (windowSize >= dictSize + srcSize) {
         
     | 
| 
      
 1165 
     | 
    
         
            +
                        return windowLog; /* Window size large enough already */
         
     | 
| 
      
 1166 
     | 
    
         
            +
                    } else if (dictAndWindowSize >= maxWindowSize) {
         
     | 
| 
      
 1167 
     | 
    
         
            +
                        return ZSTD_WINDOWLOG_MAX; /* Larger than max window log */
         
     | 
| 
      
 1168 
     | 
    
         
            +
                    } else  {
         
     | 
| 
      
 1169 
     | 
    
         
            +
                        return ZSTD_highbit32((U32)dictAndWindowSize - 1) + 1;
         
     | 
| 
      
 1170 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1171 
     | 
    
         
            +
                }
         
     | 
| 
      
 1172 
     | 
    
         
            +
            }
         
     | 
| 
      
 1173 
     | 
    
         
            +
             
     | 
| 
       1025 
1174 
     | 
    
         
             
            /** ZSTD_adjustCParams_internal() :
         
     | 
| 
       1026 
1175 
     | 
    
         
             
             *  optimize `cPar` for a specified input (`srcSize` and `dictSize`).
         
     | 
| 
       1027 
1176 
     | 
    
         
             
             *  mostly downsize to reduce memory consumption and initialization latency.
         
     | 
| 
       1028 
1177 
     | 
    
         
             
             * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
         
     | 
| 
      
 1178 
     | 
    
         
            +
             * `mode` is the mode for parameter adjustment. See docs for `ZSTD_cParamMode_e`.
         
     | 
| 
       1029 
1179 
     | 
    
         
             
             *  note : `srcSize==0` means 0!
         
     | 
| 
       1030 
1180 
     | 
    
         
             
             *  condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
         
     | 
| 
       1031 
1181 
     | 
    
         
             
            static ZSTD_compressionParameters
         
     | 
| 
       1032 
1182 
     | 
    
         
             
            ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
         
     | 
| 
       1033 
1183 
     | 
    
         
             
                                        unsigned long long srcSize,
         
     | 
| 
       1034 
     | 
    
         
            -
                                        size_t dictSize 
     | 
| 
      
 1184 
     | 
    
         
            +
                                        size_t dictSize,
         
     | 
| 
      
 1185 
     | 
    
         
            +
                                        ZSTD_cParamMode_e mode)
         
     | 
| 
       1035 
1186 
     | 
    
         
             
            {
         
     | 
| 
       1036 
     | 
    
         
            -
                 
     | 
| 
       1037 
     | 
    
         
            -
                 
     | 
| 
      
 1187 
     | 
    
         
            +
                const U64 minSrcSize = 513; /* (1<<9) + 1 */
         
     | 
| 
      
 1188 
     | 
    
         
            +
                const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
         
     | 
| 
       1038 
1189 
     | 
    
         
             
                assert(ZSTD_checkCParams(cPar)==0);
         
     | 
| 
       1039 
1190 
     | 
    
         | 
| 
       1040 
1191 
     | 
    
         
             
                if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
         
     | 
| 
       1041 
1192 
     | 
    
         
             
                    srcSize = minSrcSize;
         
     | 
| 
       1042 
1193 
     | 
    
         | 
| 
      
 1194 
     | 
    
         
            +
                switch (mode) {
         
     | 
| 
      
 1195 
     | 
    
         
            +
                case ZSTD_cpm_noAttachDict:
         
     | 
| 
      
 1196 
     | 
    
         
            +
                case ZSTD_cpm_unknown:
         
     | 
| 
      
 1197 
     | 
    
         
            +
                case ZSTD_cpm_createCDict:
         
     | 
| 
      
 1198 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1199 
     | 
    
         
            +
                case ZSTD_cpm_attachDict:
         
     | 
| 
      
 1200 
     | 
    
         
            +
                    dictSize = 0;
         
     | 
| 
      
 1201 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1202 
     | 
    
         
            +
                default:
         
     | 
| 
      
 1203 
     | 
    
         
            +
                    assert(0);
         
     | 
| 
      
 1204 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1205 
     | 
    
         
            +
                }
         
     | 
| 
      
 1206 
     | 
    
         
            +
             
     | 
| 
       1043 
1207 
     | 
    
         
             
                /* resize windowLog if input is small enough, to use less memory */
         
     | 
| 
       1044 
1208 
     | 
    
         
             
                if ( (srcSize < maxWindowResize)
         
     | 
| 
       1045 
1209 
     | 
    
         
             
                  && (dictSize < maxWindowResize) )  {
         
     | 
| 
         @@ -1049,10 +1213,11 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, 
     | 
|
| 
       1049 
1213 
     | 
    
         
             
                                        ZSTD_highbit32(tSize-1) + 1;
         
     | 
| 
       1050 
1214 
     | 
    
         
             
                    if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
         
     | 
| 
       1051 
1215 
     | 
    
         
             
                }
         
     | 
| 
       1052 
     | 
    
         
            -
                 
     | 
| 
       1053 
     | 
    
         
            -
             
     | 
| 
       1054 
     | 
    
         
            -
                    if ( 
     | 
| 
       1055 
     | 
    
         
            -
             
     | 
| 
      
 1216 
     | 
    
         
            +
                {   U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize);
         
     | 
| 
      
 1217 
     | 
    
         
            +
                    U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
         
     | 
| 
      
 1218 
     | 
    
         
            +
                    if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1;
         
     | 
| 
      
 1219 
     | 
    
         
            +
                    if (cycleLog > dictAndWindowLog)
         
     | 
| 
      
 1220 
     | 
    
         
            +
                        cPar.chainLog -= (cycleLog - dictAndWindowLog);
         
     | 
| 
       1056 
1221 
     | 
    
         
             
                }
         
     | 
| 
       1057 
1222 
     | 
    
         | 
| 
       1058 
1223 
     | 
    
         
             
                if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN)
         
     | 
| 
         @@ -1068,31 +1233,38 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar, 
     | 
|
| 
       1068 
1233 
     | 
    
         
             
            {
         
     | 
| 
       1069 
1234 
     | 
    
         
             
                cPar = ZSTD_clampCParams(cPar);   /* resulting cPar is necessarily valid (all parameters within range) */
         
     | 
| 
       1070 
1235 
     | 
    
         
             
                if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN;
         
     | 
| 
       1071 
     | 
    
         
            -
                return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
         
     | 
| 
      
 1236 
     | 
    
         
            +
                return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown);
         
     | 
| 
       1072 
1237 
     | 
    
         
             
            }
         
     | 
| 
       1073 
1238 
     | 
    
         | 
| 
       1074 
     | 
    
         
            -
            static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
         
     | 
| 
       1075 
     | 
    
         
            -
            static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
         
     | 
| 
      
 1239 
     | 
    
         
            +
            static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
         
     | 
| 
      
 1240 
     | 
    
         
            +
            static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
         
     | 
| 
      
 1241 
     | 
    
         
            +
             
     | 
| 
      
 1242 
     | 
    
         
            +
            static void ZSTD_overrideCParams(
         
     | 
| 
      
 1243 
     | 
    
         
            +
                          ZSTD_compressionParameters* cParams,
         
     | 
| 
      
 1244 
     | 
    
         
            +
                    const ZSTD_compressionParameters* overrides)
         
     | 
| 
      
 1245 
     | 
    
         
            +
            {
         
     | 
| 
      
 1246 
     | 
    
         
            +
                if (overrides->windowLog)    cParams->windowLog    = overrides->windowLog;
         
     | 
| 
      
 1247 
     | 
    
         
            +
                if (overrides->hashLog)      cParams->hashLog      = overrides->hashLog;
         
     | 
| 
      
 1248 
     | 
    
         
            +
                if (overrides->chainLog)     cParams->chainLog     = overrides->chainLog;
         
     | 
| 
      
 1249 
     | 
    
         
            +
                if (overrides->searchLog)    cParams->searchLog    = overrides->searchLog;
         
     | 
| 
      
 1250 
     | 
    
         
            +
                if (overrides->minMatch)     cParams->minMatch     = overrides->minMatch;
         
     | 
| 
      
 1251 
     | 
    
         
            +
                if (overrides->targetLength) cParams->targetLength = overrides->targetLength;
         
     | 
| 
      
 1252 
     | 
    
         
            +
                if (overrides->strategy)     cParams->strategy     = overrides->strategy;
         
     | 
| 
      
 1253 
     | 
    
         
            +
            }
         
     | 
| 
       1076 
1254 
     | 
    
         | 
| 
       1077 
1255 
     | 
    
         
             
            ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
         
     | 
| 
       1078 
     | 
    
         
            -
                    const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
         
     | 
| 
      
 1256 
     | 
    
         
            +
                    const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
         
     | 
| 
       1079 
1257 
     | 
    
         
             
            {
         
     | 
| 
       1080 
1258 
     | 
    
         
             
                ZSTD_compressionParameters cParams;
         
     | 
| 
       1081 
1259 
     | 
    
         
             
                if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
         
     | 
| 
       1082 
1260 
     | 
    
         
             
                  srcSizeHint = CCtxParams->srcSizeHint;
         
     | 
| 
       1083 
1261 
     | 
    
         
             
                }
         
     | 
| 
       1084 
     | 
    
         
            -
                cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize);
         
     | 
| 
      
 1262 
     | 
    
         
            +
                cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode);
         
     | 
| 
       1085 
1263 
     | 
    
         
             
                if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
         
     | 
| 
       1086 
     | 
    
         
            -
                 
     | 
| 
       1087 
     | 
    
         
            -
                if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
         
     | 
| 
       1088 
     | 
    
         
            -
                if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
         
     | 
| 
       1089 
     | 
    
         
            -
                if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
         
     | 
| 
       1090 
     | 
    
         
            -
                if (CCtxParams->cParams.minMatch) cParams.minMatch = CCtxParams->cParams.minMatch;
         
     | 
| 
       1091 
     | 
    
         
            -
                if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
         
     | 
| 
       1092 
     | 
    
         
            -
                if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
         
     | 
| 
      
 1264 
     | 
    
         
            +
                ZSTD_overrideCParams(&cParams, &CCtxParams->cParams);
         
     | 
| 
       1093 
1265 
     | 
    
         
             
                assert(!ZSTD_checkCParams(cParams));
         
     | 
| 
       1094 
1266 
     | 
    
         
             
                /* srcSizeHint == 0 means 0 */
         
     | 
| 
       1095 
     | 
    
         
            -
                return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
         
     | 
| 
      
 1267 
     | 
    
         
            +
                return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode);
         
     | 
| 
       1096 
1268 
     | 
    
         
             
            }
         
     | 
| 
       1097 
1269 
     | 
    
         | 
| 
       1098 
1270 
     | 
    
         
             
            static size_t
         
     | 
| 
         @@ -1123,45 +1295,61 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, 
     | 
|
| 
       1123 
1295 
     | 
    
         
             
                return tableSpace + optSpace;
         
     | 
| 
       1124 
1296 
     | 
    
         
             
            }
         
     | 
| 
       1125 
1297 
     | 
    
         | 
| 
       1126 
     | 
    
         
            -
            size_t  
     | 
| 
      
 1298 
     | 
    
         
            +
            static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
         
     | 
| 
      
 1299 
     | 
    
         
            +
                    const ZSTD_compressionParameters* cParams,
         
     | 
| 
      
 1300 
     | 
    
         
            +
                    const ldmParams_t* ldmParams,
         
     | 
| 
      
 1301 
     | 
    
         
            +
                    const int isStatic,
         
     | 
| 
      
 1302 
     | 
    
         
            +
                    const size_t buffInSize,
         
     | 
| 
      
 1303 
     | 
    
         
            +
                    const size_t buffOutSize,
         
     | 
| 
      
 1304 
     | 
    
         
            +
                    const U64 pledgedSrcSize)
         
     | 
| 
       1127 
1305 
     | 
    
         
             
            {
         
     | 
| 
       1128 
     | 
    
         
            -
                 
     | 
| 
       1129 
     | 
    
         
            -
                 
     | 
| 
       1130 
     | 
    
         
            -
             
     | 
| 
       1131 
     | 
    
         
            -
             
     | 
| 
       1132 
     | 
    
         
            -
             
     | 
| 
       1133 
     | 
    
         
            -
             
     | 
| 
       1134 
     | 
    
         
            -
             
     | 
| 
       1135 
     | 
    
         
            -
             
     | 
| 
       1136 
     | 
    
         
            -
             
     | 
| 
       1137 
     | 
    
         
            -
             
     | 
| 
       1138 
     | 
    
         
            -
                    size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
         
     | 
| 
       1139 
     | 
    
         
            -
                    size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
         
     | 
| 
      
 1306 
     | 
    
         
            +
                size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << cParams->windowLog), pledgedSrcSize));
         
     | 
| 
      
 1307 
     | 
    
         
            +
                size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
         
     | 
| 
      
 1308 
     | 
    
         
            +
                U32    const divider = (cParams->minMatch==3) ? 3 : 4;
         
     | 
| 
      
 1309 
     | 
    
         
            +
                size_t const maxNbSeq = blockSize / divider;
         
     | 
| 
      
 1310 
     | 
    
         
            +
                size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
         
     | 
| 
      
 1311 
     | 
    
         
            +
                                        + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
         
     | 
| 
      
 1312 
     | 
    
         
            +
                                        + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
         
     | 
| 
      
 1313 
     | 
    
         
            +
                size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE);
         
     | 
| 
      
 1314 
     | 
    
         
            +
                size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
         
     | 
| 
      
 1315 
     | 
    
         
            +
                size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, /* forCCtx */ 1);
         
     | 
| 
       1140 
1316 
     | 
    
         | 
| 
       1141 
     | 
    
         
            -
             
     | 
| 
       1142 
     | 
    
         
            -
             
     | 
| 
      
 1317 
     | 
    
         
            +
                size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
         
     | 
| 
      
 1318 
     | 
    
         
            +
                size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
         
     | 
| 
      
 1319 
     | 
    
         
            +
                size_t const ldmSeqSpace = ldmParams->enableLdm ?
         
     | 
| 
      
 1320 
     | 
    
         
            +
                    ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
         
     | 
| 
       1143 
1321 
     | 
    
         | 
| 
       1144 
     | 
    
         
            -
                    /* estimateCCtxSize is for one-shot compression. So no buffers should
         
     | 
| 
       1145 
     | 
    
         
            -
                     * be needed. However, we still allocate two 0-sized buffers, which can
         
     | 
| 
       1146 
     | 
    
         
            -
                     * take space under ASAN. */
         
     | 
| 
       1147 
     | 
    
         
            -
                    size_t const bufferSpace = ZSTD_cwksp_alloc_size(0)
         
     | 
| 
       1148 
     | 
    
         
            -
                                             + ZSTD_cwksp_alloc_size(0);
         
     | 
| 
       1149 
1322 
     | 
    
         | 
| 
       1150 
     | 
    
         
            -
             
     | 
| 
      
 1323 
     | 
    
         
            +
                size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
         
     | 
| 
      
 1324 
     | 
    
         
            +
                                         + ZSTD_cwksp_alloc_size(buffOutSize);
         
     | 
| 
       1151 
1325 
     | 
    
         | 
| 
       1152 
     | 
    
         
            -
             
     | 
| 
       1153 
     | 
    
         
            -
                        cctxSpace +
         
     | 
| 
       1154 
     | 
    
         
            -
                        entropySpace +
         
     | 
| 
       1155 
     | 
    
         
            -
                        blockStateSpace +
         
     | 
| 
       1156 
     | 
    
         
            -
                        ldmSpace +
         
     | 
| 
       1157 
     | 
    
         
            -
                        ldmSeqSpace +
         
     | 
| 
       1158 
     | 
    
         
            -
                        matchStateSize +
         
     | 
| 
       1159 
     | 
    
         
            -
                        tokenSpace +
         
     | 
| 
       1160 
     | 
    
         
            -
                        bufferSpace;
         
     | 
| 
      
 1326 
     | 
    
         
            +
                size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
         
     | 
| 
       1161 
1327 
     | 
    
         | 
| 
       1162 
     | 
    
         
            -
             
     | 
| 
       1163 
     | 
    
         
            -
                     
     | 
| 
       1164 
     | 
    
         
            -
             
     | 
| 
      
 1328 
     | 
    
         
            +
                size_t const neededSpace =
         
     | 
| 
      
 1329 
     | 
    
         
            +
                    cctxSpace +
         
     | 
| 
      
 1330 
     | 
    
         
            +
                    entropySpace +
         
     | 
| 
      
 1331 
     | 
    
         
            +
                    blockStateSpace +
         
     | 
| 
      
 1332 
     | 
    
         
            +
                    ldmSpace +
         
     | 
| 
      
 1333 
     | 
    
         
            +
                    ldmSeqSpace +
         
     | 
| 
      
 1334 
     | 
    
         
            +
                    matchStateSize +
         
     | 
| 
      
 1335 
     | 
    
         
            +
                    tokenSpace +
         
     | 
| 
      
 1336 
     | 
    
         
            +
                    bufferSpace;
         
     | 
| 
      
 1337 
     | 
    
         
            +
             
     | 
| 
      
 1338 
     | 
    
         
            +
                DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
         
     | 
| 
      
 1339 
     | 
    
         
            +
                return neededSpace;
         
     | 
| 
      
 1340 
     | 
    
         
            +
            }
         
     | 
| 
      
 1341 
     | 
    
         
            +
             
     | 
| 
      
 1342 
     | 
    
         
            +
            size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
         
     | 
| 
      
 1343 
     | 
    
         
            +
            {
         
     | 
| 
      
 1344 
     | 
    
         
            +
                ZSTD_compressionParameters const cParams =
         
     | 
| 
      
 1345 
     | 
    
         
            +
                            ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
         
     | 
| 
      
 1346 
     | 
    
         
            +
             
     | 
| 
      
 1347 
     | 
    
         
            +
                RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
         
     | 
| 
      
 1348 
     | 
    
         
            +
                /* estimateCCtxSize is for one-shot compression. So no buffers should
         
     | 
| 
      
 1349 
     | 
    
         
            +
                 * be needed. However, we still allocate two 0-sized buffers, which can
         
     | 
| 
      
 1350 
     | 
    
         
            +
                 * take space under ASAN. */
         
     | 
| 
      
 1351 
     | 
    
         
            +
                return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
         
     | 
| 
      
 1352 
     | 
    
         
            +
                    &cParams, ¶ms->ldmParams, 1, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN);
         
     | 
| 
       1165 
1353 
     | 
    
         
             
            }
         
     | 
| 
       1166 
1354 
     | 
    
         | 
| 
       1167 
1355 
     | 
    
         
             
            size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
         
     | 
| 
         @@ -1172,7 +1360,7 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) 
     | 
|
| 
       1172 
1360 
     | 
    
         | 
| 
       1173 
1361 
     | 
    
         
             
            static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
         
     | 
| 
       1174 
1362 
     | 
    
         
             
            {
         
     | 
| 
       1175 
     | 
    
         
            -
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
         
     | 
| 
      
 1363 
     | 
    
         
            +
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
         
     | 
| 
       1176 
1364 
     | 
    
         
             
                return ZSTD_estimateCCtxSize_usingCParams(cParams);
         
     | 
| 
       1177 
1365 
     | 
    
         
             
            }
         
     | 
| 
       1178 
1366 
     | 
    
         | 
| 
         @@ -1191,15 +1379,18 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params) 
     | 
|
| 
       1191 
1379 
     | 
    
         
             
            {
         
     | 
| 
       1192 
1380 
     | 
    
         
             
                RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
         
     | 
| 
       1193 
1381 
     | 
    
         
             
                {   ZSTD_compressionParameters const cParams =
         
     | 
| 
       1194 
     | 
    
         
            -
                            ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0);
         
     | 
| 
       1195 
     | 
    
         
            -
                    size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
         
     | 
| 
      
 1382 
     | 
    
         
            +
                            ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
         
     | 
| 
       1196 
1383 
     | 
    
         
             
                    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
         
     | 
| 
       1197 
     | 
    
         
            -
                    size_t const inBuffSize = ( 
     | 
| 
       1198 
     | 
    
         
            -
             
     | 
| 
       1199 
     | 
    
         
            -
             
     | 
| 
       1200 
     | 
    
         
            -
             
     | 
| 
       1201 
     | 
    
         
            -
             
     | 
| 
       1202 
     | 
    
         
            -
             
     | 
| 
      
 1384 
     | 
    
         
            +
                    size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered)
         
     | 
| 
      
 1385 
     | 
    
         
            +
                            ? ((size_t)1 << cParams.windowLog) + blockSize
         
     | 
| 
      
 1386 
     | 
    
         
            +
                            : 0;
         
     | 
| 
      
 1387 
     | 
    
         
            +
                    size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
         
     | 
| 
      
 1388 
     | 
    
         
            +
                            ? ZSTD_compressBound(blockSize) + 1
         
     | 
| 
      
 1389 
     | 
    
         
            +
                            : 0;
         
     | 
| 
      
 1390 
     | 
    
         
            +
             
     | 
| 
      
 1391 
     | 
    
         
            +
                    return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
         
     | 
| 
      
 1392 
     | 
    
         
            +
                        &cParams, ¶ms->ldmParams, 1, inBuffSize, outBuffSize,
         
     | 
| 
      
 1393 
     | 
    
         
            +
                        ZSTD_CONTENTSIZE_UNKNOWN);
         
     | 
| 
       1203 
1394 
     | 
    
         
             
                }
         
     | 
| 
       1204 
1395 
     | 
    
         
             
            }
         
     | 
| 
       1205 
1396 
     | 
    
         | 
| 
         @@ -1211,7 +1402,7 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams) 
     | 
|
| 
       1211 
1402 
     | 
    
         | 
| 
       1212 
1403 
     | 
    
         
             
            static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
         
     | 
| 
       1213 
1404 
     | 
    
         
             
            {
         
     | 
| 
       1214 
     | 
    
         
            -
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
         
     | 
| 
      
 1405 
     | 
    
         
            +
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
         
     | 
| 
       1215 
1406 
     | 
    
         
             
                return ZSTD_estimateCStreamSize_usingCParams(cParams);
         
     | 
| 
       1216 
1407 
     | 
    
         
             
            }
         
     | 
| 
       1217 
1408 
     | 
    
         | 
| 
         @@ -1304,16 +1495,6 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms) 
     | 
|
| 
       1304 
1495 
     | 
    
         
             
                ms->dictMatchState = NULL;
         
     | 
| 
       1305 
1496 
     | 
    
         
             
            }
         
     | 
| 
       1306 
1497 
     | 
    
         | 
| 
       1307 
     | 
    
         
            -
            /**
         
     | 
| 
       1308 
     | 
    
         
            -
             * Indicates whether this compression proceeds directly from user-provided
         
     | 
| 
       1309 
     | 
    
         
            -
             * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
         
     | 
| 
       1310 
     | 
    
         
            -
             * whether the context needs to buffer the input/output (ZSTDb_buffered).
         
     | 
| 
       1311 
     | 
    
         
            -
             */
         
     | 
| 
       1312 
     | 
    
         
            -
            typedef enum {
         
     | 
| 
       1313 
     | 
    
         
            -
                ZSTDb_not_buffered,
         
     | 
| 
       1314 
     | 
    
         
            -
                ZSTDb_buffered
         
     | 
| 
       1315 
     | 
    
         
            -
            } ZSTD_buffered_policy_e;
         
     | 
| 
       1316 
     | 
    
         
            -
             
     | 
| 
       1317 
1498 
     | 
    
         
             
            /**
         
     | 
| 
       1318 
1499 
     | 
    
         
             
             * Controls, for this matchState reset, whether the tables need to be cleared /
         
     | 
| 
       1319 
1500 
     | 
    
         
             
             * prepared for the coming compression (ZSTDcrp_makeClean), or whether the
         
     | 
| 
         @@ -1441,45 +1622,32 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, 
     | 
|
| 
       1441 
1622 
     | 
    
         
             
                    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
         
     | 
| 
       1442 
1623 
     | 
    
         
             
                    U32    const divider = (params.cParams.minMatch==3) ? 3 : 4;
         
     | 
| 
       1443 
1624 
     | 
    
         
             
                    size_t const maxNbSeq = blockSize / divider;
         
     | 
| 
       1444 
     | 
    
         
            -
                    size_t const  
     | 
| 
       1445 
     | 
    
         
            -
             
     | 
| 
       1446 
     | 
    
         
            -
             
     | 
| 
       1447 
     | 
    
         
            -
                    size_t const  
     | 
| 
       1448 
     | 
    
         
            -
             
     | 
| 
       1449 
     | 
    
         
            -
             
     | 
| 
      
 1625 
     | 
    
         
            +
                    size_t const buffOutSize = (zbuff == ZSTDb_buffered && params.outBufferMode == ZSTD_bm_buffered)
         
     | 
| 
      
 1626 
     | 
    
         
            +
                            ? ZSTD_compressBound(blockSize) + 1
         
     | 
| 
      
 1627 
     | 
    
         
            +
                            : 0;
         
     | 
| 
      
 1628 
     | 
    
         
            +
                    size_t const buffInSize = (zbuff == ZSTDb_buffered && params.inBufferMode == ZSTD_bm_buffered)
         
     | 
| 
      
 1629 
     | 
    
         
            +
                            ? windowSize + blockSize
         
     | 
| 
      
 1630 
     | 
    
         
            +
                            : 0;
         
     | 
| 
       1450 
1631 
     | 
    
         
             
                    size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
         
     | 
| 
       1451 
1632 
     | 
    
         | 
| 
       1452 
     | 
    
         
            -
                     
     | 
| 
      
 1633 
     | 
    
         
            +
                    int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window);
         
     | 
| 
      
 1634 
     | 
    
         
            +
                    ZSTD_indexResetPolicy_e needsIndexReset =
         
     | 
| 
      
 1635 
     | 
    
         
            +
                        (!indexTooClose && zc->initialized) ? ZSTDirp_continue : ZSTDirp_reset;
         
     | 
| 
       1453 
1636 
     | 
    
         | 
| 
       1454 
     | 
    
         
            -
                     
     | 
| 
       1455 
     | 
    
         
            -
                         
     | 
| 
       1456 
     | 
    
         
            -
             
     | 
| 
      
 1637 
     | 
    
         
            +
                    size_t const neededSpace =
         
     | 
| 
      
 1638 
     | 
    
         
            +
                        ZSTD_estimateCCtxSize_usingCCtxParams_internal(
         
     | 
| 
      
 1639 
     | 
    
         
            +
                            ¶ms.cParams, ¶ms.ldmParams, zc->staticSize != 0,
         
     | 
| 
      
 1640 
     | 
    
         
            +
                            buffInSize, buffOutSize, pledgedSrcSize);
         
     | 
| 
      
 1641 
     | 
    
         
            +
                    FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!");
         
     | 
| 
       1457 
1642 
     | 
    
         | 
| 
       1458 
1643 
     | 
    
         
             
                    if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
         
     | 
| 
       1459 
1644 
     | 
    
         | 
| 
       1460 
1645 
     | 
    
         
             
                    /* Check if workspace is large enough, alloc a new one if needed */
         
     | 
| 
       1461 
     | 
    
         
            -
                    { 
     | 
| 
       1462 
     | 
    
         
            -
                        size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE);
         
     | 
| 
       1463 
     | 
    
         
            -
                        size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
         
     | 
| 
       1464 
     | 
    
         
            -
                        size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + ZSTD_cwksp_alloc_size(buffOutSize);
         
     | 
| 
       1465 
     | 
    
         
            -
                        size_t const ldmSpace = ZSTD_ldm_getTableSize(params.ldmParams);
         
     | 
| 
       1466 
     | 
    
         
            -
                        size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq));
         
     | 
| 
       1467 
     | 
    
         
            -
             
     | 
| 
       1468 
     | 
    
         
            -
                        size_t const neededSpace =
         
     | 
| 
       1469 
     | 
    
         
            -
                            cctxSpace +
         
     | 
| 
       1470 
     | 
    
         
            -
                            entropySpace +
         
     | 
| 
       1471 
     | 
    
         
            -
                            blockStateSpace +
         
     | 
| 
       1472 
     | 
    
         
            -
                            ldmSpace +
         
     | 
| 
       1473 
     | 
    
         
            -
                            ldmSeqSpace +
         
     | 
| 
       1474 
     | 
    
         
            -
                            matchStateSize +
         
     | 
| 
       1475 
     | 
    
         
            -
                            tokenSpace +
         
     | 
| 
       1476 
     | 
    
         
            -
                            bufferSpace;
         
     | 
| 
       1477 
     | 
    
         
            -
             
     | 
| 
      
 1646 
     | 
    
         
            +
                    {
         
     | 
| 
       1478 
1647 
     | 
    
         
             
                        int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;
         
     | 
| 
       1479 
1648 
     | 
    
         
             
                        int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);
         
     | 
| 
       1480 
1649 
     | 
    
         | 
| 
       1481 
     | 
    
         
            -
                        DEBUGLOG(4, "Need % 
     | 
| 
       1482 
     | 
    
         
            -
                                    neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
         
     | 
| 
      
 1650 
     | 
    
         
            +
                        DEBUGLOG(4, "Need %zu B workspace", neededSpace);
         
     | 
| 
       1483 
1651 
     | 
    
         
             
                        DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
         
     | 
| 
       1484 
1652 
     | 
    
         | 
| 
       1485 
1653 
     | 
    
         
             
                        if (workspaceTooSmall || workspaceWasteful) {
         
     | 
| 
         @@ -1503,7 +1671,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, 
     | 
|
| 
       1503 
1671 
     | 
    
         
             
                            RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
         
     | 
| 
       1504 
1672 
     | 
    
         
             
                            zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
         
     | 
| 
       1505 
1673 
     | 
    
         
             
                            RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
         
     | 
| 
       1506 
     | 
    
         
            -
                            zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws,  
     | 
| 
      
 1674 
     | 
    
         
            +
                            zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, ENTROPY_WORKSPACE_SIZE);
         
     | 
| 
       1507 
1675 
     | 
    
         
             
                            RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
         
     | 
| 
       1508 
1676 
     | 
    
         
             
                    }   }
         
     | 
| 
       1509 
1677 
     | 
    
         | 
| 
         @@ -1534,6 +1702,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, 
     | 
|
| 
       1534 
1702 
     | 
    
         
             
                    zc->seqStore.maxNbLit = blockSize;
         
     | 
| 
       1535 
1703 
     | 
    
         | 
| 
       1536 
1704 
     | 
    
         
             
                    /* buffers */
         
     | 
| 
      
 1705 
     | 
    
         
            +
                    zc->bufferedPolicy = zbuff;
         
     | 
| 
       1537 
1706 
     | 
    
         
             
                    zc->inBuffSize = buffInSize;
         
     | 
| 
       1538 
1707 
     | 
    
         
             
                    zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize);
         
     | 
| 
       1539 
1708 
     | 
    
         
             
                    zc->outBuffSize = buffOutSize;
         
     | 
| 
         @@ -1546,7 +1715,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, 
     | 
|
| 
       1546 
1715 
     | 
    
         
             
                              ((size_t)1) << (params.ldmParams.hashLog -
         
     | 
| 
       1547 
1716 
     | 
    
         
             
                                              params.ldmParams.bucketSizeLog);
         
     | 
| 
       1548 
1717 
     | 
    
         
             
                        zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, ldmBucketSize);
         
     | 
| 
       1549 
     | 
    
         
            -
                         
     | 
| 
      
 1718 
     | 
    
         
            +
                        ZSTD_memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize);
         
     | 
| 
       1550 
1719 
     | 
    
         
             
                    }
         
     | 
| 
       1551 
1720 
     | 
    
         | 
| 
       1552 
1721 
     | 
    
         
             
                    /* sequences storage */
         
     | 
| 
         @@ -1570,7 +1739,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, 
     | 
|
| 
       1570 
1739 
     | 
    
         
             
                        /* TODO: avoid memset? */
         
     | 
| 
       1571 
1740 
     | 
    
         
             
                        size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
         
     | 
| 
       1572 
1741 
     | 
    
         
             
                        zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));
         
     | 
| 
       1573 
     | 
    
         
            -
                         
     | 
| 
      
 1742 
     | 
    
         
            +
                        ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
         
     | 
| 
       1574 
1743 
     | 
    
         
             
                        zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
         
     | 
| 
       1575 
1744 
     | 
    
         
             
                        zc->maxNbLdmSequences = maxNbLdmSeq;
         
     | 
| 
       1576 
1745 
     | 
    
         | 
| 
         @@ -1579,6 +1748,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, 
     | 
|
| 
       1579 
1748 
     | 
    
         
             
                        zc->ldmState.loadedDictEnd = 0;
         
     | 
| 
       1580 
1749 
     | 
    
         
             
                    }
         
     | 
| 
       1581 
1750 
     | 
    
         | 
| 
      
 1751 
     | 
    
         
            +
                    /* Due to alignment, when reusing a workspace, we can actually consume
         
     | 
| 
      
 1752 
     | 
    
         
            +
                     * up to 3 extra bytes for alignment. See the comments in zstd_cwksp.h
         
     | 
| 
      
 1753 
     | 
    
         
            +
                     */
         
     | 
| 
      
 1754 
     | 
    
         
            +
                    assert(ZSTD_cwksp_used(ws) >= neededSpace &&
         
     | 
| 
      
 1755 
     | 
    
         
            +
                           ZSTD_cwksp_used(ws) <= neededSpace + 3);
         
     | 
| 
      
 1756 
     | 
    
         
            +
             
     | 
| 
       1582 
1757 
     | 
    
         
             
                    DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
         
     | 
| 
       1583 
1758 
     | 
    
         
             
                    zc->initialized = 1;
         
     | 
| 
       1584 
1759 
     | 
    
         | 
| 
         @@ -1618,12 +1793,14 @@ static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict, 
     | 
|
| 
       1618 
1793 
     | 
    
         
             
                                             U64 pledgedSrcSize)
         
     | 
| 
       1619 
1794 
     | 
    
         
             
            {
         
     | 
| 
       1620 
1795 
     | 
    
         
             
                size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];
         
     | 
| 
       1621 
     | 
    
         
            -
                 
     | 
| 
       1622 
     | 
    
         
            -
             
     | 
| 
       1623 
     | 
    
         
            -
             
     | 
| 
       1624 
     | 
    
         
            -
             
     | 
| 
       1625 
     | 
    
         
            -
             
     | 
| 
       1626 
     | 
    
         
            -
             
     | 
| 
      
 1796 
     | 
    
         
            +
                int const dedicatedDictSearch = cdict->matchState.dedicatedDictSearch;
         
     | 
| 
      
 1797 
     | 
    
         
            +
                return dedicatedDictSearch
         
     | 
| 
      
 1798 
     | 
    
         
            +
                    || ( ( pledgedSrcSize <= cutoff
         
     | 
| 
      
 1799 
     | 
    
         
            +
                        || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
         
     | 
| 
      
 1800 
     | 
    
         
            +
                        || params->attachDictPref == ZSTD_dictForceAttach )
         
     | 
| 
      
 1801 
     | 
    
         
            +
                      && params->attachDictPref != ZSTD_dictForceCopy
         
     | 
| 
      
 1802 
     | 
    
         
            +
                      && !params->forceWindow ); /* dictMatchState isn't correctly
         
     | 
| 
      
 1803 
     | 
    
         
            +
                                                  * handled in _enforceMaxDist */
         
     | 
| 
       1627 
1804 
     | 
    
         
             
            }
         
     | 
| 
       1628 
1805 
     | 
    
         | 
| 
       1629 
1806 
     | 
    
         
             
            static size_t
         
     | 
| 
         @@ -1633,17 +1810,24 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx, 
     | 
|
| 
       1633 
1810 
     | 
    
         
             
                                    U64 pledgedSrcSize,
         
     | 
| 
       1634 
1811 
     | 
    
         
             
                                    ZSTD_buffered_policy_e zbuff)
         
     | 
| 
       1635 
1812 
     | 
    
         
             
            {
         
     | 
| 
       1636 
     | 
    
         
            -
                { 
     | 
| 
      
 1813 
     | 
    
         
            +
                {
         
     | 
| 
      
 1814 
     | 
    
         
            +
                    ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams;
         
     | 
| 
       1637 
1815 
     | 
    
         
             
                    unsigned const windowLog = params.cParams.windowLog;
         
     | 
| 
       1638 
1816 
     | 
    
         
             
                    assert(windowLog != 0);
         
     | 
| 
       1639 
1817 
     | 
    
         
             
                    /* Resize working context table params for input only, since the dict
         
     | 
| 
       1640 
1818 
     | 
    
         
             
                     * has its own tables. */
         
     | 
| 
       1641 
     | 
    
         
            -
                    /*  
     | 
| 
       1642 
     | 
    
         
            -
             
     | 
| 
      
 1819 
     | 
    
         
            +
                    /* pledgedSrcSize == 0 means 0! */
         
     | 
| 
      
 1820 
     | 
    
         
            +
             
     | 
| 
      
 1821 
     | 
    
         
            +
                    if (cdict->matchState.dedicatedDictSearch) {
         
     | 
| 
      
 1822 
     | 
    
         
            +
                        ZSTD_dedicatedDictSearch_revertCParams(&adjusted_cdict_cParams);
         
     | 
| 
      
 1823 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1824 
     | 
    
         
            +
             
     | 
| 
      
 1825 
     | 
    
         
            +
                    params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize,
         
     | 
| 
      
 1826 
     | 
    
         
            +
                                                                 cdict->dictContentSize, ZSTD_cpm_attachDict);
         
     | 
| 
       1643 
1827 
     | 
    
         
             
                    params.cParams.windowLog = windowLog;
         
     | 
| 
       1644 
1828 
     | 
    
         
             
                    FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
         
     | 
| 
       1645 
1829 
     | 
    
         
             
                                                             ZSTDcrp_makeClean, zbuff), "");
         
     | 
| 
       1646 
     | 
    
         
            -
                    assert(cctx->appliedParams.cParams.strategy ==  
     | 
| 
      
 1830 
     | 
    
         
            +
                    assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy);
         
     | 
| 
       1647 
1831 
     | 
    
         
             
                }
         
     | 
| 
       1648 
1832 
     | 
    
         | 
| 
       1649 
1833 
     | 
    
         
             
                {   const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
         
     | 
| 
         @@ -1670,7 +1854,7 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx, 
     | 
|
| 
       1670 
1854 
     | 
    
         
             
                cctx->dictID = cdict->dictID;
         
     | 
| 
       1671 
1855 
     | 
    
         | 
| 
       1672 
1856 
     | 
    
         
             
                /* copy block state */
         
     | 
| 
       1673 
     | 
    
         
            -
                 
     | 
| 
      
 1857 
     | 
    
         
            +
                ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
         
     | 
| 
       1674 
1858 
     | 
    
         | 
| 
       1675 
1859 
     | 
    
         
             
                return 0;
         
     | 
| 
       1676 
1860 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1683,6 +1867,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, 
     | 
|
| 
       1683 
1867 
     | 
    
         
             
            {
         
     | 
| 
       1684 
1868 
     | 
    
         
             
                const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
         
     | 
| 
       1685 
1869 
     | 
    
         | 
| 
      
 1870 
     | 
    
         
            +
                assert(!cdict->matchState.dedicatedDictSearch);
         
     | 
| 
      
 1871 
     | 
    
         
            +
             
     | 
| 
       1686 
1872 
     | 
    
         
             
                DEBUGLOG(4, "copying dictionary into context");
         
     | 
| 
       1687 
1873 
     | 
    
         | 
| 
       1688 
1874 
     | 
    
         
             
                {   unsigned const windowLog = params.cParams.windowLog;
         
     | 
| 
         @@ -1703,10 +1889,10 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, 
     | 
|
| 
       1703 
1889 
     | 
    
         
             
                {   size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);
         
     | 
| 
       1704 
1890 
     | 
    
         
             
                    size_t const hSize =  (size_t)1 << cdict_cParams->hashLog;
         
     | 
| 
       1705 
1891 
     | 
    
         | 
| 
       1706 
     | 
    
         
            -
                     
     | 
| 
      
 1892 
     | 
    
         
            +
                    ZSTD_memcpy(cctx->blockState.matchState.hashTable,
         
     | 
| 
       1707 
1893 
     | 
    
         
             
                           cdict->matchState.hashTable,
         
     | 
| 
       1708 
1894 
     | 
    
         
             
                           hSize * sizeof(U32));
         
     | 
| 
       1709 
     | 
    
         
            -
                     
     | 
| 
      
 1895 
     | 
    
         
            +
                    ZSTD_memcpy(cctx->blockState.matchState.chainTable,
         
     | 
| 
       1710 
1896 
     | 
    
         
             
                           cdict->matchState.chainTable,
         
     | 
| 
       1711 
1897 
     | 
    
         
             
                           chainSize * sizeof(U32));
         
     | 
| 
       1712 
1898 
     | 
    
         
             
                }
         
     | 
| 
         @@ -1715,7 +1901,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, 
     | 
|
| 
       1715 
1901 
     | 
    
         
             
                {   int const h3log = cctx->blockState.matchState.hashLog3;
         
     | 
| 
       1716 
1902 
     | 
    
         
             
                    size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
         
     | 
| 
       1717 
1903 
     | 
    
         
             
                    assert(cdict->matchState.hashLog3 == 0);
         
     | 
| 
       1718 
     | 
    
         
            -
                     
     | 
| 
      
 1904 
     | 
    
         
            +
                    ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
         
     | 
| 
       1719 
1905 
     | 
    
         
             
                }
         
     | 
| 
       1720 
1906 
     | 
    
         | 
| 
       1721 
1907 
     | 
    
         
             
                ZSTD_cwksp_mark_tables_clean(&cctx->workspace);
         
     | 
| 
         @@ -1731,7 +1917,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, 
     | 
|
| 
       1731 
1917 
     | 
    
         
             
                cctx->dictID = cdict->dictID;
         
     | 
| 
       1732 
1918 
     | 
    
         | 
| 
       1733 
1919 
     | 
    
         
             
                /* copy block state */
         
     | 
| 
       1734 
     | 
    
         
            -
                 
     | 
| 
      
 1920 
     | 
    
         
            +
                ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
         
     | 
| 
       1735 
1921 
     | 
    
         | 
| 
       1736 
1922 
     | 
    
         
             
                return 0;
         
     | 
| 
       1737 
1923 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1775,7 +1961,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, 
     | 
|
| 
       1775 
1961 
     | 
    
         
             
                RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong,
         
     | 
| 
       1776 
1962 
     | 
    
         
             
                                "Can't copy a ctx that's not in init stage.");
         
     | 
| 
       1777 
1963 
     | 
    
         | 
| 
       1778 
     | 
    
         
            -
                 
     | 
| 
      
 1964 
     | 
    
         
            +
                ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
         
     | 
| 
       1779 
1965 
     | 
    
         
             
                {   ZSTD_CCtx_params params = dstCCtx->requestedParams;
         
     | 
| 
       1780 
1966 
     | 
    
         
             
                    /* Copy only compression parameters related to tables. */
         
     | 
| 
       1781 
1967 
     | 
    
         
             
                    params.cParams = srcCCtx->appliedParams.cParams;
         
     | 
| 
         @@ -1797,13 +1983,13 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, 
     | 
|
| 
       1797 
1983 
     | 
    
         
             
                    int const h3log = srcCCtx->blockState.matchState.hashLog3;
         
     | 
| 
       1798 
1984 
     | 
    
         
             
                    size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
         
     | 
| 
       1799 
1985 
     | 
    
         | 
| 
       1800 
     | 
    
         
            -
                     
     | 
| 
      
 1986 
     | 
    
         
            +
                    ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable,
         
     | 
| 
       1801 
1987 
     | 
    
         
             
                           srcCCtx->blockState.matchState.hashTable,
         
     | 
| 
       1802 
1988 
     | 
    
         
             
                           hSize * sizeof(U32));
         
     | 
| 
       1803 
     | 
    
         
            -
                     
     | 
| 
      
 1989 
     | 
    
         
            +
                    ZSTD_memcpy(dstCCtx->blockState.matchState.chainTable,
         
     | 
| 
       1804 
1990 
     | 
    
         
             
                           srcCCtx->blockState.matchState.chainTable,
         
     | 
| 
       1805 
1991 
     | 
    
         
             
                           chainSize * sizeof(U32));
         
     | 
| 
       1806 
     | 
    
         
            -
                     
     | 
| 
      
 1992 
     | 
    
         
            +
                    ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable3,
         
     | 
| 
       1807 
1993 
     | 
    
         
             
                           srcCCtx->blockState.matchState.hashTable3,
         
     | 
| 
       1808 
1994 
     | 
    
         
             
                           h3Size * sizeof(U32));
         
     | 
| 
       1809 
1995 
     | 
    
         
             
                }
         
     | 
| 
         @@ -1821,7 +2007,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, 
     | 
|
| 
       1821 
2007 
     | 
    
         
             
                dstCCtx->dictID = srcCCtx->dictID;
         
     | 
| 
       1822 
2008 
     | 
    
         | 
| 
       1823 
2009 
     | 
    
         
             
                /* copy block state */
         
     | 
| 
       1824 
     | 
    
         
            -
                 
     | 
| 
      
 2010 
     | 
    
         
            +
                ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock));
         
     | 
| 
       1825 
2011 
     | 
    
         | 
| 
       1826 
2012 
     | 
    
         
             
                return 0;
         
     | 
| 
       1827 
2013 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1834,7 +2020,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, 
     | 
|
| 
       1834 
2020 
     | 
    
         
             
            size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
         
     | 
| 
       1835 
2021 
     | 
    
         
             
            {
         
     | 
| 
       1836 
2022 
     | 
    
         
             
                ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
         
     | 
| 
       1837 
     | 
    
         
            -
                ZSTD_buffered_policy_e const zbuff =  
     | 
| 
      
 2023 
     | 
    
         
            +
                ZSTD_buffered_policy_e const zbuff = srcCCtx->bufferedPolicy;
         
     | 
| 
       1838 
2024 
     | 
    
         
             
                ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1);
         
     | 
| 
       1839 
2025 
     | 
    
         
             
                if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
         
     | 
| 
       1840 
2026 
     | 
    
         
             
                fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN);
         
     | 
| 
         @@ -1861,7 +2047,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa 
     | 
|
| 
       1861 
2047 
     | 
    
         
             
                assert((size & (ZSTD_ROWSIZE-1)) == 0);  /* multiple of ZSTD_ROWSIZE */
         
     | 
| 
       1862 
2048 
     | 
    
         
             
                assert(size < (1U<<31));   /* can be casted to int */
         
     | 
| 
       1863 
2049 
     | 
    
         | 
| 
       1864 
     | 
    
         
            -
            #if  
     | 
| 
      
 2050 
     | 
    
         
            +
            #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
         
     | 
| 
       1865 
2051 
     | 
    
         
             
                /* To validate that the table re-use logic is sound, and that we don't
         
     | 
| 
       1866 
2052 
     | 
    
         
             
                 * access table space that we haven't cleaned, we re-"poison" the table
         
     | 
| 
       1867 
2053 
     | 
    
         
             
                 * space every time we mark it dirty.
         
     | 
| 
         @@ -1958,10 +2144,10 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams) 
     | 
|
| 
       1958 
2144 
     | 
    
         
             
                return (cctxParams->targetCBlockSize != 0);
         
     | 
| 
       1959 
2145 
     | 
    
         
             
            }
         
     | 
| 
       1960 
2146 
     | 
    
         | 
| 
       1961 
     | 
    
         
            -
            /*  
     | 
| 
      
 2147 
     | 
    
         
            +
            /* ZSTD_entropyCompressSequences_internal():
         
     | 
| 
       1962 
2148 
     | 
    
         
             
             * actually compresses both literals and sequences */
         
     | 
| 
       1963 
2149 
     | 
    
         
             
            MEM_STATIC size_t
         
     | 
| 
       1964 
     | 
    
         
            -
             
     | 
| 
      
 2150 
     | 
    
         
            +
            ZSTD_entropyCompressSequences_internal(seqStore_t* seqStorePtr,
         
     | 
| 
       1965 
2151 
     | 
    
         
             
                                      const ZSTD_entropyCTables_t* prevEntropy,
         
     | 
| 
       1966 
2152 
     | 
    
         
             
                                            ZSTD_entropyCTables_t* nextEntropy,
         
     | 
| 
       1967 
2153 
     | 
    
         
             
                                      const ZSTD_CCtx_params* cctxParams,
         
     | 
| 
         @@ -1971,7 +2157,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, 
     | 
|
| 
       1971 
2157 
     | 
    
         
             
            {
         
     | 
| 
       1972 
2158 
     | 
    
         
             
                const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
         
     | 
| 
       1973 
2159 
     | 
    
         
             
                ZSTD_strategy const strategy = cctxParams->cParams.strategy;
         
     | 
| 
       1974 
     | 
    
         
            -
                unsigned count 
     | 
| 
      
 2160 
     | 
    
         
            +
                unsigned* count = (unsigned*)entropyWorkspace;
         
     | 
| 
       1975 
2161 
     | 
    
         
             
                FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
         
     | 
| 
       1976 
2162 
     | 
    
         
             
                FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
         
     | 
| 
       1977 
2163 
     | 
    
         
             
                FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
         
     | 
| 
         @@ -1987,8 +2173,12 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, 
     | 
|
| 
       1987 
2173 
     | 
    
         
             
                BYTE* seqHead;
         
     | 
| 
       1988 
2174 
     | 
    
         
             
                BYTE* lastNCount = NULL;
         
     | 
| 
       1989 
2175 
     | 
    
         | 
| 
       1990 
     | 
    
         
            -
                 
     | 
| 
      
 2176 
     | 
    
         
            +
                entropyWorkspace = count + (MaxSeq + 1);
         
     | 
| 
      
 2177 
     | 
    
         
            +
                entropyWkspSize -= (MaxSeq + 1) * sizeof(*count);
         
     | 
| 
      
 2178 
     | 
    
         
            +
             
     | 
| 
      
 2179 
     | 
    
         
            +
                DEBUGLOG(4, "ZSTD_entropyCompressSequences_internal (nbSeq=%zu)", nbSeq);
         
     | 
| 
       1991 
2180 
     | 
    
         
             
                ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
         
     | 
| 
      
 2181 
     | 
    
         
            +
                assert(entropyWkspSize >= HUF_WORKSPACE_SIZE);
         
     | 
| 
       1992 
2182 
     | 
    
         | 
| 
       1993 
2183 
     | 
    
         
             
                /* Compress literals */
         
     | 
| 
       1994 
2184 
     | 
    
         
             
                {   const BYTE* const literals = seqStorePtr->litStart;
         
     | 
| 
         @@ -2023,7 +2213,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, 
     | 
|
| 
       2023 
2213 
     | 
    
         
             
                assert(op <= oend);
         
     | 
| 
       2024 
2214 
     | 
    
         
             
                if (nbSeq==0) {
         
     | 
| 
       2025 
2215 
     | 
    
         
             
                    /* Copy the old tables over as if we repeated them */
         
     | 
| 
       2026 
     | 
    
         
            -
                     
     | 
| 
      
 2216 
     | 
    
         
            +
                    ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
         
     | 
| 
       2027 
2217 
     | 
    
         
             
                    return (size_t)(op - ostart);
         
     | 
| 
       2028 
2218 
     | 
    
         
             
                }
         
     | 
| 
       2029 
2219 
     | 
    
         | 
| 
         @@ -2148,7 +2338,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, 
     | 
|
| 
       2148 
2338 
     | 
    
         
             
            }
         
     | 
| 
       2149 
2339 
     | 
    
         | 
| 
       2150 
2340 
     | 
    
         
             
            MEM_STATIC size_t
         
     | 
| 
       2151 
     | 
    
         
            -
             
     | 
| 
      
 2341 
     | 
    
         
            +
            ZSTD_entropyCompressSequences(seqStore_t* seqStorePtr,
         
     | 
| 
       2152 
2342 
     | 
    
         
             
                                   const ZSTD_entropyCTables_t* prevEntropy,
         
     | 
| 
       2153 
2343 
     | 
    
         
             
                                         ZSTD_entropyCTables_t* nextEntropy,
         
     | 
| 
       2154 
2344 
     | 
    
         
             
                                   const ZSTD_CCtx_params* cctxParams,
         
     | 
| 
         @@ -2157,7 +2347,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr, 
     | 
|
| 
       2157 
2347 
     | 
    
         
             
                                         void* entropyWorkspace, size_t entropyWkspSize,
         
     | 
| 
       2158 
2348 
     | 
    
         
             
                                         int bmi2)
         
     | 
| 
       2159 
2349 
     | 
    
         
             
            {
         
     | 
| 
       2160 
     | 
    
         
            -
                size_t const cSize =  
     | 
| 
      
 2350 
     | 
    
         
            +
                size_t const cSize = ZSTD_entropyCompressSequences_internal(
         
     | 
| 
       2161 
2351 
     | 
    
         
             
                                        seqStorePtr, prevEntropy, nextEntropy, cctxParams,
         
     | 
| 
       2162 
2352 
     | 
    
         
             
                                        dst, dstCapacity,
         
     | 
| 
       2163 
2353 
     | 
    
         
             
                                        entropyWorkspace, entropyWkspSize, bmi2);
         
     | 
| 
         @@ -2167,13 +2357,13 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr, 
     | 
|
| 
       2167 
2357 
     | 
    
         
             
                 */
         
     | 
| 
       2168 
2358 
     | 
    
         
             
                if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
         
     | 
| 
       2169 
2359 
     | 
    
         
             
                    return 0;  /* block not compressed */
         
     | 
| 
       2170 
     | 
    
         
            -
                FORWARD_IF_ERROR(cSize, " 
     | 
| 
      
 2360 
     | 
    
         
            +
                FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSequences_internal failed");
         
     | 
| 
       2171 
2361 
     | 
    
         | 
| 
       2172 
2362 
     | 
    
         
             
                /* Check compressibility */
         
     | 
| 
       2173 
2363 
     | 
    
         
             
                {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
         
     | 
| 
       2174 
2364 
     | 
    
         
             
                    if (cSize >= maxCSize) return 0;  /* block not compressed */
         
     | 
| 
       2175 
2365 
     | 
    
         
             
                }
         
     | 
| 
       2176 
     | 
    
         
            -
             
     | 
| 
      
 2366 
     | 
    
         
            +
                DEBUGLOG(4, "ZSTD_entropyCompressSequences() cSize: %zu\n", cSize);
         
     | 
| 
       2177 
2367 
     | 
    
         
             
                return cSize;
         
     | 
| 
       2178 
2368 
     | 
    
         
             
            }
         
     | 
| 
       2179 
2369 
     | 
    
         | 
| 
         @@ -2182,7 +2372,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr, 
     | 
|
| 
       2182 
2372 
     | 
    
         
             
             * assumption : strat is a valid strategy */
         
     | 
| 
       2183 
2373 
     | 
    
         
             
            ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
         
     | 
| 
       2184 
2374 
     | 
    
         
             
            {
         
     | 
| 
       2185 
     | 
    
         
            -
                static const ZSTD_blockCompressor blockCompressor[ 
     | 
| 
      
 2375 
     | 
    
         
            +
                static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
         
     | 
| 
       2186 
2376 
     | 
    
         
             
                    { ZSTD_compressBlock_fast  /* default for 0 */,
         
     | 
| 
       2187 
2377 
     | 
    
         
             
                      ZSTD_compressBlock_fast,
         
     | 
| 
       2188 
2378 
     | 
    
         
             
                      ZSTD_compressBlock_doubleFast,
         
     | 
| 
         @@ -2212,7 +2402,17 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo 
     | 
|
| 
       2212 
2402 
     | 
    
         
             
                      ZSTD_compressBlock_btlazy2_dictMatchState,
         
     | 
| 
       2213 
2403 
     | 
    
         
             
                      ZSTD_compressBlock_btopt_dictMatchState,
         
     | 
| 
       2214 
2404 
     | 
    
         
             
                      ZSTD_compressBlock_btultra_dictMatchState,
         
     | 
| 
       2215 
     | 
    
         
            -
                      ZSTD_compressBlock_btultra_dictMatchState }
         
     | 
| 
      
 2405 
     | 
    
         
            +
                      ZSTD_compressBlock_btultra_dictMatchState },
         
     | 
| 
      
 2406 
     | 
    
         
            +
                    { NULL  /* default for 0 */,
         
     | 
| 
      
 2407 
     | 
    
         
            +
                      NULL,
         
     | 
| 
      
 2408 
     | 
    
         
            +
                      NULL,
         
     | 
| 
      
 2409 
     | 
    
         
            +
                      ZSTD_compressBlock_greedy_dedicatedDictSearch,
         
     | 
| 
      
 2410 
     | 
    
         
            +
                      ZSTD_compressBlock_lazy_dedicatedDictSearch,
         
     | 
| 
      
 2411 
     | 
    
         
            +
                      ZSTD_compressBlock_lazy2_dedicatedDictSearch,
         
     | 
| 
      
 2412 
     | 
    
         
            +
                      NULL,
         
     | 
| 
      
 2413 
     | 
    
         
            +
                      NULL,
         
     | 
| 
      
 2414 
     | 
    
         
            +
                      NULL,
         
     | 
| 
      
 2415 
     | 
    
         
            +
                      NULL }
         
     | 
| 
       2216 
2416 
     | 
    
         
             
                };
         
     | 
| 
       2217 
2417 
     | 
    
         
             
                ZSTD_blockCompressor selectedCompressor;
         
     | 
| 
       2218 
2418 
     | 
    
         
             
                ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
         
     | 
| 
         @@ -2226,7 +2426,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo 
     | 
|
| 
       2226 
2426 
     | 
    
         
             
            static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
         
     | 
| 
       2227 
2427 
     | 
    
         
             
                                               const BYTE* anchor, size_t lastLLSize)
         
     | 
| 
       2228 
2428 
     | 
    
         
             
            {
         
     | 
| 
       2229 
     | 
    
         
            -
                 
     | 
| 
      
 2429 
     | 
    
         
            +
                ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize);
         
     | 
| 
       2230 
2430 
     | 
    
         
             
                seqStorePtr->lit += lastLLSize;
         
     | 
| 
       2231 
2431 
     | 
    
         
             
            }
         
     | 
| 
       2232 
2432 
     | 
    
         | 
| 
         @@ -2247,7 +2447,11 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) 
     | 
|
| 
       2247 
2447 
     | 
    
         
             
                /* Assert that we have correctly flushed the ctx params into the ms's copy */
         
     | 
| 
       2248 
2448 
     | 
    
         
             
                ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
         
     | 
| 
       2249 
2449 
     | 
    
         
             
                if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
         
     | 
| 
       2250 
     | 
    
         
            -
                     
     | 
| 
      
 2450 
     | 
    
         
            +
                    if (zc->appliedParams.cParams.strategy >= ZSTD_btopt) {
         
     | 
| 
      
 2451 
     | 
    
         
            +
                        ZSTD_ldm_skipRawSeqStoreBytes(&zc->externSeqStore, srcSize);
         
     | 
| 
      
 2452 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 2453 
     | 
    
         
            +
                        ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
         
     | 
| 
      
 2454 
     | 
    
         
            +
                    }
         
     | 
| 
       2251 
2455 
     | 
    
         
             
                    return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */
         
     | 
| 
       2252 
2456 
     | 
    
         
             
                }
         
     | 
| 
       2253 
2457 
     | 
    
         
             
                ZSTD_resetSeqStore(&(zc->seqStore));
         
     | 
| 
         @@ -2263,10 +2467,10 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) 
     | 
|
| 
       2263 
2467 
     | 
    
         
             
                /* limited update after a very long match */
         
     | 
| 
       2264 
2468 
     | 
    
         
             
                {   const BYTE* const base = ms->window.base;
         
     | 
| 
       2265 
2469 
     | 
    
         
             
                    const BYTE* const istart = (const BYTE*)src;
         
     | 
| 
       2266 
     | 
    
         
            -
                    const U32  
     | 
| 
      
 2470 
     | 
    
         
            +
                    const U32 curr = (U32)(istart-base);
         
     | 
| 
       2267 
2471 
     | 
    
         
             
                    if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1));   /* ensure no overflow */
         
     | 
| 
       2268 
     | 
    
         
            -
                    if ( 
     | 
| 
       2269 
     | 
    
         
            -
                        ms->nextToUpdate =  
     | 
| 
      
 2472 
     | 
    
         
            +
                    if (curr > ms->nextToUpdate + 384)
         
     | 
| 
      
 2473 
     | 
    
         
            +
                        ms->nextToUpdate = curr - MIN(192, (U32)(curr - ms->nextToUpdate - 384));
         
     | 
| 
       2270 
2474 
     | 
    
         
             
                }
         
     | 
| 
       2271 
2475 
     | 
    
         | 
| 
       2272 
2476 
     | 
    
         
             
                /* select and store sequences */
         
     | 
| 
         @@ -2286,7 +2490,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) 
     | 
|
| 
       2286 
2490 
     | 
    
         
             
                                                   src, srcSize);
         
     | 
| 
       2287 
2491 
     | 
    
         
             
                        assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
         
     | 
| 
       2288 
2492 
     | 
    
         
             
                    } else if (zc->appliedParams.ldmParams.enableLdm) {
         
     | 
| 
       2289 
     | 
    
         
            -
                        rawSeqStore_t ldmSeqStore =  
     | 
| 
      
 2493 
     | 
    
         
            +
                        rawSeqStore_t ldmSeqStore = kNullRawSeqStore;
         
     | 
| 
       2290 
2494 
     | 
    
         | 
| 
       2291 
2495 
     | 
    
         
             
                        ldmSeqStore.seq = zc->ldmSequences;
         
     | 
| 
       2292 
2496 
     | 
    
         
             
                        ldmSeqStore.capacity = zc->maxNbLdmSequences;
         
     | 
| 
         @@ -2303,6 +2507,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) 
     | 
|
| 
       2303 
2507 
     | 
    
         
             
                        assert(ldmSeqStore.pos == ldmSeqStore.size);
         
     | 
| 
       2304 
2508 
     | 
    
         
             
                    } else {   /* not long range mode */
         
     | 
| 
       2305 
2509 
     | 
    
         
             
                        ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);
         
     | 
| 
      
 2510 
     | 
    
         
            +
                        ms->ldmSeqStore = NULL;
         
     | 
| 
       2306 
2511 
     | 
    
         
             
                        lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
         
     | 
| 
       2307 
2512 
     | 
    
         
             
                    }
         
     | 
| 
       2308 
2513 
     | 
    
         
             
                    {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
         
     | 
| 
         @@ -2314,17 +2519,25 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) 
     | 
|
| 
       2314 
2519 
     | 
    
         
             
            static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
         
     | 
| 
       2315 
2520 
     | 
    
         
             
            {
         
     | 
| 
       2316 
2521 
     | 
    
         
             
                const seqStore_t* seqStore = ZSTD_getSeqStore(zc);
         
     | 
| 
       2317 
     | 
    
         
            -
                const seqDef*  
     | 
| 
       2318 
     | 
    
         
            -
                size_t  
     | 
| 
      
 2522 
     | 
    
         
            +
                const seqDef* seqStoreSeqs = seqStore->sequencesStart;
         
     | 
| 
      
 2523 
     | 
    
         
            +
                size_t seqStoreSeqSize = seqStore->sequences - seqStoreSeqs;
         
     | 
| 
      
 2524 
     | 
    
         
            +
                size_t seqStoreLiteralsSize = (size_t)(seqStore->lit - seqStore->litStart);
         
     | 
| 
      
 2525 
     | 
    
         
            +
                size_t literalsRead = 0;
         
     | 
| 
      
 2526 
     | 
    
         
            +
                size_t lastLLSize;
         
     | 
| 
       2319 
2527 
     | 
    
         | 
| 
       2320 
2528 
     | 
    
         
             
                ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex];
         
     | 
| 
       2321 
     | 
    
         
            -
                size_t i; 
     | 
| 
      
 2529 
     | 
    
         
            +
                size_t i;
         
     | 
| 
      
 2530 
     | 
    
         
            +
                repcodes_t updatedRepcodes;
         
     | 
| 
       2322 
2531 
     | 
    
         | 
| 
       2323 
2532 
     | 
    
         
             
                assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences);
         
     | 
| 
       2324 
     | 
    
         
            -
                 
     | 
| 
       2325 
     | 
    
         
            -
             
     | 
| 
       2326 
     | 
    
         
            -
             
     | 
| 
       2327 
     | 
    
         
            -
             
     | 
| 
      
 2533 
     | 
    
         
            +
                /* Ensure we have enough space for last literals "sequence" */
         
     | 
| 
      
 2534 
     | 
    
         
            +
                assert(zc->seqCollector.maxSequences >= seqStoreSeqSize + 1);
         
     | 
| 
      
 2535 
     | 
    
         
            +
                ZSTD_memcpy(updatedRepcodes.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
         
     | 
| 
      
 2536 
     | 
    
         
            +
                for (i = 0; i < seqStoreSeqSize; ++i) {
         
     | 
| 
      
 2537 
     | 
    
         
            +
                    U32 rawOffset = seqStoreSeqs[i].offset - ZSTD_REP_NUM;
         
     | 
| 
      
 2538 
     | 
    
         
            +
                    outSeqs[i].litLength = seqStoreSeqs[i].litLength;
         
     | 
| 
      
 2539 
     | 
    
         
            +
                    outSeqs[i].matchLength = seqStoreSeqs[i].matchLength + MINMATCH;
         
     | 
| 
      
 2540 
     | 
    
         
            +
                    outSeqs[i].rep = 0;
         
     | 
| 
       2328 
2541 
     | 
    
         | 
| 
       2329 
2542 
     | 
    
         
             
                    if (i == seqStore->longLengthPos) {
         
     | 
| 
       2330 
2543 
     | 
    
         
             
                        if (seqStore->longLengthID == 1) {
         
     | 
| 
         @@ -2334,39 +2547,44 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc) 
     | 
|
| 
       2334 
2547 
     | 
    
         
             
                        }
         
     | 
| 
       2335 
2548 
     | 
    
         
             
                    }
         
     | 
| 
       2336 
2549 
     | 
    
         | 
| 
       2337 
     | 
    
         
            -
                    if ( 
     | 
| 
       2338 
     | 
    
         
            -
                         
     | 
| 
       2339 
     | 
    
         
            -
                         
     | 
| 
       2340 
     | 
    
         
            -
             
     | 
| 
       2341 
     | 
    
         
            -
             
     | 
| 
       2342 
     | 
    
         
            -
             
     | 
| 
       2343 
     | 
    
         
            -
             
     | 
| 
      
 2550 
     | 
    
         
            +
                    if (seqStoreSeqs[i].offset <= ZSTD_REP_NUM) {
         
     | 
| 
      
 2551 
     | 
    
         
            +
                        /* Derive the correct offset corresponding to a repcode */
         
     | 
| 
      
 2552 
     | 
    
         
            +
                        outSeqs[i].rep = seqStoreSeqs[i].offset;
         
     | 
| 
      
 2553 
     | 
    
         
            +
                        if (outSeqs[i].litLength != 0) {
         
     | 
| 
      
 2554 
     | 
    
         
            +
                            rawOffset = updatedRepcodes.rep[outSeqs[i].rep - 1];
         
     | 
| 
      
 2555 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 2556 
     | 
    
         
            +
                            if (outSeqs[i].rep == 3) {
         
     | 
| 
      
 2557 
     | 
    
         
            +
                                rawOffset = updatedRepcodes.rep[0] - 1;
         
     | 
| 
       2344 
2558 
     | 
    
         
             
                            } else {
         
     | 
| 
       2345 
     | 
    
         
            -
                                 
     | 
| 
      
 2559 
     | 
    
         
            +
                                rawOffset = updatedRepcodes.rep[outSeqs[i].rep];
         
     | 
| 
       2346 
2560 
     | 
    
         
             
                            }
         
     | 
| 
       2347 
     | 
    
         
            -
                            ++outSeqs[i].rep;
         
     | 
| 
       2348 
     | 
    
         
            -
                        }
         
     | 
| 
       2349 
     | 
    
         
            -
                        assert(repIdx >= -3);
         
     | 
| 
       2350 
     | 
    
         
            -
                        outSeqs[i].offset = repIdx >= 0 ? outSeqs[repIdx].offset : repStartValue[-repIdx - 1];
         
     | 
| 
       2351 
     | 
    
         
            -
                        if (outSeqs[i].rep == 4) {
         
     | 
| 
       2352 
     | 
    
         
            -
                            --outSeqs[i].offset;
         
     | 
| 
       2353 
2561 
     | 
    
         
             
                        }
         
     | 
| 
       2354 
     | 
    
         
            -
                    } else {
         
     | 
| 
       2355 
     | 
    
         
            -
                        outSeqs[i].offset -= ZSTD_REP_NUM;
         
     | 
| 
       2356 
2562 
     | 
    
         
             
                    }
         
     | 
| 
       2357 
     | 
    
         
            -
             
     | 
| 
       2358 
     | 
    
         
            -
                     
     | 
| 
       2359 
     | 
    
         
            -
             
     | 
| 
       2360 
     | 
    
         
            -
                     
     | 
| 
      
 2563 
     | 
    
         
            +
                    outSeqs[i].offset = rawOffset;
         
     | 
| 
      
 2564 
     | 
    
         
            +
                    /* seqStoreSeqs[i].offset == offCode+1, and ZSTD_updateRep() expects offCode
         
     | 
| 
      
 2565 
     | 
    
         
            +
                       so we provide seqStoreSeqs[i].offset - 1 */
         
     | 
| 
      
 2566 
     | 
    
         
            +
                    updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep,
         
     | 
| 
      
 2567 
     | 
    
         
            +
                                                     seqStoreSeqs[i].offset - 1,
         
     | 
| 
      
 2568 
     | 
    
         
            +
                                                     seqStoreSeqs[i].litLength == 0);
         
     | 
| 
      
 2569 
     | 
    
         
            +
                    literalsRead += outSeqs[i].litLength;
         
     | 
| 
       2361 
2570 
     | 
    
         
             
                }
         
     | 
| 
       2362 
     | 
    
         
            -
                 
     | 
| 
      
 2571 
     | 
    
         
            +
                /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0.
         
     | 
| 
      
 2572 
     | 
    
         
            +
                 * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker
         
     | 
| 
      
 2573 
     | 
    
         
            +
                 * for the block boundary, according to the API.
         
     | 
| 
      
 2574 
     | 
    
         
            +
                 */
         
     | 
| 
      
 2575 
     | 
    
         
            +
                assert(seqStoreLiteralsSize >= literalsRead);
         
     | 
| 
      
 2576 
     | 
    
         
            +
                lastLLSize = seqStoreLiteralsSize - literalsRead;
         
     | 
| 
      
 2577 
     | 
    
         
            +
                outSeqs[i].litLength = (U32)lastLLSize;
         
     | 
| 
      
 2578 
     | 
    
         
            +
                outSeqs[i].matchLength = outSeqs[i].offset = outSeqs[i].rep = 0;
         
     | 
| 
      
 2579 
     | 
    
         
            +
                seqStoreSeqSize++;
         
     | 
| 
      
 2580 
     | 
    
         
            +
                zc->seqCollector.seqIndex += seqStoreSeqSize;
         
     | 
| 
       2363 
2581 
     | 
    
         
             
            }
         
     | 
| 
       2364 
2582 
     | 
    
         | 
| 
       2365 
     | 
    
         
            -
            size_t  
     | 
| 
       2366 
     | 
    
         
            -
             
     | 
| 
      
 2583 
     | 
    
         
            +
            size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
         
     | 
| 
      
 2584 
     | 
    
         
            +
                                          size_t outSeqsSize, const void* src, size_t srcSize)
         
     | 
| 
       2367 
2585 
     | 
    
         
             
            {
         
     | 
| 
       2368 
2586 
     | 
    
         
             
                const size_t dstCapacity = ZSTD_compressBound(srcSize);
         
     | 
| 
       2369 
     | 
    
         
            -
                void* dst =  
     | 
| 
      
 2587 
     | 
    
         
            +
                void* dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
         
     | 
| 
       2370 
2588 
     | 
    
         
             
                SeqCollector seqCollector;
         
     | 
| 
       2371 
2589 
     | 
    
         | 
| 
       2372 
2590 
     | 
    
         
             
                RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
         
     | 
| 
         @@ -2378,16 +2596,47 @@ size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, 
     | 
|
| 
       2378 
2596 
     | 
    
         
             
                zc->seqCollector = seqCollector;
         
     | 
| 
       2379 
2597 
     | 
    
         | 
| 
       2380 
2598 
     | 
    
         
             
                ZSTD_compress2(zc, dst, dstCapacity, src, srcSize);
         
     | 
| 
       2381 
     | 
    
         
            -
                 
     | 
| 
      
 2599 
     | 
    
         
            +
                ZSTD_customFree(dst, ZSTD_defaultCMem);
         
     | 
| 
       2382 
2600 
     | 
    
         
             
                return zc->seqCollector.seqIndex;
         
     | 
| 
       2383 
2601 
     | 
    
         
             
            }
         
     | 
| 
       2384 
2602 
     | 
    
         | 
| 
       2385 
     | 
    
         
            -
             
     | 
| 
       2386 
     | 
    
         
            -
             
     | 
| 
      
 2603 
     | 
    
         
            +
            size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize) {
         
     | 
| 
      
 2604 
     | 
    
         
            +
                size_t in = 0;
         
     | 
| 
      
 2605 
     | 
    
         
            +
                size_t out = 0;
         
     | 
| 
      
 2606 
     | 
    
         
            +
                for (; in < seqsSize; ++in) {
         
     | 
| 
      
 2607 
     | 
    
         
            +
                    if (sequences[in].offset == 0 && sequences[in].matchLength == 0) {
         
     | 
| 
      
 2608 
     | 
    
         
            +
                        if (in != seqsSize - 1) {
         
     | 
| 
      
 2609 
     | 
    
         
            +
                            sequences[in+1].litLength += sequences[in].litLength;
         
     | 
| 
      
 2610 
     | 
    
         
            +
                        }
         
     | 
| 
      
 2611 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 2612 
     | 
    
         
            +
                        sequences[out] = sequences[in];
         
     | 
| 
      
 2613 
     | 
    
         
            +
                        ++out;
         
     | 
| 
      
 2614 
     | 
    
         
            +
                    }
         
     | 
| 
      
 2615 
     | 
    
         
            +
                }
         
     | 
| 
      
 2616 
     | 
    
         
            +
                return out;
         
     | 
| 
      
 2617 
     | 
    
         
            +
            }
         
     | 
| 
      
 2618 
     | 
    
         
            +
             
     | 
| 
      
 2619 
     | 
    
         
            +
            /* Unrolled loop to read four size_ts of input at a time. Returns 1 if is RLE, 0 if not. */
         
     | 
| 
      
 2620 
     | 
    
         
            +
            static int ZSTD_isRLE(const BYTE* src, size_t length) {
         
     | 
| 
      
 2621 
     | 
    
         
            +
                const BYTE* ip = src;
         
     | 
| 
      
 2622 
     | 
    
         
            +
                const BYTE value = ip[0];
         
     | 
| 
      
 2623 
     | 
    
         
            +
                const size_t valueST = (size_t)((U64)value * 0x0101010101010101ULL);
         
     | 
| 
      
 2624 
     | 
    
         
            +
                const size_t unrollSize = sizeof(size_t) * 4;
         
     | 
| 
      
 2625 
     | 
    
         
            +
                const size_t unrollMask = unrollSize - 1;
         
     | 
| 
      
 2626 
     | 
    
         
            +
                const size_t prefixLength = length & unrollMask;
         
     | 
| 
       2387 
2627 
     | 
    
         
             
                size_t i;
         
     | 
| 
       2388 
     | 
    
         
            -
                 
     | 
| 
       2389 
     | 
    
         
            -
                 
     | 
| 
       2390 
     | 
    
         
            -
             
     | 
| 
      
 2628 
     | 
    
         
            +
                size_t u;
         
     | 
| 
      
 2629 
     | 
    
         
            +
                if (length == 1) return 1;
         
     | 
| 
      
 2630 
     | 
    
         
            +
                /* Check if prefix is RLE first before using unrolled loop */
         
     | 
| 
      
 2631 
     | 
    
         
            +
                if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) {
         
     | 
| 
      
 2632 
     | 
    
         
            +
                    return 0;
         
     | 
| 
      
 2633 
     | 
    
         
            +
                }
         
     | 
| 
      
 2634 
     | 
    
         
            +
                for (i = prefixLength; i != length; i += unrollSize) {
         
     | 
| 
      
 2635 
     | 
    
         
            +
                    for (u = 0; u < unrollSize; u += sizeof(size_t)) {
         
     | 
| 
      
 2636 
     | 
    
         
            +
                        if (MEM_readST(ip + i + u) != valueST) {
         
     | 
| 
      
 2637 
     | 
    
         
            +
                            return 0;
         
     | 
| 
      
 2638 
     | 
    
         
            +
                        }
         
     | 
| 
      
 2639 
     | 
    
         
            +
                    }
         
     | 
| 
       2391 
2640 
     | 
    
         
             
                }
         
     | 
| 
       2392 
2641 
     | 
    
         
             
                return 1;
         
     | 
| 
       2393 
2642 
     | 
    
         
             
            }
         
     | 
| 
         @@ -2434,18 +2683,25 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, 
     | 
|
| 
       2434 
2683 
     | 
    
         | 
| 
       2435 
2684 
     | 
    
         
             
                if (zc->seqCollector.collectSequences) {
         
     | 
| 
       2436 
2685 
     | 
    
         
             
                    ZSTD_copyBlockSequences(zc);
         
     | 
| 
      
 2686 
     | 
    
         
            +
                    ZSTD_confirmRepcodesAndEntropyTables(zc);
         
     | 
| 
       2437 
2687 
     | 
    
         
             
                    return 0;
         
     | 
| 
       2438 
2688 
     | 
    
         
             
                }
         
     | 
| 
       2439 
2689 
     | 
    
         | 
| 
       2440 
2690 
     | 
    
         
             
                /* encode sequences and literals */
         
     | 
| 
       2441 
     | 
    
         
            -
                cSize =  
     | 
| 
      
 2691 
     | 
    
         
            +
                cSize = ZSTD_entropyCompressSequences(&zc->seqStore,
         
     | 
| 
       2442 
2692 
     | 
    
         
             
                        &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
         
     | 
| 
       2443 
2693 
     | 
    
         
             
                        &zc->appliedParams,
         
     | 
| 
       2444 
2694 
     | 
    
         
             
                        dst, dstCapacity,
         
     | 
| 
       2445 
2695 
     | 
    
         
             
                        srcSize,
         
     | 
| 
       2446 
     | 
    
         
            -
                        zc->entropyWorkspace,  
     | 
| 
      
 2696 
     | 
    
         
            +
                        zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
         
     | 
| 
       2447 
2697 
     | 
    
         
             
                        zc->bmi2);
         
     | 
| 
       2448 
2698 
     | 
    
         | 
| 
      
 2699 
     | 
    
         
            +
                if (zc->seqCollector.collectSequences) {
         
     | 
| 
      
 2700 
     | 
    
         
            +
                    ZSTD_copyBlockSequences(zc);
         
     | 
| 
      
 2701 
     | 
    
         
            +
                    return 0;
         
     | 
| 
      
 2702 
     | 
    
         
            +
                }
         
     | 
| 
      
 2703 
     | 
    
         
            +
             
     | 
| 
      
 2704 
     | 
    
         
            +
             
     | 
| 
       2449 
2705 
     | 
    
         
             
                if (frame &&
         
     | 
| 
       2450 
2706 
     | 
    
         
             
                    /* We don't want to emit our first block as a RLE even if it qualifies because
         
     | 
| 
       2451 
2707 
     | 
    
         
             
                     * doing so will cause the decoder (cli only) to throw a "should consume all input error."
         
     | 
| 
         @@ -2593,7 +2849,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx, 
     | 
|
| 
       2593 
2849 
     | 
    
         | 
| 
       2594 
2850 
     | 
    
         
             
                assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
         
     | 
| 
       2595 
2851 
     | 
    
         | 
| 
       2596 
     | 
    
         
            -
                DEBUGLOG( 
     | 
| 
      
 2852 
     | 
    
         
            +
                DEBUGLOG(4, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
         
     | 
| 
       2597 
2853 
     | 
    
         
             
                if (cctx->appliedParams.fParams.checksumFlag && srcSize)
         
     | 
| 
       2598 
2854 
     | 
    
         
             
                    XXH64_update(&cctx->xxhState, src, srcSize);
         
     | 
| 
       2599 
2855 
     | 
    
         | 
| 
         @@ -2673,7 +2929,6 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, 
     | 
|
| 
       2673 
2929 
     | 
    
         
             
                                "dst buf is too small to fit worst-case frame header size.");
         
     | 
| 
       2674 
2930 
     | 
    
         
             
                DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
         
     | 
| 
       2675 
2931 
     | 
    
         
             
                            !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
         
     | 
| 
       2676 
     | 
    
         
            -
             
     | 
| 
       2677 
2932 
     | 
    
         
             
                if (params->format == ZSTD_f_zstd1) {
         
     | 
| 
       2678 
2933 
     | 
    
         
             
                    MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
         
     | 
| 
       2679 
2934 
     | 
    
         
             
                    pos = 4;
         
     | 
| 
         @@ -2725,6 +2980,7 @@ size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSe 
     | 
|
| 
       2725 
2980 
     | 
    
         
             
                cctx->externSeqStore.size = nbSeq;
         
     | 
| 
       2726 
2981 
     | 
    
         
             
                cctx->externSeqStore.capacity = nbSeq;
         
     | 
| 
       2727 
2982 
     | 
    
         
             
                cctx->externSeqStore.pos = 0;
         
     | 
| 
      
 2983 
     | 
    
         
            +
                cctx->externSeqStore.posInSequence = 0;
         
     | 
| 
       2728 
2984 
     | 
    
         
             
                return 0;
         
     | 
| 
       2729 
2985 
     | 
    
         
             
            }
         
     | 
| 
       2730 
2986 
     | 
    
         | 
| 
         @@ -2862,8 +3118,12 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, 
     | 
|
| 
       2862 
3118 
     | 
    
         
             
                    case ZSTD_greedy:
         
     | 
| 
       2863 
3119 
     | 
    
         
             
                    case ZSTD_lazy:
         
     | 
| 
       2864 
3120 
     | 
    
         
             
                    case ZSTD_lazy2:
         
     | 
| 
       2865 
     | 
    
         
            -
                        if (chunk >= HASH_READ_SIZE)
         
     | 
| 
      
 3121 
     | 
    
         
            +
                        if (chunk >= HASH_READ_SIZE && ms->dedicatedDictSearch) {
         
     | 
| 
      
 3122 
     | 
    
         
            +
                            assert(chunk == remaining); /* must load everything in one go */
         
     | 
| 
      
 3123 
     | 
    
         
            +
                            ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, ichunk-HASH_READ_SIZE);
         
     | 
| 
      
 3124 
     | 
    
         
            +
                        } else if (chunk >= HASH_READ_SIZE) {
         
     | 
| 
       2866 
3125 
     | 
    
         
             
                            ZSTD_insertAndFindFirstIndex(ms, ichunk-HASH_READ_SIZE);
         
     | 
| 
      
 3126 
     | 
    
         
            +
                        }
         
     | 
| 
       2867 
3127 
     | 
    
         
             
                        break;
         
     | 
| 
       2868 
3128 
     | 
    
         | 
| 
       2869 
3129 
     | 
    
         
             
                    case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */
         
     | 
| 
         @@ -2887,22 +3147,28 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, 
     | 
|
| 
       2887 
3147 
     | 
    
         | 
| 
       2888 
3148 
     | 
    
         | 
| 
       2889 
3149 
     | 
    
         
             
            /* Dictionaries that assign zero probability to symbols that show up causes problems
         
     | 
| 
       2890 
     | 
    
         
            -
             
     | 
| 
       2891 
     | 
    
         
            -
             
     | 
| 
       2892 
     | 
    
         
            -
             
     | 
| 
       2893 
     | 
    
         
            -
            static  
     | 
| 
      
 3150 
     | 
    
         
            +
             * when FSE encoding. Mark dictionaries with zero probability symbols as FSE_repeat_check
         
     | 
| 
      
 3151 
     | 
    
         
            +
             * and only dictionaries with 100% valid symbols can be assumed valid.
         
     | 
| 
      
 3152 
     | 
    
         
            +
             */
         
     | 
| 
      
 3153 
     | 
    
         
            +
            static FSE_repeat ZSTD_dictNCountRepeat(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue)
         
     | 
| 
      
 3154 
     | 
    
         
            +
            {
         
     | 
| 
       2894 
3155 
     | 
    
         
             
                U32 s;
         
     | 
| 
       2895 
     | 
    
         
            -
                 
     | 
| 
      
 3156 
     | 
    
         
            +
                if (dictMaxSymbolValue < maxSymbolValue) {
         
     | 
| 
      
 3157 
     | 
    
         
            +
                    return FSE_repeat_check;
         
     | 
| 
      
 3158 
     | 
    
         
            +
                }
         
     | 
| 
       2896 
3159 
     | 
    
         
             
                for (s = 0; s <= maxSymbolValue; ++s) {
         
     | 
| 
       2897 
     | 
    
         
            -
                     
     | 
| 
      
 3160 
     | 
    
         
            +
                    if (normalizedCounter[s] == 0) {
         
     | 
| 
      
 3161 
     | 
    
         
            +
                        return FSE_repeat_check;
         
     | 
| 
      
 3162 
     | 
    
         
            +
                    }
         
     | 
| 
       2898 
3163 
     | 
    
         
             
                }
         
     | 
| 
       2899 
     | 
    
         
            -
                return  
     | 
| 
      
 3164 
     | 
    
         
            +
                return FSE_repeat_valid;
         
     | 
| 
       2900 
3165 
     | 
    
         
             
            }
         
     | 
| 
       2901 
3166 
     | 
    
         | 
| 
       2902 
3167 
     | 
    
         
             
            size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
         
     | 
| 
       2903 
     | 
    
         
            -
                                     short* offcodeNCount, unsigned* offcodeMaxValue,
         
     | 
| 
       2904 
3168 
     | 
    
         
             
                                     const void* const dict, size_t dictSize)
         
     | 
| 
       2905 
3169 
     | 
    
         
             
            {
         
     | 
| 
      
 3170 
     | 
    
         
            +
                short offcodeNCount[MaxOff+1];
         
     | 
| 
      
 3171 
     | 
    
         
            +
                unsigned offcodeMaxValue = MaxOff;
         
     | 
| 
       2906 
3172 
     | 
    
         
             
                const BYTE* dictPtr = (const BYTE*)dict;    /* skip magic num and dict ID */
         
     | 
| 
       2907 
3173 
     | 
    
         
             
                const BYTE* const dictEnd = dictPtr + dictSize;
         
     | 
| 
       2908 
3174 
     | 
    
         
             
                dictPtr += 8;
         
     | 
| 
         @@ -2924,16 +3190,16 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, 
     | 
|
| 
       2924 
3190 
     | 
    
         
             
                }
         
     | 
| 
       2925 
3191 
     | 
    
         | 
| 
       2926 
3192 
     | 
    
         
             
                {   unsigned offcodeLog;
         
     | 
| 
       2927 
     | 
    
         
            -
                    size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
         
     | 
| 
      
 3193 
     | 
    
         
            +
                    size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
         
     | 
| 
       2928 
3194 
     | 
    
         
             
                    RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
         
     | 
| 
       2929 
3195 
     | 
    
         
             
                    RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
         
     | 
| 
       2930 
     | 
    
         
            -
                    /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
         
     | 
| 
       2931 
3196 
     | 
    
         
             
                    /* fill all offset symbols to avoid garbage at end of table */
         
     | 
| 
       2932 
3197 
     | 
    
         
             
                    RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
         
     | 
| 
       2933 
3198 
     | 
    
         
             
                            bs->entropy.fse.offcodeCTable,
         
     | 
| 
       2934 
3199 
     | 
    
         
             
                            offcodeNCount, MaxOff, offcodeLog,
         
     | 
| 
       2935 
3200 
     | 
    
         
             
                            workspace, HUF_WORKSPACE_SIZE)),
         
     | 
| 
       2936 
3201 
     | 
    
         
             
                        dictionary_corrupted, "");
         
     | 
| 
      
 3202 
     | 
    
         
            +
                    /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
         
     | 
| 
       2937 
3203 
     | 
    
         
             
                    dictPtr += offcodeHeaderSize;
         
     | 
| 
       2938 
3204 
     | 
    
         
             
                }
         
     | 
| 
       2939 
3205 
     | 
    
         | 
| 
         @@ -2942,13 +3208,12 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, 
     | 
|
| 
       2942 
3208 
     | 
    
         
             
                    size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
         
     | 
| 
       2943 
3209 
     | 
    
         
             
                    RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
         
     | 
| 
       2944 
3210 
     | 
    
         
             
                    RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
         
     | 
| 
       2945 
     | 
    
         
            -
                    /* Every match length code must have non-zero probability */
         
     | 
| 
       2946 
     | 
    
         
            -
                    FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML), "");
         
     | 
| 
       2947 
3211 
     | 
    
         
             
                    RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
         
     | 
| 
       2948 
3212 
     | 
    
         
             
                            bs->entropy.fse.matchlengthCTable,
         
     | 
| 
       2949 
3213 
     | 
    
         
             
                            matchlengthNCount, matchlengthMaxValue, matchlengthLog,
         
     | 
| 
       2950 
3214 
     | 
    
         
             
                            workspace, HUF_WORKSPACE_SIZE)),
         
     | 
| 
       2951 
3215 
     | 
    
         
             
                        dictionary_corrupted, "");
         
     | 
| 
      
 3216 
     | 
    
         
            +
                    bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML);
         
     | 
| 
       2952 
3217 
     | 
    
         
             
                    dictPtr += matchlengthHeaderSize;
         
     | 
| 
       2953 
3218 
     | 
    
         
             
                }
         
     | 
| 
       2954 
3219 
     | 
    
         | 
| 
         @@ -2957,13 +3222,12 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, 
     | 
|
| 
       2957 
3222 
     | 
    
         
             
                    size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
         
     | 
| 
       2958 
3223 
     | 
    
         
             
                    RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
         
     | 
| 
       2959 
3224 
     | 
    
         
             
                    RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
         
     | 
| 
       2960 
     | 
    
         
            -
                    /* Every literal length code must have non-zero probability */
         
     | 
| 
       2961 
     | 
    
         
            -
                    FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL), "");
         
     | 
| 
       2962 
3225 
     | 
    
         
             
                    RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
         
     | 
| 
       2963 
3226 
     | 
    
         
             
                            bs->entropy.fse.litlengthCTable,
         
     | 
| 
       2964 
3227 
     | 
    
         
             
                            litlengthNCount, litlengthMaxValue, litlengthLog,
         
     | 
| 
       2965 
3228 
     | 
    
         
             
                            workspace, HUF_WORKSPACE_SIZE)),
         
     | 
| 
       2966 
3229 
     | 
    
         
             
                        dictionary_corrupted, "");
         
     | 
| 
      
 3230 
     | 
    
         
            +
                    bs->entropy.fse.litlength_repeatMode = ZSTD_dictNCountRepeat(litlengthNCount, litlengthMaxValue, MaxLL);
         
     | 
| 
       2967 
3231 
     | 
    
         
             
                    dictPtr += litlengthHeaderSize;
         
     | 
| 
       2968 
3232 
     | 
    
         
             
                }
         
     | 
| 
       2969 
3233 
     | 
    
         | 
| 
         @@ -2973,6 +3237,22 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, 
     | 
|
| 
       2973 
3237 
     | 
    
         
             
                bs->rep[2] = MEM_readLE32(dictPtr+8);
         
     | 
| 
       2974 
3238 
     | 
    
         
             
                dictPtr += 12;
         
     | 
| 
       2975 
3239 
     | 
    
         | 
| 
      
 3240 
     | 
    
         
            +
                {   size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
         
     | 
| 
      
 3241 
     | 
    
         
            +
                    U32 offcodeMax = MaxOff;
         
     | 
| 
      
 3242 
     | 
    
         
            +
                    if (dictContentSize <= ((U32)-1) - 128 KB) {
         
     | 
| 
      
 3243 
     | 
    
         
            +
                        U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
         
     | 
| 
      
 3244 
     | 
    
         
            +
                        offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
         
     | 
| 
      
 3245 
     | 
    
         
            +
                    }
         
     | 
| 
      
 3246 
     | 
    
         
            +
                    /* All offset values <= dictContentSize + 128 KB must be representable for a valid table */
         
     | 
| 
      
 3247 
     | 
    
         
            +
                    bs->entropy.fse.offcode_repeatMode = ZSTD_dictNCountRepeat(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff));
         
     | 
| 
      
 3248 
     | 
    
         
            +
             
     | 
| 
      
 3249 
     | 
    
         
            +
                    /* All repCodes must be <= dictContentSize and != 0 */
         
     | 
| 
      
 3250 
     | 
    
         
            +
                    {   U32 u;
         
     | 
| 
      
 3251 
     | 
    
         
            +
                        for (u=0; u<3; u++) {
         
     | 
| 
      
 3252 
     | 
    
         
            +
                            RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, "");
         
     | 
| 
      
 3253 
     | 
    
         
            +
                            RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
         
     | 
| 
      
 3254 
     | 
    
         
            +
                }   }   }
         
     | 
| 
      
 3255 
     | 
    
         
            +
             
     | 
| 
       2976 
3256 
     | 
    
         
             
                return dictPtr - (const BYTE*)dict;
         
     | 
| 
       2977 
3257 
     | 
    
         
             
            }
         
     | 
| 
       2978 
3258 
     | 
    
         | 
| 
         @@ -2995,8 +3275,6 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, 
     | 
|
| 
       2995 
3275 
     | 
    
         
             
            {
         
     | 
| 
       2996 
3276 
     | 
    
         
             
                const BYTE* dictPtr = (const BYTE*)dict;
         
     | 
| 
       2997 
3277 
     | 
    
         
             
                const BYTE* const dictEnd = dictPtr + dictSize;
         
     | 
| 
       2998 
     | 
    
         
            -
                short offcodeNCount[MaxOff+1];
         
     | 
| 
       2999 
     | 
    
         
            -
                unsigned offcodeMaxValue = MaxOff;
         
     | 
| 
       3000 
3278 
     | 
    
         
             
                size_t dictID;
         
     | 
| 
       3001 
3279 
     | 
    
         
             
                size_t eSize;
         
     | 
| 
       3002 
3280 
     | 
    
         | 
| 
         @@ -3005,32 +3283,16 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, 
     | 
|
| 
       3005 
3283 
     | 
    
         
             
                assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
         
     | 
| 
       3006 
3284 
     | 
    
         | 
| 
       3007 
3285 
     | 
    
         
             
                dictID = params->fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr + 4 /* skip magic number */ );
         
     | 
| 
       3008 
     | 
    
         
            -
                eSize = ZSTD_loadCEntropy(bs, workspace,  
     | 
| 
      
 3286 
     | 
    
         
            +
                eSize = ZSTD_loadCEntropy(bs, workspace, dict, dictSize);
         
     | 
| 
       3009 
3287 
     | 
    
         
             
                FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed");
         
     | 
| 
       3010 
3288 
     | 
    
         
             
                dictPtr += eSize;
         
     | 
| 
       3011 
3289 
     | 
    
         | 
| 
       3012 
     | 
    
         
            -
                { 
     | 
| 
       3013 
     | 
    
         
            -
                     
     | 
| 
       3014 
     | 
    
         
            -
                    if (dictContentSize <= ((U32)-1) - 128 KB) {
         
     | 
| 
       3015 
     | 
    
         
            -
                        U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
         
     | 
| 
       3016 
     | 
    
         
            -
                        offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
         
     | 
| 
       3017 
     | 
    
         
            -
                    }
         
     | 
| 
       3018 
     | 
    
         
            -
                    /* All offset values <= dictContentSize + 128 KB must be representable */
         
     | 
| 
       3019 
     | 
    
         
            -
                    FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)), "");
         
     | 
| 
       3020 
     | 
    
         
            -
                    /* All repCodes must be <= dictContentSize and != 0*/
         
     | 
| 
       3021 
     | 
    
         
            -
                    {   U32 u;
         
     | 
| 
       3022 
     | 
    
         
            -
                        for (u=0; u<3; u++) {
         
     | 
| 
       3023 
     | 
    
         
            -
                            RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, "");
         
     | 
| 
       3024 
     | 
    
         
            -
                            RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
         
     | 
| 
       3025 
     | 
    
         
            -
                    }   }
         
     | 
| 
       3026 
     | 
    
         
            -
             
     | 
| 
       3027 
     | 
    
         
            -
                    bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
         
     | 
| 
       3028 
     | 
    
         
            -
                    bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
         
     | 
| 
       3029 
     | 
    
         
            -
                    bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
         
     | 
| 
      
 3290 
     | 
    
         
            +
                {
         
     | 
| 
      
 3291 
     | 
    
         
            +
                    size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
         
     | 
| 
       3030 
3292 
     | 
    
         
             
                    FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(
         
     | 
| 
       3031 
3293 
     | 
    
         
             
                        ms, NULL, ws, params, dictPtr, dictContentSize, dtlm), "");
         
     | 
| 
       3032 
     | 
    
         
            -
                    return dictID;
         
     | 
| 
       3033 
3294 
     | 
    
         
             
                }
         
     | 
| 
      
 3295 
     | 
    
         
            +
                return dictID;
         
     | 
| 
       3034 
3296 
     | 
    
         
             
            }
         
     | 
| 
       3035 
3297 
     | 
    
         | 
| 
       3036 
3298 
     | 
    
         
             
            /** ZSTD_compress_insertDictionary() :
         
     | 
| 
         @@ -3074,7 +3336,7 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, 
     | 
|
| 
       3074 
3336 
     | 
    
         
             
            }
         
     | 
| 
       3075 
3337 
     | 
    
         | 
| 
       3076 
3338 
     | 
    
         
             
            #define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB)
         
     | 
| 
       3077 
     | 
    
         
            -
            #define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER ( 
     | 
| 
      
 3339 
     | 
    
         
            +
            #define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6ULL)
         
     | 
| 
       3078 
3340 
     | 
    
         | 
| 
       3079 
3341 
     | 
    
         
             
            /*! ZSTD_compressBegin_internal() :
         
     | 
| 
       3080 
3342 
     | 
    
         
             
             * @return : 0, or an error code */
         
     | 
| 
         @@ -3106,7 +3368,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, 
     | 
|
| 
       3106 
3368 
     | 
    
         
             
                            ZSTD_compress_insertDictionary(
         
     | 
| 
       3107 
3369 
     | 
    
         
             
                                    cctx->blockState.prevCBlock, &cctx->blockState.matchState,
         
     | 
| 
       3108 
3370 
     | 
    
         
             
                                    &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
         
     | 
| 
       3109 
     | 
    
         
            -
                                    cdict->dictContentSize, dictContentType, dtlm,
         
     | 
| 
      
 3371 
     | 
    
         
            +
                                    cdict->dictContentSize, cdict->dictContentType, dtlm,
         
     | 
| 
       3110 
3372 
     | 
    
         
             
                                    cctx->entropyWorkspace)
         
     | 
| 
       3111 
3373 
     | 
    
         
             
                          : ZSTD_compress_insertDictionary(
         
     | 
| 
       3112 
3374 
     | 
    
         
             
                                    cctx->blockState.prevCBlock, &cctx->blockState.matchState,
         
     | 
| 
         @@ -3153,7 +3415,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, 
     | 
|
| 
       3153 
3415 
     | 
    
         | 
| 
       3154 
3416 
     | 
    
         
             
            size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
         
     | 
| 
       3155 
3417 
     | 
    
         
             
            {
         
     | 
| 
       3156 
     | 
    
         
            -
                ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
         
     | 
| 
      
 3418 
     | 
    
         
            +
                ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict);
         
     | 
| 
       3157 
3419 
     | 
    
         
             
                ZSTD_CCtx_params const cctxParams =
         
     | 
| 
       3158 
3420 
     | 
    
         
             
                        ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, ¶ms);
         
     | 
| 
       3159 
3421 
     | 
    
         
             
                DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
         
     | 
| 
         @@ -3234,7 +3496,6 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, 
     | 
|
| 
       3234 
3496 
     | 
    
         
             
                return cSize + endResult;
         
     | 
| 
       3235 
3497 
     | 
    
         
             
            }
         
     | 
| 
       3236 
3498 
     | 
    
         | 
| 
       3237 
     | 
    
         
            -
             
     | 
| 
       3238 
3499 
     | 
    
         
             
            static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
         
     | 
| 
       3239 
3500 
     | 
    
         
             
                                                  void* dst, size_t dstCapacity,
         
     | 
| 
       3240 
3501 
     | 
    
         
             
                                            const void* src, size_t srcSize,
         
     | 
| 
         @@ -3287,7 +3548,7 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, 
     | 
|
| 
       3287 
3548 
     | 
    
         
             
                                     const void* dict, size_t dictSize,
         
     | 
| 
       3288 
3549 
     | 
    
         
             
                                           int compressionLevel)
         
     | 
| 
       3289 
3550 
     | 
    
         
             
            {
         
     | 
| 
       3290 
     | 
    
         
            -
                ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0);
         
     | 
| 
      
 3551 
     | 
    
         
            +
                ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict);
         
     | 
| 
       3291 
3552 
     | 
    
         
             
                ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, ¶ms);
         
     | 
| 
       3292 
3553 
     | 
    
         
             
                DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize);
         
     | 
| 
       3293 
3554 
     | 
    
         
             
                assert(params.fParams.contentSizeFlag == 1);
         
     | 
| 
         @@ -3309,10 +3570,17 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, 
     | 
|
| 
       3309 
3570 
     | 
    
         
             
                                 int compressionLevel)
         
     | 
| 
       3310 
3571 
     | 
    
         
             
            {
         
     | 
| 
       3311 
3572 
     | 
    
         
             
                size_t result;
         
     | 
| 
      
 3573 
     | 
    
         
            +
            #if ZSTD_COMPRESS_HEAPMODE
         
     | 
| 
      
 3574 
     | 
    
         
            +
                ZSTD_CCtx* cctx = ZSTD_createCCtx();
         
     | 
| 
      
 3575 
     | 
    
         
            +
                RETURN_ERROR_IF(!cctx, memory_allocation, "ZSTD_createCCtx failed");
         
     | 
| 
      
 3576 
     | 
    
         
            +
                result = ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel);
         
     | 
| 
      
 3577 
     | 
    
         
            +
                ZSTD_freeCCtx(cctx);
         
     | 
| 
      
 3578 
     | 
    
         
            +
            #else
         
     | 
| 
       3312 
3579 
     | 
    
         
             
                ZSTD_CCtx ctxBody;
         
     | 
| 
       3313 
3580 
     | 
    
         
             
                ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem);
         
     | 
| 
       3314 
3581 
     | 
    
         
             
                result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
         
     | 
| 
       3315 
3582 
     | 
    
         
             
                ZSTD_freeCCtxContent(&ctxBody);   /* can't free ctxBody itself, as it's on stack; free only heap content */
         
     | 
| 
      
 3583 
     | 
    
         
            +
            #endif
         
     | 
| 
       3316 
3584 
     | 
    
         
             
                return result;
         
     | 
| 
       3317 
3585 
     | 
    
         
             
            }
         
     | 
| 
       3318 
3586 
     | 
    
         | 
| 
         @@ -3335,7 +3603,7 @@ size_t ZSTD_estimateCDictSize_advanced( 
     | 
|
| 
       3335 
3603 
     | 
    
         | 
| 
       3336 
3604 
     | 
    
         
             
            size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
         
     | 
| 
       3337 
3605 
     | 
    
         
             
            {
         
     | 
| 
       3338 
     | 
    
         
            -
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
         
     | 
| 
      
 3606 
     | 
    
         
            +
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
         
     | 
| 
       3339 
3607 
     | 
    
         
             
                return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
         
     | 
| 
       3340 
3608 
     | 
    
         
             
            }
         
     | 
| 
       3341 
3609 
     | 
    
         | 
| 
         @@ -3353,20 +3621,25 @@ static size_t ZSTD_initCDict_internal( 
     | 
|
| 
       3353 
3621 
     | 
    
         
             
                          const void* dictBuffer, size_t dictSize,
         
     | 
| 
       3354 
3622 
     | 
    
         
             
                                ZSTD_dictLoadMethod_e dictLoadMethod,
         
     | 
| 
       3355 
3623 
     | 
    
         
             
                                ZSTD_dictContentType_e dictContentType,
         
     | 
| 
       3356 
     | 
    
         
            -
                                 
     | 
| 
      
 3624 
     | 
    
         
            +
                                ZSTD_CCtx_params params)
         
     | 
| 
       3357 
3625 
     | 
    
         
             
            {
         
     | 
| 
       3358 
3626 
     | 
    
         
             
                DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType);
         
     | 
| 
       3359 
     | 
    
         
            -
                assert(!ZSTD_checkCParams(cParams));
         
     | 
| 
       3360 
     | 
    
         
            -
                cdict->matchState.cParams = cParams;
         
     | 
| 
      
 3627 
     | 
    
         
            +
                assert(!ZSTD_checkCParams(params.cParams));
         
     | 
| 
      
 3628 
     | 
    
         
            +
                cdict->matchState.cParams = params.cParams;
         
     | 
| 
      
 3629 
     | 
    
         
            +
                cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch;
         
     | 
| 
      
 3630 
     | 
    
         
            +
                if (cdict->matchState.dedicatedDictSearch && dictSize > ZSTD_CHUNKSIZE_MAX) {
         
     | 
| 
      
 3631 
     | 
    
         
            +
                    cdict->matchState.dedicatedDictSearch = 0;
         
     | 
| 
      
 3632 
     | 
    
         
            +
                }
         
     | 
| 
       3361 
3633 
     | 
    
         
             
                if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
         
     | 
| 
       3362 
3634 
     | 
    
         
             
                    cdict->dictContent = dictBuffer;
         
     | 
| 
       3363 
3635 
     | 
    
         
             
                } else {
         
     | 
| 
       3364 
3636 
     | 
    
         
             
                     void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
         
     | 
| 
       3365 
3637 
     | 
    
         
             
                    RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!");
         
     | 
| 
       3366 
3638 
     | 
    
         
             
                    cdict->dictContent = internalBuffer;
         
     | 
| 
       3367 
     | 
    
         
            -
                     
     | 
| 
      
 3639 
     | 
    
         
            +
                    ZSTD_memcpy(internalBuffer, dictBuffer, dictSize);
         
     | 
| 
       3368 
3640 
     | 
    
         
             
                }
         
     | 
| 
       3369 
3641 
     | 
    
         
             
                cdict->dictContentSize = dictSize;
         
     | 
| 
      
 3642 
     | 
    
         
            +
                cdict->dictContentType = dictContentType;
         
     | 
| 
       3370 
3643 
     | 
    
         | 
| 
       3371 
3644 
     | 
    
         
             
                cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE);
         
     | 
| 
       3372 
3645 
     | 
    
         | 
| 
         @@ -3376,18 +3649,15 @@ static size_t ZSTD_initCDict_internal( 
     | 
|
| 
       3376 
3649 
     | 
    
         
             
                FORWARD_IF_ERROR(ZSTD_reset_matchState(
         
     | 
| 
       3377 
3650 
     | 
    
         
             
                    &cdict->matchState,
         
     | 
| 
       3378 
3651 
     | 
    
         
             
                    &cdict->workspace,
         
     | 
| 
       3379 
     | 
    
         
            -
                    &cParams,
         
     | 
| 
      
 3652 
     | 
    
         
            +
                    ¶ms.cParams,
         
     | 
| 
       3380 
3653 
     | 
    
         
             
                    ZSTDcrp_makeClean,
         
     | 
| 
       3381 
3654 
     | 
    
         
             
                    ZSTDirp_reset,
         
     | 
| 
       3382 
3655 
     | 
    
         
             
                    ZSTD_resetTarget_CDict), "");
         
     | 
| 
       3383 
3656 
     | 
    
         
             
                /* (Maybe) load the dictionary
         
     | 
| 
       3384 
3657 
     | 
    
         
             
                 * Skips loading the dictionary if it is < 8 bytes.
         
     | 
| 
       3385 
3658 
     | 
    
         
             
                 */
         
     | 
| 
       3386 
     | 
    
         
            -
                {    
     | 
| 
       3387 
     | 
    
         
            -
                    memset(¶ms, 0, sizeof(params));
         
     | 
| 
       3388 
     | 
    
         
            -
                    params.compressionLevel = ZSTD_CLEVEL_DEFAULT;
         
     | 
| 
      
 3659 
     | 
    
         
            +
                {   params.compressionLevel = ZSTD_CLEVEL_DEFAULT;
         
     | 
| 
       3389 
3660 
     | 
    
         
             
                    params.fParams.contentSizeFlag = 1;
         
     | 
| 
       3390 
     | 
    
         
            -
                    params.cParams = cParams;
         
     | 
| 
       3391 
3661 
     | 
    
         
             
                    {   size_t const dictID = ZSTD_compress_insertDictionary(
         
     | 
| 
       3392 
3662 
     | 
    
         
             
                                &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace,
         
     | 
| 
       3393 
3663 
     | 
    
         
             
                                ¶ms, cdict->dictContent, cdict->dictContentSize,
         
     | 
| 
         @@ -3401,13 +3671,11 @@ static size_t ZSTD_initCDict_internal( 
     | 
|
| 
       3401 
3671 
     | 
    
         
             
                return 0;
         
     | 
| 
       3402 
3672 
     | 
    
         
             
            }
         
     | 
| 
       3403 
3673 
     | 
    
         | 
| 
       3404 
     | 
    
         
            -
            ZSTD_CDict*  
     | 
| 
      
 3674 
     | 
    
         
            +
            static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
         
     | 
| 
       3405 
3675 
     | 
    
         
             
                                                  ZSTD_dictLoadMethod_e dictLoadMethod,
         
     | 
| 
       3406 
     | 
    
         
            -
                                                  ZSTD_dictContentType_e dictContentType,
         
     | 
| 
       3407 
3676 
     | 
    
         
             
                                                  ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
         
     | 
| 
       3408 
3677 
     | 
    
         
             
            {
         
     | 
| 
       3409 
     | 
    
         
            -
                 
     | 
| 
       3410 
     | 
    
         
            -
                if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
         
     | 
| 
      
 3678 
     | 
    
         
            +
                if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
         
     | 
| 
       3411 
3679 
     | 
    
         | 
| 
       3412 
3680 
     | 
    
         
             
                {   size_t const workspaceSize =
         
     | 
| 
       3413 
3681 
     | 
    
         
             
                        ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +
         
     | 
| 
         @@ -3415,16 +3683,16 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, 
     | 
|
| 
       3415 
3683 
     | 
    
         
             
                        ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0) +
         
     | 
| 
       3416 
3684 
     | 
    
         
             
                        (dictLoadMethod == ZSTD_dlm_byRef ? 0
         
     | 
| 
       3417 
3685 
     | 
    
         
             
                         : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))));
         
     | 
| 
       3418 
     | 
    
         
            -
                    void* const workspace =  
     | 
| 
      
 3686 
     | 
    
         
            +
                    void* const workspace = ZSTD_customMalloc(workspaceSize, customMem);
         
     | 
| 
       3419 
3687 
     | 
    
         
             
                    ZSTD_cwksp ws;
         
     | 
| 
       3420 
3688 
     | 
    
         
             
                    ZSTD_CDict* cdict;
         
     | 
| 
       3421 
3689 
     | 
    
         | 
| 
       3422 
3690 
     | 
    
         
             
                    if (!workspace) {
         
     | 
| 
       3423 
     | 
    
         
            -
                         
     | 
| 
      
 3691 
     | 
    
         
            +
                        ZSTD_customFree(workspace, customMem);
         
     | 
| 
       3424 
3692 
     | 
    
         
             
                        return NULL;
         
     | 
| 
       3425 
3693 
     | 
    
         
             
                    }
         
     | 
| 
       3426 
3694 
     | 
    
         | 
| 
       3427 
     | 
    
         
            -
                    ZSTD_cwksp_init(&ws, workspace, workspaceSize);
         
     | 
| 
      
 3695 
     | 
    
         
            +
                    ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc);
         
     | 
| 
       3428 
3696 
     | 
    
         | 
| 
       3429 
3697 
     | 
    
         
             
                    cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
         
     | 
| 
       3430 
3698 
     | 
    
         
             
                    assert(cdict != NULL);
         
     | 
| 
         @@ -3432,35 +3700,94 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, 
     | 
|
| 
       3432 
3700 
     | 
    
         
             
                    cdict->customMem = customMem;
         
     | 
| 
       3433 
3701 
     | 
    
         
             
                    cdict->compressionLevel = 0; /* signals advanced API usage */
         
     | 
| 
       3434 
3702 
     | 
    
         | 
| 
       3435 
     | 
    
         
            -
                    if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
         
     | 
| 
       3436 
     | 
    
         
            -
                                                    dictBuffer, dictSize,
         
     | 
| 
       3437 
     | 
    
         
            -
                                                    dictLoadMethod, dictContentType,
         
     | 
| 
       3438 
     | 
    
         
            -
                                                    cParams) )) {
         
     | 
| 
       3439 
     | 
    
         
            -
                        ZSTD_freeCDict(cdict);
         
     | 
| 
       3440 
     | 
    
         
            -
                        return NULL;
         
     | 
| 
       3441 
     | 
    
         
            -
                    }
         
     | 
| 
       3442 
     | 
    
         
            -
             
     | 
| 
       3443 
3703 
     | 
    
         
             
                    return cdict;
         
     | 
| 
       3444 
3704 
     | 
    
         
             
                }
         
     | 
| 
       3445 
3705 
     | 
    
         
             
            }
         
     | 
| 
       3446 
3706 
     | 
    
         | 
| 
      
 3707 
     | 
    
         
            +
            ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
         
     | 
| 
      
 3708 
     | 
    
         
            +
                                                  ZSTD_dictLoadMethod_e dictLoadMethod,
         
     | 
| 
      
 3709 
     | 
    
         
            +
                                                  ZSTD_dictContentType_e dictContentType,
         
     | 
| 
      
 3710 
     | 
    
         
            +
                                                  ZSTD_compressionParameters cParams,
         
     | 
| 
      
 3711 
     | 
    
         
            +
                                                  ZSTD_customMem customMem)
         
     | 
| 
      
 3712 
     | 
    
         
            +
            {
         
     | 
| 
      
 3713 
     | 
    
         
            +
                ZSTD_CCtx_params cctxParams;
         
     | 
| 
      
 3714 
     | 
    
         
            +
                ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
         
     | 
| 
      
 3715 
     | 
    
         
            +
                ZSTD_CCtxParams_init(&cctxParams, 0);
         
     | 
| 
      
 3716 
     | 
    
         
            +
                cctxParams.cParams = cParams;
         
     | 
| 
      
 3717 
     | 
    
         
            +
                cctxParams.customMem = customMem;
         
     | 
| 
      
 3718 
     | 
    
         
            +
                return ZSTD_createCDict_advanced2(
         
     | 
| 
      
 3719 
     | 
    
         
            +
                    dictBuffer, dictSize,
         
     | 
| 
      
 3720 
     | 
    
         
            +
                    dictLoadMethod, dictContentType,
         
     | 
| 
      
 3721 
     | 
    
         
            +
                    &cctxParams, customMem);
         
     | 
| 
      
 3722 
     | 
    
         
            +
            }
         
     | 
| 
      
 3723 
     | 
    
         
            +
             
     | 
| 
      
 3724 
     | 
    
         
            +
            ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2(
         
     | 
| 
      
 3725 
     | 
    
         
            +
                    const void* dict, size_t dictSize,
         
     | 
| 
      
 3726 
     | 
    
         
            +
                    ZSTD_dictLoadMethod_e dictLoadMethod,
         
     | 
| 
      
 3727 
     | 
    
         
            +
                    ZSTD_dictContentType_e dictContentType,
         
     | 
| 
      
 3728 
     | 
    
         
            +
                    const ZSTD_CCtx_params* originalCctxParams,
         
     | 
| 
      
 3729 
     | 
    
         
            +
                    ZSTD_customMem customMem)
         
     | 
| 
      
 3730 
     | 
    
         
            +
            {
         
     | 
| 
      
 3731 
     | 
    
         
            +
                ZSTD_CCtx_params cctxParams = *originalCctxParams;
         
     | 
| 
      
 3732 
     | 
    
         
            +
                ZSTD_compressionParameters cParams;
         
     | 
| 
      
 3733 
     | 
    
         
            +
                ZSTD_CDict* cdict;
         
     | 
| 
      
 3734 
     | 
    
         
            +
             
     | 
| 
      
 3735 
     | 
    
         
            +
                DEBUGLOG(3, "ZSTD_createCDict_advanced2, mode %u", (unsigned)dictContentType);
         
     | 
| 
      
 3736 
     | 
    
         
            +
                if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
         
     | 
| 
      
 3737 
     | 
    
         
            +
             
     | 
| 
      
 3738 
     | 
    
         
            +
                if (cctxParams.enableDedicatedDictSearch) {
         
     | 
| 
      
 3739 
     | 
    
         
            +
                    cParams = ZSTD_dedicatedDictSearch_getCParams(
         
     | 
| 
      
 3740 
     | 
    
         
            +
                        cctxParams.compressionLevel, dictSize);
         
     | 
| 
      
 3741 
     | 
    
         
            +
                    ZSTD_overrideCParams(&cParams, &cctxParams.cParams);
         
     | 
| 
      
 3742 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 3743 
     | 
    
         
            +
                    cParams = ZSTD_getCParamsFromCCtxParams(
         
     | 
| 
      
 3744 
     | 
    
         
            +
                        &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
         
     | 
| 
      
 3745 
     | 
    
         
            +
                }
         
     | 
| 
      
 3746 
     | 
    
         
            +
             
     | 
| 
      
 3747 
     | 
    
         
            +
                if (!ZSTD_dedicatedDictSearch_isSupported(&cParams)) {
         
     | 
| 
      
 3748 
     | 
    
         
            +
                    /* Fall back to non-DDSS params */
         
     | 
| 
      
 3749 
     | 
    
         
            +
                    cctxParams.enableDedicatedDictSearch = 0;
         
     | 
| 
      
 3750 
     | 
    
         
            +
                    cParams = ZSTD_getCParamsFromCCtxParams(
         
     | 
| 
      
 3751 
     | 
    
         
            +
                        &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
         
     | 
| 
      
 3752 
     | 
    
         
            +
                }
         
     | 
| 
      
 3753 
     | 
    
         
            +
             
     | 
| 
      
 3754 
     | 
    
         
            +
                cctxParams.cParams = cParams;
         
     | 
| 
      
 3755 
     | 
    
         
            +
             
     | 
| 
      
 3756 
     | 
    
         
            +
                cdict = ZSTD_createCDict_advanced_internal(dictSize,
         
     | 
| 
      
 3757 
     | 
    
         
            +
                                    dictLoadMethod, cctxParams.cParams,
         
     | 
| 
      
 3758 
     | 
    
         
            +
                                    customMem);
         
     | 
| 
      
 3759 
     | 
    
         
            +
             
     | 
| 
      
 3760 
     | 
    
         
            +
                if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
         
     | 
| 
      
 3761 
     | 
    
         
            +
                                                dict, dictSize,
         
     | 
| 
      
 3762 
     | 
    
         
            +
                                                dictLoadMethod, dictContentType,
         
     | 
| 
      
 3763 
     | 
    
         
            +
                                                cctxParams) )) {
         
     | 
| 
      
 3764 
     | 
    
         
            +
                    ZSTD_freeCDict(cdict);
         
     | 
| 
      
 3765 
     | 
    
         
            +
                    return NULL;
         
     | 
| 
      
 3766 
     | 
    
         
            +
                }
         
     | 
| 
      
 3767 
     | 
    
         
            +
             
     | 
| 
      
 3768 
     | 
    
         
            +
                return cdict;
         
     | 
| 
      
 3769 
     | 
    
         
            +
            }
         
     | 
| 
      
 3770 
     | 
    
         
            +
             
     | 
| 
       3447 
3771 
     | 
    
         
             
            ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
         
     | 
| 
       3448 
3772 
     | 
    
         
             
            {
         
     | 
| 
       3449 
     | 
    
         
            -
                ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
         
     | 
| 
       3450 
     | 
    
         
            -
                ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dict, dictSize,
         
     | 
| 
      
 3773 
     | 
    
         
            +
                ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
         
     | 
| 
      
 3774 
     | 
    
         
            +
                ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize,
         
     | 
| 
       3451 
3775 
     | 
    
         
             
                                                              ZSTD_dlm_byCopy, ZSTD_dct_auto,
         
     | 
| 
       3452 
3776 
     | 
    
         
             
                                                              cParams, ZSTD_defaultCMem);
         
     | 
| 
       3453 
3777 
     | 
    
         
             
                if (cdict)
         
     | 
| 
       3454 
     | 
    
         
            -
                    cdict->compressionLevel = compressionLevel == 0 ? ZSTD_CLEVEL_DEFAULT : compressionLevel;
         
     | 
| 
      
 3778 
     | 
    
         
            +
                    cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel;
         
     | 
| 
       3455 
3779 
     | 
    
         
             
                return cdict;
         
     | 
| 
       3456 
3780 
     | 
    
         
             
            }
         
     | 
| 
       3457 
3781 
     | 
    
         | 
| 
       3458 
3782 
     | 
    
         
             
            ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
         
     | 
| 
       3459 
3783 
     | 
    
         
             
            {
         
     | 
| 
       3460 
     | 
    
         
            -
                ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
         
     | 
| 
       3461 
     | 
    
         
            -
                 
     | 
| 
      
 3784 
     | 
    
         
            +
                ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
         
     | 
| 
      
 3785 
     | 
    
         
            +
                ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize,
         
     | 
| 
       3462 
3786 
     | 
    
         
             
                                                 ZSTD_dlm_byRef, ZSTD_dct_auto,
         
     | 
| 
       3463 
3787 
     | 
    
         
             
                                                 cParams, ZSTD_defaultCMem);
         
     | 
| 
      
 3788 
     | 
    
         
            +
                if (cdict)
         
     | 
| 
      
 3789 
     | 
    
         
            +
                    cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel;
         
     | 
| 
      
 3790 
     | 
    
         
            +
                return cdict;
         
     | 
| 
       3464 
3791 
     | 
    
         
             
            }
         
     | 
| 
       3465 
3792 
     | 
    
         | 
| 
       3466 
3793 
     | 
    
         
             
            size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
         
     | 
| 
         @@ -3470,7 +3797,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict) 
     | 
|
| 
       3470 
3797 
     | 
    
         
             
                    int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict);
         
     | 
| 
       3471 
3798 
     | 
    
         
             
                    ZSTD_cwksp_free(&cdict->workspace, cMem);
         
     | 
| 
       3472 
3799 
     | 
    
         
             
                    if (!cdictInWorkspace) {
         
     | 
| 
       3473 
     | 
    
         
            -
                         
     | 
| 
      
 3800 
     | 
    
         
            +
                        ZSTD_customFree(cdict, cMem);
         
     | 
| 
       3474 
3801 
     | 
    
         
             
                    }
         
     | 
| 
       3475 
3802 
     | 
    
         
             
                    return 0;
         
     | 
| 
       3476 
3803 
     | 
    
         
             
                }
         
     | 
| 
         @@ -3503,12 +3830,13 @@ const ZSTD_CDict* ZSTD_initStaticCDict( 
     | 
|
| 
       3503 
3830 
     | 
    
         
             
                                        + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)
         
     | 
| 
       3504 
3831 
     | 
    
         
             
                                        + matchStateSize;
         
     | 
| 
       3505 
3832 
     | 
    
         
             
                ZSTD_CDict* cdict;
         
     | 
| 
      
 3833 
     | 
    
         
            +
                ZSTD_CCtx_params params;
         
     | 
| 
       3506 
3834 
     | 
    
         | 
| 
       3507 
3835 
     | 
    
         
             
                if ((size_t)workspace & 7) return NULL;  /* 8-aligned */
         
     | 
| 
       3508 
3836 
     | 
    
         | 
| 
       3509 
3837 
     | 
    
         
             
                {
         
     | 
| 
       3510 
3838 
     | 
    
         
             
                    ZSTD_cwksp ws;
         
     | 
| 
       3511 
     | 
    
         
            -
                    ZSTD_cwksp_init(&ws, workspace, workspaceSize);
         
     | 
| 
      
 3839 
     | 
    
         
            +
                    ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc);
         
     | 
| 
       3512 
3840 
     | 
    
         
             
                    cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
         
     | 
| 
       3513 
3841 
     | 
    
         
             
                    if (cdict == NULL) return NULL;
         
     | 
| 
       3514 
3842 
     | 
    
         
             
                    ZSTD_cwksp_move(&cdict->workspace, &ws);
         
     | 
| 
         @@ -3518,10 +3846,13 @@ const ZSTD_CDict* ZSTD_initStaticCDict( 
     | 
|
| 
       3518 
3846 
     | 
    
         
             
                    (unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
         
     | 
| 
       3519 
3847 
     | 
    
         
             
                if (workspaceSize < neededSize) return NULL;
         
     | 
| 
       3520 
3848 
     | 
    
         | 
| 
      
 3849 
     | 
    
         
            +
                ZSTD_CCtxParams_init(¶ms, 0);
         
     | 
| 
      
 3850 
     | 
    
         
            +
                params.cParams = cParams;
         
     | 
| 
      
 3851 
     | 
    
         
            +
             
     | 
| 
       3521 
3852 
     | 
    
         
             
                if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
         
     | 
| 
       3522 
3853 
     | 
    
         
             
                                                          dict, dictSize,
         
     | 
| 
       3523 
3854 
     | 
    
         
             
                                                          dictLoadMethod, dictContentType,
         
     | 
| 
       3524 
     | 
    
         
            -
                                                           
     | 
| 
      
 3855 
     | 
    
         
            +
                                                          params) ))
         
     | 
| 
       3525 
3856 
     | 
    
         
             
                    return NULL;
         
     | 
| 
       3526 
3857 
     | 
    
         | 
| 
       3527 
3858 
     | 
    
         
             
                return cdict;
         
     | 
| 
         @@ -3533,6 +3864,17 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) 
     | 
|
| 
       3533 
3864 
     | 
    
         
             
                return cdict->matchState.cParams;
         
     | 
| 
       3534 
3865 
     | 
    
         
             
            }
         
     | 
| 
       3535 
3866 
     | 
    
         | 
| 
      
 3867 
     | 
    
         
            +
            /*! ZSTD_getDictID_fromCDict() :
         
     | 
| 
      
 3868 
     | 
    
         
            +
             *  Provides the dictID of the dictionary loaded into `cdict`.
         
     | 
| 
      
 3869 
     | 
    
         
            +
             *  If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
         
     | 
| 
      
 3870 
     | 
    
         
            +
             *  Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
         
     | 
| 
      
 3871 
     | 
    
         
            +
            unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict)
         
     | 
| 
      
 3872 
     | 
    
         
            +
            {
         
     | 
| 
      
 3873 
     | 
    
         
            +
                if (cdict==NULL) return 0;
         
     | 
| 
      
 3874 
     | 
    
         
            +
                return cdict->dictID;
         
     | 
| 
      
 3875 
     | 
    
         
            +
            }
         
     | 
| 
      
 3876 
     | 
    
         
            +
             
     | 
| 
      
 3877 
     | 
    
         
            +
             
     | 
| 
       3536 
3878 
     | 
    
         
             
            /* ZSTD_compressBegin_usingCDict_advanced() :
         
     | 
| 
       3537 
3879 
     | 
    
         
             
             * cdict must be != NULL */
         
     | 
| 
       3538 
3880 
     | 
    
         
             
            size_t ZSTD_compressBegin_usingCDict_advanced(
         
     | 
| 
         @@ -3640,32 +3982,12 @@ size_t ZSTD_CStreamOutSize(void) 
     | 
|
| 
       3640 
3982 
     | 
    
         
             
                return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
         
     | 
| 
       3641 
3983 
     | 
    
         
             
            }
         
     | 
| 
       3642 
3984 
     | 
    
         | 
| 
       3643 
     | 
    
         
            -
            static  
     | 
| 
       3644 
     | 
    
         
            -
                                const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType,
         
     | 
| 
       3645 
     | 
    
         
            -
                                const ZSTD_CDict* const cdict,
         
     | 
| 
       3646 
     | 
    
         
            -
                                ZSTD_CCtx_params params, unsigned long long const pledgedSrcSize)
         
     | 
| 
      
 3985 
     | 
    
         
            +
            static ZSTD_cParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize)
         
     | 
| 
       3647 
3986 
     | 
    
         
             
            {
         
     | 
| 
       3648 
     | 
    
         
            -
                 
     | 
| 
       3649 
     | 
    
         
            -
             
     | 
| 
       3650 
     | 
    
         
            -
                 
     | 
| 
       3651 
     | 
    
         
            -
             
     | 
| 
       3652 
     | 
    
         
            -
                assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
         
     | 
| 
       3653 
     | 
    
         
            -
                assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
         
     | 
| 
       3654 
     | 
    
         
            -
             
     | 
| 
       3655 
     | 
    
         
            -
                FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
         
     | 
| 
       3656 
     | 
    
         
            -
                                                     dict, dictSize, dictContentType, ZSTD_dtlm_fast,
         
     | 
| 
       3657 
     | 
    
         
            -
                                                     cdict,
         
     | 
| 
       3658 
     | 
    
         
            -
                                                     ¶ms, pledgedSrcSize,
         
     | 
| 
       3659 
     | 
    
         
            -
                                                     ZSTDb_buffered) , "");
         
     | 
| 
       3660 
     | 
    
         
            -
             
     | 
| 
       3661 
     | 
    
         
            -
                cctx->inToCompress = 0;
         
     | 
| 
       3662 
     | 
    
         
            -
                cctx->inBuffPos = 0;
         
     | 
| 
       3663 
     | 
    
         
            -
                cctx->inBuffTarget = cctx->blockSize
         
     | 
| 
       3664 
     | 
    
         
            -
                                  + (cctx->blockSize == pledgedSrcSize);   /* for small input: avoid automatic flush on reaching end of block, since it would require to add a 3-bytes null block to end frame */
         
     | 
| 
       3665 
     | 
    
         
            -
                cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;
         
     | 
| 
       3666 
     | 
    
         
            -
                cctx->streamStage = zcss_load;
         
     | 
| 
       3667 
     | 
    
         
            -
                cctx->frameEnded = 0;
         
     | 
| 
       3668 
     | 
    
         
            -
                return 0;   /* ready to go */
         
     | 
| 
      
 3987 
     | 
    
         
            +
                if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize))
         
     | 
| 
      
 3988 
     | 
    
         
            +
                    return ZSTD_cpm_attachDict;
         
     | 
| 
      
 3989 
     | 
    
         
            +
                else
         
     | 
| 
      
 3990 
     | 
    
         
            +
                    return ZSTD_cpm_noAttachDict;
         
     | 
| 
       3669 
3991 
     | 
    
         
             
            }
         
     | 
| 
       3670 
3992 
     | 
    
         | 
| 
       3671 
3993 
     | 
    
         
             
            /* ZSTD_resetCStream():
         
     | 
| 
         @@ -3815,12 +4137,17 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, 
     | 
|
| 
       3815 
4137 
     | 
    
         | 
| 
       3816 
4138 
     | 
    
         
             
                /* check expectations */
         
     | 
| 
       3817 
4139 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%u", (unsigned)flushMode);
         
     | 
| 
       3818 
     | 
    
         
            -
                 
     | 
| 
       3819 
     | 
    
         
            -
             
     | 
| 
       3820 
     | 
    
         
            -
             
     | 
| 
       3821 
     | 
    
         
            -
                 
     | 
| 
      
 4140 
     | 
    
         
            +
                if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) {
         
     | 
| 
      
 4141 
     | 
    
         
            +
                    assert(zcs->inBuff != NULL);
         
     | 
| 
      
 4142 
     | 
    
         
            +
                    assert(zcs->inBuffSize > 0);
         
     | 
| 
      
 4143 
     | 
    
         
            +
                }
         
     | 
| 
      
 4144 
     | 
    
         
            +
                if (zcs->appliedParams.outBufferMode == ZSTD_bm_buffered) {
         
     | 
| 
      
 4145 
     | 
    
         
            +
                    assert(zcs->outBuff !=  NULL);
         
     | 
| 
      
 4146 
     | 
    
         
            +
                    assert(zcs->outBuffSize > 0);
         
     | 
| 
      
 4147 
     | 
    
         
            +
                }
         
     | 
| 
       3822 
4148 
     | 
    
         
             
                assert(output->pos <= output->size);
         
     | 
| 
       3823 
4149 
     | 
    
         
             
                assert(input->pos <= input->size);
         
     | 
| 
      
 4150 
     | 
    
         
            +
                assert((U32)flushMode <= (U32)ZSTD_e_end);
         
     | 
| 
       3824 
4151 
     | 
    
         | 
| 
       3825 
4152 
     | 
    
         
             
                while (someMoreWork) {
         
     | 
| 
       3826 
4153 
     | 
    
         
             
                    switch(zcs->streamStage)
         
     | 
| 
         @@ -3830,7 +4157,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, 
     | 
|
| 
       3830 
4157 
     | 
    
         | 
| 
       3831 
4158 
     | 
    
         
             
                    case zcss_load:
         
     | 
| 
       3832 
4159 
     | 
    
         
             
                        if ( (flushMode == ZSTD_e_end)
         
     | 
| 
       3833 
     | 
    
         
            -
                          && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip) 
     | 
| 
      
 4160 
     | 
    
         
            +
                          && ( (size_t)(oend-op) >= ZSTD_compressBound(iend-ip)     /* Enough output space */
         
     | 
| 
      
 4161 
     | 
    
         
            +
                            || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)  /* OR we are allowed to return dstSizeTooSmall */
         
     | 
| 
       3834 
4162 
     | 
    
         
             
                          && (zcs->inBuffPos == 0) ) {
         
     | 
| 
       3835 
4163 
     | 
    
         
             
                            /* shortcut to compression pass directly into output buffer */
         
     | 
| 
       3836 
4164 
     | 
    
         
             
                            size_t const cSize = ZSTD_compressEnd(zcs,
         
     | 
| 
         @@ -3843,8 +4171,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, 
     | 
|
| 
       3843 
4171 
     | 
    
         
             
                            ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
         
     | 
| 
       3844 
4172 
     | 
    
         
             
                            someMoreWork = 0; break;
         
     | 
| 
       3845 
4173 
     | 
    
         
             
                        }
         
     | 
| 
       3846 
     | 
    
         
            -
                        /* complete loading into inBuffer */
         
     | 
| 
       3847 
     | 
    
         
            -
                         
     | 
| 
      
 4174 
     | 
    
         
            +
                        /* complete loading into inBuffer in buffered mode */
         
     | 
| 
      
 4175 
     | 
    
         
            +
                        if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) {
         
     | 
| 
      
 4176 
     | 
    
         
            +
                            size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
         
     | 
| 
       3848 
4177 
     | 
    
         
             
                            size_t const loaded = ZSTD_limitCopy(
         
     | 
| 
       3849 
4178 
     | 
    
         
             
                                                    zcs->inBuff + zcs->inBuffPos, toLoad,
         
     | 
| 
       3850 
4179 
     | 
    
         
             
                                                    ip, iend-ip);
         
     | 
| 
         @@ -3864,31 +4193,49 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, 
     | 
|
| 
       3864 
4193 
     | 
    
         
             
                        }
         
     | 
| 
       3865 
4194 
     | 
    
         
             
                        /* compress current block (note : this stage cannot be stopped in the middle) */
         
     | 
| 
       3866 
4195 
     | 
    
         
             
                        DEBUGLOG(5, "stream compression stage (flushMode==%u)", flushMode);
         
     | 
| 
       3867 
     | 
    
         
            -
                        {    
     | 
| 
      
 4196 
     | 
    
         
            +
                        {   int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered);
         
     | 
| 
      
 4197 
     | 
    
         
            +
                            void* cDst;
         
     | 
| 
       3868 
4198 
     | 
    
         
             
                            size_t cSize;
         
     | 
| 
       3869 
     | 
    
         
            -
                            size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
         
     | 
| 
       3870 
4199 
     | 
    
         
             
                            size_t oSize = oend-op;
         
     | 
| 
       3871 
     | 
    
         
            -
                             
     | 
| 
       3872 
     | 
    
         
            -
             
     | 
| 
      
 4200 
     | 
    
         
            +
                            size_t const iSize = inputBuffered
         
     | 
| 
      
 4201 
     | 
    
         
            +
                                ? zcs->inBuffPos - zcs->inToCompress
         
     | 
| 
      
 4202 
     | 
    
         
            +
                                : MIN((size_t)(iend - ip), zcs->blockSize);
         
     | 
| 
      
 4203 
     | 
    
         
            +
                            if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)
         
     | 
| 
       3873 
4204 
     | 
    
         
             
                                cDst = op;   /* compress into output buffer, to skip flush stage */
         
     | 
| 
       3874 
4205 
     | 
    
         
             
                            else
         
     | 
| 
       3875 
4206 
     | 
    
         
             
                                cDst = zcs->outBuff, oSize = zcs->outBuffSize;
         
     | 
| 
       3876 
     | 
    
         
            -
                             
     | 
| 
       3877 
     | 
    
         
            -
             
     | 
| 
       3878 
     | 
    
         
            -
             
     | 
| 
       3879 
     | 
    
         
            -
             
     | 
| 
       3880 
     | 
    
         
            -
             
     | 
| 
       3881 
     | 
    
         
            -
             
     | 
| 
       3882 
     | 
    
         
            -
             
     | 
| 
       3883 
     | 
    
         
            -
             
     | 
| 
       3884 
     | 
    
         
            -
             
     | 
| 
       3885 
     | 
    
         
            -
             
     | 
| 
       3886 
     | 
    
         
            -
                                zcs-> 
     | 
| 
       3887 
     | 
    
         
            -
             
     | 
| 
       3888 
     | 
    
         
            -
             
     | 
| 
       3889 
     | 
    
         
            -
             
     | 
| 
       3890 
     | 
    
         
            -
             
     | 
| 
       3891 
     | 
    
         
            -
             
     | 
| 
      
 4207 
     | 
    
         
            +
                            if (inputBuffered) {
         
     | 
| 
      
 4208 
     | 
    
         
            +
                                unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend);
         
     | 
| 
      
 4209 
     | 
    
         
            +
                                cSize = lastBlock ?
         
     | 
| 
      
 4210 
     | 
    
         
            +
                                        ZSTD_compressEnd(zcs, cDst, oSize,
         
     | 
| 
      
 4211 
     | 
    
         
            +
                                                    zcs->inBuff + zcs->inToCompress, iSize) :
         
     | 
| 
      
 4212 
     | 
    
         
            +
                                        ZSTD_compressContinue(zcs, cDst, oSize,
         
     | 
| 
      
 4213 
     | 
    
         
            +
                                                    zcs->inBuff + zcs->inToCompress, iSize);
         
     | 
| 
      
 4214 
     | 
    
         
            +
                                FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
         
     | 
| 
      
 4215 
     | 
    
         
            +
                                zcs->frameEnded = lastBlock;
         
     | 
| 
      
 4216 
     | 
    
         
            +
                                /* prepare next block */
         
     | 
| 
      
 4217 
     | 
    
         
            +
                                zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
         
     | 
| 
      
 4218 
     | 
    
         
            +
                                if (zcs->inBuffTarget > zcs->inBuffSize)
         
     | 
| 
      
 4219 
     | 
    
         
            +
                                    zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
         
     | 
| 
      
 4220 
     | 
    
         
            +
                                DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
         
     | 
| 
      
 4221 
     | 
    
         
            +
                                        (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
         
     | 
| 
      
 4222 
     | 
    
         
            +
                                if (!lastBlock)
         
     | 
| 
      
 4223 
     | 
    
         
            +
                                    assert(zcs->inBuffTarget <= zcs->inBuffSize);
         
     | 
| 
      
 4224 
     | 
    
         
            +
                                zcs->inToCompress = zcs->inBuffPos;
         
     | 
| 
      
 4225 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 4226 
     | 
    
         
            +
                                unsigned const lastBlock = (ip + iSize == iend);
         
     | 
| 
      
 4227 
     | 
    
         
            +
                                assert(flushMode == ZSTD_e_end /* Already validated */);
         
     | 
| 
      
 4228 
     | 
    
         
            +
                                cSize = lastBlock ?
         
     | 
| 
      
 4229 
     | 
    
         
            +
                                        ZSTD_compressEnd(zcs, cDst, oSize, ip, iSize) :
         
     | 
| 
      
 4230 
     | 
    
         
            +
                                        ZSTD_compressContinue(zcs, cDst, oSize, ip, iSize);
         
     | 
| 
      
 4231 
     | 
    
         
            +
                                /* Consume the input prior to error checking to mirror buffered mode. */
         
     | 
| 
      
 4232 
     | 
    
         
            +
                                if (iSize > 0)
         
     | 
| 
      
 4233 
     | 
    
         
            +
                                    ip += iSize;
         
     | 
| 
      
 4234 
     | 
    
         
            +
                                FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
         
     | 
| 
      
 4235 
     | 
    
         
            +
                                zcs->frameEnded = lastBlock;
         
     | 
| 
      
 4236 
     | 
    
         
            +
                                if (lastBlock)
         
     | 
| 
      
 4237 
     | 
    
         
            +
                                    assert(ip == iend);
         
     | 
| 
      
 4238 
     | 
    
         
            +
                            }
         
     | 
| 
       3892 
4239 
     | 
    
         
             
                            if (cDst == op) {  /* no need to flush */
         
     | 
| 
       3893 
4240 
     | 
    
         
             
                                op += cSize;
         
     | 
| 
       3894 
4241 
     | 
    
         
             
                                if (zcs->frameEnded) {
         
     | 
| 
         @@ -3905,6 +4252,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, 
     | 
|
| 
       3905 
4252 
     | 
    
         
             
            	    /* fall-through */
         
     | 
| 
       3906 
4253 
     | 
    
         
             
                    case zcss_flush:
         
     | 
| 
       3907 
4254 
     | 
    
         
             
                        DEBUGLOG(5, "flush stage");
         
     | 
| 
      
 4255 
     | 
    
         
            +
                        assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
         
     | 
| 
       3908 
4256 
     | 
    
         
             
                        {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
         
     | 
| 
       3909 
4257 
     | 
    
         
             
                            size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op),
         
     | 
| 
       3910 
4258 
     | 
    
         
             
                                        zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
         
     | 
| 
         @@ -3959,6 +4307,116 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf 
     | 
|
| 
       3959 
4307 
     | 
    
         
             
                return ZSTD_nextInputSizeHint_MTorST(zcs);
         
     | 
| 
       3960 
4308 
     | 
    
         
             
            }
         
     | 
| 
       3961 
4309 
     | 
    
         | 
| 
      
 4310 
     | 
    
         
            +
            /* After a compression call set the expected input/output buffer.
         
     | 
| 
      
 4311 
     | 
    
         
            +
             * This is validated at the start of the next compression call.
         
     | 
| 
      
 4312 
     | 
    
         
            +
             */
         
     | 
| 
      
 4313 
     | 
    
         
            +
            static void ZSTD_setBufferExpectations(ZSTD_CCtx* cctx, ZSTD_outBuffer const* output, ZSTD_inBuffer const* input)
         
     | 
| 
      
 4314 
     | 
    
         
            +
            {
         
     | 
| 
      
 4315 
     | 
    
         
            +
                if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
         
     | 
| 
      
 4316 
     | 
    
         
            +
                    cctx->expectedInBuffer = *input;
         
     | 
| 
      
 4317 
     | 
    
         
            +
                }
         
     | 
| 
      
 4318 
     | 
    
         
            +
                if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
         
     | 
| 
      
 4319 
     | 
    
         
            +
                    cctx->expectedOutBufferSize = output->size - output->pos;
         
     | 
| 
      
 4320 
     | 
    
         
            +
                }
         
     | 
| 
      
 4321 
     | 
    
         
            +
            }
         
     | 
| 
      
 4322 
     | 
    
         
            +
             
     | 
| 
      
 4323 
     | 
    
         
            +
            /* Validate that the input/output buffers match the expectations set by
         
     | 
| 
      
 4324 
     | 
    
         
            +
             * ZSTD_setBufferExpectations.
         
     | 
| 
      
 4325 
     | 
    
         
            +
             */
         
     | 
| 
      
 4326 
     | 
    
         
            +
            static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx,
         
     | 
| 
      
 4327 
     | 
    
         
            +
                                                    ZSTD_outBuffer const* output,
         
     | 
| 
      
 4328 
     | 
    
         
            +
                                                    ZSTD_inBuffer const* input,
         
     | 
| 
      
 4329 
     | 
    
         
            +
                                                    ZSTD_EndDirective endOp)
         
     | 
| 
      
 4330 
     | 
    
         
            +
            {
         
     | 
| 
      
 4331 
     | 
    
         
            +
                if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
         
     | 
| 
      
 4332 
     | 
    
         
            +
                    ZSTD_inBuffer const expect = cctx->expectedInBuffer;
         
     | 
| 
      
 4333 
     | 
    
         
            +
                    if (expect.src != input->src || expect.pos != input->pos || expect.size != input->size)
         
     | 
| 
      
 4334 
     | 
    
         
            +
                        RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer enabled but input differs!");
         
     | 
| 
      
 4335 
     | 
    
         
            +
                    if (endOp != ZSTD_e_end)
         
     | 
| 
      
 4336 
     | 
    
         
            +
                        RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer can only be used with ZSTD_e_end!");
         
     | 
| 
      
 4337 
     | 
    
         
            +
                }
         
     | 
| 
      
 4338 
     | 
    
         
            +
                if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
         
     | 
| 
      
 4339 
     | 
    
         
            +
                    size_t const outBufferSize = output->size - output->pos;
         
     | 
| 
      
 4340 
     | 
    
         
            +
                    if (cctx->expectedOutBufferSize != outBufferSize)
         
     | 
| 
      
 4341 
     | 
    
         
            +
                        RETURN_ERROR(dstBuffer_wrong, "ZSTD_c_stableOutBuffer enabled but output size differs!");
         
     | 
| 
      
 4342 
     | 
    
         
            +
                }
         
     | 
| 
      
 4343 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 4344 
     | 
    
         
            +
            }
         
     | 
| 
      
 4345 
     | 
    
         
            +
             
     | 
| 
      
 4346 
     | 
    
         
            +
            static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
         
     | 
| 
      
 4347 
     | 
    
         
            +
                                                         ZSTD_EndDirective endOp,
         
     | 
| 
      
 4348 
     | 
    
         
            +
                                                         size_t inSize) {
         
     | 
| 
      
 4349 
     | 
    
         
            +
                ZSTD_CCtx_params params = cctx->requestedParams;
         
     | 
| 
      
 4350 
     | 
    
         
            +
                ZSTD_prefixDict const prefixDict = cctx->prefixDict;
         
     | 
| 
      
 4351 
     | 
    
         
            +
                FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */
         
     | 
| 
      
 4352 
     | 
    
         
            +
                ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));   /* single usage */
         
     | 
| 
      
 4353 
     | 
    
         
            +
                assert(prefixDict.dict==NULL || cctx->cdict==NULL);    /* only one can be set */
         
     | 
| 
      
 4354 
     | 
    
         
            +
                if (cctx->cdict)
         
     | 
| 
      
 4355 
     | 
    
         
            +
                    params.compressionLevel = cctx->cdict->compressionLevel; /* let cdict take priority in terms of compression level */
         
     | 
| 
      
 4356 
     | 
    
         
            +
                DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
         
     | 
| 
      
 4357 
     | 
    
         
            +
                if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1;  /* auto-fix pledgedSrcSize */
         
     | 
| 
      
 4358 
     | 
    
         
            +
                {
         
     | 
| 
      
 4359 
     | 
    
         
            +
                    size_t const dictSize = prefixDict.dict
         
     | 
| 
      
 4360 
     | 
    
         
            +
                            ? prefixDict.dictSize
         
     | 
| 
      
 4361 
     | 
    
         
            +
                            : (cctx->cdict ? cctx->cdict->dictContentSize : 0);
         
     | 
| 
      
 4362 
     | 
    
         
            +
                    ZSTD_cParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, ¶ms, cctx->pledgedSrcSizePlusOne - 1);
         
     | 
| 
      
 4363 
     | 
    
         
            +
                    params.cParams = ZSTD_getCParamsFromCCtxParams(
         
     | 
| 
      
 4364 
     | 
    
         
            +
                            ¶ms, cctx->pledgedSrcSizePlusOne-1,
         
     | 
| 
      
 4365 
     | 
    
         
            +
                            dictSize, mode);
         
     | 
| 
      
 4366 
     | 
    
         
            +
                }
         
     | 
| 
      
 4367 
     | 
    
         
            +
             
     | 
| 
      
 4368 
     | 
    
         
            +
                if (ZSTD_CParams_shouldEnableLdm(¶ms.cParams)) {
         
     | 
| 
      
 4369 
     | 
    
         
            +
                    /* Enable LDM by default for optimal parser and window size >= 128MB */
         
     | 
| 
      
 4370 
     | 
    
         
            +
                    DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)");
         
     | 
| 
      
 4371 
     | 
    
         
            +
                    params.ldmParams.enableLdm = 1;
         
     | 
| 
      
 4372 
     | 
    
         
            +
                }
         
     | 
| 
      
 4373 
     | 
    
         
            +
             
     | 
| 
      
 4374 
     | 
    
         
            +
            #ifdef ZSTD_MULTITHREAD
         
     | 
| 
      
 4375 
     | 
    
         
            +
                if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
         
     | 
| 
      
 4376 
     | 
    
         
            +
                    params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
         
     | 
| 
      
 4377 
     | 
    
         
            +
                }
         
     | 
| 
      
 4378 
     | 
    
         
            +
                if (params.nbWorkers > 0) {
         
     | 
| 
      
 4379 
     | 
    
         
            +
                    /* mt context creation */
         
     | 
| 
      
 4380 
     | 
    
         
            +
                    if (cctx->mtctx == NULL) {
         
     | 
| 
      
 4381 
     | 
    
         
            +
                        DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
         
     | 
| 
      
 4382 
     | 
    
         
            +
                                    params.nbWorkers);
         
     | 
| 
      
 4383 
     | 
    
         
            +
                        cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem, cctx->pool);
         
     | 
| 
      
 4384 
     | 
    
         
            +
                        RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!");
         
     | 
| 
      
 4385 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4386 
     | 
    
         
            +
                    /* mt compression */
         
     | 
| 
      
 4387 
     | 
    
         
            +
                    DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
         
     | 
| 
      
 4388 
     | 
    
         
            +
                    FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(
         
     | 
| 
      
 4389 
     | 
    
         
            +
                                cctx->mtctx,
         
     | 
| 
      
 4390 
     | 
    
         
            +
                                prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
         
     | 
| 
      
 4391 
     | 
    
         
            +
                                cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
         
     | 
| 
      
 4392 
     | 
    
         
            +
                    cctx->streamStage = zcss_load;
         
     | 
| 
      
 4393 
     | 
    
         
            +
                    cctx->appliedParams = params;
         
     | 
| 
      
 4394 
     | 
    
         
            +
                } else
         
     | 
| 
      
 4395 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 4396 
     | 
    
         
            +
                {   U64 const pledgedSrcSize = cctx->pledgedSrcSizePlusOne - 1;
         
     | 
| 
      
 4397 
     | 
    
         
            +
                    assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
         
     | 
| 
      
 4398 
     | 
    
         
            +
                    FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
         
     | 
| 
      
 4399 
     | 
    
         
            +
                            prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, ZSTD_dtlm_fast,
         
     | 
| 
      
 4400 
     | 
    
         
            +
                            cctx->cdict,
         
     | 
| 
      
 4401 
     | 
    
         
            +
                            ¶ms, pledgedSrcSize,
         
     | 
| 
      
 4402 
     | 
    
         
            +
                            ZSTDb_buffered) , "");
         
     | 
| 
      
 4403 
     | 
    
         
            +
                    assert(cctx->appliedParams.nbWorkers == 0);
         
     | 
| 
      
 4404 
     | 
    
         
            +
                    cctx->inToCompress = 0;
         
     | 
| 
      
 4405 
     | 
    
         
            +
                    cctx->inBuffPos = 0;
         
     | 
| 
      
 4406 
     | 
    
         
            +
                    if (cctx->appliedParams.inBufferMode == ZSTD_bm_buffered) {
         
     | 
| 
      
 4407 
     | 
    
         
            +
                        /* for small input: avoid automatic flush on reaching end of block, since
         
     | 
| 
      
 4408 
     | 
    
         
            +
                        * it would require to add a 3-bytes null block to end frame
         
     | 
| 
      
 4409 
     | 
    
         
            +
                        */
         
     | 
| 
      
 4410 
     | 
    
         
            +
                        cctx->inBuffTarget = cctx->blockSize + (cctx->blockSize == pledgedSrcSize);
         
     | 
| 
      
 4411 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 4412 
     | 
    
         
            +
                        cctx->inBuffTarget = 0;
         
     | 
| 
      
 4413 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4414 
     | 
    
         
            +
                    cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;
         
     | 
| 
      
 4415 
     | 
    
         
            +
                    cctx->streamStage = zcss_load;
         
     | 
| 
      
 4416 
     | 
    
         
            +
                    cctx->frameEnded = 0;
         
     | 
| 
      
 4417 
     | 
    
         
            +
                }
         
     | 
| 
      
 4418 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 4419 
     | 
    
         
            +
            }
         
     | 
| 
       3962 
4420 
     | 
    
         | 
| 
       3963 
4421 
     | 
    
         
             
            size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
         
     | 
| 
       3964 
4422 
     | 
    
         
             
                                         ZSTD_outBuffer* output,
         
     | 
| 
         @@ -3967,82 +4425,65 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx, 
     | 
|
| 
       3967 
4425 
     | 
    
         
             
            {
         
     | 
| 
       3968 
4426 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
         
     | 
| 
       3969 
4427 
     | 
    
         
             
                /* check conditions */
         
     | 
| 
       3970 
     | 
    
         
            -
                RETURN_ERROR_IF(output->pos > output->size,  
     | 
| 
       3971 
     | 
    
         
            -
                RETURN_ERROR_IF(input->pos  > input->size,  
     | 
| 
       3972 
     | 
    
         
            -
                 
     | 
| 
      
 4428 
     | 
    
         
            +
                RETURN_ERROR_IF(output->pos > output->size, dstSize_tooSmall, "invalid output buffer");
         
     | 
| 
      
 4429 
     | 
    
         
            +
                RETURN_ERROR_IF(input->pos  > input->size, srcSize_wrong, "invalid input buffer");
         
     | 
| 
      
 4430 
     | 
    
         
            +
                RETURN_ERROR_IF((U32)endOp > (U32)ZSTD_e_end, parameter_outOfBound, "invalid endDirective");
         
     | 
| 
      
 4431 
     | 
    
         
            +
                assert(cctx != NULL);
         
     | 
| 
       3973 
4432 
     | 
    
         | 
| 
       3974 
4433 
     | 
    
         
             
                /* transparent initialization stage */
         
     | 
| 
       3975 
4434 
     | 
    
         
             
                if (cctx->streamStage == zcss_init) {
         
     | 
| 
       3976 
     | 
    
         
            -
                     
     | 
| 
       3977 
     | 
    
         
            -
                     
     | 
| 
       3978 
     | 
    
         
            -
             
     | 
| 
       3979 
     | 
    
         
            -
                    memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));   /* single usage */
         
     | 
| 
       3980 
     | 
    
         
            -
                    assert(prefixDict.dict==NULL || cctx->cdict==NULL);    /* only one can be set */
         
     | 
| 
       3981 
     | 
    
         
            -
                    DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
         
     | 
| 
       3982 
     | 
    
         
            -
                    if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */
         
     | 
| 
       3983 
     | 
    
         
            -
                    params.cParams = ZSTD_getCParamsFromCCtxParams(
         
     | 
| 
       3984 
     | 
    
         
            -
                            &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
         
     | 
| 
       3985 
     | 
    
         
            -
             
     | 
| 
       3986 
     | 
    
         
            -
             
     | 
| 
       3987 
     | 
    
         
            -
            #ifdef ZSTD_MULTITHREAD
         
     | 
| 
       3988 
     | 
    
         
            -
                    if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
         
     | 
| 
       3989 
     | 
    
         
            -
                        params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
         
     | 
| 
       3990 
     | 
    
         
            -
                    }
         
     | 
| 
       3991 
     | 
    
         
            -
                    if (params.nbWorkers > 0) {
         
     | 
| 
       3992 
     | 
    
         
            -
                        /* mt context creation */
         
     | 
| 
       3993 
     | 
    
         
            -
                        if (cctx->mtctx == NULL) {
         
     | 
| 
       3994 
     | 
    
         
            -
                            DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
         
     | 
| 
       3995 
     | 
    
         
            -
                                        params.nbWorkers);
         
     | 
| 
       3996 
     | 
    
         
            -
                            cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem);
         
     | 
| 
       3997 
     | 
    
         
            -
                            RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!");
         
     | 
| 
       3998 
     | 
    
         
            -
                        }
         
     | 
| 
       3999 
     | 
    
         
            -
                        /* mt compression */
         
     | 
| 
       4000 
     | 
    
         
            -
                        DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
         
     | 
| 
       4001 
     | 
    
         
            -
                        FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(
         
     | 
| 
       4002 
     | 
    
         
            -
                                    cctx->mtctx,
         
     | 
| 
       4003 
     | 
    
         
            -
                                    prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
         
     | 
| 
       4004 
     | 
    
         
            -
                                    cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
         
     | 
| 
       4005 
     | 
    
         
            -
                        cctx->streamStage = zcss_load;
         
     | 
| 
       4006 
     | 
    
         
            -
                        cctx->appliedParams.nbWorkers = params.nbWorkers;
         
     | 
| 
       4007 
     | 
    
         
            -
                    } else
         
     | 
| 
       4008 
     | 
    
         
            -
            #endif
         
     | 
| 
       4009 
     | 
    
         
            -
                    {   FORWARD_IF_ERROR( ZSTD_resetCStream_internal(cctx,
         
     | 
| 
       4010 
     | 
    
         
            -
                                        prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
         
     | 
| 
       4011 
     | 
    
         
            -
                                        cctx->cdict,
         
     | 
| 
       4012 
     | 
    
         
            -
                                        params, cctx->pledgedSrcSizePlusOne-1) , "");
         
     | 
| 
       4013 
     | 
    
         
            -
                        assert(cctx->streamStage == zcss_load);
         
     | 
| 
       4014 
     | 
    
         
            -
                        assert(cctx->appliedParams.nbWorkers == 0);
         
     | 
| 
       4015 
     | 
    
         
            -
                }   }
         
     | 
| 
      
 4435 
     | 
    
         
            +
                    FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, endOp, input->size), "CompressStream2 initialization failed");
         
     | 
| 
      
 4436 
     | 
    
         
            +
                    ZSTD_setBufferExpectations(cctx, output, input);    /* Set initial buffer expectations now that we've initialized */
         
     | 
| 
      
 4437 
     | 
    
         
            +
                }
         
     | 
| 
       4016 
4438 
     | 
    
         
             
                /* end of transparent initialization stage */
         
     | 
| 
       4017 
4439 
     | 
    
         | 
| 
      
 4440 
     | 
    
         
            +
                FORWARD_IF_ERROR(ZSTD_checkBufferStability(cctx, output, input, endOp), "invalid buffers");
         
     | 
| 
       4018 
4441 
     | 
    
         
             
                /* compression stage */
         
     | 
| 
       4019 
4442 
     | 
    
         
             
            #ifdef ZSTD_MULTITHREAD
         
     | 
| 
       4020 
4443 
     | 
    
         
             
                if (cctx->appliedParams.nbWorkers > 0) {
         
     | 
| 
       4021 
     | 
    
         
            -
                    int const forceMaxProgress = (endOp == ZSTD_e_flush || endOp == ZSTD_e_end);
         
     | 
| 
       4022 
4444 
     | 
    
         
             
                    size_t flushMin;
         
     | 
| 
       4023 
     | 
    
         
            -
                    assert(forceMaxProgress || endOp == ZSTD_e_continue /* Protection for a new flush type */);
         
     | 
| 
       4024 
4445 
     | 
    
         
             
                    if (cctx->cParamsChanged) {
         
     | 
| 
       4025 
4446 
     | 
    
         
             
                        ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams);
         
     | 
| 
       4026 
4447 
     | 
    
         
             
                        cctx->cParamsChanged = 0;
         
     | 
| 
       4027 
4448 
     | 
    
         
             
                    }
         
     | 
| 
       4028 
     | 
    
         
            -
                     
     | 
| 
      
 4449 
     | 
    
         
            +
                    for (;;) {
         
     | 
| 
      
 4450 
     | 
    
         
            +
                        size_t const ipos = input->pos;
         
     | 
| 
      
 4451 
     | 
    
         
            +
                        size_t const opos = output->pos;
         
     | 
| 
       4029 
4452 
     | 
    
         
             
                        flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
         
     | 
| 
       4030 
4453 
     | 
    
         
             
                        if ( ZSTD_isError(flushMin)
         
     | 
| 
       4031 
4454 
     | 
    
         
             
                          || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
         
     | 
| 
       4032 
4455 
     | 
    
         
             
                            ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
         
     | 
| 
       4033 
4456 
     | 
    
         
             
                        }
         
     | 
| 
       4034 
4457 
     | 
    
         
             
                        FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed");
         
     | 
| 
       4035 
     | 
    
         
            -
             
     | 
| 
      
 4458 
     | 
    
         
            +
             
     | 
| 
      
 4459 
     | 
    
         
            +
                        if (endOp == ZSTD_e_continue) {
         
     | 
| 
      
 4460 
     | 
    
         
            +
                            /* We only require some progress with ZSTD_e_continue, not maximal progress.
         
     | 
| 
      
 4461 
     | 
    
         
            +
                             * We're done if we've consumed or produced any bytes, or either buffer is
         
     | 
| 
      
 4462 
     | 
    
         
            +
                             * full.
         
     | 
| 
      
 4463 
     | 
    
         
            +
                             */
         
     | 
| 
      
 4464 
     | 
    
         
            +
                            if (input->pos != ipos || output->pos != opos || input->pos == input->size || output->pos == output->size)
         
     | 
| 
      
 4465 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 4466 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 4467 
     | 
    
         
            +
                            assert(endOp == ZSTD_e_flush || endOp == ZSTD_e_end);
         
     | 
| 
      
 4468 
     | 
    
         
            +
                            /* We require maximal progress. We're done when the flush is complete or the
         
     | 
| 
      
 4469 
     | 
    
         
            +
                             * output buffer is full.
         
     | 
| 
      
 4470 
     | 
    
         
            +
                             */
         
     | 
| 
      
 4471 
     | 
    
         
            +
                            if (flushMin == 0 || output->pos == output->size)
         
     | 
| 
      
 4472 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 4473 
     | 
    
         
            +
                        }
         
     | 
| 
      
 4474 
     | 
    
         
            +
                    }
         
     | 
| 
       4036 
4475 
     | 
    
         
             
                    DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
         
     | 
| 
       4037 
4476 
     | 
    
         
             
                    /* Either we don't require maximum forward progress, we've finished the
         
     | 
| 
       4038 
4477 
     | 
    
         
             
                     * flush, or we are out of output space.
         
     | 
| 
       4039 
4478 
     | 
    
         
             
                     */
         
     | 
| 
       4040 
     | 
    
         
            -
                    assert( 
     | 
| 
      
 4479 
     | 
    
         
            +
                    assert(endOp == ZSTD_e_continue || flushMin == 0 || output->pos == output->size);
         
     | 
| 
      
 4480 
     | 
    
         
            +
                    ZSTD_setBufferExpectations(cctx, output, input);
         
     | 
| 
       4041 
4481 
     | 
    
         
             
                    return flushMin;
         
     | 
| 
       4042 
4482 
     | 
    
         
             
                }
         
     | 
| 
       4043 
4483 
     | 
    
         
             
            #endif
         
     | 
| 
       4044 
4484 
     | 
    
         
             
                FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) , "");
         
     | 
| 
       4045 
4485 
     | 
    
         
             
                DEBUGLOG(5, "completed ZSTD_compressStream2");
         
     | 
| 
      
 4486 
     | 
    
         
            +
                ZSTD_setBufferExpectations(cctx, output, input);
         
     | 
| 
       4046 
4487 
     | 
    
         
             
                return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
         
     | 
| 
       4047 
4488 
     | 
    
         
             
            }
         
     | 
| 
       4048 
4489 
     | 
    
         | 
| 
         @@ -4065,14 +4506,22 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx, 
     | 
|
| 
       4065 
4506 
     | 
    
         
             
                                  void* dst, size_t dstCapacity,
         
     | 
| 
       4066 
4507 
     | 
    
         
             
                                  const void* src, size_t srcSize)
         
     | 
| 
       4067 
4508 
     | 
    
         
             
            {
         
     | 
| 
      
 4509 
     | 
    
         
            +
                ZSTD_bufferMode_e const originalInBufferMode = cctx->requestedParams.inBufferMode;
         
     | 
| 
      
 4510 
     | 
    
         
            +
                ZSTD_bufferMode_e const originalOutBufferMode = cctx->requestedParams.outBufferMode;
         
     | 
| 
       4068 
4511 
     | 
    
         
             
                DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize);
         
     | 
| 
       4069 
4512 
     | 
    
         
             
                ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
         
     | 
| 
      
 4513 
     | 
    
         
            +
                /* Enable stable input/output buffers. */
         
     | 
| 
      
 4514 
     | 
    
         
            +
                cctx->requestedParams.inBufferMode = ZSTD_bm_stable;
         
     | 
| 
      
 4515 
     | 
    
         
            +
                cctx->requestedParams.outBufferMode = ZSTD_bm_stable;
         
     | 
| 
       4070 
4516 
     | 
    
         
             
                {   size_t oPos = 0;
         
     | 
| 
       4071 
4517 
     | 
    
         
             
                    size_t iPos = 0;
         
     | 
| 
       4072 
4518 
     | 
    
         
             
                    size_t const result = ZSTD_compressStream2_simpleArgs(cctx,
         
     | 
| 
       4073 
4519 
     | 
    
         
             
                                                    dst, dstCapacity, &oPos,
         
     | 
| 
       4074 
4520 
     | 
    
         
             
                                                    src, srcSize, &iPos,
         
     | 
| 
       4075 
4521 
     | 
    
         
             
                                                    ZSTD_e_end);
         
     | 
| 
      
 4522 
     | 
    
         
            +
                    /* Reset to the original values. */
         
     | 
| 
      
 4523 
     | 
    
         
            +
                    cctx->requestedParams.inBufferMode = originalInBufferMode;
         
     | 
| 
      
 4524 
     | 
    
         
            +
                    cctx->requestedParams.outBufferMode = originalOutBufferMode;
         
     | 
| 
       4076 
4525 
     | 
    
         
             
                    FORWARD_IF_ERROR(result, "ZSTD_compressStream2_simpleArgs failed");
         
     | 
| 
       4077 
4526 
     | 
    
         
             
                    if (result != 0) {  /* compression not completed, due to lack of output space */
         
     | 
| 
       4078 
4527 
     | 
    
         
             
                        assert(oPos == dstCapacity);
         
     | 
| 
         @@ -4083,6 +4532,409 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx, 
     | 
|
| 
       4083 
4532 
     | 
    
         
             
                }
         
     | 
| 
       4084 
4533 
     | 
    
         
             
            }
         
     | 
| 
       4085 
4534 
     | 
    
         | 
| 
      
 4535 
     | 
    
         
            +
            typedef struct {
         
     | 
| 
      
 4536 
     | 
    
         
            +
                U32 idx;             /* Index in array of ZSTD_Sequence */
         
     | 
| 
      
 4537 
     | 
    
         
            +
                U32 posInSequence;   /* Position within sequence at idx */
         
     | 
| 
      
 4538 
     | 
    
         
            +
                size_t posInSrc;        /* Number of bytes given by sequences provided so far */
         
     | 
| 
      
 4539 
     | 
    
         
            +
            } ZSTD_sequencePosition;
         
     | 
| 
      
 4540 
     | 
    
         
            +
             
     | 
| 
      
 4541 
     | 
    
         
            +
            /* Returns a ZSTD error code if sequence is not valid */
         
     | 
| 
      
 4542 
     | 
    
         
            +
            static size_t ZSTD_validateSequence(U32 offCode, U32 matchLength,
         
     | 
| 
      
 4543 
     | 
    
         
            +
                                                size_t posInSrc, U32 windowLog, size_t dictSize, U32 minMatch) {
         
     | 
| 
      
 4544 
     | 
    
         
            +
                size_t offsetBound;
         
     | 
| 
      
 4545 
     | 
    
         
            +
                U32 windowSize = 1 << windowLog;
         
     | 
| 
      
 4546 
     | 
    
         
            +
                /* posInSrc represents the amount of data the the decoder would decode up to this point.
         
     | 
| 
      
 4547 
     | 
    
         
            +
                 * As long as the amount of data decoded is less than or equal to window size, offsets may be
         
     | 
| 
      
 4548 
     | 
    
         
            +
                 * larger than the total length of output decoded in order to reference the dict, even larger than
         
     | 
| 
      
 4549 
     | 
    
         
            +
                 * window size. After output surpasses windowSize, we're limited to windowSize offsets again.
         
     | 
| 
      
 4550 
     | 
    
         
            +
                 */
         
     | 
| 
      
 4551 
     | 
    
         
            +
                offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
         
     | 
| 
      
 4552 
     | 
    
         
            +
                RETURN_ERROR_IF(offCode > offsetBound + ZSTD_REP_MOVE, corruption_detected, "Offset too large!");
         
     | 
| 
      
 4553 
     | 
    
         
            +
                RETURN_ERROR_IF(matchLength < minMatch, corruption_detected, "Matchlength too small");
         
     | 
| 
      
 4554 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 4555 
     | 
    
         
            +
            }
         
     | 
| 
      
 4556 
     | 
    
         
            +
             
     | 
| 
      
 4557 
     | 
    
         
            +
            /* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */
         
     | 
| 
      
 4558 
     | 
    
         
            +
            static U32 ZSTD_finalizeOffCode(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0) {
         
     | 
| 
      
 4559 
     | 
    
         
            +
                U32 offCode = rawOffset + ZSTD_REP_MOVE;
         
     | 
| 
      
 4560 
     | 
    
         
            +
                U32 repCode = 0;
         
     | 
| 
      
 4561 
     | 
    
         
            +
             
     | 
| 
      
 4562 
     | 
    
         
            +
                if (!ll0 && rawOffset == rep[0]) {
         
     | 
| 
      
 4563 
     | 
    
         
            +
                    repCode = 1;
         
     | 
| 
      
 4564 
     | 
    
         
            +
                } else if (rawOffset == rep[1]) {
         
     | 
| 
      
 4565 
     | 
    
         
            +
                    repCode = 2 - ll0;
         
     | 
| 
      
 4566 
     | 
    
         
            +
                } else if (rawOffset == rep[2]) {
         
     | 
| 
      
 4567 
     | 
    
         
            +
                    repCode = 3 - ll0;
         
     | 
| 
      
 4568 
     | 
    
         
            +
                } else if (ll0 && rawOffset == rep[0] - 1) {
         
     | 
| 
      
 4569 
     | 
    
         
            +
                    repCode = 3;
         
     | 
| 
      
 4570 
     | 
    
         
            +
                }
         
     | 
| 
      
 4571 
     | 
    
         
            +
                if (repCode) {
         
     | 
| 
      
 4572 
     | 
    
         
            +
                    /* ZSTD_storeSeq expects a number in the range [0, 2] to represent a repcode */
         
     | 
| 
      
 4573 
     | 
    
         
            +
                    offCode = repCode - 1;
         
     | 
| 
      
 4574 
     | 
    
         
            +
                }
         
     | 
| 
      
 4575 
     | 
    
         
            +
                return offCode;
         
     | 
| 
      
 4576 
     | 
    
         
            +
            }
         
     | 
| 
      
 4577 
     | 
    
         
            +
             
     | 
| 
      
 4578 
     | 
    
         
            +
            /* Returns 0 on success, and a ZSTD_error otherwise. This function scans through an array of
         
     | 
| 
      
 4579 
     | 
    
         
            +
             * ZSTD_Sequence, storing the sequences it finds, until it reaches a block delimiter.
         
     | 
| 
      
 4580 
     | 
    
         
            +
             */
         
     | 
| 
      
 4581 
     | 
    
         
            +
            static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
         
     | 
| 
      
 4582 
     | 
    
         
            +
                                                                         const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
         
     | 
| 
      
 4583 
     | 
    
         
            +
                                                                         const void* src, size_t blockSize) {
         
     | 
| 
      
 4584 
     | 
    
         
            +
                U32 idx = seqPos->idx;
         
     | 
| 
      
 4585 
     | 
    
         
            +
                BYTE const* ip = (BYTE const*)(src);
         
     | 
| 
      
 4586 
     | 
    
         
            +
                const BYTE* const iend = ip + blockSize;
         
     | 
| 
      
 4587 
     | 
    
         
            +
                repcodes_t updatedRepcodes;
         
     | 
| 
      
 4588 
     | 
    
         
            +
                U32 dictSize;
         
     | 
| 
      
 4589 
     | 
    
         
            +
                U32 litLength;
         
     | 
| 
      
 4590 
     | 
    
         
            +
                U32 matchLength;
         
     | 
| 
      
 4591 
     | 
    
         
            +
                U32 ll0;
         
     | 
| 
      
 4592 
     | 
    
         
            +
                U32 offCode;
         
     | 
| 
      
 4593 
     | 
    
         
            +
             
     | 
| 
      
 4594 
     | 
    
         
            +
                if (cctx->cdict) {
         
     | 
| 
      
 4595 
     | 
    
         
            +
                    dictSize = (U32)cctx->cdict->dictContentSize;
         
     | 
| 
      
 4596 
     | 
    
         
            +
                } else if (cctx->prefixDict.dict) {
         
     | 
| 
      
 4597 
     | 
    
         
            +
                    dictSize = (U32)cctx->prefixDict.dictSize;
         
     | 
| 
      
 4598 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 4599 
     | 
    
         
            +
                    dictSize = 0;
         
     | 
| 
      
 4600 
     | 
    
         
            +
                }
         
     | 
| 
      
 4601 
     | 
    
         
            +
                ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
         
     | 
| 
      
 4602 
     | 
    
         
            +
                for (; (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0) && idx < inSeqsSize; ++idx) {
         
     | 
| 
      
 4603 
     | 
    
         
            +
                    litLength = inSeqs[idx].litLength;
         
     | 
| 
      
 4604 
     | 
    
         
            +
                    matchLength = inSeqs[idx].matchLength;
         
     | 
| 
      
 4605 
     | 
    
         
            +
                    ll0 = litLength == 0;
         
     | 
| 
      
 4606 
     | 
    
         
            +
                    offCode = ZSTD_finalizeOffCode(inSeqs[idx].offset, updatedRepcodes.rep, ll0);
         
     | 
| 
      
 4607 
     | 
    
         
            +
                    updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
         
     | 
| 
      
 4608 
     | 
    
         
            +
             
     | 
| 
      
 4609 
     | 
    
         
            +
                    DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength);
         
     | 
| 
      
 4610 
     | 
    
         
            +
                    if (cctx->appliedParams.validateSequences) {
         
     | 
| 
      
 4611 
     | 
    
         
            +
                        seqPos->posInSrc += litLength + matchLength;
         
     | 
| 
      
 4612 
     | 
    
         
            +
                        FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc,
         
     | 
| 
      
 4613 
     | 
    
         
            +
                                                            cctx->appliedParams.cParams.windowLog, dictSize,
         
     | 
| 
      
 4614 
     | 
    
         
            +
                                                            cctx->appliedParams.cParams.minMatch),
         
     | 
| 
      
 4615 
     | 
    
         
            +
                                                            "Sequence validation failed");
         
     | 
| 
      
 4616 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4617 
     | 
    
         
            +
                    RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation,
         
     | 
| 
      
 4618 
     | 
    
         
            +
                                    "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
         
     | 
| 
      
 4619 
     | 
    
         
            +
                    ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH);
         
     | 
| 
      
 4620 
     | 
    
         
            +
                    ip += matchLength + litLength;
         
     | 
| 
      
 4621 
     | 
    
         
            +
                }
         
     | 
| 
      
 4622 
     | 
    
         
            +
                ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
         
     | 
| 
      
 4623 
     | 
    
         
            +
             
     | 
| 
      
 4624 
     | 
    
         
            +
                if (inSeqs[idx].litLength) {
         
     | 
| 
      
 4625 
     | 
    
         
            +
                    DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength);
         
     | 
| 
      
 4626 
     | 
    
         
            +
                    ZSTD_storeLastLiterals(&cctx->seqStore, ip, inSeqs[idx].litLength);
         
     | 
| 
      
 4627 
     | 
    
         
            +
                    ip += inSeqs[idx].litLength;
         
     | 
| 
      
 4628 
     | 
    
         
            +
                    seqPos->posInSrc += inSeqs[idx].litLength;
         
     | 
| 
      
 4629 
     | 
    
         
            +
                }
         
     | 
| 
      
 4630 
     | 
    
         
            +
                RETURN_ERROR_IF(ip != iend, corruption_detected, "Blocksize doesn't agree with block delimiter!");
         
     | 
| 
      
 4631 
     | 
    
         
            +
                seqPos->idx = idx+1;
         
     | 
| 
      
 4632 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 4633 
     | 
    
         
            +
            }
         
     | 
| 
      
 4634 
     | 
    
         
            +
             
     | 
| 
      
 4635 
     | 
    
         
            +
            /* Returns the number of bytes to move the current read position back by. Only non-zero
         
     | 
| 
      
 4636 
     | 
    
         
            +
             * if we ended up splitting a sequence. Otherwise, it may return a ZSTD error if something
         
     | 
| 
      
 4637 
     | 
    
         
            +
             * went wrong.
         
     | 
| 
      
 4638 
     | 
    
         
            +
             *
         
     | 
| 
      
 4639 
     | 
    
         
            +
             * This function will attempt to scan through blockSize bytes represented by the sequences
         
     | 
| 
      
 4640 
     | 
    
         
            +
             * in inSeqs, storing any (partial) sequences.
         
     | 
| 
      
 4641 
     | 
    
         
            +
             *
         
     | 
| 
      
 4642 
     | 
    
         
            +
             * Occasionally, we may want to change the actual number of bytes we consumed from inSeqs to
         
     | 
| 
      
 4643 
     | 
    
         
            +
             * avoid splitting a match, or to avoid splitting a match such that it would produce a match
         
     | 
| 
      
 4644 
     | 
    
         
            +
             * smaller than MINMATCH. In this case, we return the number of bytes that we didn't read from this block.
         
     | 
| 
      
 4645 
     | 
    
         
            +
             */
         
     | 
| 
      
 4646 
     | 
    
         
            +
            static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
         
     | 
| 
      
 4647 
     | 
    
         
            +
                                                                   const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
         
     | 
| 
      
 4648 
     | 
    
         
            +
                                                                   const void* src, size_t blockSize) {
         
     | 
| 
      
 4649 
     | 
    
         
            +
                U32 idx = seqPos->idx;
         
     | 
| 
      
 4650 
     | 
    
         
            +
                U32 startPosInSequence = seqPos->posInSequence;
         
     | 
| 
      
 4651 
     | 
    
         
            +
                U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize;
         
     | 
| 
      
 4652 
     | 
    
         
            +
                size_t dictSize;
         
     | 
| 
      
 4653 
     | 
    
         
            +
                BYTE const* ip = (BYTE const*)(src);
         
     | 
| 
      
 4654 
     | 
    
         
            +
                BYTE const* iend = ip + blockSize;  /* May be adjusted if we decide to process fewer than blockSize bytes */
         
     | 
| 
      
 4655 
     | 
    
         
            +
                repcodes_t updatedRepcodes;
         
     | 
| 
      
 4656 
     | 
    
         
            +
                U32 bytesAdjustment = 0;
         
     | 
| 
      
 4657 
     | 
    
         
            +
                U32 finalMatchSplit = 0;
         
     | 
| 
      
 4658 
     | 
    
         
            +
                U32 litLength;
         
     | 
| 
      
 4659 
     | 
    
         
            +
                U32 matchLength;
         
     | 
| 
      
 4660 
     | 
    
         
            +
                U32 rawOffset;
         
     | 
| 
      
 4661 
     | 
    
         
            +
                U32 offCode;
         
     | 
| 
      
 4662 
     | 
    
         
            +
             
     | 
| 
      
 4663 
     | 
    
         
            +
                if (cctx->cdict) {
         
     | 
| 
      
 4664 
     | 
    
         
            +
                    dictSize = cctx->cdict->dictContentSize;
         
     | 
| 
      
 4665 
     | 
    
         
            +
                } else if (cctx->prefixDict.dict) {
         
     | 
| 
      
 4666 
     | 
    
         
            +
                    dictSize = cctx->prefixDict.dictSize;
         
     | 
| 
      
 4667 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 4668 
     | 
    
         
            +
                    dictSize = 0;
         
     | 
| 
      
 4669 
     | 
    
         
            +
                }
         
     | 
| 
      
 4670 
     | 
    
         
            +
                DEBUGLOG(5, "ZSTD_copySequencesToSeqStore: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize);
         
     | 
| 
      
 4671 
     | 
    
         
            +
                DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
         
     | 
| 
      
 4672 
     | 
    
         
            +
                ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
         
     | 
| 
      
 4673 
     | 
    
         
            +
                while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) {
         
     | 
| 
      
 4674 
     | 
    
         
            +
                    const ZSTD_Sequence currSeq = inSeqs[idx];
         
     | 
| 
      
 4675 
     | 
    
         
            +
                    litLength = currSeq.litLength;
         
     | 
| 
      
 4676 
     | 
    
         
            +
                    matchLength = currSeq.matchLength;
         
     | 
| 
      
 4677 
     | 
    
         
            +
                    rawOffset = currSeq.offset;
         
     | 
| 
      
 4678 
     | 
    
         
            +
             
     | 
| 
      
 4679 
     | 
    
         
            +
                    /* Modify the sequence depending on where endPosInSequence lies */
         
     | 
| 
      
 4680 
     | 
    
         
            +
                    if (endPosInSequence >= currSeq.litLength + currSeq.matchLength) {
         
     | 
| 
      
 4681 
     | 
    
         
            +
                        if (startPosInSequence >= litLength) {
         
     | 
| 
      
 4682 
     | 
    
         
            +
                            startPosInSequence -= litLength;
         
     | 
| 
      
 4683 
     | 
    
         
            +
                            litLength = 0;
         
     | 
| 
      
 4684 
     | 
    
         
            +
                            matchLength -= startPosInSequence;
         
     | 
| 
      
 4685 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 4686 
     | 
    
         
            +
                            litLength -= startPosInSequence;
         
     | 
| 
      
 4687 
     | 
    
         
            +
                        }
         
     | 
| 
      
 4688 
     | 
    
         
            +
                        /* Move to the next sequence */
         
     | 
| 
      
 4689 
     | 
    
         
            +
                        endPosInSequence -= currSeq.litLength + currSeq.matchLength;
         
     | 
| 
      
 4690 
     | 
    
         
            +
                        startPosInSequence = 0;
         
     | 
| 
      
 4691 
     | 
    
         
            +
                        idx++;
         
     | 
| 
      
 4692 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 4693 
     | 
    
         
            +
                        /* This is the final (partial) sequence we're adding from inSeqs, and endPosInSequence
         
     | 
| 
      
 4694 
     | 
    
         
            +
                           does not reach the end of the match. So, we have to split the sequence */
         
     | 
| 
      
 4695 
     | 
    
         
            +
                        DEBUGLOG(6, "Require a split: diff: %u, idx: %u PIS: %u",
         
     | 
| 
      
 4696 
     | 
    
         
            +
                                 currSeq.litLength + currSeq.matchLength - endPosInSequence, idx, endPosInSequence);
         
     | 
| 
      
 4697 
     | 
    
         
            +
                        if (endPosInSequence > litLength) {
         
     | 
| 
      
 4698 
     | 
    
         
            +
                            U32 firstHalfMatchLength;
         
     | 
| 
      
 4699 
     | 
    
         
            +
                            litLength = startPosInSequence >= litLength ? 0 : litLength - startPosInSequence;
         
     | 
| 
      
 4700 
     | 
    
         
            +
                            firstHalfMatchLength = endPosInSequence - startPosInSequence - litLength;
         
     | 
| 
      
 4701 
     | 
    
         
            +
                            if (matchLength > blockSize && firstHalfMatchLength >= cctx->appliedParams.cParams.minMatch) {
         
     | 
| 
      
 4702 
     | 
    
         
            +
                                /* Only ever split the match if it is larger than the block size */
         
     | 
| 
      
 4703 
     | 
    
         
            +
                                U32 secondHalfMatchLength = currSeq.matchLength + currSeq.litLength - endPosInSequence;
         
     | 
| 
      
 4704 
     | 
    
         
            +
                                if (secondHalfMatchLength < cctx->appliedParams.cParams.minMatch) {
         
     | 
| 
      
 4705 
     | 
    
         
            +
                                    /* Move the endPosInSequence backward so that it creates match of minMatch length */
         
     | 
| 
      
 4706 
     | 
    
         
            +
                                    endPosInSequence -= cctx->appliedParams.cParams.minMatch - secondHalfMatchLength;
         
     | 
| 
      
 4707 
     | 
    
         
            +
                                    bytesAdjustment = cctx->appliedParams.cParams.minMatch - secondHalfMatchLength;
         
     | 
| 
      
 4708 
     | 
    
         
            +
                                    firstHalfMatchLength -= bytesAdjustment;
         
     | 
| 
      
 4709 
     | 
    
         
            +
                                }
         
     | 
| 
      
 4710 
     | 
    
         
            +
                                matchLength = firstHalfMatchLength;
         
     | 
| 
      
 4711 
     | 
    
         
            +
                                /* Flag that we split the last match - after storing the sequence, exit the loop,
         
     | 
| 
      
 4712 
     | 
    
         
            +
                                   but keep the value of endPosInSequence */
         
     | 
| 
      
 4713 
     | 
    
         
            +
                                finalMatchSplit = 1;
         
     | 
| 
      
 4714 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 4715 
     | 
    
         
            +
                                /* Move the position in sequence backwards so that we don't split match, and break to store
         
     | 
| 
      
 4716 
     | 
    
         
            +
                                 * the last literals. We use the original currSeq.litLength as a marker for where endPosInSequence
         
     | 
| 
      
 4717 
     | 
    
         
            +
                                 * should go. We prefer to do this whenever it is not necessary to split the match, or if doing so
         
     | 
| 
      
 4718 
     | 
    
         
            +
                                 * would cause the first half of the match to be too small
         
     | 
| 
      
 4719 
     | 
    
         
            +
                                 */
         
     | 
| 
      
 4720 
     | 
    
         
            +
                                bytesAdjustment = endPosInSequence - currSeq.litLength;
         
     | 
| 
      
 4721 
     | 
    
         
            +
                                endPosInSequence = currSeq.litLength;
         
     | 
| 
      
 4722 
     | 
    
         
            +
                                break;
         
     | 
| 
      
 4723 
     | 
    
         
            +
                            }
         
     | 
| 
      
 4724 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 4725 
     | 
    
         
            +
                            /* This sequence ends inside the literals, break to store the last literals */
         
     | 
| 
      
 4726 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 4727 
     | 
    
         
            +
                        }
         
     | 
| 
      
 4728 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4729 
     | 
    
         
            +
                    /* Check if this offset can be represented with a repcode */
         
     | 
| 
      
 4730 
     | 
    
         
            +
                    {   U32 ll0 = (litLength == 0);
         
     | 
| 
      
 4731 
     | 
    
         
            +
                        offCode = ZSTD_finalizeOffCode(rawOffset, updatedRepcodes.rep, ll0);
         
     | 
| 
      
 4732 
     | 
    
         
            +
                        updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
         
     | 
| 
      
 4733 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4734 
     | 
    
         
            +
             
     | 
| 
      
 4735 
     | 
    
         
            +
                    if (cctx->appliedParams.validateSequences) {
         
     | 
| 
      
 4736 
     | 
    
         
            +
                        seqPos->posInSrc += litLength + matchLength;
         
     | 
| 
      
 4737 
     | 
    
         
            +
                        FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc,
         
     | 
| 
      
 4738 
     | 
    
         
            +
                                                               cctx->appliedParams.cParams.windowLog, dictSize,
         
     | 
| 
      
 4739 
     | 
    
         
            +
                                                               cctx->appliedParams.cParams.minMatch),
         
     | 
| 
      
 4740 
     | 
    
         
            +
                                                               "Sequence validation failed");
         
     | 
| 
      
 4741 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4742 
     | 
    
         
            +
                    DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength);
         
     | 
| 
      
 4743 
     | 
    
         
            +
                    RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation,
         
     | 
| 
      
 4744 
     | 
    
         
            +
                                    "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
         
     | 
| 
      
 4745 
     | 
    
         
            +
                    ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH);
         
     | 
| 
      
 4746 
     | 
    
         
            +
                    ip += matchLength + litLength;
         
     | 
| 
      
 4747 
     | 
    
         
            +
                }
         
     | 
| 
      
 4748 
     | 
    
         
            +
                DEBUGLOG(5, "Ending seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
         
     | 
| 
      
 4749 
     | 
    
         
            +
                assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength);
         
     | 
| 
      
 4750 
     | 
    
         
            +
                seqPos->idx = idx;
         
     | 
| 
      
 4751 
     | 
    
         
            +
                seqPos->posInSequence = endPosInSequence;
         
     | 
| 
      
 4752 
     | 
    
         
            +
                ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
         
     | 
| 
      
 4753 
     | 
    
         
            +
             
     | 
| 
      
 4754 
     | 
    
         
            +
                iend -= bytesAdjustment;
         
     | 
| 
      
 4755 
     | 
    
         
            +
                if (ip != iend) {
         
     | 
| 
      
 4756 
     | 
    
         
            +
                    /* Store any last literals */
         
     | 
| 
      
 4757 
     | 
    
         
            +
                    U32 lastLLSize = (U32)(iend - ip);
         
     | 
| 
      
 4758 
     | 
    
         
            +
                    assert(ip <= iend);
         
     | 
| 
      
 4759 
     | 
    
         
            +
                    DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize);
         
     | 
| 
      
 4760 
     | 
    
         
            +
                    ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize);
         
     | 
| 
      
 4761 
     | 
    
         
            +
                    seqPos->posInSrc += lastLLSize;
         
     | 
| 
      
 4762 
     | 
    
         
            +
                }
         
     | 
| 
      
 4763 
     | 
    
         
            +
             
     | 
| 
      
 4764 
     | 
    
         
            +
                return bytesAdjustment;
         
     | 
| 
      
 4765 
     | 
    
         
            +
            }
         
     | 
| 
      
 4766 
     | 
    
         
            +
             
     | 
| 
      
 4767 
     | 
    
         
            +
            typedef size_t (*ZSTD_sequenceCopier) (ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
         
     | 
| 
      
 4768 
     | 
    
         
            +
                                                   const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
         
     | 
| 
      
 4769 
     | 
    
         
            +
                                                   const void* src, size_t blockSize);
         
     | 
| 
      
 4770 
     | 
    
         
            +
            static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode) {
         
     | 
| 
      
 4771 
     | 
    
         
            +
                ZSTD_sequenceCopier sequenceCopier = NULL;
         
     | 
| 
      
 4772 
     | 
    
         
            +
                assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode));
         
     | 
| 
      
 4773 
     | 
    
         
            +
                if (mode == ZSTD_sf_explicitBlockDelimiters) {
         
     | 
| 
      
 4774 
     | 
    
         
            +
                    return ZSTD_copySequencesToSeqStoreExplicitBlockDelim;
         
     | 
| 
      
 4775 
     | 
    
         
            +
                } else if (mode == ZSTD_sf_noBlockDelimiters) {
         
     | 
| 
      
 4776 
     | 
    
         
            +
                    return ZSTD_copySequencesToSeqStoreNoBlockDelim;
         
     | 
| 
      
 4777 
     | 
    
         
            +
                }
         
     | 
| 
      
 4778 
     | 
    
         
            +
                assert(sequenceCopier != NULL);
         
     | 
| 
      
 4779 
     | 
    
         
            +
                return sequenceCopier;
         
     | 
| 
      
 4780 
     | 
    
         
            +
            }
         
     | 
| 
      
 4781 
     | 
    
         
            +
             
     | 
| 
      
 4782 
     | 
    
         
            +
            /* Compress, block-by-block, all of the sequences given.
         
     | 
| 
      
 4783 
     | 
    
         
            +
             *
         
     | 
| 
      
 4784 
     | 
    
         
            +
             * Returns the cumulative size of all compressed blocks (including their headers), otherwise a ZSTD error.
         
     | 
| 
      
 4785 
     | 
    
         
            +
             */
         
     | 
| 
      
 4786 
     | 
    
         
            +
            static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
         
     | 
| 
      
 4787 
     | 
    
         
            +
                                                          void* dst, size_t dstCapacity,
         
     | 
| 
      
 4788 
     | 
    
         
            +
                                                          const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
         
     | 
| 
      
 4789 
     | 
    
         
            +
                                                          const void* src, size_t srcSize) {
         
     | 
| 
      
 4790 
     | 
    
         
            +
                size_t cSize = 0;
         
     | 
| 
      
 4791 
     | 
    
         
            +
                U32 lastBlock;
         
     | 
| 
      
 4792 
     | 
    
         
            +
                size_t blockSize;
         
     | 
| 
      
 4793 
     | 
    
         
            +
                size_t compressedSeqsSize;
         
     | 
| 
      
 4794 
     | 
    
         
            +
                size_t remaining = srcSize;
         
     | 
| 
      
 4795 
     | 
    
         
            +
                ZSTD_sequencePosition seqPos = {0, 0, 0};
         
     | 
| 
      
 4796 
     | 
    
         
            +
             
     | 
| 
      
 4797 
     | 
    
         
            +
                BYTE const* ip = (BYTE const*)src;
         
     | 
| 
      
 4798 
     | 
    
         
            +
                BYTE* op = (BYTE*)dst;
         
     | 
| 
      
 4799 
     | 
    
         
            +
                ZSTD_sequenceCopier sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
         
     | 
| 
      
 4800 
     | 
    
         
            +
             
     | 
| 
      
 4801 
     | 
    
         
            +
                DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize);
         
     | 
| 
      
 4802 
     | 
    
         
            +
                /* Special case: empty frame */
         
     | 
| 
      
 4803 
     | 
    
         
            +
                if (remaining == 0) {
         
     | 
| 
      
 4804 
     | 
    
         
            +
                    U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1);
         
     | 
| 
      
 4805 
     | 
    
         
            +
                    RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "No room for empty frame block header");
         
     | 
| 
      
 4806 
     | 
    
         
            +
                    MEM_writeLE32(op, cBlockHeader24);
         
     | 
| 
      
 4807 
     | 
    
         
            +
                    op += ZSTD_blockHeaderSize;
         
     | 
| 
      
 4808 
     | 
    
         
            +
                    dstCapacity -= ZSTD_blockHeaderSize;
         
     | 
| 
      
 4809 
     | 
    
         
            +
                    cSize += ZSTD_blockHeaderSize;
         
     | 
| 
      
 4810 
     | 
    
         
            +
                }
         
     | 
| 
      
 4811 
     | 
    
         
            +
             
     | 
| 
      
 4812 
     | 
    
         
            +
                while (remaining) {
         
     | 
| 
      
 4813 
     | 
    
         
            +
                    size_t cBlockSize;
         
     | 
| 
      
 4814 
     | 
    
         
            +
                    size_t additionalByteAdjustment;
         
     | 
| 
      
 4815 
     | 
    
         
            +
                    lastBlock = remaining <= cctx->blockSize;
         
     | 
| 
      
 4816 
     | 
    
         
            +
                    blockSize = lastBlock ? (U32)remaining : (U32)cctx->blockSize;
         
     | 
| 
      
 4817 
     | 
    
         
            +
                    ZSTD_resetSeqStore(&cctx->seqStore);
         
     | 
| 
      
 4818 
     | 
    
         
            +
                    DEBUGLOG(4, "Working on new block. Blocksize: %zu", blockSize);
         
     | 
| 
      
 4819 
     | 
    
         
            +
             
     | 
| 
      
 4820 
     | 
    
         
            +
                    additionalByteAdjustment = sequenceCopier(cctx, &seqPos, inSeqs, inSeqsSize, ip, blockSize);
         
     | 
| 
      
 4821 
     | 
    
         
            +
                    FORWARD_IF_ERROR(additionalByteAdjustment, "Bad sequence copy");
         
     | 
| 
      
 4822 
     | 
    
         
            +
                    blockSize -= additionalByteAdjustment;
         
     | 
| 
      
 4823 
     | 
    
         
            +
             
     | 
| 
      
 4824 
     | 
    
         
            +
                    /* If blocks are too small, emit as a nocompress block */
         
     | 
| 
      
 4825 
     | 
    
         
            +
                    if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
         
     | 
| 
      
 4826 
     | 
    
         
            +
                        cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
         
     | 
| 
      
 4827 
     | 
    
         
            +
                        FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
         
     | 
| 
      
 4828 
     | 
    
         
            +
                        DEBUGLOG(4, "Block too small, writing out nocompress block: cSize: %zu", cBlockSize);
         
     | 
| 
      
 4829 
     | 
    
         
            +
                        cSize += cBlockSize;
         
     | 
| 
      
 4830 
     | 
    
         
            +
                        ip += blockSize;
         
     | 
| 
      
 4831 
     | 
    
         
            +
                        op += cBlockSize;
         
     | 
| 
      
 4832 
     | 
    
         
            +
                        remaining -= blockSize;
         
     | 
| 
      
 4833 
     | 
    
         
            +
                        dstCapacity -= cBlockSize;
         
     | 
| 
      
 4834 
     | 
    
         
            +
                        continue;
         
     | 
| 
      
 4835 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4836 
     | 
    
         
            +
             
     | 
| 
      
 4837 
     | 
    
         
            +
                    compressedSeqsSize = ZSTD_entropyCompressSequences(&cctx->seqStore,
         
     | 
| 
      
 4838 
     | 
    
         
            +
                                            &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy,
         
     | 
| 
      
 4839 
     | 
    
         
            +
                                            &cctx->appliedParams,
         
     | 
| 
      
 4840 
     | 
    
         
            +
                                            op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
         
     | 
| 
      
 4841 
     | 
    
         
            +
                                            blockSize,
         
     | 
| 
      
 4842 
     | 
    
         
            +
                                            cctx->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
         
     | 
| 
      
 4843 
     | 
    
         
            +
                                            cctx->bmi2);
         
     | 
| 
      
 4844 
     | 
    
         
            +
                    FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
         
     | 
| 
      
 4845 
     | 
    
         
            +
                    DEBUGLOG(4, "Compressed sequences size: %zu", compressedSeqsSize);
         
     | 
| 
      
 4846 
     | 
    
         
            +
             
     | 
| 
      
 4847 
     | 
    
         
            +
                    if (!cctx->isFirstBlock &&
         
     | 
| 
      
 4848 
     | 
    
         
            +
                        ZSTD_maybeRLE(&cctx->seqStore) &&
         
     | 
| 
      
 4849 
     | 
    
         
            +
                        ZSTD_isRLE((BYTE const*)src, srcSize)) {
         
     | 
| 
      
 4850 
     | 
    
         
            +
                        /* We don't want to emit our first block as a RLE even if it qualifies because
         
     | 
| 
      
 4851 
     | 
    
         
            +
                        * doing so will cause the decoder (cli only) to throw a "should consume all input error."
         
     | 
| 
      
 4852 
     | 
    
         
            +
                        * This is only an issue for zstd <= v1.4.3
         
     | 
| 
      
 4853 
     | 
    
         
            +
                        */
         
     | 
| 
      
 4854 
     | 
    
         
            +
                        compressedSeqsSize = 1;
         
     | 
| 
      
 4855 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4856 
     | 
    
         
            +
             
     | 
| 
      
 4857 
     | 
    
         
            +
                    if (compressedSeqsSize == 0) {
         
     | 
| 
      
 4858 
     | 
    
         
            +
                        /* ZSTD_noCompressBlock writes the block header as well */
         
     | 
| 
      
 4859 
     | 
    
         
            +
                        cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
         
     | 
| 
      
 4860 
     | 
    
         
            +
                        FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
         
     | 
| 
      
 4861 
     | 
    
         
            +
                        DEBUGLOG(4, "Writing out nocompress block, size: %zu", cBlockSize);
         
     | 
| 
      
 4862 
     | 
    
         
            +
                    } else if (compressedSeqsSize == 1) {
         
     | 
| 
      
 4863 
     | 
    
         
            +
                        cBlockSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, blockSize, lastBlock);
         
     | 
| 
      
 4864 
     | 
    
         
            +
                        FORWARD_IF_ERROR(cBlockSize, "RLE compress block failed");
         
     | 
| 
      
 4865 
     | 
    
         
            +
                        DEBUGLOG(4, "Writing out RLE block, size: %zu", cBlockSize);
         
     | 
| 
      
 4866 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 4867 
     | 
    
         
            +
                        U32 cBlockHeader;
         
     | 
| 
      
 4868 
     | 
    
         
            +
                        /* Error checking and repcodes update */
         
     | 
| 
      
 4869 
     | 
    
         
            +
                        ZSTD_confirmRepcodesAndEntropyTables(cctx);
         
     | 
| 
      
 4870 
     | 
    
         
            +
                        if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
         
     | 
| 
      
 4871 
     | 
    
         
            +
                            cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
         
     | 
| 
      
 4872 
     | 
    
         
            +
             
     | 
| 
      
 4873 
     | 
    
         
            +
                        /* Write block header into beginning of block*/
         
     | 
| 
      
 4874 
     | 
    
         
            +
                        cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3);
         
     | 
| 
      
 4875 
     | 
    
         
            +
                        MEM_writeLE24(op, cBlockHeader);
         
     | 
| 
      
 4876 
     | 
    
         
            +
                        cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize;
         
     | 
| 
      
 4877 
     | 
    
         
            +
                        DEBUGLOG(4, "Writing out compressed block, size: %zu", cBlockSize);
         
     | 
| 
      
 4878 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4879 
     | 
    
         
            +
             
     | 
| 
      
 4880 
     | 
    
         
            +
                    cSize += cBlockSize;
         
     | 
| 
      
 4881 
     | 
    
         
            +
                    DEBUGLOG(4, "cSize running total: %zu", cSize);
         
     | 
| 
      
 4882 
     | 
    
         
            +
             
     | 
| 
      
 4883 
     | 
    
         
            +
                    if (lastBlock) {
         
     | 
| 
      
 4884 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 4885 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 4886 
     | 
    
         
            +
                        ip += blockSize;
         
     | 
| 
      
 4887 
     | 
    
         
            +
                        op += cBlockSize;
         
     | 
| 
      
 4888 
     | 
    
         
            +
                        remaining -= blockSize;
         
     | 
| 
      
 4889 
     | 
    
         
            +
                        dstCapacity -= cBlockSize;
         
     | 
| 
      
 4890 
     | 
    
         
            +
                        cctx->isFirstBlock = 0;
         
     | 
| 
      
 4891 
     | 
    
         
            +
                    }
         
     | 
| 
      
 4892 
     | 
    
         
            +
                }
         
     | 
| 
      
 4893 
     | 
    
         
            +
             
     | 
| 
      
 4894 
     | 
    
         
            +
                return cSize;
         
     | 
| 
      
 4895 
     | 
    
         
            +
            }
         
     | 
| 
      
 4896 
     | 
    
         
            +
             
     | 
| 
      
 4897 
     | 
    
         
            +
            size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstCapacity,
         
     | 
| 
      
 4898 
     | 
    
         
            +
                                          const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
         
     | 
| 
      
 4899 
     | 
    
         
            +
                                          const void* src, size_t srcSize) {
         
     | 
| 
      
 4900 
     | 
    
         
            +
                BYTE* op = (BYTE*)dst;
         
     | 
| 
      
 4901 
     | 
    
         
            +
                size_t cSize = 0;
         
     | 
| 
      
 4902 
     | 
    
         
            +
                size_t compressedBlocksSize = 0;
         
     | 
| 
      
 4903 
     | 
    
         
            +
                size_t frameHeaderSize = 0;
         
     | 
| 
      
 4904 
     | 
    
         
            +
             
     | 
| 
      
 4905 
     | 
    
         
            +
                /* Transparent initialization stage, same as compressStream2() */
         
     | 
| 
      
 4906 
     | 
    
         
            +
                DEBUGLOG(3, "ZSTD_compressSequences()");
         
     | 
| 
      
 4907 
     | 
    
         
            +
                assert(cctx != NULL);
         
     | 
| 
      
 4908 
     | 
    
         
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed");
         
     | 
| 
      
 4909 
     | 
    
         
            +
                /* Begin writing output, starting with frame header */
         
     | 
| 
      
 4910 
     | 
    
         
            +
                frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, &cctx->appliedParams, srcSize, cctx->dictID);
         
     | 
| 
      
 4911 
     | 
    
         
            +
                op += frameHeaderSize;
         
     | 
| 
      
 4912 
     | 
    
         
            +
                dstCapacity -= frameHeaderSize;
         
     | 
| 
      
 4913 
     | 
    
         
            +
                cSize += frameHeaderSize;
         
     | 
| 
      
 4914 
     | 
    
         
            +
                if (cctx->appliedParams.fParams.checksumFlag && srcSize) {
         
     | 
| 
      
 4915 
     | 
    
         
            +
                    XXH64_update(&cctx->xxhState, src, srcSize);
         
     | 
| 
      
 4916 
     | 
    
         
            +
                }
         
     | 
| 
      
 4917 
     | 
    
         
            +
                /* cSize includes block header size and compressed sequences size */
         
     | 
| 
      
 4918 
     | 
    
         
            +
                compressedBlocksSize = ZSTD_compressSequences_internal(cctx,
         
     | 
| 
      
 4919 
     | 
    
         
            +
                                                                       op, dstCapacity,
         
     | 
| 
      
 4920 
     | 
    
         
            +
                                                                       inSeqs, inSeqsSize,
         
     | 
| 
      
 4921 
     | 
    
         
            +
                                                                       src, srcSize);
         
     | 
| 
      
 4922 
     | 
    
         
            +
                FORWARD_IF_ERROR(compressedBlocksSize, "Compressing blocks failed!");
         
     | 
| 
      
 4923 
     | 
    
         
            +
                cSize += compressedBlocksSize;
         
     | 
| 
      
 4924 
     | 
    
         
            +
                dstCapacity -= compressedBlocksSize;
         
     | 
| 
      
 4925 
     | 
    
         
            +
             
     | 
| 
      
 4926 
     | 
    
         
            +
                if (cctx->appliedParams.fParams.checksumFlag) {
         
     | 
| 
      
 4927 
     | 
    
         
            +
                    U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
         
     | 
| 
      
 4928 
     | 
    
         
            +
                    RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
         
     | 
| 
      
 4929 
     | 
    
         
            +
                    DEBUGLOG(4, "Write checksum : %08X", (unsigned)checksum);
         
     | 
| 
      
 4930 
     | 
    
         
            +
                    MEM_writeLE32((char*)dst + cSize, checksum);
         
     | 
| 
      
 4931 
     | 
    
         
            +
                    cSize += 4;
         
     | 
| 
      
 4932 
     | 
    
         
            +
                }
         
     | 
| 
      
 4933 
     | 
    
         
            +
             
     | 
| 
      
 4934 
     | 
    
         
            +
                DEBUGLOG(3, "Final compressed size: %zu", cSize);
         
     | 
| 
      
 4935 
     | 
    
         
            +
                return cSize;
         
     | 
| 
      
 4936 
     | 
    
         
            +
            }
         
     | 
| 
      
 4937 
     | 
    
         
            +
             
     | 
| 
       4086 
4938 
     | 
    
         
             
            /*======   Finalize   ======*/
         
     | 
| 
       4087 
4939 
     | 
    
         | 
| 
       4088 
4940 
     | 
    
         
             
            /*! ZSTD_flushStream() :
         
     | 
| 
         @@ -4223,25 +5075,103 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV 
     | 
|
| 
       4223 
5075 
     | 
    
         
             
            },
         
     | 
| 
       4224 
5076 
     | 
    
         
             
            };
         
     | 
| 
       4225 
5077 
     | 
    
         | 
| 
      
 5078 
     | 
    
         
            +
            static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize)
         
     | 
| 
      
 5079 
     | 
    
         
            +
            {
         
     | 
| 
      
 5080 
     | 
    
         
            +
                ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict);
         
     | 
| 
      
 5081 
     | 
    
         
            +
                switch (cParams.strategy) {
         
     | 
| 
      
 5082 
     | 
    
         
            +
                    case ZSTD_fast:
         
     | 
| 
      
 5083 
     | 
    
         
            +
                    case ZSTD_dfast:
         
     | 
| 
      
 5084 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 5085 
     | 
    
         
            +
                    case ZSTD_greedy:
         
     | 
| 
      
 5086 
     | 
    
         
            +
                    case ZSTD_lazy:
         
     | 
| 
      
 5087 
     | 
    
         
            +
                    case ZSTD_lazy2:
         
     | 
| 
      
 5088 
     | 
    
         
            +
                        cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG;
         
     | 
| 
      
 5089 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 5090 
     | 
    
         
            +
                    case ZSTD_btlazy2:
         
     | 
| 
      
 5091 
     | 
    
         
            +
                    case ZSTD_btopt:
         
     | 
| 
      
 5092 
     | 
    
         
            +
                    case ZSTD_btultra:
         
     | 
| 
      
 5093 
     | 
    
         
            +
                    case ZSTD_btultra2:
         
     | 
| 
      
 5094 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 5095 
     | 
    
         
            +
                }
         
     | 
| 
      
 5096 
     | 
    
         
            +
                return cParams;
         
     | 
| 
      
 5097 
     | 
    
         
            +
            }
         
     | 
| 
      
 5098 
     | 
    
         
            +
             
     | 
| 
      
 5099 
     | 
    
         
            +
            static int ZSTD_dedicatedDictSearch_isSupported(
         
     | 
| 
      
 5100 
     | 
    
         
            +
                    ZSTD_compressionParameters const* cParams)
         
     | 
| 
      
 5101 
     | 
    
         
            +
            {
         
     | 
| 
      
 5102 
     | 
    
         
            +
                return (cParams->strategy >= ZSTD_greedy) && (cParams->strategy <= ZSTD_lazy2);
         
     | 
| 
      
 5103 
     | 
    
         
            +
            }
         
     | 
| 
      
 5104 
     | 
    
         
            +
             
     | 
| 
      
 5105 
     | 
    
         
            +
            /**
         
     | 
| 
      
 5106 
     | 
    
         
            +
             * Reverses the adjustment applied to cparams when enabling dedicated dict
         
     | 
| 
      
 5107 
     | 
    
         
            +
             * search. This is used to recover the params set to be used in the working
         
     | 
| 
      
 5108 
     | 
    
         
            +
             * context. (Otherwise, those tables would also grow.)
         
     | 
| 
      
 5109 
     | 
    
         
            +
             */
         
     | 
| 
      
 5110 
     | 
    
         
            +
            static void ZSTD_dedicatedDictSearch_revertCParams(
         
     | 
| 
      
 5111 
     | 
    
         
            +
                    ZSTD_compressionParameters* cParams) {
         
     | 
| 
      
 5112 
     | 
    
         
            +
                switch (cParams->strategy) {
         
     | 
| 
      
 5113 
     | 
    
         
            +
                    case ZSTD_fast:
         
     | 
| 
      
 5114 
     | 
    
         
            +
                    case ZSTD_dfast:
         
     | 
| 
      
 5115 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 5116 
     | 
    
         
            +
                    case ZSTD_greedy:
         
     | 
| 
      
 5117 
     | 
    
         
            +
                    case ZSTD_lazy:
         
     | 
| 
      
 5118 
     | 
    
         
            +
                    case ZSTD_lazy2:
         
     | 
| 
      
 5119 
     | 
    
         
            +
                        cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG;
         
     | 
| 
      
 5120 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 5121 
     | 
    
         
            +
                    case ZSTD_btlazy2:
         
     | 
| 
      
 5122 
     | 
    
         
            +
                    case ZSTD_btopt:
         
     | 
| 
      
 5123 
     | 
    
         
            +
                    case ZSTD_btultra:
         
     | 
| 
      
 5124 
     | 
    
         
            +
                    case ZSTD_btultra2:
         
     | 
| 
      
 5125 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 5126 
     | 
    
         
            +
                }
         
     | 
| 
      
 5127 
     | 
    
         
            +
            }
         
     | 
| 
      
 5128 
     | 
    
         
            +
             
     | 
| 
      
 5129 
     | 
    
         
            +
            static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
         
     | 
| 
      
 5130 
     | 
    
         
            +
            {
         
     | 
| 
      
 5131 
     | 
    
         
            +
                switch (mode) {
         
     | 
| 
      
 5132 
     | 
    
         
            +
                case ZSTD_cpm_unknown:
         
     | 
| 
      
 5133 
     | 
    
         
            +
                case ZSTD_cpm_noAttachDict:
         
     | 
| 
      
 5134 
     | 
    
         
            +
                case ZSTD_cpm_createCDict:
         
     | 
| 
      
 5135 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 5136 
     | 
    
         
            +
                case ZSTD_cpm_attachDict:
         
     | 
| 
      
 5137 
     | 
    
         
            +
                    dictSize = 0;
         
     | 
| 
      
 5138 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 5139 
     | 
    
         
            +
                default:
         
     | 
| 
      
 5140 
     | 
    
         
            +
                    assert(0);
         
     | 
| 
      
 5141 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 5142 
     | 
    
         
            +
                }
         
     | 
| 
      
 5143 
     | 
    
         
            +
                {   int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN;
         
     | 
| 
      
 5144 
     | 
    
         
            +
                    size_t const addedSize = unknown && dictSize > 0 ? 500 : 0;
         
     | 
| 
      
 5145 
     | 
    
         
            +
                    return unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize;
         
     | 
| 
      
 5146 
     | 
    
         
            +
                }
         
     | 
| 
      
 5147 
     | 
    
         
            +
            }
         
     | 
| 
      
 5148 
     | 
    
         
            +
             
     | 
| 
       4226 
5149 
     | 
    
         
             
            /*! ZSTD_getCParams_internal() :
         
     | 
| 
       4227 
5150 
     | 
    
         
             
             * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
         
     | 
| 
       4228 
5151 
     | 
    
         
             
             *  Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown.
         
     | 
| 
       4229 
     | 
    
         
            -
             *        Use dictSize == 0 for unknown or unused. 
     | 
| 
       4230 
     | 
    
         
            -
             
     | 
| 
      
 5152 
     | 
    
         
            +
             *        Use dictSize == 0 for unknown or unused.
         
     | 
| 
      
 5153 
     | 
    
         
            +
             *  Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_cParamMode_e`. */
         
     | 
| 
      
 5154 
     | 
    
         
            +
            static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
         
     | 
| 
       4231 
5155 
     | 
    
         
             
            {
         
     | 
| 
       4232 
     | 
    
         
            -
                 
     | 
| 
       4233 
     | 
    
         
            -
                size_t const addedSize = unknown && dictSize > 0 ? 500 : 0;
         
     | 
| 
       4234 
     | 
    
         
            -
                U64 const rSize = unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize;
         
     | 
| 
      
 5156 
     | 
    
         
            +
                U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode);
         
     | 
| 
       4235 
5157 
     | 
    
         
             
                U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
         
     | 
| 
       4236 
     | 
    
         
            -
                int row 
     | 
| 
      
 5158 
     | 
    
         
            +
                int row;
         
     | 
| 
       4237 
5159 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel);
         
     | 
| 
      
 5160 
     | 
    
         
            +
             
     | 
| 
      
 5161 
     | 
    
         
            +
                /* row */
         
     | 
| 
       4238 
5162 
     | 
    
         
             
                if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT;   /* 0 == default */
         
     | 
| 
       4239 
     | 
    
         
            -
                if (compressionLevel < 0) row = 0;   /* entry 0 is baseline for fast mode */
         
     | 
| 
       4240 
     | 
    
         
            -
                if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
         
     | 
| 
      
 5163 
     | 
    
         
            +
                else if (compressionLevel < 0) row = 0;   /* entry 0 is baseline for fast mode */
         
     | 
| 
      
 5164 
     | 
    
         
            +
                else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
         
     | 
| 
      
 5165 
     | 
    
         
            +
                else row = compressionLevel;
         
     | 
| 
      
 5166 
     | 
    
         
            +
             
     | 
| 
       4241 
5167 
     | 
    
         
             
                {   ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
         
     | 
| 
       4242 
     | 
    
         
            -
                     
     | 
| 
      
 5168 
     | 
    
         
            +
                    /* acceleration factor */
         
     | 
| 
      
 5169 
     | 
    
         
            +
                    if (compressionLevel < 0) {
         
     | 
| 
      
 5170 
     | 
    
         
            +
                        int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel);
         
     | 
| 
      
 5171 
     | 
    
         
            +
                        cp.targetLength = (unsigned)(-clampedCompressionLevel);
         
     | 
| 
      
 5172 
     | 
    
         
            +
                    }
         
     | 
| 
       4243 
5173 
     | 
    
         
             
                    /* refine parameters based on srcSize & dictSize */
         
     | 
| 
       4244 
     | 
    
         
            -
                    return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);
         
     | 
| 
      
 5174 
     | 
    
         
            +
                    return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode);
         
     | 
| 
       4245 
5175 
     | 
    
         
             
                }
         
     | 
| 
       4246 
5176 
     | 
    
         
             
            }
         
     | 
| 
       4247 
5177 
     | 
    
         | 
| 
         @@ -4251,18 +5181,18 @@ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, 
     | 
|
| 
       4251 
5181 
     | 
    
         
             
            ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
         
     | 
| 
       4252 
5182 
     | 
    
         
             
            {
         
     | 
| 
       4253 
5183 
     | 
    
         
             
                if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
         
     | 
| 
       4254 
     | 
    
         
            -
                return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
         
     | 
| 
      
 5184 
     | 
    
         
            +
                return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
         
     | 
| 
       4255 
5185 
     | 
    
         
             
            }
         
     | 
| 
       4256 
5186 
     | 
    
         | 
| 
       4257 
5187 
     | 
    
         
             
            /*! ZSTD_getParams() :
         
     | 
| 
       4258 
5188 
     | 
    
         
             
             *  same idea as ZSTD_getCParams()
         
     | 
| 
       4259 
5189 
     | 
    
         
             
             * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
         
     | 
| 
       4260 
5190 
     | 
    
         
             
             *  Fields of `ZSTD_frameParameters` are set to default values */
         
     | 
| 
       4261 
     | 
    
         
            -
            static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
         
     | 
| 
      
 5191 
     | 
    
         
            +
            static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) {
         
     | 
| 
       4262 
5192 
     | 
    
         
             
                ZSTD_parameters params;
         
     | 
| 
       4263 
     | 
    
         
            -
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
         
     | 
| 
      
 5193 
     | 
    
         
            +
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode);
         
     | 
| 
       4264 
5194 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
         
     | 
| 
       4265 
     | 
    
         
            -
                 
     | 
| 
      
 5195 
     | 
    
         
            +
                ZSTD_memset(¶ms, 0, sizeof(params));
         
     | 
| 
       4266 
5196 
     | 
    
         
             
                params.cParams = cParams;
         
     | 
| 
       4267 
5197 
     | 
    
         
             
                params.fParams.contentSizeFlag = 1;
         
     | 
| 
       4268 
5198 
     | 
    
         
             
                return params;
         
     | 
| 
         @@ -4274,5 +5204,5 @@ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned lo 
     | 
|
| 
       4274 
5204 
     | 
    
         
             
             *  Fields of `ZSTD_frameParameters` are set to default values */
         
     | 
| 
       4275 
5205 
     | 
    
         
             
            ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
         
     | 
| 
       4276 
5206 
     | 
    
         
             
                if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
         
     | 
| 
       4277 
     | 
    
         
            -
                return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize);
         
     | 
| 
      
 5207 
     | 
    
         
            +
                return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
         
     | 
| 
       4278 
5208 
     | 
    
         
             
            }
         
     |