source: thirdparty/blosc/internal-complibs/zstd-0.7.4/compress/zstd_compress.c @ 8ebc79b

Revision 8ebc79b, 130.9 KB checked in by Hal Finkel <hfinkel@…>, 8 years ago (diff)

Add the other internal compression libraries from blocs

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