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