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 - Fast LZ compression algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2011 - 2016, Yann Collet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * BSD 2 - Clause License (http://www.opensource.org/licenses/bsd - license.php)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * modification, are permitted provided that the following conditions are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *	* Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *	  notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *	* Redistributions in binary form must reproduce the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * copyright notice, this list of conditions and the following disclaimer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * in the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * You can contact the author at :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *	- LZ4 homepage : http://www.lz4.org
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *	- LZ4 source repository : https://github.com/lz4/lz4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *	Changed for kernel usage by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *	Sven Schmidt <4sschmid@informatik.uni-hamburg.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^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)  *	Dependencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  **************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/lz4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include "lz4defs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/init.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 <asm/unaligned.h>
^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)  *	Decompression functions
^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 DEBUGLOG(l, ...) {}	/* disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #ifndef assert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define assert(condition) ((void)0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * LZ4_decompress_generic() :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * This generic decompression function covers all use cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * It shall be instantiated several times, using different sets of directives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * Note that it is important for performance that this function really get inlined,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * in order to remove useless branches during compilation optimization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static FORCE_INLINE int LZ4_decompress_generic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	 const char * const src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	 char * const dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	 int srcSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		 * If endOnInput == endOnInputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		 * this value is `dstCapacity`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	 int outputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 /* endOnOutputSize, endOnInputSize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 endCondition_directive endOnInput,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 /* full, partial */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	 earlyEnd_directive partialDecoding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	 /* noDict, withPrefix64k, usingExtDict */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	 dict_directive dict,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	 /* always <= dst, == dst when no prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	 const BYTE * const lowPrefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	 /* only if dict == usingExtDict */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 const BYTE * const dictStart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 /* note : = 0 if noDict */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 const size_t dictSize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	const BYTE *ip = (const BYTE *) src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	const BYTE * const iend = ip + srcSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	BYTE *op = (BYTE *) dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	BYTE * const oend = op + outputSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	BYTE *cpy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	const BYTE * const dictEnd = (const BYTE *)dictStart + dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	static const unsigned int inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	const int safeDecode = (endOnInput == endOnInputSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	const int checkOffset = ((safeDecode) && (dictSize < (int)(64 * KB)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	/* Set up the "end" pointers for the shortcut. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	const BYTE *const shortiend = iend -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		(endOnInput ? 14 : 8) /*maxLL*/ - 2 /*offset*/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	const BYTE *const shortoend = oend -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		(endOnInput ? 14 : 8) /*maxLL*/ - 18 /*maxML*/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	DEBUGLOG(5, "%s (srcSize:%i, dstSize:%i)", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		 srcSize, outputSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	/* Special cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	assert(lowPrefix <= op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	assert(src != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* Empty output buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if ((endOnInput) && (unlikely(outputSize == 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		return ((srcSize == 1) && (*ip == 0)) ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if ((!endOnInput) && (unlikely(outputSize == 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return (*ip == 0 ? 1 : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if ((endOnInput) && unlikely(srcSize == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/* Main Loop : decode sequences */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		size_t length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		const BYTE *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		size_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		/* get literal length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		unsigned int const token = *ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		length = token>>ML_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		/* ip < iend before the increment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		assert(!endOnInput || ip <= iend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		 * A two-stage shortcut for the most common case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		 * 1) If the literal length is 0..14, and there is enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		 * space, enter the shortcut and copy 16 bytes on behalf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		 * of the literals (in the fast mode, only 8 bytes can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		 * safely copied this way).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		 * 2) Further if the match length is 4..18, copy 18 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		 * in a similar manner; but we ensure that there's enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		 * space in the output for those 18 bytes earlier, upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		 * entering the shortcut (in other words, there is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		 * combined check for both stages).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		 * The & in the likely() below is intentionally not && so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		 * some compilers can produce better parallelized runtime code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		if ((endOnInput ? length != RUN_MASK : length <= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		   /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		    * strictly "less than" on input, to re-enter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		    * the loop with at least one byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		   && likely((endOnInput ? ip < shortiend : 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			     (op <= shortoend))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			/* Copy the literals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			LZ4_memcpy(op, ip, endOnInput ? 16 : 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			op += length; ip += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			 * The second stage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			 * prepare for match copying, decode full info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			 * If it doesn't work out, the info won't be wasted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			length = token & ML_MASK; /* match length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			offset = LZ4_readLE16(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			ip += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			match = op - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			assert(match <= op); /* check overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			/* Do not deal with overlapping matches. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			if ((length != ML_MASK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			    (offset >= 8) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			    (dict == withPrefix64k || match >= lowPrefix)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 				/* Copy the match. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				LZ4_memcpy(op + 0, match + 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				LZ4_memcpy(op + 8, match + 8, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				LZ4_memcpy(op + 16, match + 16, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 				op += length + MINMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 				/* Both stages worked, load the next token. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			 * The second stage didn't work out, but the info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			 * is ready. Propel it right to the point of match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			 * copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			goto _copy_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		/* decode literal length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		if (length == RUN_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			unsigned int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			if (unlikely(endOnInput ? ip >= iend - RUN_MASK : 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				/* overflow detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 				s = *ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				length += s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			} while (likely(endOnInput
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				? ip < iend - RUN_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				: 1) & (s == 255));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			if ((safeDecode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			    && unlikely((uptrval)(op) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 					length < (uptrval)(op))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				/* overflow detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 			if ((safeDecode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			    && unlikely((uptrval)(ip) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 					length < (uptrval)(ip))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				/* overflow detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 				goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		/* copy literals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		cpy = op + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (((endOnInput) && ((cpy > oend - MFLIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			|| (ip + length > iend - (2 + 1 + LASTLITERALS))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			|| ((!endOnInput) && (cpy > oend - WILDCOPYLENGTH))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			if (partialDecoding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				if (cpy > oend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 					 * Partial decoding :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 					 * stop in the middle of literal segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 					cpy = oend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 					length = oend - op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 				if ((endOnInput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 					&& (ip + length > iend)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 					 * Error :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 					 * read attempt beyond
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 					 * end of input buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 					goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 				if ((!endOnInput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 					&& (cpy != oend)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 					 * Error :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 					 * block decoding must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 					 * stop exactly there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 					goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				if ((endOnInput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 					&& ((ip + length != iend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 					|| (cpy > oend))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 					 * Error :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 					 * input must be consumed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 					goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			 * supports overlapping memory regions; only matters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			 * for in-place decompression scenarios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			LZ4_memmove(op, ip, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			ip += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			op += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			/* Necessarily EOF, due to parsing restrictions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			if (!partialDecoding || (cpy == oend))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			/* may overwrite up to WILDCOPYLENGTH beyond cpy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			LZ4_wildCopy(op, ip, cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			ip += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			op = cpy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		/* get offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		offset = LZ4_readLE16(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		ip += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		match = op - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		/* get matchlength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		length = token & ML_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) _copy_match:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			/* Error : offset outside buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		/* costs ~1%; silence an msan warning when offset == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		 * note : when partialDecoding, there is no guarantee that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		 * at least 4 bytes remain available in output buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		if (!partialDecoding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			assert(oend > op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			assert(oend - op >= 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			LZ4_write32(op, (U32)offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		if (length == ML_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			unsigned int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 				s = *ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 				if ((endOnInput) && (ip > iend - LASTLITERALS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 					goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 				length += s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			} while (s == 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			if ((safeDecode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 				&& unlikely(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 					(uptrval)(op) + length < (uptrval)op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				/* overflow detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 				goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		length += MINMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		/* match starting within external dictionary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		if ((dict == usingExtDict) && (match < lowPrefix)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			if (unlikely(op + length > oend - LASTLITERALS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 				/* doesn't respect parsing restriction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 				if (!partialDecoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 					goto _output_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				length = min(length, (size_t)(oend - op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			if (length <= (size_t)(lowPrefix - match)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 				 * match fits entirely within external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 				 * dictionary : just copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				memmove(op, dictEnd - (lowPrefix - match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 					length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				op += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				 * match stretches into both external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				 * dictionary and current block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 				size_t const copySize = (size_t)(lowPrefix - match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 				size_t const restSize = length - copySize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 				LZ4_memcpy(op, dictEnd - copySize, copySize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 				op += copySize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 				if (restSize > (size_t)(op - lowPrefix)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 					/* overlap copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 					BYTE * const endOfMatch = op + restSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 					const BYTE *copyFrom = lowPrefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 					while (op < endOfMatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 						*op++ = *copyFrom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 					LZ4_memcpy(op, lowPrefix, restSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 					op += restSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		/* copy match within block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		cpy = op + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		 * partialDecoding :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		 * may not respect endBlock parsing restrictions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		assert(op <= oend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		if (partialDecoding &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		    (cpy > oend - MATCH_SAFEGUARD_DISTANCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			size_t const mlen = min(length, (size_t)(oend - op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			const BYTE * const matchEnd = match + mlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 			BYTE * const copyEnd = op + mlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			if (matchEnd > op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 				/* overlap copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 				while (op < copyEnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 					*op++ = *match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 				LZ4_memcpy(op, match, mlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			op = copyEnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			if (op == oend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		if (unlikely(offset < 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			op[0] = match[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			op[1] = match[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			op[2] = match[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			op[3] = match[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			match += inc32table[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			LZ4_memcpy(op + 4, match, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			match -= dec64table[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			LZ4_copy8(op, match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			match += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		op += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		if (unlikely(cpy > oend - MATCH_SAFEGUARD_DISTANCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			BYTE * const oCopyLimit = oend - (WILDCOPYLENGTH - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			if (cpy > oend - LASTLITERALS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 				 * Error : last LASTLITERALS bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 				 * must be literals (uncompressed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 				goto _output_error;
^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) 			if (op < oCopyLimit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 				LZ4_wildCopy(op, match, oCopyLimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 				match += oCopyLimit - op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 				op = oCopyLimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			while (op < cpy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				*op++ = *match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			LZ4_copy8(op, match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			if (length > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				LZ4_wildCopy(op + 8, match + 8, cpy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		op = cpy; /* wildcopy correction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	/* end of decoding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (endOnInput) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		/* Nb of output bytes decoded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		return (int) (((char *)op) - dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		/* Nb of input bytes read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		return (int) (((const char *)ip) - src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	/* Overflow error detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) _output_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	return (int) (-(((const char *)ip) - src)) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int LZ4_decompress_safe(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	int compressedSize, int maxDecompressedSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	return LZ4_decompress_generic(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 				      compressedSize, maxDecompressedSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				      endOnInputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				      noDict, (BYTE *)dest, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int LZ4_decompress_safe_partial(const char *src, char *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	int compressedSize, int targetOutputSize, int dstCapacity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	dstCapacity = min(targetOutputSize, dstCapacity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	return LZ4_decompress_generic(src, dst, compressedSize, dstCapacity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 				      endOnInputSize, partial_decode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				      noDict, (BYTE *)dst, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int LZ4_decompress_fast(const char *source, char *dest, int originalSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	return LZ4_decompress_generic(source, dest, 0, originalSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 				      endOnOutputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 				      withPrefix64k,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 				      (BYTE *)dest - 64 * KB, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* ===== Instantiate a few more decoding cases, used more than once. ===== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) int LZ4_decompress_safe_withPrefix64k(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 				      int compressedSize, int maxOutputSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	return LZ4_decompress_generic(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 				      compressedSize, maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 				      endOnInputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 				      withPrefix64k,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 				      (BYTE *)dest - 64 * KB, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static int LZ4_decompress_safe_withSmallPrefix(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 					       int compressedSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 					       int maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 					       size_t prefixSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	return LZ4_decompress_generic(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 				      compressedSize, maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 				      endOnInputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				      noDict,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 				      (BYTE *)dest - prefixSize, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int LZ4_decompress_safe_forceExtDict(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 				     int compressedSize, int maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				     const void *dictStart, size_t dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	return LZ4_decompress_generic(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 				      compressedSize, maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 				      endOnInputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 				      usingExtDict, (BYTE *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 				      (const BYTE *)dictStart, dictSize);
^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) static int LZ4_decompress_fast_extDict(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 				       int originalSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 				       const void *dictStart, size_t dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	return LZ4_decompress_generic(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 				      0, originalSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 				      endOnOutputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 				      usingExtDict, (BYTE *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 				      (const BYTE *)dictStart, dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)  * The "double dictionary" mode, for use with e.g. ring buffers: the first part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)  * of the dictionary is passed as prefix, and the second via dictStart + dictSize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)  * These routines are used only once, in LZ4_decompress_*_continue().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static FORCE_INLINE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int LZ4_decompress_safe_doubleDict(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 				   int compressedSize, int maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 				   size_t prefixSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 				   const void *dictStart, size_t dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	return LZ4_decompress_generic(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 				      compressedSize, maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 				      endOnInputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 				      usingExtDict, (BYTE *)dest - prefixSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 				      (const BYTE *)dictStart, dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static FORCE_INLINE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int LZ4_decompress_fast_doubleDict(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 				   int originalSize, size_t prefixSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 				   const void *dictStart, size_t dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	return LZ4_decompress_generic(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 				      0, originalSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 				      endOnOutputSize, decode_full_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 				      usingExtDict, (BYTE *)dest - prefixSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 				      (const BYTE *)dictStart, dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* ===== streaming decompression functions ===== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	const char *dictionary, int dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	LZ4_streamDecode_t_internal *lz4sd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		&LZ4_streamDecode->internal_donotuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	lz4sd->prefixSize = (size_t) dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	lz4sd->prefixEnd = (const BYTE *) dictionary + dictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	lz4sd->externalDict = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	lz4sd->extDictSize	= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)  * *_continue() :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)  * These decoding functions allow decompression of multiple blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)  * in "streaming" mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)  * Previously decoded blocks must still be available at the memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)  * position where they were decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  * If it's not possible, save the relevant part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  * decoded data into a safe buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)  * and indicate where it stands using LZ4_setStreamDecode()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int LZ4_decompress_safe_continue(LZ4_streamDecode_t *LZ4_streamDecode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	const char *source, char *dest, int compressedSize, int maxOutputSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	LZ4_streamDecode_t_internal *lz4sd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		&LZ4_streamDecode->internal_donotuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	if (lz4sd->prefixSize == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		/* The first call, no dictionary yet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		assert(lz4sd->extDictSize == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		result = LZ4_decompress_safe(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 			compressedSize, maxOutputSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		if (result <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		lz4sd->prefixSize = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		lz4sd->prefixEnd = (BYTE *)dest + result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	} else if (lz4sd->prefixEnd == (BYTE *)dest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		/* They're rolling the current segment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		if (lz4sd->prefixSize >= 64 * KB - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			result = LZ4_decompress_safe_withPrefix64k(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 				compressedSize, maxOutputSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		else if (lz4sd->extDictSize == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			result = LZ4_decompress_safe_withSmallPrefix(source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 				dest, compressedSize, maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 				lz4sd->prefixSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			result = LZ4_decompress_safe_doubleDict(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 				compressedSize, maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 				lz4sd->prefixSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 				lz4sd->externalDict, lz4sd->extDictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		if (result <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		lz4sd->prefixSize += result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		lz4sd->prefixEnd  += result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		 * The buffer wraps around, or they're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		 * switching to another buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		lz4sd->extDictSize = lz4sd->prefixSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		result = LZ4_decompress_safe_forceExtDict(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 			compressedSize, maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 			lz4sd->externalDict, lz4sd->extDictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		if (result <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		lz4sd->prefixSize = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		lz4sd->prefixEnd  = (BYTE *)dest + result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) int LZ4_decompress_fast_continue(LZ4_streamDecode_t *LZ4_streamDecode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	const char *source, char *dest, int originalSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	LZ4_streamDecode_t_internal *lz4sd = &LZ4_streamDecode->internal_donotuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	if (lz4sd->prefixSize == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		assert(lz4sd->extDictSize == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		result = LZ4_decompress_fast(source, dest, originalSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		if (result <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		lz4sd->prefixSize = originalSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		lz4sd->prefixEnd = (BYTE *)dest + originalSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	} else if (lz4sd->prefixEnd == (BYTE *)dest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		if (lz4sd->prefixSize >= 64 * KB - 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		    lz4sd->extDictSize == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 			result = LZ4_decompress_fast(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 						     originalSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 			result = LZ4_decompress_fast_doubleDict(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 				originalSize, lz4sd->prefixSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 				lz4sd->externalDict, lz4sd->extDictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		if (result <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		lz4sd->prefixSize += originalSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		lz4sd->prefixEnd  += originalSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		lz4sd->extDictSize = lz4sd->prefixSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		result = LZ4_decompress_fast_extDict(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			originalSize, lz4sd->externalDict, lz4sd->extDictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		if (result <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		lz4sd->prefixSize = originalSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		lz4sd->prefixEnd = (BYTE *)dest + originalSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) int LZ4_decompress_safe_usingDict(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 				  int compressedSize, int maxOutputSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 				  const char *dictStart, int dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	if (dictSize == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		return LZ4_decompress_safe(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 					   compressedSize, maxOutputSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	if (dictStart+dictSize == dest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		if (dictSize >= 64 * KB - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 			return LZ4_decompress_safe_withPrefix64k(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 				compressedSize, maxOutputSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		return LZ4_decompress_safe_withSmallPrefix(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 			compressedSize, maxOutputSize, dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	return LZ4_decompress_safe_forceExtDict(source, dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		compressedSize, maxOutputSize, dictStart, dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) int LZ4_decompress_fast_usingDict(const char *source, char *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 				  int originalSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 				  const char *dictStart, int dictSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	if (dictSize == 0 || dictStart + dictSize == dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		return LZ4_decompress_fast(source, dest, originalSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	return LZ4_decompress_fast_extDict(source, dest, originalSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		dictStart, dictSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) #ifndef STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) EXPORT_SYMBOL(LZ4_decompress_safe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) EXPORT_SYMBOL(LZ4_decompress_safe_partial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) EXPORT_SYMBOL(LZ4_decompress_fast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) EXPORT_SYMBOL(LZ4_setStreamDecode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) EXPORT_SYMBOL(LZ4_decompress_safe_continue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) EXPORT_SYMBOL(LZ4_decompress_fast_continue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) EXPORT_SYMBOL(LZ4_decompress_safe_usingDict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) EXPORT_SYMBOL(LZ4_decompress_fast_usingDict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) MODULE_LICENSE("Dual BSD/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) MODULE_DESCRIPTION("LZ4 decompressor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) #endif