^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");