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)  * LZ4 HC - High Compression Mode of LZ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2011-2015, Yann Collet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * BSD 2 - Clause License (http://www.opensource.org/licenses/bsd - license.php)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * modification, are permitted provided that the following conditions are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *	* Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *	  notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *	* Redistributions in binary form must reproduce the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * copyright notice, this list of conditions and the following disclaimer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * in the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * You can contact the author at :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *	- LZ4 homepage : http://www.lz4.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *	- LZ4 source repository : https://github.com/lz4/lz4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *	Changed for kernel usage by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *	Sven Schmidt <4sschmid@informatik.uni-hamburg.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /*-************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *	Dependencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  **************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/lz4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include "lz4defs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <linux/string.h> /* memset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /* *************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *	Local Constants and types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  ***************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define OPTIMAL_ML (int)((ML_MASK - 1) + MINMATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define HASH_FUNCTION(i)	(((i) * 2654435761U) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	>> ((MINMATCH*8) - LZ4HC_HASH_LOG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define DELTANEXTU16(p)	chainTable[(U16)(p)] /* faster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static U32 LZ4HC_hashPtr(const void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	return HASH_FUNCTION(LZ4_read32(ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /**************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *	HC Compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  **************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static void LZ4HC_init(LZ4HC_CCtx_internal *hc4, const BYTE *start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	memset((void *)hc4->hashTable, 0, sizeof(hc4->hashTable));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	memset(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	hc4->nextToUpdate = 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	hc4->base = start - 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	hc4->end = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	hc4->dictBase = start - 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	hc4->dictLimit = 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	hc4->lowLimit = 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) /* Update chains up to ip (excluded) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static FORCE_INLINE void LZ4HC_Insert(LZ4HC_CCtx_internal *hc4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	const BYTE *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	U16 * const chainTable = hc4->chainTable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	U32 * const hashTable	= hc4->hashTable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	const BYTE * const base = hc4->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	U32 const target = (U32)(ip - base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	U32 idx = hc4->nextToUpdate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	while (idx < target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		U32 const h = LZ4HC_hashPtr(base + idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		size_t delta = idx - hashTable[h];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		if (delta > MAX_DISTANCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			delta = MAX_DISTANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		DELTANEXTU16(idx) = (U16)delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		hashTable[h] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	hc4->nextToUpdate = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static FORCE_INLINE int LZ4HC_InsertAndFindBestMatch(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	LZ4HC_CCtx_internal *hc4, /* Index table will be updated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	const BYTE *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	const BYTE * const iLimit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	const BYTE **matchpos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	const int maxNbAttempts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	U16 * const chainTable = hc4->chainTable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	U32 * const HashTable = hc4->hashTable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	const BYTE * const base = hc4->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	const BYTE * const dictBase = hc4->dictBase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	const U32 dictLimit = hc4->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	const U32 lowLimit = (hc4->lowLimit + 64 * KB > (U32)(ip - base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		? hc4->lowLimit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		: (U32)(ip - base) - (64 * KB - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	U32 matchIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	int nbAttempts = maxNbAttempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	size_t ml = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	/* HC4 match finder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	LZ4HC_Insert(hc4, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	matchIndex = HashTable[LZ4HC_hashPtr(ip)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	while ((matchIndex >= lowLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		&& (nbAttempts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		nbAttempts--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		if (matchIndex >= dictLimit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			const BYTE * const match = base + matchIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			if (*(match + ml) == *(ip + ml)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 				&& (LZ4_read32(match) == LZ4_read32(ip))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 				size_t const mlt = LZ4_count(ip + MINMATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 					match + MINMATCH, iLimit) + MINMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				if (mlt > ml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 					ml = mlt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 					*matchpos = match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			const BYTE * const match = dictBase + matchIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			if (LZ4_read32(match) == LZ4_read32(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 				size_t mlt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 				const BYTE *vLimit = ip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 					+ (dictLimit - matchIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				if (vLimit > iLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 					vLimit = iLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				mlt = LZ4_count(ip + MINMATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 					match + MINMATCH, vLimit) + MINMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				if ((ip + mlt == vLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 					&& (vLimit < iLimit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 					mlt += LZ4_count(ip + mlt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 						base + dictLimit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 						iLimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				if (mlt > ml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 					/* virtual matchpos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 					ml = mlt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 					*matchpos = base + matchIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		matchIndex -= DELTANEXTU16(matchIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	return (int)ml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	LZ4HC_CCtx_internal *hc4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	const BYTE * const ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	const BYTE * const iLowLimit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	const BYTE * const iHighLimit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	int longest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	const BYTE **matchpos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	const BYTE **startpos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	const int maxNbAttempts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	U16 * const chainTable = hc4->chainTable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	U32 * const HashTable = hc4->hashTable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	const BYTE * const base = hc4->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	const U32 dictLimit = hc4->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	const BYTE * const lowPrefixPtr = base + dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	const U32 lowLimit = (hc4->lowLimit + 64 * KB > (U32)(ip - base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		? hc4->lowLimit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		: (U32)(ip - base) - (64 * KB - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	const BYTE * const dictBase = hc4->dictBase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	U32 matchIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	int nbAttempts = maxNbAttempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	int delta = (int)(ip - iLowLimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	/* First Match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	LZ4HC_Insert(hc4, ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	matchIndex = HashTable[LZ4HC_hashPtr(ip)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	while ((matchIndex >= lowLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		&& (nbAttempts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		nbAttempts--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		if (matchIndex >= dictLimit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			const BYTE *matchPtr = base + matchIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			if (*(iLowLimit + longest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 				== *(matchPtr - delta + longest)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 					int mlt = MINMATCH + LZ4_count(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 						ip + MINMATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 						matchPtr + MINMATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 						iHighLimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 					int back = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 					while ((ip + back > iLowLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 						&& (matchPtr + back > lowPrefixPtr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 						&& (ip[back - 1] == matchPtr[back - 1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 						back--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 					mlt -= back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 					if (mlt > longest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 						longest = (int)mlt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 						*matchpos = matchPtr + back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 						*startpos = ip + back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			const BYTE * const matchPtr = dictBase + matchIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				size_t mlt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 				int back = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 				const BYTE *vLimit = ip + (dictLimit - matchIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 				if (vLimit > iHighLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 					vLimit = iHighLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 				mlt = LZ4_count(ip + MINMATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 					matchPtr + MINMATCH, vLimit) + MINMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 				if ((ip + mlt == vLimit) && (vLimit < iHighLimit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 					mlt += LZ4_count(ip + mlt, base + dictLimit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 						iHighLimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				while ((ip + back > iLowLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 					&& (matchIndex + back > lowLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 					&& (ip[back - 1] == matchPtr[back - 1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 					back--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 				mlt -= back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 				if ((int)mlt > longest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 					longest = (int)mlt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 					*matchpos = base + matchIndex + back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 					*startpos = ip + back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		matchIndex -= DELTANEXTU16(matchIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	return longest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static FORCE_INLINE int LZ4HC_encodeSequence(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	const BYTE **ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	BYTE **op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	const BYTE **anchor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	int matchLength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	const BYTE * const match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	limitedOutput_directive limitedOutputBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	BYTE *oend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	BYTE *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	/* Encode Literal length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	length = (int)(*ip - *anchor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	token = (*op)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if ((limitedOutputBuffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		&& ((*op + (length>>8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			+ length + (2 + 1 + LASTLITERALS)) > oend)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		/* Check output limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (length >= (int)RUN_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		*token = (RUN_MASK<<ML_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		len = length - RUN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		for (; len > 254 ; len -= 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			*(*op)++ = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		*(*op)++ = (BYTE)len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		*token = (BYTE)(length<<ML_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	/* Copy Literals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	LZ4_wildCopy(*op, *anchor, (*op) + length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	*op += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* Encode Offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	LZ4_writeLE16(*op, (U16)(*ip - match));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	*op += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	/* Encode MatchLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	length = (int)(matchLength - MINMATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if ((limitedOutputBuffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		&& (*op + (length>>8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			+ (1 + LASTLITERALS) > oend)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		/* Check output limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (length >= (int)ML_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		*token += ML_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		length -= ML_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		for (; length > 509 ; length -= 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			*(*op)++ = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			*(*op)++ = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		if (length > 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			length -= 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			*(*op)++ = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		*(*op)++ = (BYTE)length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		*token += (BYTE)(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	/* Prepare next loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	*ip += matchLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	*anchor = *ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int LZ4HC_compress_generic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	LZ4HC_CCtx_internal *const ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	const char * const source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	char * const dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	int const inputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	int const maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	int compressionLevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	limitedOutput_directive limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	const BYTE *ip = (const BYTE *) source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	const BYTE *anchor = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	const BYTE * const iend = ip + inputSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	const BYTE * const mflimit = iend - MFLIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	const BYTE * const matchlimit = (iend - LASTLITERALS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	BYTE *op = (BYTE *) dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	BYTE * const oend = op + maxOutputSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	unsigned int maxNbAttempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	int ml, ml2, ml3, ml0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	const BYTE *ref = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	const BYTE *start2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	const BYTE *ref2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	const BYTE *start3 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	const BYTE *ref3 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	const BYTE *start0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	const BYTE *ref0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	/* init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (compressionLevel > LZ4HC_MAX_CLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		compressionLevel = LZ4HC_MAX_CLEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	if (compressionLevel < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		compressionLevel = LZ4HC_DEFAULT_CLEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	maxNbAttempts = 1 << (compressionLevel - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	ctx->end += inputSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	/* Main Loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	while (ip < mflimit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		ml = LZ4HC_InsertAndFindBestMatch(ctx, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			matchlimit, (&ref), maxNbAttempts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		if (!ml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		/* saved, in case we would skip too much */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		start0 = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		ref0 = ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		ml0 = ml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) _Search2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		if (ip + ml < mflimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			ml2 = LZ4HC_InsertAndGetWiderMatch(ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 				ip + ml - 2, ip + 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 				matchlimit, ml, &ref2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				&start2, maxNbAttempts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			ml2 = ml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		if (ml2 == ml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			/* No better match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			if (LZ4HC_encodeSequence(&ip, &op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 				&anchor, ml, ref, limit, oend))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			continue;
^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) 		if (start0 < ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			if (start2 < ip + ml0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 				/* empirical */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 				ip = start0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 				ref = ref0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				ml = ml0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			}
^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) 		/* Here, start0 == ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		if ((start2 - ip) < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			/* First Match too small : removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			ml = ml2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			ip = start2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			ref = ref2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			goto _Search2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) _Search3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		* Currently we have :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		* ml2 > ml1, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		* ip1 + 3 <= ip2 (usually < ip1 + ml1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		if ((start2 - ip) < OPTIMAL_ML) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			int correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			int new_ml = ml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			if (new_ml > OPTIMAL_ML)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				new_ml = OPTIMAL_ML;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			if (ip + new_ml > start2 + ml2 - MINMATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 				new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			correction = new_ml - (int)(start2 - ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			if (correction > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 				start2 += correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 				ref2 += correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 				ml2 -= correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		 * Now, we have start2 = ip + new_ml,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		 * with new_ml = min(ml, OPTIMAL_ML = 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		if (start2 + ml2 < mflimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			ml3 = LZ4HC_InsertAndGetWiderMatch(ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 				start2 + ml2 - 3, start2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 				matchlimit, ml2, &ref3, &start3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 				maxNbAttempts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			ml3 = ml2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		if (ml3 == ml2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			/* No better match : 2 sequences to encode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			/* ip & ref are known; Now for ml */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			if (start2 < ip + ml)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 				ml = (int)(start2 - ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			/* Now, encode 2 sequences */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			if (LZ4HC_encodeSequence(&ip, &op, &anchor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 				ml, ref, limit, oend))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			ip = start2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			if (LZ4HC_encodeSequence(&ip, &op, &anchor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 				ml2, ref2, limit, oend))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (start3 < ip + ml + 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			/* Not enough space for match 2 : remove it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			if (start3 >= (ip + ml)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 				/* can write Seq1 immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 				 * ==> Seq2 is removed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 				 * so Seq3 becomes Seq1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 				if (start2 < ip + ml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 					int correction = (int)(ip + ml - start2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 					start2 += correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 					ref2 += correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 					ml2 -= correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 					if (ml2 < MINMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 						start2 = start3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 						ref2 = ref3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 						ml2 = ml3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 				if (LZ4HC_encodeSequence(&ip, &op, &anchor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 					ml, ref, limit, oend))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 				ip = start3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				ref = ref3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 				ml = ml3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 				start0 = start2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 				ref0 = ref2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 				ml0 = ml2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				goto _Search2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			start2 = start3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			ref2 = ref3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			ml2 = ml3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 			goto _Search3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		}
^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) 		* OK, now we have 3 ascending matches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		* let's write at least the first one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		* ip & ref are known; Now for ml
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		if (start2 < ip + ml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			if ((start2 - ip) < (int)ML_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 				int correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 				if (ml > OPTIMAL_ML)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 					ml = OPTIMAL_ML;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 				if (ip + ml > start2 + ml2 - MINMATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 					ml = (int)(start2 - ip) + ml2 - MINMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 				correction = ml - (int)(start2 - ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 				if (correction > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 					start2 += correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 					ref2 += correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 					ml2 -= correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 				ml = (int)(start2 - ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			ref, limit, oend))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		ip = start2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		ref = ref2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		ml = ml2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		start2 = start3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		ref2 = ref3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		ml2 = ml3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		goto _Search3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	/* Encode Last Literals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		int lastRun = (int)(iend - anchor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		if ((limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 			&& (((char *)op - dest) + lastRun + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 				+ ((lastRun + 255 - RUN_MASK)/255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 					> (U32)maxOutputSize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 			/* Check output limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		if (lastRun >= (int)RUN_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			*op++ = (RUN_MASK<<ML_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			lastRun -= RUN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			for (; lastRun > 254 ; lastRun -= 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 				*op++ = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			*op++ = (BYTE) lastRun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			*op++ = (BYTE)(lastRun<<ML_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		LZ4_memcpy(op, anchor, iend - anchor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		op += iend - anchor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	/* End */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	return (int) (((char *)op) - dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static int LZ4_compress_HC_extStateHC(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	void *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	const char *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	char *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	int srcSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	int maxDstSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	int compressionLevel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	LZ4HC_CCtx_internal *ctx = &((LZ4_streamHC_t *)state)->internal_donotuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	if (((size_t)(state)&(sizeof(void *) - 1)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		/* Error : state is not aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		 * for pointers (32 or 64 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	LZ4HC_init(ctx, (const BYTE *)src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	if (maxDstSize < LZ4_compressBound(srcSize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		return LZ4HC_compress_generic(ctx, src, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			srcSize, maxDstSize, compressionLevel, limitedOutput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		return LZ4HC_compress_generic(ctx, src, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			srcSize, maxDstSize, compressionLevel, noLimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) int LZ4_compress_HC(const char *src, char *dst, int srcSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	int maxDstSize, int compressionLevel, void *wrkmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	return LZ4_compress_HC_extStateHC(wrkmem, src, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		srcSize, maxDstSize, compressionLevel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) EXPORT_SYMBOL(LZ4_compress_HC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /**************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  *	Streaming Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  **************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) void LZ4_resetStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	LZ4_streamHCPtr->internal_donotuse.base = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	LZ4_streamHCPtr->internal_donotuse.compressionLevel = (unsigned int)compressionLevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	const char *dictionary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	int dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	LZ4HC_CCtx_internal *ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	if (dictSize > 64 * KB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		dictionary += dictSize - 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		dictSize = 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	LZ4HC_init(ctxPtr, (const BYTE *)dictionary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	if (dictSize >= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		LZ4HC_Insert(ctxPtr, (const BYTE *)dictionary + (dictSize - 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	ctxPtr->end = (const BYTE *)dictionary + dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	return dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) EXPORT_SYMBOL(LZ4_loadDictHC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static void LZ4HC_setExternalDict(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	LZ4HC_CCtx_internal *ctxPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	const BYTE *newBlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	if (ctxPtr->end >= ctxPtr->base + 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		/* Referencing remaining dictionary content */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		LZ4HC_Insert(ctxPtr, ctxPtr->end - 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	 * Only one memory segment for extDict,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	 * so any previous extDict is lost at this stage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	ctxPtr->lowLimit	= ctxPtr->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	ctxPtr->dictBase	= ctxPtr->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	ctxPtr->base = newBlock - ctxPtr->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	ctxPtr->end	= newBlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	/* match referencing will resume from there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	ctxPtr->nextToUpdate = ctxPtr->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int LZ4_compressHC_continue_generic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	LZ4_streamHC_t *LZ4_streamHCPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	const char *source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	int inputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	int maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	limitedOutput_directive limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	LZ4HC_CCtx_internal *ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	/* auto - init if forgotten */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (ctxPtr->base == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		LZ4HC_init(ctxPtr, (const BYTE *) source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	/* Check overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 * GB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 			- ctxPtr->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		if (dictSize > 64 * KB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 			dictSize = 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		LZ4_loadDictHC(LZ4_streamHCPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			(const char *)(ctxPtr->end) - dictSize, (int)dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	/* Check if blocks follow each other */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	if ((const BYTE *)source != ctxPtr->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		LZ4HC_setExternalDict(ctxPtr, (const BYTE *)source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	/* Check overlapping input/dictionary space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		const BYTE *sourceEnd = (const BYTE *) source + inputSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		const BYTE * const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 		const BYTE * const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		if ((sourceEnd > dictBegin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 			&& ((const BYTE *)source < dictEnd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 			if (sourceEnd > dictEnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 				sourceEnd = dictEnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 			ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 			if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 				ctxPtr->lowLimit = ctxPtr->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	return LZ4HC_compress_generic(ctxPtr, source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		inputSize, maxOutputSize, ctxPtr->compressionLevel, limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) int LZ4_compress_HC_continue(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	LZ4_streamHC_t *LZ4_streamHCPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	const char *source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	int inputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	int maxOutputSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	if (maxOutputSize < LZ4_compressBound(inputSize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		return LZ4_compressHC_continue_generic(LZ4_streamHCPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 			source, dest, inputSize, maxOutputSize, limitedOutput);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		return LZ4_compressHC_continue_generic(LZ4_streamHCPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 			source, dest, inputSize, maxOutputSize, noLimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) EXPORT_SYMBOL(LZ4_compress_HC_continue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /* dictionary saving */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int LZ4_saveDictHC(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	LZ4_streamHC_t *LZ4_streamHCPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	char *safeBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	int dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	LZ4HC_CCtx_internal *const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	int const prefixSize = (int)(streamPtr->end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		- (streamPtr->base + streamPtr->dictLimit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	if (dictSize > 64 * KB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		dictSize = 64 * KB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	if (dictSize < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		dictSize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	if (dictSize > prefixSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		dictSize = prefixSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		streamPtr->end = (const BYTE *)safeBuffer + dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		streamPtr->base = streamPtr->end - endIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		streamPtr->dictLimit = endIndex - dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		streamPtr->lowLimit = endIndex - dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		if (streamPtr->nextToUpdate < streamPtr->dictLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 			streamPtr->nextToUpdate = streamPtr->dictLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	return dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) EXPORT_SYMBOL(LZ4_saveDictHC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) MODULE_LICENSE("Dual BSD/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) MODULE_DESCRIPTION("LZ4 HC compressor");