Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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