contrib/python-zstandard/zstd/compress/zstd_compress.c
changeset 30434 2e484bdea8c4
child 30822 b54a2984cdd4
equal deleted inserted replaced
30433:96f2f50d923f 30434:2e484bdea8c4
       
     1 /**
       
     2  * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
       
     3  * All rights reserved.
       
     4  *
       
     5  * This source code is licensed under the BSD-style license found in the
       
     6  * LICENSE file in the root directory of this source tree. An additional grant
       
     7  * of patent rights can be found in the PATENTS file in the same directory.
       
     8  */
       
     9 
       
    10 
       
    11 /*-*************************************
       
    12 *  Dependencies
       
    13 ***************************************/
       
    14 #include <string.h>         /* memset */
       
    15 #include "mem.h"
       
    16 #define XXH_STATIC_LINKING_ONLY   /* XXH64_state_t */
       
    17 #include "xxhash.h"               /* XXH_reset, update, digest */
       
    18 #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
       
    19 #include "fse.h"
       
    20 #define HUF_STATIC_LINKING_ONLY
       
    21 #include "huf.h"
       
    22 #include "zstd_internal.h"  /* includes zstd.h */
       
    23 
       
    24 
       
    25 /*-*************************************
       
    26 *  Constants
       
    27 ***************************************/
       
    28 static const U32 g_searchStrength = 8;   /* control skip over incompressible data */
       
    29 #define HASH_READ_SIZE 8
       
    30 typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
       
    31 
       
    32 
       
    33 /*-*************************************
       
    34 *  Helper functions
       
    35 ***************************************/
       
    36 size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
       
    37 
       
    38 
       
    39 /*-*************************************
       
    40 *  Sequence storage
       
    41 ***************************************/
       
    42 static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
       
    43 {
       
    44     ssPtr->lit = ssPtr->litStart;
       
    45     ssPtr->sequences = ssPtr->sequencesStart;
       
    46     ssPtr->longLengthID = 0;
       
    47 }
       
    48 
       
    49 
       
    50 /*-*************************************
       
    51 *  Context memory management
       
    52 ***************************************/
       
    53 struct ZSTD_CCtx_s
       
    54 {
       
    55     const BYTE* nextSrc;    /* next block here to continue on current prefix */
       
    56     const BYTE* base;       /* All regular indexes relative to this position */
       
    57     const BYTE* dictBase;   /* extDict indexes relative to this position */
       
    58     U32   dictLimit;        /* below that point, need extDict */
       
    59     U32   lowLimit;         /* below that point, no more data */
       
    60     U32   nextToUpdate;     /* index from which to continue dictionary update */
       
    61     U32   nextToUpdate3;    /* index from which to continue dictionary update */
       
    62     U32   hashLog3;         /* dispatch table : larger == faster, more memory */
       
    63     U32   loadedDictEnd;
       
    64     ZSTD_compressionStage_e stage;
       
    65     U32   rep[ZSTD_REP_NUM];
       
    66     U32   savedRep[ZSTD_REP_NUM];
       
    67     U32   dictID;
       
    68     ZSTD_parameters params;
       
    69     void* workSpace;
       
    70     size_t workSpaceSize;
       
    71     size_t blockSize;
       
    72     U64 frameContentSize;
       
    73     XXH64_state_t xxhState;
       
    74     ZSTD_customMem customMem;
       
    75 
       
    76     seqStore_t seqStore;    /* sequences storage ptrs */
       
    77     U32* hashTable;
       
    78     U32* hashTable3;
       
    79     U32* chainTable;
       
    80     HUF_CElt* hufTable;
       
    81     U32 flagStaticTables;
       
    82     FSE_CTable offcodeCTable  [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
       
    83     FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
       
    84     FSE_CTable litlengthCTable  [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
       
    85 };
       
    86 
       
    87 ZSTD_CCtx* ZSTD_createCCtx(void)
       
    88 {
       
    89     return ZSTD_createCCtx_advanced(defaultCustomMem);
       
    90 }
       
    91 
       
    92 ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
       
    93 {
       
    94     ZSTD_CCtx* cctx;
       
    95 
       
    96     if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
       
    97     if (!customMem.customAlloc || !customMem.customFree) return NULL;
       
    98 
       
    99     cctx = (ZSTD_CCtx*) ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
       
   100     if (!cctx) return NULL;
       
   101     memset(cctx, 0, sizeof(ZSTD_CCtx));
       
   102     memcpy(&(cctx->customMem), &customMem, sizeof(customMem));
       
   103     return cctx;
       
   104 }
       
   105 
       
   106 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
       
   107 {
       
   108     if (cctx==NULL) return 0;   /* support free on NULL */
       
   109     ZSTD_free(cctx->workSpace, cctx->customMem);
       
   110     ZSTD_free(cctx, cctx->customMem);
       
   111     return 0;   /* reserved as a potential error code in the future */
       
   112 }
       
   113 
       
   114 size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
       
   115 {
       
   116     if (cctx==NULL) return 0;   /* support sizeof on NULL */
       
   117     return sizeof(*cctx) + cctx->workSpaceSize;
       
   118 }
       
   119 
       
   120 const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx)   /* hidden interface */
       
   121 {
       
   122     return &(ctx->seqStore);
       
   123 }
       
   124 
       
   125 static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx)
       
   126 {
       
   127     return cctx->params;
       
   128 }
       
   129 
       
   130 
       
   131 /** ZSTD_checkParams() :
       
   132     ensure param values remain within authorized range.
       
   133     @return : 0, or an error code if one value is beyond authorized range */
       
   134 size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
       
   135 {
       
   136 #   define CLAMPCHECK(val,min,max) { if ((val<min) | (val>max)) return ERROR(compressionParameter_unsupported); }
       
   137     CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
       
   138     CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
       
   139     CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
       
   140     CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
       
   141     { U32 const searchLengthMin = ((cParams.strategy == ZSTD_fast) | (cParams.strategy == ZSTD_greedy)) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN;
       
   142       U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1;
       
   143       CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); }
       
   144     CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
       
   145     if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) return ERROR(compressionParameter_unsupported);
       
   146     return 0;
       
   147 }
       
   148 
       
   149 
       
   150 /** ZSTD_adjustCParams() :
       
   151     optimize `cPar` for a given input (`srcSize` and `dictSize`).
       
   152     mostly downsizing to reduce memory consumption and initialization.
       
   153     Both `srcSize` and `dictSize` are optional (use 0 if unknown),
       
   154     but if both are 0, no optimization can be done.
       
   155     Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */
       
   156 ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
       
   157 {
       
   158     if (srcSize+dictSize == 0) return cPar;   /* no size information available : no adjustment */
       
   159 
       
   160     /* resize params, to use less memory when necessary */
       
   161     {   U32 const minSrcSize = (srcSize==0) ? 500 : 0;
       
   162         U64 const rSize = srcSize + dictSize + minSrcSize;
       
   163         if (rSize < ((U64)1<<ZSTD_WINDOWLOG_MAX)) {
       
   164             U32 const srcLog = MAX(ZSTD_HASHLOG_MIN, ZSTD_highbit32((U32)(rSize)-1) + 1);
       
   165             if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
       
   166     }   }
       
   167     if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
       
   168     {   U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) | (cPar.strategy == ZSTD_btopt) | (cPar.strategy == ZSTD_btopt2);
       
   169         U32 const maxChainLog = cPar.windowLog+btPlus;
       
   170         if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; }   /* <= ZSTD_CHAINLOG_MAX */
       
   171 
       
   172     if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* required for frame header */
       
   173 
       
   174     return cPar;
       
   175 }
       
   176 
       
   177 
       
   178 size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
       
   179 {
       
   180     size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
       
   181     U32    const divider = (cParams.searchLength==3) ? 3 : 4;
       
   182     size_t const maxNbSeq = blockSize / divider;
       
   183     size_t const tokenSpace = blockSize + 11*maxNbSeq;
       
   184 
       
   185     size_t const chainSize = (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
       
   186     size_t const hSize = ((size_t)1) << cParams.hashLog;
       
   187     U32    const hashLog3 = (cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
       
   188     size_t const h3Size = ((size_t)1) << hashLog3;
       
   189     size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
       
   190 
       
   191     size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
       
   192                           + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
       
   193     size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
       
   194                              + (((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btopt2)) ? optSpace : 0);
       
   195 
       
   196     return sizeof(ZSTD_CCtx) + neededSpace;
       
   197 }
       
   198 
       
   199 
       
   200 static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2)
       
   201 {
       
   202     return (param1.cParams.hashLog  == param2.cParams.hashLog)
       
   203          & (param1.cParams.chainLog == param2.cParams.chainLog)
       
   204          & (param1.cParams.strategy == param2.cParams.strategy)
       
   205          & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3));
       
   206 }
       
   207 
       
   208 /*! ZSTD_continueCCtx() :
       
   209     reuse CCtx without reset (note : requires no dictionary) */
       
   210 static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize)
       
   211 {
       
   212     U32 const end = (U32)(cctx->nextSrc - cctx->base);
       
   213     cctx->params = params;
       
   214     cctx->frameContentSize = frameContentSize;
       
   215     cctx->lowLimit = end;
       
   216     cctx->dictLimit = end;
       
   217     cctx->nextToUpdate = end+1;
       
   218     cctx->stage = ZSTDcs_init;
       
   219     cctx->dictID = 0;
       
   220     cctx->loadedDictEnd = 0;
       
   221     { int i; for (i=0; i<ZSTD_REP_NUM; i++) cctx->rep[i] = repStartValue[i]; }
       
   222     cctx->seqStore.litLengthSum = 0;  /* force reset of btopt stats */
       
   223     XXH64_reset(&cctx->xxhState, 0);
       
   224     return 0;
       
   225 }
       
   226 
       
   227 typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e;
       
   228 
       
   229 /*! ZSTD_resetCCtx_advanced() :
       
   230     note : 'params' must be validated */
       
   231 static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
       
   232                                        ZSTD_parameters params, U64 frameContentSize,
       
   233                                        ZSTD_compResetPolicy_e const crp)
       
   234 {
       
   235     if (crp == ZSTDcrp_continue)
       
   236         if (ZSTD_equivalentParams(params, zc->params))
       
   237             return ZSTD_continueCCtx(zc, params, frameContentSize);
       
   238 
       
   239     {   size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
       
   240         U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
       
   241         size_t const maxNbSeq = blockSize / divider;
       
   242         size_t const tokenSpace = blockSize + 11*maxNbSeq;
       
   243         size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
       
   244         size_t const hSize = ((size_t)1) << params.cParams.hashLog;
       
   245         U32    const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
       
   246         size_t const h3Size = ((size_t)1) << hashLog3;
       
   247         size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
       
   248         void* ptr;
       
   249 
       
   250         /* Check if workSpace is large enough, alloc a new one if needed */
       
   251         {   size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
       
   252                                   + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
       
   253             size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
       
   254                                   + (((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) ? optSpace : 0);
       
   255             if (zc->workSpaceSize < neededSpace) {
       
   256                 ZSTD_free(zc->workSpace, zc->customMem);
       
   257                 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
       
   258                 if (zc->workSpace == NULL) return ERROR(memory_allocation);
       
   259                 zc->workSpaceSize = neededSpace;
       
   260         }   }
       
   261 
       
   262         if (crp!=ZSTDcrp_noMemset) memset(zc->workSpace, 0, tableSpace);   /* reset tables only */
       
   263         XXH64_reset(&zc->xxhState, 0);
       
   264         zc->hashLog3 = hashLog3;
       
   265         zc->hashTable = (U32*)(zc->workSpace);
       
   266         zc->chainTable = zc->hashTable + hSize;
       
   267         zc->hashTable3 = zc->chainTable + chainSize;
       
   268         ptr = zc->hashTable3 + h3Size;
       
   269         zc->hufTable = (HUF_CElt*)ptr;
       
   270         zc->flagStaticTables = 0;
       
   271         ptr = ((U32*)ptr) + 256;  /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
       
   272 
       
   273         zc->nextToUpdate = 1;
       
   274         zc->nextSrc = NULL;
       
   275         zc->base = NULL;
       
   276         zc->dictBase = NULL;
       
   277         zc->dictLimit = 0;
       
   278         zc->lowLimit = 0;
       
   279         zc->params = params;
       
   280         zc->blockSize = blockSize;
       
   281         zc->frameContentSize = frameContentSize;
       
   282         { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
       
   283 
       
   284         if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) {
       
   285             zc->seqStore.litFreq = (U32*)ptr;
       
   286             zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
       
   287             zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
       
   288             zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
       
   289             ptr = zc->seqStore.offCodeFreq + (MaxOff+1);
       
   290             zc->seqStore.matchTable = (ZSTD_match_t*)ptr;
       
   291             ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
       
   292             zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
       
   293             ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
       
   294             zc->seqStore.litLengthSum = 0;
       
   295         }
       
   296         zc->seqStore.sequencesStart = (seqDef*)ptr;
       
   297         ptr = zc->seqStore.sequencesStart + maxNbSeq;
       
   298         zc->seqStore.llCode = (BYTE*) ptr;
       
   299         zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
       
   300         zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
       
   301         zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
       
   302 
       
   303         zc->stage = ZSTDcs_init;
       
   304         zc->dictID = 0;
       
   305         zc->loadedDictEnd = 0;
       
   306 
       
   307         return 0;
       
   308     }
       
   309 }
       
   310 
       
   311 
       
   312 /*! ZSTD_copyCCtx() :
       
   313 *   Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
       
   314 *   Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
       
   315 *   @return : 0, or an error code */
       
   316 size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
       
   317 {
       
   318     if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
       
   319 
       
   320     memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
       
   321     ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, pledgedSrcSize, ZSTDcrp_noMemset);
       
   322 
       
   323     /* copy tables */
       
   324     {   size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
       
   325         size_t const hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
       
   326         size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
       
   327         size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
       
   328         memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace);
       
   329     }
       
   330 
       
   331     /* copy dictionary offsets */
       
   332     dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
       
   333     dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
       
   334     dstCCtx->nextSrc      = srcCCtx->nextSrc;
       
   335     dstCCtx->base         = srcCCtx->base;
       
   336     dstCCtx->dictBase     = srcCCtx->dictBase;
       
   337     dstCCtx->dictLimit    = srcCCtx->dictLimit;
       
   338     dstCCtx->lowLimit     = srcCCtx->lowLimit;
       
   339     dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
       
   340     dstCCtx->dictID       = srcCCtx->dictID;
       
   341 
       
   342     /* copy entropy tables */
       
   343     dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
       
   344     if (srcCCtx->flagStaticTables) {
       
   345         memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
       
   346         memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable));
       
   347         memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable));
       
   348         memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable));
       
   349     }
       
   350 
       
   351     return 0;
       
   352 }
       
   353 
       
   354 
       
   355 /*! ZSTD_reduceTable() :
       
   356 *   reduce table indexes by `reducerValue` */
       
   357 static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reducerValue)
       
   358 {
       
   359     U32 u;
       
   360     for (u=0 ; u < size ; u++) {
       
   361         if (table[u] < reducerValue) table[u] = 0;
       
   362         else table[u] -= reducerValue;
       
   363     }
       
   364 }
       
   365 
       
   366 /*! ZSTD_reduceIndex() :
       
   367 *   rescale all indexes to avoid future overflow (indexes are U32) */
       
   368 static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
       
   369 {
       
   370     { U32 const hSize = 1 << zc->params.cParams.hashLog;
       
   371       ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); }
       
   372 
       
   373     { U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
       
   374       ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
       
   375 
       
   376     { U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
       
   377       ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
       
   378 }
       
   379 
       
   380 
       
   381 /*-*******************************************************
       
   382 *  Block entropic compression
       
   383 *********************************************************/
       
   384 
       
   385 /* See doc/zstd_compression_format.md for detailed format description */
       
   386 
       
   387 size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
   388 {
       
   389     if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
       
   390     memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
       
   391     MEM_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
       
   392     return ZSTD_blockHeaderSize+srcSize;
       
   393 }
       
   394 
       
   395 
       
   396 static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
   397 {
       
   398     BYTE* const ostart = (BYTE* const)dst;
       
   399     U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
       
   400 
       
   401     if (srcSize + flSize > dstCapacity) return ERROR(dstSize_tooSmall);
       
   402 
       
   403     switch(flSize)
       
   404     {
       
   405         case 1: /* 2 - 1 - 5 */
       
   406             ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
       
   407             break;
       
   408         case 2: /* 2 - 2 - 12 */
       
   409             MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
       
   410             break;
       
   411         default:   /*note : should not be necessary : flSize is within {1,2,3} */
       
   412         case 3: /* 2 - 2 - 20 */
       
   413             MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
       
   414             break;
       
   415     }
       
   416 
       
   417     memcpy(ostart + flSize, src, srcSize);
       
   418     return srcSize + flSize;
       
   419 }
       
   420 
       
   421 static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
   422 {
       
   423     BYTE* const ostart = (BYTE* const)dst;
       
   424     U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
       
   425 
       
   426     (void)dstCapacity;  /* dstCapacity already guaranteed to be >=4, hence large enough */
       
   427 
       
   428     switch(flSize)
       
   429     {
       
   430         case 1: /* 2 - 1 - 5 */
       
   431             ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
       
   432             break;
       
   433         case 2: /* 2 - 2 - 12 */
       
   434             MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
       
   435             break;
       
   436         default:   /*note : should not be necessary : flSize is necessarily within {1,2,3} */
       
   437         case 3: /* 2 - 2 - 20 */
       
   438             MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
       
   439             break;
       
   440     }
       
   441 
       
   442     ostart[flSize] = *(const BYTE*)src;
       
   443     return flSize+1;
       
   444 }
       
   445 
       
   446 
       
   447 static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; }
       
   448 
       
   449 static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
       
   450                                      void* dst, size_t dstCapacity,
       
   451                                const void* src, size_t srcSize)
       
   452 {
       
   453     size_t const minGain = ZSTD_minGain(srcSize);
       
   454     size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
       
   455     BYTE*  const ostart = (BYTE*)dst;
       
   456     U32 singleStream = srcSize < 256;
       
   457     symbolEncodingType_e hType = set_compressed;
       
   458     size_t cLitSize;
       
   459 
       
   460 
       
   461     /* small ? don't even attempt compression (speed opt) */
       
   462 #   define LITERAL_NOENTROPY 63
       
   463     {   size_t const minLitSize = zc->flagStaticTables ? 6 : LITERAL_NOENTROPY;
       
   464         if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
       
   465     }
       
   466 
       
   467     if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
       
   468     if (zc->flagStaticTables && (lhSize==3)) {
       
   469         hType = set_repeat;
       
   470         singleStream = 1;
       
   471         cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable);
       
   472     } else {
       
   473         cLitSize = singleStream ? HUF_compress1X(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11)
       
   474                                 : HUF_compress2 (ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11);
       
   475     }
       
   476 
       
   477     if ((cLitSize==0) | (cLitSize >= srcSize - minGain))
       
   478         return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
       
   479     if (cLitSize==1)
       
   480         return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
       
   481 
       
   482     /* Build header */
       
   483     switch(lhSize)
       
   484     {
       
   485     case 3: /* 2 - 2 - 10 - 10 */
       
   486         {   U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
       
   487             MEM_writeLE24(ostart, lhc);
       
   488             break;
       
   489         }
       
   490     case 4: /* 2 - 2 - 14 - 14 */
       
   491         {   U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
       
   492             MEM_writeLE32(ostart, lhc);
       
   493             break;
       
   494         }
       
   495     default:   /* should not be necessary, lhSize is only {3,4,5} */
       
   496     case 5: /* 2 - 2 - 18 - 18 */
       
   497         {   U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
       
   498             MEM_writeLE32(ostart, lhc);
       
   499             ostart[4] = (BYTE)(cLitSize >> 10);
       
   500             break;
       
   501         }
       
   502     }
       
   503     return lhSize+cLitSize;
       
   504 }
       
   505 
       
   506 static const BYTE LL_Code[64] = {  0,  1,  2,  3,  4,  5,  6,  7,
       
   507                                    8,  9, 10, 11, 12, 13, 14, 15,
       
   508                                   16, 16, 17, 17, 18, 18, 19, 19,
       
   509                                   20, 20, 20, 20, 21, 21, 21, 21,
       
   510                                   22, 22, 22, 22, 22, 22, 22, 22,
       
   511                                   23, 23, 23, 23, 23, 23, 23, 23,
       
   512                                   24, 24, 24, 24, 24, 24, 24, 24,
       
   513                                   24, 24, 24, 24, 24, 24, 24, 24 };
       
   514 
       
   515 static const BYTE ML_Code[128] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
       
   516                                   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
       
   517                                   32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
       
   518                                   38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
       
   519                                   40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
       
   520                                   41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
       
   521                                   42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
       
   522                                   42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
       
   523 
       
   524 
       
   525 void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
       
   526 {
       
   527     BYTE const LL_deltaCode = 19;
       
   528     BYTE const ML_deltaCode = 36;
       
   529     const seqDef* const sequences = seqStorePtr->sequencesStart;
       
   530     BYTE* const llCodeTable = seqStorePtr->llCode;
       
   531     BYTE* const ofCodeTable = seqStorePtr->ofCode;
       
   532     BYTE* const mlCodeTable = seqStorePtr->mlCode;
       
   533     U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
       
   534     U32 u;
       
   535     for (u=0; u<nbSeq; u++) {
       
   536         U32 const llv = sequences[u].litLength;
       
   537         U32 const mlv = sequences[u].matchLength;
       
   538         llCodeTable[u] = (llv> 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv];
       
   539         ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
       
   540         mlCodeTable[u] = (mlv>127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv];
       
   541     }
       
   542     if (seqStorePtr->longLengthID==1)
       
   543         llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
       
   544     if (seqStorePtr->longLengthID==2)
       
   545         mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
       
   546 }
       
   547 
       
   548 
       
   549 size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
       
   550                               void* dst, size_t dstCapacity,
       
   551                               size_t srcSize)
       
   552 {
       
   553     const seqStore_t* seqStorePtr = &(zc->seqStore);
       
   554     U32 count[MaxSeq+1];
       
   555     S16 norm[MaxSeq+1];
       
   556     FSE_CTable* CTable_LitLength = zc->litlengthCTable;
       
   557     FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
       
   558     FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
       
   559     U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
       
   560     const seqDef* const sequences = seqStorePtr->sequencesStart;
       
   561     const BYTE* const ofCodeTable = seqStorePtr->ofCode;
       
   562     const BYTE* const llCodeTable = seqStorePtr->llCode;
       
   563     const BYTE* const mlCodeTable = seqStorePtr->mlCode;
       
   564     BYTE* const ostart = (BYTE*)dst;
       
   565     BYTE* const oend = ostart + dstCapacity;
       
   566     BYTE* op = ostart;
       
   567     size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
       
   568     BYTE* seqHead;
       
   569 
       
   570     /* Compress literals */
       
   571     {   const BYTE* const literals = seqStorePtr->litStart;
       
   572         size_t const litSize = seqStorePtr->lit - literals;
       
   573         size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize);
       
   574         if (ZSTD_isError(cSize)) return cSize;
       
   575         op += cSize;
       
   576     }
       
   577 
       
   578     /* Sequences Header */
       
   579     if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall);
       
   580     if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq;
       
   581     else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
       
   582     else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
       
   583     if (nbSeq==0) goto _check_compressibility;
       
   584 
       
   585     /* seqHead : flags for FSE encoding type */
       
   586     seqHead = op++;
       
   587 
       
   588 #define MIN_SEQ_FOR_DYNAMIC_FSE   64
       
   589 #define MAX_SEQ_FOR_STATIC_FSE  1000
       
   590 
       
   591     /* convert length/distances into codes */
       
   592     ZSTD_seqToCodes(seqStorePtr);
       
   593 
       
   594     /* CTable for Literal Lengths */
       
   595     {   U32 max = MaxLL;
       
   596         size_t const mostFrequent = FSE_countFast(count, &max, llCodeTable, nbSeq);
       
   597         if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
       
   598             *op++ = llCodeTable[0];
       
   599             FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
       
   600             LLtype = set_rle;
       
   601         } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
       
   602             LLtype = set_repeat;
       
   603         } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
       
   604             FSE_buildCTable(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog);
       
   605             LLtype = set_basic;
       
   606         } else {
       
   607             size_t nbSeq_1 = nbSeq;
       
   608             const U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
       
   609             if (count[llCodeTable[nbSeq-1]]>1) { count[llCodeTable[nbSeq-1]]--; nbSeq_1--; }
       
   610             FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
       
   611             { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
       
   612               if (FSE_isError(NCountSize)) return ERROR(GENERIC);
       
   613               op += NCountSize; }
       
   614             FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
       
   615             LLtype = set_compressed;
       
   616     }   }
       
   617 
       
   618     /* CTable for Offsets */
       
   619     {   U32 max = MaxOff;
       
   620         size_t const mostFrequent = FSE_countFast(count, &max, ofCodeTable, nbSeq);
       
   621         if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
       
   622             *op++ = ofCodeTable[0];
       
   623             FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
       
   624             Offtype = set_rle;
       
   625         } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
       
   626             Offtype = set_repeat;
       
   627         } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
       
   628             FSE_buildCTable(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog);
       
   629             Offtype = set_basic;
       
   630         } else {
       
   631             size_t nbSeq_1 = nbSeq;
       
   632             const U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
       
   633             if (count[ofCodeTable[nbSeq-1]]>1) { count[ofCodeTable[nbSeq-1]]--; nbSeq_1--; }
       
   634             FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
       
   635             { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
       
   636               if (FSE_isError(NCountSize)) return ERROR(GENERIC);
       
   637               op += NCountSize; }
       
   638             FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
       
   639             Offtype = set_compressed;
       
   640     }   }
       
   641 
       
   642     /* CTable for MatchLengths */
       
   643     {   U32 max = MaxML;
       
   644         size_t const mostFrequent = FSE_countFast(count, &max, mlCodeTable, nbSeq);
       
   645         if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
       
   646             *op++ = *mlCodeTable;
       
   647             FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
       
   648             MLtype = set_rle;
       
   649         } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
       
   650             MLtype = set_repeat;
       
   651         } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
       
   652             FSE_buildCTable(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog);
       
   653             MLtype = set_basic;
       
   654         } else {
       
   655             size_t nbSeq_1 = nbSeq;
       
   656             const U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
       
   657             if (count[mlCodeTable[nbSeq-1]]>1) { count[mlCodeTable[nbSeq-1]]--; nbSeq_1--; }
       
   658             FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
       
   659             { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
       
   660               if (FSE_isError(NCountSize)) return ERROR(GENERIC);
       
   661               op += NCountSize; }
       
   662             FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
       
   663             MLtype = set_compressed;
       
   664     }   }
       
   665 
       
   666     *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
       
   667     zc->flagStaticTables = 0;
       
   668 
       
   669     /* Encoding Sequences */
       
   670     {   BIT_CStream_t blockStream;
       
   671         FSE_CState_t  stateMatchLength;
       
   672         FSE_CState_t  stateOffsetBits;
       
   673         FSE_CState_t  stateLitLength;
       
   674 
       
   675         CHECK_E(BIT_initCStream(&blockStream, op, oend-op), dstSize_tooSmall); /* not enough space remaining */
       
   676 
       
   677         /* first symbols */
       
   678         FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
       
   679         FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);
       
   680         FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);
       
   681         BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
       
   682         if (MEM_32bits()) BIT_flushBits(&blockStream);
       
   683         BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
       
   684         if (MEM_32bits()) BIT_flushBits(&blockStream);
       
   685         BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
       
   686         BIT_flushBits(&blockStream);
       
   687 
       
   688         {   size_t n;
       
   689             for (n=nbSeq-2 ; n<nbSeq ; n--) {      /* intentional underflow */
       
   690                 BYTE const llCode = llCodeTable[n];
       
   691                 BYTE const ofCode = ofCodeTable[n];
       
   692                 BYTE const mlCode = mlCodeTable[n];
       
   693                 U32  const llBits = LL_bits[llCode];
       
   694                 U32  const ofBits = ofCode;                                     /* 32b*/  /* 64b*/
       
   695                 U32  const mlBits = ML_bits[mlCode];
       
   696                                                                                 /* (7)*/  /* (7)*/
       
   697                 FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode);       /* 15 */  /* 15 */
       
   698                 FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);      /* 24 */  /* 24 */
       
   699                 if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
       
   700                 FSE_encodeSymbol(&blockStream, &stateLitLength, llCode);        /* 16 */  /* 33 */
       
   701                 if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
       
   702                     BIT_flushBits(&blockStream);                                /* (7)*/
       
   703                 BIT_addBits(&blockStream, sequences[n].litLength, llBits);
       
   704                 if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
       
   705                 BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
       
   706                 if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
       
   707                 BIT_addBits(&blockStream, sequences[n].offset, ofBits);         /* 31 */
       
   708                 BIT_flushBits(&blockStream);                                    /* (7)*/
       
   709         }   }
       
   710 
       
   711         FSE_flushCState(&blockStream, &stateMatchLength);
       
   712         FSE_flushCState(&blockStream, &stateOffsetBits);
       
   713         FSE_flushCState(&blockStream, &stateLitLength);
       
   714 
       
   715         {   size_t const streamSize = BIT_closeCStream(&blockStream);
       
   716             if (streamSize==0) return ERROR(dstSize_tooSmall);   /* not enough space */
       
   717             op += streamSize;
       
   718     }   }
       
   719 
       
   720     /* check compressibility */
       
   721 _check_compressibility:
       
   722     { size_t const minGain = ZSTD_minGain(srcSize);
       
   723       size_t const maxCSize = srcSize - minGain;
       
   724       if ((size_t)(op-ostart) >= maxCSize) return 0; }
       
   725 
       
   726     /* confirm repcodes */
       
   727     { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = zc->savedRep[i]; }
       
   728 
       
   729     return op - ostart;
       
   730 }
       
   731 
       
   732 
       
   733 /*! ZSTD_storeSeq() :
       
   734     Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
       
   735     `offsetCode` : distance to match, or 0 == repCode.
       
   736     `matchCode` : matchLength - MINMATCH
       
   737 */
       
   738 MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
       
   739 {
       
   740 #if 0  /* for debug */
       
   741     static const BYTE* g_start = NULL;
       
   742     const U32 pos = (U32)(literals - g_start);
       
   743     if (g_start==NULL) g_start = literals;
       
   744     //if ((pos > 1) && (pos < 50000))
       
   745         printf("Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
       
   746                pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
       
   747 #endif
       
   748     /* copy Literals */
       
   749     ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
       
   750     seqStorePtr->lit += litLength;
       
   751 
       
   752     /* literal Length */
       
   753     if (litLength>0xFFFF) { seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
       
   754     seqStorePtr->sequences[0].litLength = (U16)litLength;
       
   755 
       
   756     /* match offset */
       
   757     seqStorePtr->sequences[0].offset = offsetCode + 1;
       
   758 
       
   759     /* match Length */
       
   760     if (matchCode>0xFFFF) { seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
       
   761     seqStorePtr->sequences[0].matchLength = (U16)matchCode;
       
   762 
       
   763     seqStorePtr->sequences++;
       
   764 }
       
   765 
       
   766 
       
   767 /*-*************************************
       
   768 *  Match length counter
       
   769 ***************************************/
       
   770 static unsigned ZSTD_NbCommonBytes (register size_t val)
       
   771 {
       
   772     if (MEM_isLittleEndian()) {
       
   773         if (MEM_64bits()) {
       
   774 #       if defined(_MSC_VER) && defined(_WIN64)
       
   775             unsigned long r = 0;
       
   776             _BitScanForward64( &r, (U64)val );
       
   777             return (unsigned)(r>>3);
       
   778 #       elif defined(__GNUC__) && (__GNUC__ >= 3)
       
   779             return (__builtin_ctzll((U64)val) >> 3);
       
   780 #       else
       
   781             static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
       
   782             return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
       
   783 #       endif
       
   784         } else { /* 32 bits */
       
   785 #       if defined(_MSC_VER)
       
   786             unsigned long r=0;
       
   787             _BitScanForward( &r, (U32)val );
       
   788             return (unsigned)(r>>3);
       
   789 #       elif defined(__GNUC__) && (__GNUC__ >= 3)
       
   790             return (__builtin_ctz((U32)val) >> 3);
       
   791 #       else
       
   792             static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
       
   793             return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
       
   794 #       endif
       
   795         }
       
   796     } else {  /* Big Endian CPU */
       
   797         if (MEM_64bits()) {
       
   798 #       if defined(_MSC_VER) && defined(_WIN64)
       
   799             unsigned long r = 0;
       
   800             _BitScanReverse64( &r, val );
       
   801             return (unsigned)(r>>3);
       
   802 #       elif defined(__GNUC__) && (__GNUC__ >= 3)
       
   803             return (__builtin_clzll(val) >> 3);
       
   804 #       else
       
   805             unsigned r;
       
   806             const unsigned n32 = sizeof(size_t)*4;   /* calculate this way due to compiler complaining in 32-bits mode */
       
   807             if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
       
   808             if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
       
   809             r += (!val);
       
   810             return r;
       
   811 #       endif
       
   812         } else { /* 32 bits */
       
   813 #       if defined(_MSC_VER)
       
   814             unsigned long r = 0;
       
   815             _BitScanReverse( &r, (unsigned long)val );
       
   816             return (unsigned)(r>>3);
       
   817 #       elif defined(__GNUC__) && (__GNUC__ >= 3)
       
   818             return (__builtin_clz((U32)val) >> 3);
       
   819 #       else
       
   820             unsigned r;
       
   821             if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
       
   822             r += (!val);
       
   823             return r;
       
   824 #       endif
       
   825     }   }
       
   826 }
       
   827 
       
   828 
       
   829 static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
       
   830 {
       
   831     const BYTE* const pStart = pIn;
       
   832     const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
       
   833 
       
   834     while (pIn < pInLoopLimit) {
       
   835         size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
       
   836         if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
       
   837         pIn += ZSTD_NbCommonBytes(diff);
       
   838         return (size_t)(pIn - pStart);
       
   839     }
       
   840     if (MEM_64bits()) if ((pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
       
   841     if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
       
   842     if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
       
   843     return (size_t)(pIn - pStart);
       
   844 }
       
   845 
       
   846 /** ZSTD_count_2segments() :
       
   847 *   can count match length with `ip` & `match` in 2 different segments.
       
   848 *   convention : on reaching mEnd, match count continue starting from iStart
       
   849 */
       
   850 static size_t ZSTD_count_2segments(const BYTE* ip, const BYTE* match, const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
       
   851 {
       
   852     const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);
       
   853     size_t const matchLength = ZSTD_count(ip, match, vEnd);
       
   854     if (match + matchLength != mEnd) return matchLength;
       
   855     return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);
       
   856 }
       
   857 
       
   858 
       
   859 /*-*************************************
       
   860 *  Hashes
       
   861 ***************************************/
       
   862 static const U32 prime3bytes = 506832829U;
       
   863 static U32    ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes)  >> (32-h) ; }
       
   864 MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); }   /* only in zstd_opt.h */
       
   865 
       
   866 static const U32 prime4bytes = 2654435761U;
       
   867 static U32    ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
       
   868 static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
       
   869 
       
   870 static const U64 prime5bytes = 889523592379ULL;
       
   871 static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u  << (64-40)) * prime5bytes) >> (64-h)) ; }
       
   872 static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
       
   873 
       
   874 static const U64 prime6bytes = 227718039650203ULL;
       
   875 static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u  << (64-48)) * prime6bytes) >> (64-h)) ; }
       
   876 static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
       
   877 
       
   878 static const U64 prime7bytes = 58295818150454627ULL;
       
   879 static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u  << (64-56)) * prime7bytes) >> (64-h)) ; }
       
   880 static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
       
   881 
       
   882 static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
       
   883 static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
       
   884 static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
       
   885 
       
   886 static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
       
   887 {
       
   888     switch(mls)
       
   889     {
       
   890     default:
       
   891     case 4: return ZSTD_hash4Ptr(p, hBits);
       
   892     case 5: return ZSTD_hash5Ptr(p, hBits);
       
   893     case 6: return ZSTD_hash6Ptr(p, hBits);
       
   894     case 7: return ZSTD_hash7Ptr(p, hBits);
       
   895     case 8: return ZSTD_hash8Ptr(p, hBits);
       
   896     }
       
   897 }
       
   898 
       
   899 
       
   900 /*-*************************************
       
   901 *  Fast Scan
       
   902 ***************************************/
       
   903 static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
       
   904 {
       
   905     U32* const hashTable = zc->hashTable;
       
   906     U32  const hBits = zc->params.cParams.hashLog;
       
   907     const BYTE* const base = zc->base;
       
   908     const BYTE* ip = base + zc->nextToUpdate;
       
   909     const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
       
   910     const size_t fastHashFillStep = 3;
       
   911 
       
   912     while(ip <= iend) {
       
   913         hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
       
   914         ip += fastHashFillStep;
       
   915     }
       
   916 }
       
   917 
       
   918 
       
   919 FORCE_INLINE
       
   920 void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
       
   921                                const void* src, size_t srcSize,
       
   922                                const U32 mls)
       
   923 {
       
   924     U32* const hashTable = cctx->hashTable;
       
   925     U32  const hBits = cctx->params.cParams.hashLog;
       
   926     seqStore_t* seqStorePtr = &(cctx->seqStore);
       
   927     const BYTE* const base = cctx->base;
       
   928     const BYTE* const istart = (const BYTE*)src;
       
   929     const BYTE* ip = istart;
       
   930     const BYTE* anchor = istart;
       
   931     const U32   lowestIndex = cctx->dictLimit;
       
   932     const BYTE* const lowest = base + lowestIndex;
       
   933     const BYTE* const iend = istart + srcSize;
       
   934     const BYTE* const ilimit = iend - HASH_READ_SIZE;
       
   935     U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
       
   936     U32 offsetSaved = 0;
       
   937 
       
   938     /* init */
       
   939     ip += (ip==lowest);
       
   940     {   U32 const maxRep = (U32)(ip-lowest);
       
   941         if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
       
   942         if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
       
   943     }
       
   944 
       
   945     /* Main Search Loop */
       
   946     while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
       
   947         size_t mLength;
       
   948         size_t const h = ZSTD_hashPtr(ip, hBits, mls);
       
   949         U32 const current = (U32)(ip-base);
       
   950         U32 const matchIndex = hashTable[h];
       
   951         const BYTE* match = base + matchIndex;
       
   952         hashTable[h] = current;   /* update hash table */
       
   953 
       
   954         if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
       
   955             mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
       
   956             ip++;
       
   957             ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
       
   958         } else {
       
   959             U32 offset;
       
   960             if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
       
   961                 ip += ((ip-anchor) >> g_searchStrength) + 1;
       
   962                 continue;
       
   963             }
       
   964             mLength = ZSTD_count(ip+4, match+4, iend) + 4;
       
   965             offset = (U32)(ip-match);
       
   966             while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
       
   967             offset_2 = offset_1;
       
   968             offset_1 = offset;
       
   969 
       
   970             ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
       
   971         }
       
   972 
       
   973         /* match found */
       
   974         ip += mLength;
       
   975         anchor = ip;
       
   976 
       
   977         if (ip <= ilimit) {
       
   978             /* Fill Table */
       
   979             hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;  /* here because current+2 could be > iend-8 */
       
   980             hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
       
   981             /* check immediate repcode */
       
   982             while ( (ip <= ilimit)
       
   983                  && ( (offset_2>0)
       
   984                  & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
       
   985                 /* store sequence */
       
   986                 size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
       
   987                 { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; }  /* swap offset_2 <=> offset_1 */
       
   988                 hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
       
   989                 ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
       
   990                 ip += rLength;
       
   991                 anchor = ip;
       
   992                 continue;   /* faster when present ... (?) */
       
   993     }   }   }
       
   994 
       
   995     /* save reps for next block */
       
   996     cctx->savedRep[0] = offset_1 ? offset_1 : offsetSaved;
       
   997     cctx->savedRep[1] = offset_2 ? offset_2 : offsetSaved;
       
   998 
       
   999     /* Last Literals */
       
  1000     {   size_t const lastLLSize = iend - anchor;
       
  1001         memcpy(seqStorePtr->lit, anchor, lastLLSize);
       
  1002         seqStorePtr->lit += lastLLSize;
       
  1003     }
       
  1004 }
       
  1005 
       
  1006 
       
  1007 static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
       
  1008                        const void* src, size_t srcSize)
       
  1009 {
       
  1010     const U32 mls = ctx->params.cParams.searchLength;
       
  1011     switch(mls)
       
  1012     {
       
  1013     default:
       
  1014     case 4 :
       
  1015         ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
       
  1016     case 5 :
       
  1017         ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
       
  1018     case 6 :
       
  1019         ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
       
  1020     case 7 :
       
  1021         ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
       
  1022     }
       
  1023 }
       
  1024 
       
  1025 
       
  1026 static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
       
  1027                                  const void* src, size_t srcSize,
       
  1028                                  const U32 mls)
       
  1029 {
       
  1030     U32* hashTable = ctx->hashTable;
       
  1031     const U32 hBits = ctx->params.cParams.hashLog;
       
  1032     seqStore_t* seqStorePtr = &(ctx->seqStore);
       
  1033     const BYTE* const base = ctx->base;
       
  1034     const BYTE* const dictBase = ctx->dictBase;
       
  1035     const BYTE* const istart = (const BYTE*)src;
       
  1036     const BYTE* ip = istart;
       
  1037     const BYTE* anchor = istart;
       
  1038     const U32   lowestIndex = ctx->lowLimit;
       
  1039     const BYTE* const dictStart = dictBase + lowestIndex;
       
  1040     const U32   dictLimit = ctx->dictLimit;
       
  1041     const BYTE* const lowPrefixPtr = base + dictLimit;
       
  1042     const BYTE* const dictEnd = dictBase + dictLimit;
       
  1043     const BYTE* const iend = istart + srcSize;
       
  1044     const BYTE* const ilimit = iend - 8;
       
  1045     U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
       
  1046 
       
  1047     /* Search Loop */
       
  1048     while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
       
  1049         const size_t h = ZSTD_hashPtr(ip, hBits, mls);
       
  1050         const U32 matchIndex = hashTable[h];
       
  1051         const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
       
  1052         const BYTE* match = matchBase + matchIndex;
       
  1053         const U32 current = (U32)(ip-base);
       
  1054         const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
       
  1055         const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
       
  1056         const BYTE* repMatch = repBase + repIndex;
       
  1057         size_t mLength;
       
  1058         hashTable[h] = current;   /* update hash table */
       
  1059 
       
  1060         if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
       
  1061            && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
       
  1062             const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
       
  1063             mLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
       
  1064             ip++;
       
  1065             ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
       
  1066         } else {
       
  1067             if ( (matchIndex < lowestIndex) ||
       
  1068                  (MEM_read32(match) != MEM_read32(ip)) ) {
       
  1069                 ip += ((ip-anchor) >> g_searchStrength) + 1;
       
  1070                 continue;
       
  1071             }
       
  1072             {   const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
       
  1073                 const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
       
  1074                 U32 offset;
       
  1075                 mLength = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
       
  1076                 while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
       
  1077                 offset = current - matchIndex;
       
  1078                 offset_2 = offset_1;
       
  1079                 offset_1 = offset;
       
  1080                 ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
       
  1081         }   }
       
  1082 
       
  1083         /* found a match : store it */
       
  1084         ip += mLength;
       
  1085         anchor = ip;
       
  1086 
       
  1087         if (ip <= ilimit) {
       
  1088             /* Fill Table */
       
  1089             hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
       
  1090             hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
       
  1091             /* check immediate repcode */
       
  1092             while (ip <= ilimit) {
       
  1093                 U32 const current2 = (U32)(ip-base);
       
  1094                 U32 const repIndex2 = current2 - offset_2;
       
  1095                 const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
       
  1096                 if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
       
  1097                    && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
       
  1098                     const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
       
  1099                     size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
       
  1100                     U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
       
  1101                     ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
       
  1102                     hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
       
  1103                     ip += repLength2;
       
  1104                     anchor = ip;
       
  1105                     continue;
       
  1106                 }
       
  1107                 break;
       
  1108     }   }   }
       
  1109 
       
  1110     /* save reps for next block */
       
  1111     ctx->savedRep[0] = offset_1; ctx->savedRep[1] = offset_2;
       
  1112 
       
  1113     /* Last Literals */
       
  1114     {   size_t const lastLLSize = iend - anchor;
       
  1115         memcpy(seqStorePtr->lit, anchor, lastLLSize);
       
  1116         seqStorePtr->lit += lastLLSize;
       
  1117     }
       
  1118 }
       
  1119 
       
  1120 
       
  1121 static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
       
  1122                          const void* src, size_t srcSize)
       
  1123 {
       
  1124     U32 const mls = ctx->params.cParams.searchLength;
       
  1125     switch(mls)
       
  1126     {
       
  1127     default:
       
  1128     case 4 :
       
  1129         ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
       
  1130     case 5 :
       
  1131         ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
       
  1132     case 6 :
       
  1133         ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
       
  1134     case 7 :
       
  1135         ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
       
  1136     }
       
  1137 }
       
  1138 
       
  1139 
       
  1140 /*-*************************************
       
  1141 *  Double Fast
       
  1142 ***************************************/
       
  1143 static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
       
  1144 {
       
  1145     U32* const hashLarge = cctx->hashTable;
       
  1146     U32  const hBitsL = cctx->params.cParams.hashLog;
       
  1147     U32* const hashSmall = cctx->chainTable;
       
  1148     U32  const hBitsS = cctx->params.cParams.chainLog;
       
  1149     const BYTE* const base = cctx->base;
       
  1150     const BYTE* ip = base + cctx->nextToUpdate;
       
  1151     const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
       
  1152     const size_t fastHashFillStep = 3;
       
  1153 
       
  1154     while(ip <= iend) {
       
  1155         hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
       
  1156         hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
       
  1157         ip += fastHashFillStep;
       
  1158     }
       
  1159 }
       
  1160 
       
  1161 
       
  1162 FORCE_INLINE
       
  1163 void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
       
  1164                                  const void* src, size_t srcSize,
       
  1165                                  const U32 mls)
       
  1166 {
       
  1167     U32* const hashLong = cctx->hashTable;
       
  1168     const U32 hBitsL = cctx->params.cParams.hashLog;
       
  1169     U32* const hashSmall = cctx->chainTable;
       
  1170     const U32 hBitsS = cctx->params.cParams.chainLog;
       
  1171     seqStore_t* seqStorePtr = &(cctx->seqStore);
       
  1172     const BYTE* const base = cctx->base;
       
  1173     const BYTE* const istart = (const BYTE*)src;
       
  1174     const BYTE* ip = istart;
       
  1175     const BYTE* anchor = istart;
       
  1176     const U32 lowestIndex = cctx->dictLimit;
       
  1177     const BYTE* const lowest = base + lowestIndex;
       
  1178     const BYTE* const iend = istart + srcSize;
       
  1179     const BYTE* const ilimit = iend - HASH_READ_SIZE;
       
  1180     U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
       
  1181     U32 offsetSaved = 0;
       
  1182 
       
  1183     /* init */
       
  1184     ip += (ip==lowest);
       
  1185     {   U32 const maxRep = (U32)(ip-lowest);
       
  1186         if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
       
  1187         if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
       
  1188     }
       
  1189 
       
  1190     /* Main Search Loop */
       
  1191     while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
       
  1192         size_t mLength;
       
  1193         size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
       
  1194         size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
       
  1195         U32 const current = (U32)(ip-base);
       
  1196         U32 const matchIndexL = hashLong[h2];
       
  1197         U32 const matchIndexS = hashSmall[h];
       
  1198         const BYTE* matchLong = base + matchIndexL;
       
  1199         const BYTE* match = base + matchIndexS;
       
  1200         hashLong[h2] = hashSmall[h] = current;   /* update hash tables */
       
  1201 
       
  1202         if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
       
  1203             mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
       
  1204             ip++;
       
  1205             ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
       
  1206         } else {
       
  1207             U32 offset;
       
  1208             if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
       
  1209                 mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
       
  1210                 offset = (U32)(ip-matchLong);
       
  1211                 while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
       
  1212             } else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
       
  1213                 size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
       
  1214                 U32 const matchIndex3 = hashLong[h3];
       
  1215                 const BYTE* match3 = base + matchIndex3;
       
  1216                 hashLong[h3] = current + 1;
       
  1217                 if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
       
  1218                     mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
       
  1219                     ip++;
       
  1220                     offset = (U32)(ip-match3);
       
  1221                     while (((ip>anchor) & (match3>lowest)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
       
  1222                 } else {
       
  1223                     mLength = ZSTD_count(ip+4, match+4, iend) + 4;
       
  1224                     offset = (U32)(ip-match);
       
  1225                     while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
       
  1226                 }
       
  1227             } else {
       
  1228                 ip += ((ip-anchor) >> g_searchStrength) + 1;
       
  1229                 continue;
       
  1230             }
       
  1231 
       
  1232             offset_2 = offset_1;
       
  1233             offset_1 = offset;
       
  1234 
       
  1235             ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
       
  1236         }
       
  1237 
       
  1238         /* match found */
       
  1239         ip += mLength;
       
  1240         anchor = ip;
       
  1241 
       
  1242         if (ip <= ilimit) {
       
  1243             /* Fill Table */
       
  1244             hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
       
  1245                 hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;  /* here because current+2 could be > iend-8 */
       
  1246             hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
       
  1247                 hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
       
  1248 
       
  1249             /* check immediate repcode */
       
  1250             while ( (ip <= ilimit)
       
  1251                  && ( (offset_2>0)
       
  1252                  & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
       
  1253                 /* store sequence */
       
  1254                 size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
       
  1255                 { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
       
  1256                 hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
       
  1257                 hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
       
  1258                 ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
       
  1259                 ip += rLength;
       
  1260                 anchor = ip;
       
  1261                 continue;   /* faster when present ... (?) */
       
  1262     }   }   }
       
  1263 
       
  1264     /* save reps for next block */
       
  1265     cctx->savedRep[0] = offset_1 ? offset_1 : offsetSaved;
       
  1266     cctx->savedRep[1] = offset_2 ? offset_2 : offsetSaved;
       
  1267 
       
  1268     /* Last Literals */
       
  1269     {   size_t const lastLLSize = iend - anchor;
       
  1270         memcpy(seqStorePtr->lit, anchor, lastLLSize);
       
  1271         seqStorePtr->lit += lastLLSize;
       
  1272     }
       
  1273 }
       
  1274 
       
  1275 
       
  1276 static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  1277 {
       
  1278     const U32 mls = ctx->params.cParams.searchLength;
       
  1279     switch(mls)
       
  1280     {
       
  1281     default:
       
  1282     case 4 :
       
  1283         ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
       
  1284     case 5 :
       
  1285         ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
       
  1286     case 6 :
       
  1287         ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
       
  1288     case 7 :
       
  1289         ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
       
  1290     }
       
  1291 }
       
  1292 
       
  1293 
       
  1294 static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
       
  1295                                  const void* src, size_t srcSize,
       
  1296                                  const U32 mls)
       
  1297 {
       
  1298     U32* const hashLong = ctx->hashTable;
       
  1299     U32  const hBitsL = ctx->params.cParams.hashLog;
       
  1300     U32* const hashSmall = ctx->chainTable;
       
  1301     U32  const hBitsS = ctx->params.cParams.chainLog;
       
  1302     seqStore_t* seqStorePtr = &(ctx->seqStore);
       
  1303     const BYTE* const base = ctx->base;
       
  1304     const BYTE* const dictBase = ctx->dictBase;
       
  1305     const BYTE* const istart = (const BYTE*)src;
       
  1306     const BYTE* ip = istart;
       
  1307     const BYTE* anchor = istart;
       
  1308     const U32   lowestIndex = ctx->lowLimit;
       
  1309     const BYTE* const dictStart = dictBase + lowestIndex;
       
  1310     const U32   dictLimit = ctx->dictLimit;
       
  1311     const BYTE* const lowPrefixPtr = base + dictLimit;
       
  1312     const BYTE* const dictEnd = dictBase + dictLimit;
       
  1313     const BYTE* const iend = istart + srcSize;
       
  1314     const BYTE* const ilimit = iend - 8;
       
  1315     U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
       
  1316 
       
  1317     /* Search Loop */
       
  1318     while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
       
  1319         const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
       
  1320         const U32 matchIndex = hashSmall[hSmall];
       
  1321         const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
       
  1322         const BYTE* match = matchBase + matchIndex;
       
  1323 
       
  1324         const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
       
  1325         const U32 matchLongIndex = hashLong[hLong];
       
  1326         const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
       
  1327         const BYTE* matchLong = matchLongBase + matchLongIndex;
       
  1328 
       
  1329         const U32 current = (U32)(ip-base);
       
  1330         const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
       
  1331         const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
       
  1332         const BYTE* repMatch = repBase + repIndex;
       
  1333         size_t mLength;
       
  1334         hashSmall[hSmall] = hashLong[hLong] = current;   /* update hash table */
       
  1335 
       
  1336         if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
       
  1337            && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
       
  1338             const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
       
  1339             mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
       
  1340             ip++;
       
  1341             ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
       
  1342         } else {
       
  1343             if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
       
  1344                 const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
       
  1345                 const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
       
  1346                 U32 offset;
       
  1347                 mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
       
  1348                 offset = current - matchLongIndex;
       
  1349                 while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; }   /* catch up */
       
  1350                 offset_2 = offset_1;
       
  1351                 offset_1 = offset;
       
  1352                 ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
       
  1353 
       
  1354             } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
       
  1355                 size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
       
  1356                 U32 const matchIndex3 = hashLong[h3];
       
  1357                 const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
       
  1358                 const BYTE* match3 = match3Base + matchIndex3;
       
  1359                 U32 offset;
       
  1360                 hashLong[h3] = current + 1;
       
  1361                 if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
       
  1362                     const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
       
  1363                     const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
       
  1364                     mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
       
  1365                     ip++;
       
  1366                     offset = current+1 - matchIndex3;
       
  1367                     while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
       
  1368                 } else {
       
  1369                     const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
       
  1370                     const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
       
  1371                     mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
       
  1372                     offset = current - matchIndex;
       
  1373                     while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
       
  1374                 }
       
  1375                 offset_2 = offset_1;
       
  1376                 offset_1 = offset;
       
  1377                 ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
       
  1378 
       
  1379             } else {
       
  1380                 ip += ((ip-anchor) >> g_searchStrength) + 1;
       
  1381                 continue;
       
  1382         }   }
       
  1383 
       
  1384         /* found a match : store it */
       
  1385         ip += mLength;
       
  1386         anchor = ip;
       
  1387 
       
  1388         if (ip <= ilimit) {
       
  1389             /* Fill Table */
       
  1390 			hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
       
  1391 			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
       
  1392             hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
       
  1393             hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
       
  1394             /* check immediate repcode */
       
  1395             while (ip <= ilimit) {
       
  1396                 U32 const current2 = (U32)(ip-base);
       
  1397                 U32 const repIndex2 = current2 - offset_2;
       
  1398                 const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
       
  1399                 if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
       
  1400                    && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
       
  1401                     const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
       
  1402                     size_t const repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
       
  1403                     U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
       
  1404                     ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
       
  1405                     hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
       
  1406                     hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
       
  1407                     ip += repLength2;
       
  1408                     anchor = ip;
       
  1409                     continue;
       
  1410                 }
       
  1411                 break;
       
  1412     }   }   }
       
  1413 
       
  1414     /* save reps for next block */
       
  1415     ctx->savedRep[0] = offset_1; ctx->savedRep[1] = offset_2;
       
  1416 
       
  1417     /* Last Literals */
       
  1418     {   size_t const lastLLSize = iend - anchor;
       
  1419         memcpy(seqStorePtr->lit, anchor, lastLLSize);
       
  1420         seqStorePtr->lit += lastLLSize;
       
  1421     }
       
  1422 }
       
  1423 
       
  1424 
       
  1425 static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
       
  1426                          const void* src, size_t srcSize)
       
  1427 {
       
  1428     U32 const mls = ctx->params.cParams.searchLength;
       
  1429     switch(mls)
       
  1430     {
       
  1431     default:
       
  1432     case 4 :
       
  1433         ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
       
  1434     case 5 :
       
  1435         ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
       
  1436     case 6 :
       
  1437         ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
       
  1438     case 7 :
       
  1439         ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
       
  1440     }
       
  1441 }
       
  1442 
       
  1443 
       
  1444 /*-*************************************
       
  1445 *  Binary Tree search
       
  1446 ***************************************/
       
  1447 /** ZSTD_insertBt1() : add one or multiple positions to tree.
       
  1448 *   ip : assumed <= iend-8 .
       
  1449 *   @return : nb of positions added */
       
  1450 static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
       
  1451                           U32 extDict)
       
  1452 {
       
  1453     U32*   const hashTable = zc->hashTable;
       
  1454     U32    const hashLog = zc->params.cParams.hashLog;
       
  1455     size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
       
  1456     U32*   const bt = zc->chainTable;
       
  1457     U32    const btLog  = zc->params.cParams.chainLog - 1;
       
  1458     U32    const btMask = (1 << btLog) - 1;
       
  1459     U32 matchIndex = hashTable[h];
       
  1460     size_t commonLengthSmaller=0, commonLengthLarger=0;
       
  1461     const BYTE* const base = zc->base;
       
  1462     const BYTE* const dictBase = zc->dictBase;
       
  1463     const U32 dictLimit = zc->dictLimit;
       
  1464     const BYTE* const dictEnd = dictBase + dictLimit;
       
  1465     const BYTE* const prefixStart = base + dictLimit;
       
  1466     const BYTE* match;
       
  1467     const U32 current = (U32)(ip-base);
       
  1468     const U32 btLow = btMask >= current ? 0 : current - btMask;
       
  1469     U32* smallerPtr = bt + 2*(current&btMask);
       
  1470     U32* largerPtr  = smallerPtr + 1;
       
  1471     U32 dummy32;   /* to be nullified at the end */
       
  1472     U32 const windowLow = zc->lowLimit;
       
  1473     U32 matchEndIdx = current+8;
       
  1474     size_t bestLength = 8;
       
  1475 #ifdef ZSTD_C_PREDICT
       
  1476     U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
       
  1477     U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
       
  1478     predictedSmall += (predictedSmall>0);
       
  1479     predictedLarge += (predictedLarge>0);
       
  1480 #endif /* ZSTD_C_PREDICT */
       
  1481 
       
  1482     hashTable[h] = current;   /* Update Hash Table */
       
  1483 
       
  1484     while (nbCompares-- && (matchIndex > windowLow)) {
       
  1485         U32* nextPtr = bt + 2*(matchIndex & btMask);
       
  1486         size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
       
  1487 #ifdef ZSTD_C_PREDICT   /* note : can create issues when hlog small <= 11 */
       
  1488         const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
       
  1489         if (matchIndex == predictedSmall) {
       
  1490             /* no need to check length, result known */
       
  1491             *smallerPtr = matchIndex;
       
  1492             if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
       
  1493             smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
       
  1494             matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
       
  1495             predictedSmall = predictPtr[1] + (predictPtr[1]>0);
       
  1496             continue;
       
  1497         }
       
  1498         if (matchIndex == predictedLarge) {
       
  1499             *largerPtr = matchIndex;
       
  1500             if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
       
  1501             largerPtr = nextPtr;
       
  1502             matchIndex = nextPtr[0];
       
  1503             predictedLarge = predictPtr[0] + (predictPtr[0]>0);
       
  1504             continue;
       
  1505         }
       
  1506 #endif
       
  1507         if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
       
  1508             match = base + matchIndex;
       
  1509             if (match[matchLength] == ip[matchLength])
       
  1510                 matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
       
  1511         } else {
       
  1512             match = dictBase + matchIndex;
       
  1513             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
       
  1514             if (matchIndex+matchLength >= dictLimit)
       
  1515 				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
       
  1516         }
       
  1517 
       
  1518         if (matchLength > bestLength) {
       
  1519             bestLength = matchLength;
       
  1520             if (matchLength > matchEndIdx - matchIndex)
       
  1521                 matchEndIdx = matchIndex + (U32)matchLength;
       
  1522         }
       
  1523 
       
  1524         if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
       
  1525             break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
       
  1526 
       
  1527         if (match[matchLength] < ip[matchLength]) {  /* necessarily within correct buffer */
       
  1528             /* match is smaller than current */
       
  1529             *smallerPtr = matchIndex;             /* update smaller idx */
       
  1530             commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
       
  1531             if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
       
  1532             smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
       
  1533             matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
       
  1534         } else {
       
  1535             /* match is larger than current */
       
  1536             *largerPtr = matchIndex;
       
  1537             commonLengthLarger = matchLength;
       
  1538             if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
       
  1539             largerPtr = nextPtr;
       
  1540             matchIndex = nextPtr[0];
       
  1541     }   }
       
  1542 
       
  1543     *smallerPtr = *largerPtr = 0;
       
  1544     if (bestLength > 384) return MIN(192, (U32)(bestLength - 384));   /* speed optimization */
       
  1545     if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
       
  1546     return 1;
       
  1547 }
       
  1548 
       
  1549 
       
  1550 static size_t ZSTD_insertBtAndFindBestMatch (
       
  1551                         ZSTD_CCtx* zc,
       
  1552                         const BYTE* const ip, const BYTE* const iend,
       
  1553                         size_t* offsetPtr,
       
  1554                         U32 nbCompares, const U32 mls,
       
  1555                         U32 extDict)
       
  1556 {
       
  1557     U32*   const hashTable = zc->hashTable;
       
  1558     U32    const hashLog = zc->params.cParams.hashLog;
       
  1559     size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
       
  1560     U32*   const bt = zc->chainTable;
       
  1561     U32    const btLog  = zc->params.cParams.chainLog - 1;
       
  1562     U32    const btMask = (1 << btLog) - 1;
       
  1563     U32 matchIndex  = hashTable[h];
       
  1564     size_t commonLengthSmaller=0, commonLengthLarger=0;
       
  1565     const BYTE* const base = zc->base;
       
  1566     const BYTE* const dictBase = zc->dictBase;
       
  1567     const U32 dictLimit = zc->dictLimit;
       
  1568     const BYTE* const dictEnd = dictBase + dictLimit;
       
  1569     const BYTE* const prefixStart = base + dictLimit;
       
  1570     const U32 current = (U32)(ip-base);
       
  1571     const U32 btLow = btMask >= current ? 0 : current - btMask;
       
  1572     const U32 windowLow = zc->lowLimit;
       
  1573     U32* smallerPtr = bt + 2*(current&btMask);
       
  1574     U32* largerPtr  = bt + 2*(current&btMask) + 1;
       
  1575     U32 matchEndIdx = current+8;
       
  1576     U32 dummy32;   /* to be nullified at the end */
       
  1577     size_t bestLength = 0;
       
  1578 
       
  1579     hashTable[h] = current;   /* Update Hash Table */
       
  1580 
       
  1581     while (nbCompares-- && (matchIndex > windowLow)) {
       
  1582         U32* nextPtr = bt + 2*(matchIndex & btMask);
       
  1583         size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
       
  1584         const BYTE* match;
       
  1585 
       
  1586         if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
       
  1587             match = base + matchIndex;
       
  1588             if (match[matchLength] == ip[matchLength])
       
  1589                 matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
       
  1590         } else {
       
  1591             match = dictBase + matchIndex;
       
  1592             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
       
  1593             if (matchIndex+matchLength >= dictLimit)
       
  1594 				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
       
  1595         }
       
  1596 
       
  1597         if (matchLength > bestLength) {
       
  1598             if (matchLength > matchEndIdx - matchIndex)
       
  1599                 matchEndIdx = matchIndex + (U32)matchLength;
       
  1600             if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
       
  1601                 bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
       
  1602             if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
       
  1603                 break;   /* drop, to guarantee consistency (miss a little bit of compression) */
       
  1604         }
       
  1605 
       
  1606         if (match[matchLength] < ip[matchLength]) {
       
  1607             /* match is smaller than current */
       
  1608             *smallerPtr = matchIndex;             /* update smaller idx */
       
  1609             commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
       
  1610             if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
       
  1611             smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
       
  1612             matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
       
  1613         } else {
       
  1614             /* match is larger than current */
       
  1615             *largerPtr = matchIndex;
       
  1616             commonLengthLarger = matchLength;
       
  1617             if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
       
  1618             largerPtr = nextPtr;
       
  1619             matchIndex = nextPtr[0];
       
  1620     }   }
       
  1621 
       
  1622     *smallerPtr = *largerPtr = 0;
       
  1623 
       
  1624     zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
       
  1625     return bestLength;
       
  1626 }
       
  1627 
       
  1628 
       
  1629 static void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
       
  1630 {
       
  1631     const BYTE* const base = zc->base;
       
  1632     const U32 target = (U32)(ip - base);
       
  1633     U32 idx = zc->nextToUpdate;
       
  1634 
       
  1635     while(idx < target)
       
  1636         idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
       
  1637 }
       
  1638 
       
  1639 /** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
       
  1640 static size_t ZSTD_BtFindBestMatch (
       
  1641                         ZSTD_CCtx* zc,
       
  1642                         const BYTE* const ip, const BYTE* const iLimit,
       
  1643                         size_t* offsetPtr,
       
  1644                         const U32 maxNbAttempts, const U32 mls)
       
  1645 {
       
  1646     if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
       
  1647     ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
       
  1648     return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
       
  1649 }
       
  1650 
       
  1651 
       
  1652 static size_t ZSTD_BtFindBestMatch_selectMLS (
       
  1653                         ZSTD_CCtx* zc,   /* Index table will be updated */
       
  1654                         const BYTE* ip, const BYTE* const iLimit,
       
  1655                         size_t* offsetPtr,
       
  1656                         const U32 maxNbAttempts, const U32 matchLengthSearch)
       
  1657 {
       
  1658     switch(matchLengthSearch)
       
  1659     {
       
  1660     default :
       
  1661     case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
       
  1662     case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
       
  1663     case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
       
  1664     }
       
  1665 }
       
  1666 
       
  1667 
       
  1668 static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
       
  1669 {
       
  1670     const BYTE* const base = zc->base;
       
  1671     const U32 target = (U32)(ip - base);
       
  1672     U32 idx = zc->nextToUpdate;
       
  1673 
       
  1674     while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
       
  1675 }
       
  1676 
       
  1677 
       
  1678 /** Tree updater, providing best match */
       
  1679 static size_t ZSTD_BtFindBestMatch_extDict (
       
  1680                         ZSTD_CCtx* zc,
       
  1681                         const BYTE* const ip, const BYTE* const iLimit,
       
  1682                         size_t* offsetPtr,
       
  1683                         const U32 maxNbAttempts, const U32 mls)
       
  1684 {
       
  1685     if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
       
  1686     ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
       
  1687     return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
       
  1688 }
       
  1689 
       
  1690 
       
  1691 static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
       
  1692                         ZSTD_CCtx* zc,   /* Index table will be updated */
       
  1693                         const BYTE* ip, const BYTE* const iLimit,
       
  1694                         size_t* offsetPtr,
       
  1695                         const U32 maxNbAttempts, const U32 matchLengthSearch)
       
  1696 {
       
  1697     switch(matchLengthSearch)
       
  1698     {
       
  1699     default :
       
  1700     case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
       
  1701     case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
       
  1702     case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
       
  1703     }
       
  1704 }
       
  1705 
       
  1706 
       
  1707 
       
  1708 /* *********************************
       
  1709 *  Hash Chain
       
  1710 ***********************************/
       
  1711 #define NEXT_IN_CHAIN(d, mask)   chainTable[(d) & mask]
       
  1712 
       
  1713 /* Update chains up to ip (excluded)
       
  1714    Assumption : always within prefix (ie. not within extDict) */
       
  1715 FORCE_INLINE
       
  1716 U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
       
  1717 {
       
  1718     U32* const hashTable  = zc->hashTable;
       
  1719     const U32 hashLog = zc->params.cParams.hashLog;
       
  1720     U32* const chainTable = zc->chainTable;
       
  1721     const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1;
       
  1722     const BYTE* const base = zc->base;
       
  1723     const U32 target = (U32)(ip - base);
       
  1724     U32 idx = zc->nextToUpdate;
       
  1725 
       
  1726     while(idx < target) { /* catch up */
       
  1727         size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
       
  1728         NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
       
  1729         hashTable[h] = idx;
       
  1730         idx++;
       
  1731     }
       
  1732 
       
  1733     zc->nextToUpdate = target;
       
  1734     return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
       
  1735 }
       
  1736 
       
  1737 
       
  1738 
       
  1739 FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */
       
  1740 size_t ZSTD_HcFindBestMatch_generic (
       
  1741                         ZSTD_CCtx* zc,   /* Index table will be updated */
       
  1742                         const BYTE* const ip, const BYTE* const iLimit,
       
  1743                         size_t* offsetPtr,
       
  1744                         const U32 maxNbAttempts, const U32 mls, const U32 extDict)
       
  1745 {
       
  1746     U32* const chainTable = zc->chainTable;
       
  1747     const U32 chainSize = (1 << zc->params.cParams.chainLog);
       
  1748     const U32 chainMask = chainSize-1;
       
  1749     const BYTE* const base = zc->base;
       
  1750     const BYTE* const dictBase = zc->dictBase;
       
  1751     const U32 dictLimit = zc->dictLimit;
       
  1752     const BYTE* const prefixStart = base + dictLimit;
       
  1753     const BYTE* const dictEnd = dictBase + dictLimit;
       
  1754     const U32 lowLimit = zc->lowLimit;
       
  1755     const U32 current = (U32)(ip-base);
       
  1756     const U32 minChain = current > chainSize ? current - chainSize : 0;
       
  1757     int nbAttempts=maxNbAttempts;
       
  1758     size_t ml=EQUAL_READ32-1;
       
  1759 
       
  1760     /* HC4 match finder */
       
  1761     U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
       
  1762 
       
  1763     for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
       
  1764         const BYTE* match;
       
  1765         size_t currentMl=0;
       
  1766         if ((!extDict) || matchIndex >= dictLimit) {
       
  1767             match = base + matchIndex;
       
  1768             if (match[ml] == ip[ml])   /* potentially better */
       
  1769                 currentMl = ZSTD_count(ip, match, iLimit);
       
  1770         } else {
       
  1771             match = dictBase + matchIndex;
       
  1772             if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
       
  1773                 currentMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
       
  1774         }
       
  1775 
       
  1776         /* save best solution */
       
  1777         if (currentMl > ml) { ml = currentMl; *offsetPtr = current - matchIndex + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ }
       
  1778 
       
  1779         if (matchIndex <= minChain) break;
       
  1780         matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
       
  1781     }
       
  1782 
       
  1783     return ml;
       
  1784 }
       
  1785 
       
  1786 
       
  1787 FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS (
       
  1788                         ZSTD_CCtx* zc,
       
  1789                         const BYTE* ip, const BYTE* const iLimit,
       
  1790                         size_t* offsetPtr,
       
  1791                         const U32 maxNbAttempts, const U32 matchLengthSearch)
       
  1792 {
       
  1793     switch(matchLengthSearch)
       
  1794     {
       
  1795     default :
       
  1796     case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
       
  1797     case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
       
  1798     case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
       
  1799     }
       
  1800 }
       
  1801 
       
  1802 
       
  1803 FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
       
  1804                         ZSTD_CCtx* zc,
       
  1805                         const BYTE* ip, const BYTE* const iLimit,
       
  1806                         size_t* offsetPtr,
       
  1807                         const U32 maxNbAttempts, const U32 matchLengthSearch)
       
  1808 {
       
  1809     switch(matchLengthSearch)
       
  1810     {
       
  1811     default :
       
  1812     case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
       
  1813     case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
       
  1814     case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
       
  1815     }
       
  1816 }
       
  1817 
       
  1818 
       
  1819 /* *******************************
       
  1820 *  Common parser - lazy strategy
       
  1821 *********************************/
       
  1822 FORCE_INLINE
       
  1823 void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
       
  1824                                      const void* src, size_t srcSize,
       
  1825                                      const U32 searchMethod, const U32 depth)
       
  1826 {
       
  1827     seqStore_t* seqStorePtr = &(ctx->seqStore);
       
  1828     const BYTE* const istart = (const BYTE*)src;
       
  1829     const BYTE* ip = istart;
       
  1830     const BYTE* anchor = istart;
       
  1831     const BYTE* const iend = istart + srcSize;
       
  1832     const BYTE* const ilimit = iend - 8;
       
  1833     const BYTE* const base = ctx->base + ctx->dictLimit;
       
  1834 
       
  1835     U32 const maxSearches = 1 << ctx->params.cParams.searchLog;
       
  1836     U32 const mls = ctx->params.cParams.searchLength;
       
  1837 
       
  1838     typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
       
  1839                         size_t* offsetPtr,
       
  1840                         U32 maxNbAttempts, U32 matchLengthSearch);
       
  1841     searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
       
  1842     U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1], savedOffset=0;
       
  1843 
       
  1844     /* init */
       
  1845     ip += (ip==base);
       
  1846     ctx->nextToUpdate3 = ctx->nextToUpdate;
       
  1847     {   U32 const maxRep = (U32)(ip-base);
       
  1848         if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
       
  1849         if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
       
  1850     }
       
  1851 
       
  1852     /* Match Loop */
       
  1853     while (ip < ilimit) {
       
  1854         size_t matchLength=0;
       
  1855         size_t offset=0;
       
  1856         const BYTE* start=ip+1;
       
  1857 
       
  1858         /* check repCode */
       
  1859         if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
       
  1860             /* repcode : we take it */
       
  1861             matchLength = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
       
  1862             if (depth==0) goto _storeSequence;
       
  1863         }
       
  1864 
       
  1865         /* first search (depth 0) */
       
  1866         {   size_t offsetFound = 99999999;
       
  1867             size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
       
  1868             if (ml2 > matchLength)
       
  1869                 matchLength = ml2, start = ip, offset=offsetFound;
       
  1870         }
       
  1871 
       
  1872         if (matchLength < EQUAL_READ32) {
       
  1873             ip += ((ip-anchor) >> g_searchStrength) + 1;   /* jump faster over incompressible sections */
       
  1874             continue;
       
  1875         }
       
  1876 
       
  1877         /* let's try to find a better solution */
       
  1878         if (depth>=1)
       
  1879         while (ip<ilimit) {
       
  1880             ip ++;
       
  1881             if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
       
  1882                 size_t const mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
       
  1883                 int const gain2 = (int)(mlRep * 3);
       
  1884                 int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
       
  1885                 if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
       
  1886                     matchLength = mlRep, offset = 0, start = ip;
       
  1887             }
       
  1888             {   size_t offset2=99999999;
       
  1889                 size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
       
  1890                 int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
       
  1891                 int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
       
  1892                 if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
       
  1893                     matchLength = ml2, offset = offset2, start = ip;
       
  1894                     continue;   /* search a better one */
       
  1895             }   }
       
  1896 
       
  1897             /* let's find an even better one */
       
  1898             if ((depth==2) && (ip<ilimit)) {
       
  1899                 ip ++;
       
  1900                 if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
       
  1901                     size_t const ml2 = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
       
  1902                     int const gain2 = (int)(ml2 * 4);
       
  1903                     int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
       
  1904                     if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
       
  1905                         matchLength = ml2, offset = 0, start = ip;
       
  1906                 }
       
  1907                 {   size_t offset2=99999999;
       
  1908                     size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
       
  1909                     int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
       
  1910                     int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
       
  1911                     if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
       
  1912                         matchLength = ml2, offset = offset2, start = ip;
       
  1913                         continue;
       
  1914             }   }   }
       
  1915             break;  /* nothing found : store previous solution */
       
  1916         }
       
  1917 
       
  1918         /* catch up */
       
  1919         if (offset) {
       
  1920             while ((start>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE]))   /* only search for offset within prefix */
       
  1921                 { start--; matchLength++; }
       
  1922             offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
       
  1923         }
       
  1924 
       
  1925         /* store sequence */
       
  1926 _storeSequence:
       
  1927         {   size_t const litLength = start - anchor;
       
  1928             ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
       
  1929             anchor = ip = start + matchLength;
       
  1930         }
       
  1931 
       
  1932         /* check immediate repcode */
       
  1933         while ( (ip <= ilimit)
       
  1934              && ((offset_2>0)
       
  1935              & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
       
  1936             /* store sequence */
       
  1937             matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
       
  1938             offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
       
  1939             ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
       
  1940             ip += matchLength;
       
  1941             anchor = ip;
       
  1942             continue;   /* faster when present ... (?) */
       
  1943     }   }
       
  1944 
       
  1945     /* Save reps for next block */
       
  1946     ctx->savedRep[0] = offset_1 ? offset_1 : savedOffset;
       
  1947     ctx->savedRep[1] = offset_2 ? offset_2 : savedOffset;
       
  1948 
       
  1949     /* Last Literals */
       
  1950     {   size_t const lastLLSize = iend - anchor;
       
  1951         memcpy(seqStorePtr->lit, anchor, lastLLSize);
       
  1952         seqStorePtr->lit += lastLLSize;
       
  1953     }
       
  1954 }
       
  1955 
       
  1956 
       
  1957 static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  1958 {
       
  1959     ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
       
  1960 }
       
  1961 
       
  1962 static void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  1963 {
       
  1964     ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
       
  1965 }
       
  1966 
       
  1967 static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  1968 {
       
  1969     ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
       
  1970 }
       
  1971 
       
  1972 static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  1973 {
       
  1974     ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
       
  1975 }
       
  1976 
       
  1977 
       
  1978 FORCE_INLINE
       
  1979 void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
       
  1980                                      const void* src, size_t srcSize,
       
  1981                                      const U32 searchMethod, const U32 depth)
       
  1982 {
       
  1983     seqStore_t* seqStorePtr = &(ctx->seqStore);
       
  1984     const BYTE* const istart = (const BYTE*)src;
       
  1985     const BYTE* ip = istart;
       
  1986     const BYTE* anchor = istart;
       
  1987     const BYTE* const iend = istart + srcSize;
       
  1988     const BYTE* const ilimit = iend - 8;
       
  1989     const BYTE* const base = ctx->base;
       
  1990     const U32 dictLimit = ctx->dictLimit;
       
  1991     const U32 lowestIndex = ctx->lowLimit;
       
  1992     const BYTE* const prefixStart = base + dictLimit;
       
  1993     const BYTE* const dictBase = ctx->dictBase;
       
  1994     const BYTE* const dictEnd  = dictBase + dictLimit;
       
  1995     const BYTE* const dictStart  = dictBase + ctx->lowLimit;
       
  1996 
       
  1997     const U32 maxSearches = 1 << ctx->params.cParams.searchLog;
       
  1998     const U32 mls = ctx->params.cParams.searchLength;
       
  1999 
       
  2000     typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
       
  2001                         size_t* offsetPtr,
       
  2002                         U32 maxNbAttempts, U32 matchLengthSearch);
       
  2003     searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
       
  2004 
       
  2005     U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1];
       
  2006 
       
  2007     /* init */
       
  2008     ctx->nextToUpdate3 = ctx->nextToUpdate;
       
  2009     ip += (ip == prefixStart);
       
  2010 
       
  2011     /* Match Loop */
       
  2012     while (ip < ilimit) {
       
  2013         size_t matchLength=0;
       
  2014         size_t offset=0;
       
  2015         const BYTE* start=ip+1;
       
  2016         U32 current = (U32)(ip-base);
       
  2017 
       
  2018         /* check repCode */
       
  2019         {   const U32 repIndex = (U32)(current+1 - offset_1);
       
  2020             const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
       
  2021             const BYTE* const repMatch = repBase + repIndex;
       
  2022             if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */
       
  2023             if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
       
  2024                 /* repcode detected we should take it */
       
  2025                 const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
       
  2026                 matchLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
       
  2027                 if (depth==0) goto _storeSequence;
       
  2028         }   }
       
  2029 
       
  2030         /* first search (depth 0) */
       
  2031         {   size_t offsetFound = 99999999;
       
  2032             size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
       
  2033             if (ml2 > matchLength)
       
  2034                 matchLength = ml2, start = ip, offset=offsetFound;
       
  2035         }
       
  2036 
       
  2037          if (matchLength < EQUAL_READ32) {
       
  2038             ip += ((ip-anchor) >> g_searchStrength) + 1;   /* jump faster over incompressible sections */
       
  2039             continue;
       
  2040         }
       
  2041 
       
  2042         /* let's try to find a better solution */
       
  2043         if (depth>=1)
       
  2044         while (ip<ilimit) {
       
  2045             ip ++;
       
  2046             current++;
       
  2047             /* check repCode */
       
  2048             if (offset) {
       
  2049                 const U32 repIndex = (U32)(current - offset_1);
       
  2050                 const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
       
  2051                 const BYTE* const repMatch = repBase + repIndex;
       
  2052                 if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
       
  2053                 if (MEM_read32(ip) == MEM_read32(repMatch)) {
       
  2054                     /* repcode detected */
       
  2055                     const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
       
  2056                     size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
       
  2057                     int const gain2 = (int)(repLength * 3);
       
  2058                     int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
       
  2059                     if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
       
  2060                         matchLength = repLength, offset = 0, start = ip;
       
  2061             }   }
       
  2062 
       
  2063             /* search match, depth 1 */
       
  2064             {   size_t offset2=99999999;
       
  2065                 size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
       
  2066                 int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
       
  2067                 int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
       
  2068                 if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
       
  2069                     matchLength = ml2, offset = offset2, start = ip;
       
  2070                     continue;   /* search a better one */
       
  2071             }   }
       
  2072 
       
  2073             /* let's find an even better one */
       
  2074             if ((depth==2) && (ip<ilimit)) {
       
  2075                 ip ++;
       
  2076                 current++;
       
  2077                 /* check repCode */
       
  2078                 if (offset) {
       
  2079                     const U32 repIndex = (U32)(current - offset_1);
       
  2080                     const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
       
  2081                     const BYTE* const repMatch = repBase + repIndex;
       
  2082                     if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
       
  2083                     if (MEM_read32(ip) == MEM_read32(repMatch)) {
       
  2084                         /* repcode detected */
       
  2085                         const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
       
  2086                         size_t repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
       
  2087                         int gain2 = (int)(repLength * 4);
       
  2088                         int gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
       
  2089                         if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
       
  2090                             matchLength = repLength, offset = 0, start = ip;
       
  2091                 }   }
       
  2092 
       
  2093                 /* search match, depth 2 */
       
  2094                 {   size_t offset2=99999999;
       
  2095                     size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
       
  2096                     int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
       
  2097                     int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
       
  2098                     if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
       
  2099                         matchLength = ml2, offset = offset2, start = ip;
       
  2100                         continue;
       
  2101             }   }   }
       
  2102             break;  /* nothing found : store previous solution */
       
  2103         }
       
  2104 
       
  2105         /* catch up */
       
  2106         if (offset) {
       
  2107             U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
       
  2108             const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
       
  2109             const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
       
  2110             while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; }  /* catch up */
       
  2111             offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
       
  2112         }
       
  2113 
       
  2114         /* store sequence */
       
  2115 _storeSequence:
       
  2116         {   size_t const litLength = start - anchor;
       
  2117             ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
       
  2118             anchor = ip = start + matchLength;
       
  2119         }
       
  2120 
       
  2121         /* check immediate repcode */
       
  2122         while (ip <= ilimit) {
       
  2123             const U32 repIndex = (U32)((ip-base) - offset_2);
       
  2124             const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
       
  2125             const BYTE* const repMatch = repBase + repIndex;
       
  2126             if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
       
  2127             if (MEM_read32(ip) == MEM_read32(repMatch)) {
       
  2128                 /* repcode detected we should take it */
       
  2129                 const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
       
  2130                 matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
       
  2131                 offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset;   /* swap offset history */
       
  2132                 ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
       
  2133                 ip += matchLength;
       
  2134                 anchor = ip;
       
  2135                 continue;   /* faster when present ... (?) */
       
  2136             }
       
  2137             break;
       
  2138     }   }
       
  2139 
       
  2140     /* Save reps for next block */
       
  2141     ctx->savedRep[0] = offset_1; ctx->savedRep[1] = offset_2;
       
  2142 
       
  2143     /* Last Literals */
       
  2144     {   size_t const lastLLSize = iend - anchor;
       
  2145         memcpy(seqStorePtr->lit, anchor, lastLLSize);
       
  2146         seqStorePtr->lit += lastLLSize;
       
  2147     }
       
  2148 }
       
  2149 
       
  2150 
       
  2151 void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2152 {
       
  2153     ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
       
  2154 }
       
  2155 
       
  2156 static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2157 {
       
  2158     ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
       
  2159 }
       
  2160 
       
  2161 static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2162 {
       
  2163     ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
       
  2164 }
       
  2165 
       
  2166 static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2167 {
       
  2168     ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
       
  2169 }
       
  2170 
       
  2171 
       
  2172 /* The optimal parser */
       
  2173 #include "zstd_opt.h"
       
  2174 
       
  2175 static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2176 {
       
  2177 #ifdef ZSTD_OPT_H_91842398743
       
  2178     ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
       
  2179 #else
       
  2180     (void)ctx; (void)src; (void)srcSize;
       
  2181     return;
       
  2182 #endif
       
  2183 }
       
  2184 
       
  2185 static void ZSTD_compressBlock_btopt2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2186 {
       
  2187 #ifdef ZSTD_OPT_H_91842398743
       
  2188     ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
       
  2189 #else
       
  2190     (void)ctx; (void)src; (void)srcSize;
       
  2191     return;
       
  2192 #endif
       
  2193 }
       
  2194 
       
  2195 static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2196 {
       
  2197 #ifdef ZSTD_OPT_H_91842398743
       
  2198     ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
       
  2199 #else
       
  2200     (void)ctx; (void)src; (void)srcSize;
       
  2201     return;
       
  2202 #endif
       
  2203 }
       
  2204 
       
  2205 static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
       
  2206 {
       
  2207 #ifdef ZSTD_OPT_H_91842398743
       
  2208     ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
       
  2209 #else
       
  2210     (void)ctx; (void)src; (void)srcSize;
       
  2211     return;
       
  2212 #endif
       
  2213 }
       
  2214 
       
  2215 
       
  2216 typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
       
  2217 
       
  2218 static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
       
  2219 {
       
  2220     static const ZSTD_blockCompressor blockCompressor[2][8] = {
       
  2221         { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
       
  2222         { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
       
  2223     };
       
  2224 
       
  2225     return blockCompressor[extDict][(U32)strat];
       
  2226 }
       
  2227 
       
  2228 
       
  2229 static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
  2230 {
       
  2231     ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
       
  2232     const BYTE* const base = zc->base;
       
  2233     const BYTE* const istart = (const BYTE*)src;
       
  2234     const U32 current = (U32)(istart-base);
       
  2235     if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0;   /* don't even attempt compression below a certain srcSize */
       
  2236     ZSTD_resetSeqStore(&(zc->seqStore));
       
  2237     if (current > zc->nextToUpdate + 384)
       
  2238         zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384));   /* update tree not updated after finding very long rep matches */
       
  2239     blockCompressor(zc, src, srcSize);
       
  2240     return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
       
  2241 }
       
  2242 
       
  2243 
       
  2244 /*! ZSTD_compress_generic() :
       
  2245 *   Compress a chunk of data into one or multiple blocks.
       
  2246 *   All blocks will be terminated, all input will be consumed.
       
  2247 *   Function will issue an error if there is not enough `dstCapacity` to hold the compressed content.
       
  2248 *   Frame is supposed already started (header already produced)
       
  2249 *   @return : compressed size, or an error code
       
  2250 */
       
  2251 static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
       
  2252                                      void* dst, size_t dstCapacity,
       
  2253                                const void* src, size_t srcSize,
       
  2254                                      U32 lastFrameChunk)
       
  2255 {
       
  2256     size_t blockSize = cctx->blockSize;
       
  2257     size_t remaining = srcSize;
       
  2258     const BYTE* ip = (const BYTE*)src;
       
  2259     BYTE* const ostart = (BYTE*)dst;
       
  2260     BYTE* op = ostart;
       
  2261     U32 const maxDist = 1 << cctx->params.cParams.windowLog;
       
  2262 
       
  2263     if (cctx->params.fParams.checksumFlag && srcSize)
       
  2264         XXH64_update(&cctx->xxhState, src, srcSize);
       
  2265 
       
  2266     while (remaining) {
       
  2267         U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
       
  2268         size_t cSize;
       
  2269 
       
  2270         if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) return ERROR(dstSize_tooSmall);   /* not enough space to store compressed block */
       
  2271         if (remaining < blockSize) blockSize = remaining;
       
  2272 
       
  2273         /* preemptive overflow correction */
       
  2274         if (cctx->lowLimit > (1<<30)) {
       
  2275             U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2);
       
  2276             U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1;
       
  2277             U32 const supLog = MAX(cctx->params.cParams.chainLog, 17 /* blockSize */);
       
  2278             U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog);   /* preserve position % chainSize, ensure current-repcode doesn't underflow */
       
  2279             U32 const correction = cctx->lowLimit - newLowLimit;
       
  2280             ZSTD_reduceIndex(cctx, correction);
       
  2281             cctx->base += correction;
       
  2282             cctx->dictBase += correction;
       
  2283             cctx->lowLimit = newLowLimit;
       
  2284             cctx->dictLimit -= correction;
       
  2285             if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0;
       
  2286             else cctx->nextToUpdate -= correction;
       
  2287         }
       
  2288 
       
  2289         if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
       
  2290             /* enforce maxDist */
       
  2291             U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
       
  2292             if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
       
  2293             if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
       
  2294         }
       
  2295 
       
  2296         cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
       
  2297         if (ZSTD_isError(cSize)) return cSize;
       
  2298 
       
  2299         if (cSize == 0) {  /* block is not compressible */
       
  2300             U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
       
  2301             if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
       
  2302             MEM_writeLE32(op, cBlockHeader24);   /* no pb, 4th byte will be overwritten */
       
  2303             memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
       
  2304             cSize = ZSTD_blockHeaderSize+blockSize;
       
  2305         } else {
       
  2306             U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
       
  2307             MEM_writeLE24(op, cBlockHeader24);
       
  2308             cSize += ZSTD_blockHeaderSize;
       
  2309         }
       
  2310 
       
  2311         remaining -= blockSize;
       
  2312         dstCapacity -= cSize;
       
  2313         ip += blockSize;
       
  2314         op += cSize;
       
  2315     }
       
  2316 
       
  2317     if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
       
  2318     return op-ostart;
       
  2319 }
       
  2320 
       
  2321 
       
  2322 static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
       
  2323                                     ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
       
  2324 {   BYTE* const op = (BYTE*)dst;
       
  2325     U32   const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536);   /* 0-3 */
       
  2326     U32   const checksumFlag = params.fParams.checksumFlag>0;
       
  2327     U32   const windowSize = 1U << params.cParams.windowLog;
       
  2328     U32   const singleSegment = params.fParams.contentSizeFlag && (windowSize > (pledgedSrcSize-1));
       
  2329     BYTE  const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
       
  2330     U32   const fcsCode = params.fParams.contentSizeFlag ?
       
  2331                      (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) :   /* 0-3 */
       
  2332                       0;
       
  2333     BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
       
  2334     size_t pos;
       
  2335 
       
  2336     if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
       
  2337 
       
  2338     MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
       
  2339     op[4] = frameHeaderDecriptionByte; pos=5;
       
  2340     if (!singleSegment) op[pos++] = windowLogByte;
       
  2341     switch(dictIDSizeCode)
       
  2342     {
       
  2343         default:   /* impossible */
       
  2344         case 0 : break;
       
  2345         case 1 : op[pos] = (BYTE)(dictID); pos++; break;
       
  2346         case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
       
  2347         case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
       
  2348     }
       
  2349     switch(fcsCode)
       
  2350     {
       
  2351         default:   /* impossible */
       
  2352         case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
       
  2353         case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
       
  2354         case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
       
  2355         case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
       
  2356     }
       
  2357     return pos;
       
  2358 }
       
  2359 
       
  2360 
       
  2361 static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
       
  2362                               void* dst, size_t dstCapacity,
       
  2363                         const void* src, size_t srcSize,
       
  2364                                U32 frame, U32 lastFrameChunk)
       
  2365 {
       
  2366     const BYTE* const ip = (const BYTE*) src;
       
  2367     size_t fhSize = 0;
       
  2368 
       
  2369     if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
       
  2370 
       
  2371     if (frame && (cctx->stage==ZSTDcs_init)) {
       
  2372         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, cctx->frameContentSize, cctx->dictID);
       
  2373         if (ZSTD_isError(fhSize)) return fhSize;
       
  2374         dstCapacity -= fhSize;
       
  2375         dst = (char*)dst + fhSize;
       
  2376         cctx->stage = ZSTDcs_ongoing;
       
  2377     }
       
  2378 
       
  2379     /* Check if blocks follow each other */
       
  2380     if (src != cctx->nextSrc) {
       
  2381         /* not contiguous */
       
  2382         ptrdiff_t const delta = cctx->nextSrc - ip;
       
  2383         cctx->lowLimit = cctx->dictLimit;
       
  2384         cctx->dictLimit = (U32)(cctx->nextSrc - cctx->base);
       
  2385         cctx->dictBase = cctx->base;
       
  2386         cctx->base -= delta;
       
  2387         cctx->nextToUpdate = cctx->dictLimit;
       
  2388         if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit;   /* too small extDict */
       
  2389     }
       
  2390 
       
  2391     /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
       
  2392     if ((ip+srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
       
  2393         ptrdiff_t const highInputIdx = (ip + srcSize) - cctx->dictBase;
       
  2394         U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)cctx->dictLimit) ? cctx->dictLimit : (U32)highInputIdx;
       
  2395         cctx->lowLimit = lowLimitMax;
       
  2396     }
       
  2397 
       
  2398     cctx->nextSrc = ip + srcSize;
       
  2399 
       
  2400     {   size_t const cSize = frame ?
       
  2401                              ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
       
  2402                              ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
       
  2403         if (ZSTD_isError(cSize)) return cSize;
       
  2404         return cSize + fhSize;
       
  2405     }
       
  2406 }
       
  2407 
       
  2408 
       
  2409 size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
       
  2410                               void* dst, size_t dstCapacity,
       
  2411                         const void* src, size_t srcSize)
       
  2412 {
       
  2413     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 0);
       
  2414 }
       
  2415 
       
  2416 
       
  2417 size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx)
       
  2418 {
       
  2419     return MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog);
       
  2420 }
       
  2421 
       
  2422 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
  2423 {
       
  2424     size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
       
  2425     if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
       
  2426     return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0, 0);
       
  2427 }
       
  2428 
       
  2429 
       
  2430 static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t srcSize)
       
  2431 {
       
  2432     const BYTE* const ip = (const BYTE*) src;
       
  2433     const BYTE* const iend = ip + srcSize;
       
  2434 
       
  2435     /* input becomes current prefix */
       
  2436     zc->lowLimit = zc->dictLimit;
       
  2437     zc->dictLimit = (U32)(zc->nextSrc - zc->base);
       
  2438     zc->dictBase = zc->base;
       
  2439     zc->base += ip - zc->nextSrc;
       
  2440     zc->nextToUpdate = zc->dictLimit;
       
  2441     zc->loadedDictEnd = (U32)(iend - zc->base);
       
  2442 
       
  2443     zc->nextSrc = iend;
       
  2444     if (srcSize <= HASH_READ_SIZE) return 0;
       
  2445 
       
  2446     switch(zc->params.cParams.strategy)
       
  2447     {
       
  2448     case ZSTD_fast:
       
  2449         ZSTD_fillHashTable (zc, iend, zc->params.cParams.searchLength);
       
  2450         break;
       
  2451 
       
  2452     case ZSTD_dfast:
       
  2453         ZSTD_fillDoubleHashTable (zc, iend, zc->params.cParams.searchLength);
       
  2454         break;
       
  2455 
       
  2456     case ZSTD_greedy:
       
  2457     case ZSTD_lazy:
       
  2458     case ZSTD_lazy2:
       
  2459         ZSTD_insertAndFindFirstIndex (zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
       
  2460         break;
       
  2461 
       
  2462     case ZSTD_btlazy2:
       
  2463     case ZSTD_btopt:
       
  2464     case ZSTD_btopt2:
       
  2465         ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
       
  2466         break;
       
  2467 
       
  2468     default:
       
  2469         return ERROR(GENERIC);   /* strategy doesn't exist; impossible */
       
  2470     }
       
  2471 
       
  2472     zc->nextToUpdate = zc->loadedDictEnd;
       
  2473     return 0;
       
  2474 }
       
  2475 
       
  2476 
       
  2477 /* Dictionaries that assign zero probability to symbols that show up causes problems
       
  2478    when FSE encoding.  Refuse dictionaries that assign zero probability to symbols
       
  2479    that we may encounter during compression.
       
  2480    NOTE: This behavior is not standard and could be improved in the future. */
       
  2481 static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
       
  2482     U32 s;
       
  2483     if (dictMaxSymbolValue < maxSymbolValue) return ERROR(dictionary_corrupted);
       
  2484     for (s = 0; s <= maxSymbolValue; ++s) {
       
  2485         if (normalizedCounter[s] == 0) return ERROR(dictionary_corrupted);
       
  2486     }
       
  2487     return 0;
       
  2488 }
       
  2489 
       
  2490 
       
  2491 /* Dictionary format :
       
  2492     Magic == ZSTD_DICT_MAGIC (4 bytes)
       
  2493     HUF_writeCTable(256)
       
  2494     FSE_writeNCount(off)
       
  2495     FSE_writeNCount(ml)
       
  2496     FSE_writeNCount(ll)
       
  2497     RepOffsets
       
  2498     Dictionary content
       
  2499 */
       
  2500 /*! ZSTD_loadDictEntropyStats() :
       
  2501     @return : size read from dictionary
       
  2502     note : magic number supposed already checked */
       
  2503 static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
       
  2504 {
       
  2505     const BYTE* dictPtr = (const BYTE*)dict;
       
  2506     const BYTE* const dictEnd = dictPtr + dictSize;
       
  2507     short offcodeNCount[MaxOff+1];
       
  2508     unsigned offcodeMaxValue = MaxOff;
       
  2509 
       
  2510     {   size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
       
  2511         if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
       
  2512         dictPtr += hufHeaderSize;
       
  2513     }
       
  2514 
       
  2515     {   unsigned offcodeLog;
       
  2516         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
       
  2517         if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
       
  2518         if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
       
  2519         /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
       
  2520         CHECK_E (FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
       
  2521         dictPtr += offcodeHeaderSize;
       
  2522     }
       
  2523 
       
  2524     {   short matchlengthNCount[MaxML+1];
       
  2525         unsigned matchlengthMaxValue = MaxML, matchlengthLog;
       
  2526         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
       
  2527         if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
       
  2528         if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
       
  2529         /* Every match length code must have non-zero probability */
       
  2530         CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
       
  2531         CHECK_E (FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
       
  2532         dictPtr += matchlengthHeaderSize;
       
  2533     }
       
  2534 
       
  2535     {   short litlengthNCount[MaxLL+1];
       
  2536         unsigned litlengthMaxValue = MaxLL, litlengthLog;
       
  2537         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
       
  2538         if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
       
  2539         if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
       
  2540         /* Every literal length code must have non-zero probability */
       
  2541         CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
       
  2542         CHECK_E(FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
       
  2543         dictPtr += litlengthHeaderSize;
       
  2544     }
       
  2545 
       
  2546     if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
       
  2547     cctx->rep[0] = MEM_readLE32(dictPtr+0); if (cctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
       
  2548     cctx->rep[1] = MEM_readLE32(dictPtr+4); if (cctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
       
  2549     cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
       
  2550     dictPtr += 12;
       
  2551 
       
  2552     {   U32 offcodeMax = MaxOff;
       
  2553         if ((size_t)(dictEnd - dictPtr) <= ((U32)-1) - 128 KB) {
       
  2554             U32 const maxOffset = (U32)(dictEnd - dictPtr) + 128 KB; /* The maximum offset that must be supported */
       
  2555             /* Calculate minimum offset code required to represent maxOffset */
       
  2556             offcodeMax = ZSTD_highbit32(maxOffset);
       
  2557         }
       
  2558         /* Every possible supported offset <= dictContentSize + 128 KB must be representable */
       
  2559         CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
       
  2560     }
       
  2561 
       
  2562     cctx->flagStaticTables = 1;
       
  2563     return dictPtr - (const BYTE*)dict;
       
  2564 }
       
  2565 
       
  2566 /** ZSTD_compress_insertDictionary() :
       
  2567 *   @return : 0, or an error code */
       
  2568 static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
       
  2569 {
       
  2570     if ((dict==NULL) || (dictSize<=8)) return 0;
       
  2571 
       
  2572     /* default : dict is pure content */
       
  2573     if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return ZSTD_loadDictionaryContent(zc, dict, dictSize);
       
  2574     zc->dictID = zc->params.fParams.noDictIDFlag ? 0 :  MEM_readLE32((const char*)dict+4);
       
  2575 
       
  2576     /* known magic number : dict is parsed for entropy stats and content */
       
  2577     {   size_t const loadError = ZSTD_loadDictEntropyStats(zc, (const char*)dict+8 /* skip dictHeader */, dictSize-8);
       
  2578         size_t const eSize = loadError + 8;
       
  2579         if (ZSTD_isError(loadError)) return loadError;
       
  2580         return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
       
  2581     }
       
  2582 }
       
  2583 
       
  2584 
       
  2585 /*! ZSTD_compressBegin_internal() :
       
  2586 *   @return : 0, or an error code */
       
  2587 static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
       
  2588                              const void* dict, size_t dictSize,
       
  2589                                    ZSTD_parameters params, U64 pledgedSrcSize)
       
  2590 {
       
  2591     ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue;
       
  2592     CHECK_F(ZSTD_resetCCtx_advanced(cctx, params, pledgedSrcSize, crp));
       
  2593     return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
       
  2594 }
       
  2595 
       
  2596 
       
  2597 /*! ZSTD_compressBegin_advanced() :
       
  2598 *   @return : 0, or an error code */
       
  2599 size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
       
  2600                              const void* dict, size_t dictSize,
       
  2601                                    ZSTD_parameters params, unsigned long long pledgedSrcSize)
       
  2602 {
       
  2603     /* compression parameters verification and optimization */
       
  2604     CHECK_F(ZSTD_checkCParams(params.cParams));
       
  2605     return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
       
  2606 }
       
  2607 
       
  2608 
       
  2609 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
       
  2610 {
       
  2611     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
       
  2612     return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
       
  2613 }
       
  2614 
       
  2615 
       
  2616 size_t ZSTD_compressBegin(ZSTD_CCtx* zc, int compressionLevel)
       
  2617 {
       
  2618     return ZSTD_compressBegin_usingDict(zc, NULL, 0, compressionLevel);
       
  2619 }
       
  2620 
       
  2621 
       
  2622 /*! ZSTD_writeEpilogue() :
       
  2623 *   Ends a frame.
       
  2624 *   @return : nb of bytes written into dst (or an error code) */
       
  2625 static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
       
  2626 {
       
  2627     BYTE* const ostart = (BYTE*)dst;
       
  2628     BYTE* op = ostart;
       
  2629     size_t fhSize = 0;
       
  2630 
       
  2631     if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong);  /* init missing */
       
  2632 
       
  2633     /* special case : empty frame */
       
  2634     if (cctx->stage == ZSTDcs_init) {
       
  2635         fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
       
  2636         if (ZSTD_isError(fhSize)) return fhSize;
       
  2637         dstCapacity -= fhSize;
       
  2638         op += fhSize;
       
  2639         cctx->stage = ZSTDcs_ongoing;
       
  2640     }
       
  2641 
       
  2642     if (cctx->stage != ZSTDcs_ending) {
       
  2643         /* write one last empty block, make it the "last" block */
       
  2644         U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
       
  2645         if (dstCapacity<4) return ERROR(dstSize_tooSmall);
       
  2646         MEM_writeLE32(op, cBlockHeader24);
       
  2647         op += ZSTD_blockHeaderSize;
       
  2648         dstCapacity -= ZSTD_blockHeaderSize;
       
  2649     }
       
  2650 
       
  2651     if (cctx->params.fParams.checksumFlag) {
       
  2652         U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
       
  2653         if (dstCapacity<4) return ERROR(dstSize_tooSmall);
       
  2654         MEM_writeLE32(op, checksum);
       
  2655         op += 4;
       
  2656     }
       
  2657 
       
  2658     cctx->stage = ZSTDcs_created;  /* return to "created but no init" status */
       
  2659     return op-ostart;
       
  2660 }
       
  2661 
       
  2662 
       
  2663 size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
       
  2664                          void* dst, size_t dstCapacity,
       
  2665                    const void* src, size_t srcSize)
       
  2666 {
       
  2667     size_t endResult;
       
  2668     size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 1);
       
  2669     if (ZSTD_isError(cSize)) return cSize;
       
  2670     endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
       
  2671     if (ZSTD_isError(endResult)) return endResult;
       
  2672     return cSize + endResult;
       
  2673 }
       
  2674 
       
  2675 
       
  2676 static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
       
  2677                                void* dst, size_t dstCapacity,
       
  2678                          const void* src, size_t srcSize,
       
  2679                          const void* dict,size_t dictSize,
       
  2680                                ZSTD_parameters params)
       
  2681 {
       
  2682     CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize));
       
  2683     return ZSTD_compressEnd(cctx, dst,  dstCapacity, src, srcSize);
       
  2684 }
       
  2685 
       
  2686 size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
       
  2687                                void* dst, size_t dstCapacity,
       
  2688                          const void* src, size_t srcSize,
       
  2689                          const void* dict,size_t dictSize,
       
  2690                                ZSTD_parameters params)
       
  2691 {
       
  2692     CHECK_F(ZSTD_checkCParams(params.cParams));
       
  2693     return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
       
  2694 }
       
  2695 
       
  2696 size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel)
       
  2697 {
       
  2698     ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize);
       
  2699     params.fParams.contentSizeFlag = 1;
       
  2700     return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
       
  2701 }
       
  2702 
       
  2703 size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
       
  2704 {
       
  2705     return ZSTD_compress_usingDict(ctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
       
  2706 }
       
  2707 
       
  2708 size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
       
  2709 {
       
  2710     size_t result;
       
  2711     ZSTD_CCtx ctxBody;
       
  2712     memset(&ctxBody, 0, sizeof(ctxBody));
       
  2713     memcpy(&ctxBody.customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
       
  2714     result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
       
  2715     ZSTD_free(ctxBody.workSpace, defaultCustomMem);  /* can't free ctxBody itself, as it's on stack; free only heap content */
       
  2716     return result;
       
  2717 }
       
  2718 
       
  2719 
       
  2720 /* =====  Dictionary API  ===== */
       
  2721 
       
  2722 struct ZSTD_CDict_s {
       
  2723     void* dictContent;
       
  2724     size_t dictContentSize;
       
  2725     ZSTD_CCtx* refContext;
       
  2726 };  /* typedef'd tp ZSTD_CDict within "zstd.h" */
       
  2727 
       
  2728 size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
       
  2729 {
       
  2730     if (cdict==NULL) return 0;   /* support sizeof on NULL */
       
  2731     return ZSTD_sizeof_CCtx(cdict->refContext) + cdict->dictContentSize;
       
  2732 }
       
  2733 
       
  2734 ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_parameters params, ZSTD_customMem customMem)
       
  2735 {
       
  2736     if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
       
  2737     if (!customMem.customAlloc || !customMem.customFree) return NULL;
       
  2738 
       
  2739     {   ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
       
  2740         void* const dictContent = ZSTD_malloc(dictSize, customMem);
       
  2741         ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
       
  2742 
       
  2743         if (!dictContent || !cdict || !cctx) {
       
  2744             ZSTD_free(dictContent, customMem);
       
  2745             ZSTD_free(cdict, customMem);
       
  2746             ZSTD_free(cctx, customMem);
       
  2747             return NULL;
       
  2748         }
       
  2749 
       
  2750         if (dictSize) {
       
  2751             memcpy(dictContent, dict, dictSize);
       
  2752         }
       
  2753         {   size_t const errorCode = ZSTD_compressBegin_advanced(cctx, dictContent, dictSize, params, 0);
       
  2754             if (ZSTD_isError(errorCode)) {
       
  2755                 ZSTD_free(dictContent, customMem);
       
  2756                 ZSTD_free(cdict, customMem);
       
  2757                 ZSTD_free(cctx, customMem);
       
  2758                 return NULL;
       
  2759         }   }
       
  2760 
       
  2761         cdict->dictContent = dictContent;
       
  2762         cdict->dictContentSize = dictSize;
       
  2763         cdict->refContext = cctx;
       
  2764         return cdict;
       
  2765     }
       
  2766 }
       
  2767 
       
  2768 ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
       
  2769 {
       
  2770     ZSTD_customMem const allocator = { NULL, NULL, NULL };
       
  2771     ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, dictSize);
       
  2772     params.fParams.contentSizeFlag = 1;
       
  2773     return ZSTD_createCDict_advanced(dict, dictSize, params, allocator);
       
  2774 }
       
  2775 
       
  2776 size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
       
  2777 {
       
  2778     if (cdict==NULL) return 0;   /* support free on NULL */
       
  2779     {   ZSTD_customMem const cMem = cdict->refContext->customMem;
       
  2780         ZSTD_freeCCtx(cdict->refContext);
       
  2781         ZSTD_free(cdict->dictContent, cMem);
       
  2782         ZSTD_free(cdict, cMem);
       
  2783         return 0;
       
  2784     }
       
  2785 }
       
  2786 
       
  2787 static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
       
  2788     return ZSTD_getParamsFromCCtx(cdict->refContext);
       
  2789 }
       
  2790 
       
  2791 size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, U64 pledgedSrcSize)
       
  2792 {
       
  2793     if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
       
  2794     else CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, cdict->refContext->params, pledgedSrcSize));
       
  2795     return 0;
       
  2796 }
       
  2797 
       
  2798 /*! ZSTD_compress_usingCDict() :
       
  2799 *   Compression using a digested Dictionary.
       
  2800 *   Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
       
  2801 *   Note that compression level is decided during dictionary creation */
       
  2802 size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
       
  2803                                 void* dst, size_t dstCapacity,
       
  2804                                 const void* src, size_t srcSize,
       
  2805                                 const ZSTD_CDict* cdict)
       
  2806 {
       
  2807     CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize));
       
  2808 
       
  2809     if (cdict->refContext->params.fParams.contentSizeFlag==1) {
       
  2810         cctx->params.fParams.contentSizeFlag = 1;
       
  2811         cctx->frameContentSize = srcSize;
       
  2812     }
       
  2813 
       
  2814     return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
       
  2815 }
       
  2816 
       
  2817 
       
  2818 
       
  2819 /* ******************************************************************
       
  2820 *  Streaming
       
  2821 ********************************************************************/
       
  2822 
       
  2823 typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
       
  2824 
       
  2825 struct ZSTD_CStream_s {
       
  2826     ZSTD_CCtx* cctx;
       
  2827     ZSTD_CDict* cdictLocal;
       
  2828     const ZSTD_CDict* cdict;
       
  2829     char*  inBuff;
       
  2830     size_t inBuffSize;
       
  2831     size_t inToCompress;
       
  2832     size_t inBuffPos;
       
  2833     size_t inBuffTarget;
       
  2834     size_t blockSize;
       
  2835     char*  outBuff;
       
  2836     size_t outBuffSize;
       
  2837     size_t outBuffContentSize;
       
  2838     size_t outBuffFlushedSize;
       
  2839     ZSTD_cStreamStage stage;
       
  2840     U32    checksum;
       
  2841     U32    frameEnded;
       
  2842     ZSTD_parameters params;
       
  2843     ZSTD_customMem customMem;
       
  2844 };   /* typedef'd to ZSTD_CStream within "zstd.h" */
       
  2845 
       
  2846 ZSTD_CStream* ZSTD_createCStream(void)
       
  2847 {
       
  2848     return ZSTD_createCStream_advanced(defaultCustomMem);
       
  2849 }
       
  2850 
       
  2851 ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
       
  2852 {
       
  2853     ZSTD_CStream* zcs;
       
  2854 
       
  2855     if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
       
  2856     if (!customMem.customAlloc || !customMem.customFree) return NULL;
       
  2857 
       
  2858     zcs = (ZSTD_CStream*)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
       
  2859     if (zcs==NULL) return NULL;
       
  2860     memset(zcs, 0, sizeof(ZSTD_CStream));
       
  2861     memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
       
  2862     zcs->cctx = ZSTD_createCCtx_advanced(customMem);
       
  2863     if (zcs->cctx == NULL) { ZSTD_freeCStream(zcs); return NULL; }
       
  2864     return zcs;
       
  2865 }
       
  2866 
       
  2867 size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
       
  2868 {
       
  2869     if (zcs==NULL) return 0;   /* support free on NULL */
       
  2870     {   ZSTD_customMem const cMem = zcs->customMem;
       
  2871         ZSTD_freeCCtx(zcs->cctx);
       
  2872         ZSTD_freeCDict(zcs->cdictLocal);
       
  2873         ZSTD_free(zcs->inBuff, cMem);
       
  2874         ZSTD_free(zcs->outBuff, cMem);
       
  2875         ZSTD_free(zcs, cMem);
       
  2876         return 0;
       
  2877     }
       
  2878 }
       
  2879 
       
  2880 
       
  2881 /*======   Initialization   ======*/
       
  2882 
       
  2883 size_t ZSTD_CStreamInSize(void)  { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
       
  2884 size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
       
  2885 
       
  2886 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
       
  2887 {
       
  2888     if (zcs->inBuffSize==0) return ERROR(stage_wrong);   /* zcs has not been init at least once */
       
  2889 
       
  2890     if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize))
       
  2891     else CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
       
  2892 
       
  2893     zcs->inToCompress = 0;
       
  2894     zcs->inBuffPos = 0;
       
  2895     zcs->inBuffTarget = zcs->blockSize;
       
  2896     zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
       
  2897     zcs->stage = zcss_load;
       
  2898     zcs->frameEnded = 0;
       
  2899     return 0;   /* ready to go */
       
  2900 }
       
  2901 
       
  2902 size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
       
  2903                                  const void* dict, size_t dictSize,
       
  2904                                  ZSTD_parameters params, unsigned long long pledgedSrcSize)
       
  2905 {
       
  2906     /* allocate buffers */
       
  2907     {   size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
       
  2908         if (zcs->inBuffSize < neededInBuffSize) {
       
  2909             zcs->inBuffSize = neededInBuffSize;
       
  2910             ZSTD_free(zcs->inBuff, zcs->customMem);
       
  2911             zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
       
  2912             if (zcs->inBuff == NULL) return ERROR(memory_allocation);
       
  2913         }
       
  2914         zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
       
  2915     }
       
  2916     if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
       
  2917         zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
       
  2918         ZSTD_free(zcs->outBuff, zcs->customMem);
       
  2919         zcs->outBuff = (char*) ZSTD_malloc(zcs->outBuffSize, zcs->customMem);
       
  2920         if (zcs->outBuff == NULL) return ERROR(memory_allocation);
       
  2921     }
       
  2922 
       
  2923     if (dict) {
       
  2924         ZSTD_freeCDict(zcs->cdictLocal);
       
  2925         zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, params, zcs->customMem);
       
  2926         if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
       
  2927         zcs->cdict = zcs->cdictLocal;
       
  2928     } else zcs->cdict = NULL;
       
  2929 
       
  2930     zcs->checksum = params.fParams.checksumFlag > 0;
       
  2931     zcs->params = params;
       
  2932 
       
  2933     return ZSTD_resetCStream(zcs, pledgedSrcSize);
       
  2934 }
       
  2935 
       
  2936 /* note : cdict must outlive compression session */
       
  2937 size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
       
  2938 {
       
  2939     ZSTD_parameters const params = ZSTD_getParamsFromCDict(cdict);
       
  2940     size_t const initError =  ZSTD_initCStream_advanced(zcs, NULL, 0, params, 0);
       
  2941     zcs->cdict = cdict;
       
  2942     return initError;
       
  2943 }
       
  2944 
       
  2945 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
       
  2946 {
       
  2947     ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
       
  2948     return ZSTD_initCStream_advanced(zcs, dict, dictSize, params, 0);
       
  2949 }
       
  2950 
       
  2951 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
       
  2952 {
       
  2953     return ZSTD_initCStream_usingDict(zcs, NULL, 0, compressionLevel);
       
  2954 }
       
  2955 
       
  2956 size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
       
  2957 {
       
  2958     if (zcs==NULL) return 0;   /* support sizeof on NULL */
       
  2959     return sizeof(zcs) + ZSTD_sizeof_CCtx(zcs->cctx) + ZSTD_sizeof_CDict(zcs->cdictLocal) + zcs->outBuffSize + zcs->inBuffSize;
       
  2960 }
       
  2961 
       
  2962 /*======   Compression   ======*/
       
  2963 
       
  2964 typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e;
       
  2965 
       
  2966 MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
  2967 {
       
  2968     size_t const length = MIN(dstCapacity, srcSize);
       
  2969     memcpy(dst, src, length);
       
  2970     return length;
       
  2971 }
       
  2972 
       
  2973 static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
       
  2974                               void* dst, size_t* dstCapacityPtr,
       
  2975                         const void* src, size_t* srcSizePtr,
       
  2976                               ZSTD_flush_e const flush)
       
  2977 {
       
  2978     U32 someMoreWork = 1;
       
  2979     const char* const istart = (const char*)src;
       
  2980     const char* const iend = istart + *srcSizePtr;
       
  2981     const char* ip = istart;
       
  2982     char* const ostart = (char*)dst;
       
  2983     char* const oend = ostart + *dstCapacityPtr;
       
  2984     char* op = ostart;
       
  2985 
       
  2986     while (someMoreWork) {
       
  2987         switch(zcs->stage)
       
  2988         {
       
  2989         case zcss_init: return ERROR(init_missing);   /* call ZBUFF_compressInit() first ! */
       
  2990 
       
  2991         case zcss_load:
       
  2992             /* complete inBuffer */
       
  2993             {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
       
  2994                 size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
       
  2995                 zcs->inBuffPos += loaded;
       
  2996                 ip += loaded;
       
  2997                 if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
       
  2998                     someMoreWork = 0; break;  /* not enough input to get a full block : stop there, wait for more */
       
  2999             }   }
       
  3000             /* compress current block (note : this stage cannot be stopped in the middle) */
       
  3001             {   void* cDst;
       
  3002                 size_t cSize;
       
  3003                 size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
       
  3004                 size_t oSize = oend-op;
       
  3005                 if (oSize >= ZSTD_compressBound(iSize))
       
  3006                     cDst = op;   /* compress directly into output buffer (avoid flush stage) */
       
  3007                 else
       
  3008                     cDst = zcs->outBuff, oSize = zcs->outBuffSize;
       
  3009                 cSize = (flush == zsf_end) ?
       
  3010                         ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
       
  3011                         ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
       
  3012                 if (ZSTD_isError(cSize)) return cSize;
       
  3013                 if (flush == zsf_end) zcs->frameEnded = 1;
       
  3014                 /* prepare next block */
       
  3015                 zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
       
  3016                 if (zcs->inBuffTarget > zcs->inBuffSize)
       
  3017                     zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;   /* note : inBuffSize >= blockSize */
       
  3018                 zcs->inToCompress = zcs->inBuffPos;
       
  3019                 if (cDst == op) { op += cSize; break; }   /* no need to flush */
       
  3020                 zcs->outBuffContentSize = cSize;
       
  3021                 zcs->outBuffFlushedSize = 0;
       
  3022                 zcs->stage = zcss_flush;   /* pass-through to flush stage */
       
  3023             }
       
  3024 
       
  3025         case zcss_flush:
       
  3026             {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
       
  3027                 size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
       
  3028                 op += flushed;
       
  3029                 zcs->outBuffFlushedSize += flushed;
       
  3030                 if (toFlush!=flushed) { someMoreWork = 0; break; }  /* dst too small to store flushed data : stop there */
       
  3031                 zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
       
  3032                 zcs->stage = zcss_load;
       
  3033                 break;
       
  3034             }
       
  3035 
       
  3036         case zcss_final:
       
  3037             someMoreWork = 0;   /* do nothing */
       
  3038             break;
       
  3039 
       
  3040         default:
       
  3041             return ERROR(GENERIC);   /* impossible */
       
  3042         }
       
  3043     }
       
  3044 
       
  3045     *srcSizePtr = ip - istart;
       
  3046     *dstCapacityPtr = op - ostart;
       
  3047     if (zcs->frameEnded) return 0;
       
  3048     {   size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
       
  3049         if (hintInSize==0) hintInSize = zcs->blockSize;
       
  3050         return hintInSize;
       
  3051     }
       
  3052 }
       
  3053 
       
  3054 size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
       
  3055 {
       
  3056     size_t sizeRead = input->size - input->pos;
       
  3057     size_t sizeWritten = output->size - output->pos;
       
  3058     size_t const result = ZSTD_compressStream_generic(zcs,
       
  3059                                                       (char*)(output->dst) + output->pos, &sizeWritten,
       
  3060                                                       (const char*)(input->src) + input->pos, &sizeRead, zsf_gather);
       
  3061     input->pos += sizeRead;
       
  3062     output->pos += sizeWritten;
       
  3063     return result;
       
  3064 }
       
  3065 
       
  3066 
       
  3067 /*======   Finalize   ======*/
       
  3068 
       
  3069 /*! ZSTD_flushStream() :
       
  3070 *   @return : amount of data remaining to flush */
       
  3071 size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
       
  3072 {
       
  3073     size_t srcSize = 0;
       
  3074     size_t sizeWritten = output->size - output->pos;
       
  3075     size_t const result = ZSTD_compressStream_generic(zcs,
       
  3076                                                      (char*)(output->dst) + output->pos, &sizeWritten,
       
  3077                                                      &srcSize, &srcSize, /* use a valid src address instead of NULL */
       
  3078                                                       zsf_flush);
       
  3079     output->pos += sizeWritten;
       
  3080     if (ZSTD_isError(result)) return result;
       
  3081     return zcs->outBuffContentSize - zcs->outBuffFlushedSize;   /* remaining to flush */
       
  3082 }
       
  3083 
       
  3084 
       
  3085 size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
       
  3086 {
       
  3087     BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
       
  3088     BYTE* const oend = (BYTE*)(output->dst) + output->size;
       
  3089     BYTE* op = ostart;
       
  3090 
       
  3091     if (zcs->stage != zcss_final) {
       
  3092         /* flush whatever remains */
       
  3093         size_t srcSize = 0;
       
  3094         size_t sizeWritten = output->size - output->pos;
       
  3095         size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten, &srcSize, &srcSize, zsf_end);  /* use a valid src address instead of NULL */
       
  3096         size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
       
  3097         op += sizeWritten;
       
  3098         if (remainingToFlush) {
       
  3099             output->pos += sizeWritten;
       
  3100             return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + (zcs->checksum * 4);
       
  3101         }
       
  3102         /* create epilogue */
       
  3103         zcs->stage = zcss_final;
       
  3104         zcs->outBuffContentSize = !notEnded ? 0 :
       
  3105             ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0);  /* write epilogue, including final empty block, into outBuff */
       
  3106     }
       
  3107 
       
  3108     /* flush epilogue */
       
  3109     {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
       
  3110         size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
       
  3111         op += flushed;
       
  3112         zcs->outBuffFlushedSize += flushed;
       
  3113         output->pos += op-ostart;
       
  3114         if (toFlush==flushed) zcs->stage = zcss_init;  /* end reached */
       
  3115         return toFlush - flushed;
       
  3116     }
       
  3117 }
       
  3118 
       
  3119 
       
  3120 
       
  3121 /*-=====  Pre-defined compression levels  =====-*/
       
  3122 
       
  3123 #define ZSTD_DEFAULT_CLEVEL 1
       
  3124 #define ZSTD_MAX_CLEVEL     22
       
  3125 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
       
  3126 
       
  3127 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
       
  3128 {   /* "default" */
       
  3129     /* W,  C,  H,  S,  L, TL, strat */
       
  3130     { 18, 12, 12,  1,  7, 16, ZSTD_fast    },  /* level  0 - never used */
       
  3131     { 19, 13, 14,  1,  7, 16, ZSTD_fast    },  /* level  1 */
       
  3132     { 19, 15, 16,  1,  6, 16, ZSTD_fast    },  /* level  2 */
       
  3133     { 20, 16, 17,  1,  5, 16, ZSTD_dfast   },  /* level  3.*/
       
  3134     { 20, 18, 18,  1,  5, 16, ZSTD_dfast   },  /* level  4.*/
       
  3135     { 20, 15, 18,  3,  5, 16, ZSTD_greedy  },  /* level  5 */
       
  3136     { 21, 16, 19,  2,  5, 16, ZSTD_lazy    },  /* level  6 */
       
  3137     { 21, 17, 20,  3,  5, 16, ZSTD_lazy    },  /* level  7 */
       
  3138     { 21, 18, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
       
  3139     { 21, 20, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  9 */
       
  3140     { 21, 19, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
       
  3141     { 22, 20, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
       
  3142     { 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
       
  3143     { 22, 21, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 13 */
       
  3144     { 22, 21, 22,  6,  5, 16, ZSTD_lazy2   },  /* level 14 */
       
  3145     { 22, 21, 21,  5,  5, 16, ZSTD_btlazy2 },  /* level 15 */
       
  3146     { 23, 22, 22,  5,  5, 16, ZSTD_btlazy2 },  /* level 16 */
       
  3147     { 23, 21, 22,  4,  5, 24, ZSTD_btopt   },  /* level 17 */
       
  3148     { 23, 23, 22,  6,  5, 32, ZSTD_btopt   },  /* level 18 */
       
  3149     { 23, 23, 22,  6,  3, 48, ZSTD_btopt   },  /* level 19 */
       
  3150     { 25, 25, 23,  7,  3, 64, ZSTD_btopt2  },  /* level 20 */
       
  3151     { 26, 26, 23,  7,  3,256, ZSTD_btopt2  },  /* level 21 */
       
  3152     { 27, 27, 25,  9,  3,512, ZSTD_btopt2  },  /* level 22 */
       
  3153 },
       
  3154 {   /* for srcSize <= 256 KB */
       
  3155     /* W,  C,  H,  S,  L,  T, strat */
       
  3156     {  0,  0,  0,  0,  0,  0, ZSTD_fast    },  /* level  0 - not used */
       
  3157     { 18, 13, 14,  1,  6,  8, ZSTD_fast    },  /* level  1 */
       
  3158     { 18, 14, 13,  1,  5,  8, ZSTD_dfast   },  /* level  2 */
       
  3159     { 18, 16, 15,  1,  5,  8, ZSTD_dfast   },  /* level  3 */
       
  3160     { 18, 15, 17,  1,  5,  8, ZSTD_greedy  },  /* level  4.*/
       
  3161     { 18, 16, 17,  4,  5,  8, ZSTD_greedy  },  /* level  5.*/
       
  3162     { 18, 16, 17,  3,  5,  8, ZSTD_lazy    },  /* level  6.*/
       
  3163     { 18, 17, 17,  4,  4,  8, ZSTD_lazy    },  /* level  7 */
       
  3164     { 18, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
       
  3165     { 18, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
       
  3166     { 18, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
       
  3167     { 18, 18, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 11.*/
       
  3168     { 18, 18, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 12.*/
       
  3169     { 18, 19, 17,  6,  4,  8, ZSTD_btlazy2 },  /* level 13 */
       
  3170     { 18, 18, 18,  4,  4, 16, ZSTD_btopt   },  /* level 14.*/
       
  3171     { 18, 18, 18,  4,  3, 16, ZSTD_btopt   },  /* level 15.*/
       
  3172     { 18, 19, 18,  6,  3, 32, ZSTD_btopt   },  /* level 16.*/
       
  3173     { 18, 19, 18,  8,  3, 64, ZSTD_btopt   },  /* level 17.*/
       
  3174     { 18, 19, 18,  9,  3,128, ZSTD_btopt   },  /* level 18.*/
       
  3175     { 18, 19, 18, 10,  3,256, ZSTD_btopt   },  /* level 19.*/
       
  3176     { 18, 19, 18, 11,  3,512, ZSTD_btopt2  },  /* level 20.*/
       
  3177     { 18, 19, 18, 12,  3,512, ZSTD_btopt2  },  /* level 21.*/
       
  3178     { 18, 19, 18, 13,  3,512, ZSTD_btopt2  },  /* level 22.*/
       
  3179 },
       
  3180 {   /* for srcSize <= 128 KB */
       
  3181     /* W,  C,  H,  S,  L,  T, strat */
       
  3182     { 17, 12, 12,  1,  7,  8, ZSTD_fast    },  /* level  0 - not used */
       
  3183     { 17, 12, 13,  1,  6,  8, ZSTD_fast    },  /* level  1 */
       
  3184     { 17, 13, 16,  1,  5,  8, ZSTD_fast    },  /* level  2 */
       
  3185     { 17, 16, 16,  2,  5,  8, ZSTD_dfast   },  /* level  3 */
       
  3186     { 17, 13, 15,  3,  4,  8, ZSTD_greedy  },  /* level  4 */
       
  3187     { 17, 15, 17,  4,  4,  8, ZSTD_greedy  },  /* level  5 */
       
  3188     { 17, 16, 17,  3,  4,  8, ZSTD_lazy    },  /* level  6 */
       
  3189     { 17, 15, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  7 */
       
  3190     { 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
       
  3191     { 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
       
  3192     { 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
       
  3193     { 17, 17, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 11 */
       
  3194     { 17, 17, 17,  8,  4,  8, ZSTD_lazy2   },  /* level 12 */
       
  3195     { 17, 18, 17,  6,  4,  8, ZSTD_btlazy2 },  /* level 13.*/
       
  3196     { 17, 17, 17,  7,  3,  8, ZSTD_btopt   },  /* level 14.*/
       
  3197     { 17, 17, 17,  7,  3, 16, ZSTD_btopt   },  /* level 15.*/
       
  3198     { 17, 18, 17,  7,  3, 32, ZSTD_btopt   },  /* level 16.*/
       
  3199     { 17, 18, 17,  7,  3, 64, ZSTD_btopt   },  /* level 17.*/
       
  3200     { 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 18.*/
       
  3201     { 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 19.*/
       
  3202     { 17, 18, 17,  9,  3,256, ZSTD_btopt2  },  /* level 20.*/
       
  3203     { 17, 18, 17, 10,  3,256, ZSTD_btopt2  },  /* level 21.*/
       
  3204     { 17, 18, 17, 11,  3,512, ZSTD_btopt2  },  /* level 22.*/
       
  3205 },
       
  3206 {   /* for srcSize <= 16 KB */
       
  3207     /* W,  C,  H,  S,  L,  T, strat */
       
  3208     { 14, 12, 12,  1,  7,  6, ZSTD_fast    },  /* level  0 - not used */
       
  3209     { 14, 14, 14,  1,  6,  6, ZSTD_fast    },  /* level  1 */
       
  3210     { 14, 14, 14,  1,  4,  6, ZSTD_fast    },  /* level  2 */
       
  3211     { 14, 14, 14,  1,  4,  6, ZSTD_dfast   },  /* level  3.*/
       
  3212     { 14, 14, 14,  4,  4,  6, ZSTD_greedy  },  /* level  4.*/
       
  3213     { 14, 14, 14,  3,  4,  6, ZSTD_lazy    },  /* level  5.*/
       
  3214     { 14, 14, 14,  4,  4,  6, ZSTD_lazy2   },  /* level  6 */
       
  3215     { 14, 14, 14,  5,  4,  6, ZSTD_lazy2   },  /* level  7 */
       
  3216     { 14, 14, 14,  6,  4,  6, ZSTD_lazy2   },  /* level  8.*/
       
  3217     { 14, 15, 14,  6,  4,  6, ZSTD_btlazy2 },  /* level  9.*/
       
  3218     { 14, 15, 14,  3,  3,  6, ZSTD_btopt   },  /* level 10.*/
       
  3219     { 14, 15, 14,  6,  3,  8, ZSTD_btopt   },  /* level 11.*/
       
  3220     { 14, 15, 14,  6,  3, 16, ZSTD_btopt   },  /* level 12.*/
       
  3221     { 14, 15, 14,  6,  3, 24, ZSTD_btopt   },  /* level 13.*/
       
  3222     { 14, 15, 15,  6,  3, 48, ZSTD_btopt   },  /* level 14.*/
       
  3223     { 14, 15, 15,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
       
  3224     { 14, 15, 15,  6,  3, 96, ZSTD_btopt   },  /* level 16.*/
       
  3225     { 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
       
  3226     { 14, 15, 15,  6,  3,256, ZSTD_btopt   },  /* level 18.*/
       
  3227     { 14, 15, 15,  7,  3,256, ZSTD_btopt   },  /* level 19.*/
       
  3228     { 14, 15, 15,  8,  3,256, ZSTD_btopt2  },  /* level 20.*/
       
  3229     { 14, 15, 15,  9,  3,256, ZSTD_btopt2  },  /* level 21.*/
       
  3230     { 14, 15, 15, 10,  3,256, ZSTD_btopt2  },  /* level 22.*/
       
  3231 },
       
  3232 };
       
  3233 
       
  3234 /*! ZSTD_getCParams() :
       
  3235 *   @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`.
       
  3236 *   Size values are optional, provide 0 if not known or unused */
       
  3237 ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize)
       
  3238 {
       
  3239     ZSTD_compressionParameters cp;
       
  3240     size_t const addedSize = srcSize ? 0 : 500;
       
  3241     U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
       
  3242     U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);   /* intentional underflow for srcSizeHint == 0 */
       
  3243     if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL;   /* 0 == default; no negative compressionLevel yet */
       
  3244     if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
       
  3245     cp = ZSTD_defaultCParameters[tableID][compressionLevel];
       
  3246     if (MEM_32bits()) {   /* auto-correction, for 32-bits mode */
       
  3247         if (cp.windowLog > ZSTD_WINDOWLOG_MAX) cp.windowLog = ZSTD_WINDOWLOG_MAX;
       
  3248         if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
       
  3249         if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
       
  3250     }
       
  3251     cp = ZSTD_adjustCParams(cp, srcSize, dictSize);
       
  3252     return cp;
       
  3253 }
       
  3254 
       
  3255 /*! ZSTD_getParams() :
       
  3256 *   same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
       
  3257 *   All fields of `ZSTD_frameParameters` are set to default (0) */
       
  3258 ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) {
       
  3259     ZSTD_parameters params;
       
  3260     ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
       
  3261     memset(&params, 0, sizeof(params));
       
  3262     params.cParams = cParams;
       
  3263     return params;
       
  3264 }