lz4hc.c revision 1c3e633c48766c58df949887297dc5838170a33f
1fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet./* 22a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet LZ4 HC - High Compression Mode of LZ4 32a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet Copyright (C) 2011-2015, Yann Collet. 42a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet 52a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 62a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet 72a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet Redistribution and use in source and binary forms, with or without 82a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet modification, are permitted provided that the following conditions are 92a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet met: 102a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet 112a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet * Redistributions of source code must retain the above copyright 122a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet notice, this list of conditions and the following disclaimer. 132a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet * Redistributions in binary form must reproduce the above 142a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet copyright notice, this list of conditions and the following disclaimer 152a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet in the documentation and/or other materials provided with the 162a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet distribution. 172a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet 182a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 192a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 202a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 212a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 222a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 232a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 242a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 252a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 262a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 272a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 282a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 292a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet 302a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet You can contact the author at : 312a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet - LZ4 source repository : https://github.com/Cyan4973/lz4 322a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 33fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.*/ 34fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 3569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 3669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 3769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./************************************** 382a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Tuning Parameter 3969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/ 40002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Colletstatic const int LZ4HC_compressionLevel_default = 9; 4169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 4269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 4369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./************************************** 442a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Includes 4569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/ 4633dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet#include "lz4hc.h" 47fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 48fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 4969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./************************************** 502a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Local Compiler Options 5169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/ 52326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#if defined(__GNUC__) 53326cada9fadeedccef8934e11144f343ecdcabcbYann Collet# pragma GCC diagnostic ignored "-Wunused-function" 54fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif 55fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 56326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#if defined (__clang__) 57326cada9fadeedccef8934e11144f343ecdcabcbYann Collet# pragma clang diagnostic ignored "-Wunused-function" 58fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif 59fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 60fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 61326cada9fadeedccef8934e11144f343ecdcabcbYann Collet/************************************** 622a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Common LZ4 definition 63326cada9fadeedccef8934e11144f343ecdcabcbYann Collet**************************************/ 64326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#define LZ4_COMMONDEFS_ONLY 65326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#include "lz4.c" 66fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 67fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 6869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./************************************** 692a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Local Constants 7069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/ 71fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define DICTIONARY_LOGSIZE 16 72fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MAXD (1<<DICTIONARY_LOGSIZE) 732a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet#define MAXD_MASK (MAXD - 1) 74fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 75fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASH_LOG (DICTIONARY_LOGSIZE-1) 76fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASHTABLESIZE (1 << HASH_LOG) 77fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASH_MASK (HASHTABLESIZE - 1) 78fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 79fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH) 80fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 81c5decf7562a3b4065922ae6460b7785eb91366f8Yann Colletstatic const int g_maxCompressionLevel = 16; 82c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet 83fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 8469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./************************************** 852a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Local Types 8669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/ 87fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef struct 88fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 892a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet U32 hashTable[HASHTABLESIZE]; 90d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U16 chainTable[MAXD]; 9133dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet const BYTE* end; /* next block here to continue on current prefix */ 9261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet const BYTE* base; /* All index relative to this position */ 9361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet const BYTE* dictBase; /* alternate base for extDict */ 941c3e633c48766c58df949887297dc5838170a33fYann Collet BYTE* inputBuffer; /* deprecated */ 9561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet U32 dictLimit; /* below that point, need extDict */ 9661289dea1d94510a4d6386bc44c08d3d15083123Yann Collet U32 lowLimit; /* below that point, no more dict */ 972a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet U32 nextToUpdate; /* index from which to continue dictionary update */ 98d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32 compressionLevel; 99fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} LZ4HC_Data_Structure; 100fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 101fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 10269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./************************************** 1032a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Local Macros 10469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/ 105fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG)) 1062a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet//#define DELTANEXTU16(p) chainTable[(p) & MAXD_MASK] /* flexible, MAXD dependent */ 1072a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet#define DELTANEXTU16(p) chainTable[(U16)(p)] /* faster */ 108fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 109326cada9fadeedccef8934e11144f343ecdcabcbYann Colletstatic U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); } 110fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 111fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 112fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 113326cada9fadeedccef8934e11144f343ecdcabcbYann Collet/************************************** 1142a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* HC Compression 115326cada9fadeedccef8934e11144f343ecdcabcbYann Collet**************************************/ 11665ee6b09c4392814167e7a039d9312aabdb5119bYann Colletstatic void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start) 117fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 118fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable)); 119fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); 120e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet hc4->nextToUpdate = 64 KB; 12165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet hc4->base = start - 64 KB; 12265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet hc4->end = start; 12365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet hc4->dictBase = start - 64 KB; 124e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet hc4->dictLimit = 64 KB; 125e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet hc4->lowLimit = 64 KB; 126fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 127fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 128fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 12969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* Update chains up to ip (excluded) */ 130fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip) 131fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 132d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U16* chainTable = hc4->chainTable; 133d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32* HashTable = hc4->hashTable; 134d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet const BYTE* const base = hc4->base; 1353dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const U32 target = (U32)(ip - base); 136d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32 idx = hc4->nextToUpdate; 137fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 138d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet while(idx < target) 139fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 1403dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet U32 h = LZ4HC_hashPtr(base+idx); 141d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet size_t delta = idx - HashTable[h]; 142fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; 1432a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet DELTANEXTU16(idx) = (U16)delta; 144d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet HashTable[h] = idx; 145d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet idx++; 146fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 1477ac18ad9dc5a5555f9129659c007fe9141e422b0Yann Collet 148d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet hc4->nextToUpdate = target; 149fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 150fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 151fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 1528a9fb8cf3229c9a704c982667c63ac440b8487baYann ColletFORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* Index table will be updated */ 153508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE* ip, const BYTE* const iLimit, 154508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** matchpos, 155508855c48826aa0544a907f02b52515aabba5e16Yann Collet const int maxNbAttempts) 156fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 157fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. U16* const chainTable = hc4->chainTable; 158d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32* const HashTable = hc4->hashTable; 159d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet const BYTE* const base = hc4->base; 160e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet const BYTE* const dictBase = hc4->dictBase; 161e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet const U32 dictLimit = hc4->dictLimit; 162508855c48826aa0544a907f02b52515aabba5e16Yann Collet const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); 163e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet U32 matchIndex; 164d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet const BYTE* match; 16569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. int nbAttempts=maxNbAttempts; 166d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet size_t ml=0; 167fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 168508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* HC4 match finder */ 169fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. LZ4HC_Insert(hc4, ip); 1703dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet matchIndex = HashTable[LZ4HC_hashPtr(ip)]; 171fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 172e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet while ((matchIndex>=lowLimit) && (nbAttempts)) 173fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 174fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. nbAttempts--; 1753dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (matchIndex >= dictLimit) 176fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 1773dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet match = base + matchIndex; 1783dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (*(match+ml) == *(ip+ml) 179326cada9fadeedccef8934e11144f343ecdcabcbYann Collet && (LZ4_read32(match) == LZ4_read32(ip))) 1803dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet { 181326cada9fadeedccef8934e11144f343ecdcabcbYann Collet size_t mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH; 1823dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (mlt > ml) { ml = mlt; *matchpos = match; } 1833dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 1843dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 1853dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet else 1863dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet { 1873dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet match = dictBase + matchIndex; 188326cada9fadeedccef8934e11144f343ecdcabcbYann Collet if (LZ4_read32(match) == LZ4_read32(ip)) 1893dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet { 1903dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet size_t mlt; 1913dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const BYTE* vLimit = ip + (dictLimit - matchIndex); 1923dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (vLimit > iLimit) vLimit = iLimit; 193326cada9fadeedccef8934e11144f343ecdcabcbYann Collet mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH; 1943dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if ((ip+mlt == vLimit) && (vLimit < iLimit)) 195326cada9fadeedccef8934e11144f343ecdcabcbYann Collet mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit); 1968a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; } /* virtual matchpos */ 1973dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 198fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 1992a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet matchIndex -= DELTANEXTU16(matchIndex); 200fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 201fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 202fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return (int)ml; 203fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 204fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 205fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 206d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletFORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( 207508855c48826aa0544a907f02b52515aabba5e16Yann Collet LZ4HC_Data_Structure* hc4, 208002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const ip, 209002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const iLowLimit, 210002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const iHighLimit, 211508855c48826aa0544a907f02b52515aabba5e16Yann Collet int longest, 212508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** matchpos, 213508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** startpos, 214508855c48826aa0544a907f02b52515aabba5e16Yann Collet const int maxNbAttempts) 215fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 216d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U16* const chainTable = hc4->chainTable; 217d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32* const HashTable = hc4->hashTable; 218d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet const BYTE* const base = hc4->base; 2193dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const U32 dictLimit = hc4->dictLimit; 220002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const lowPrefixPtr = base + dictLimit; 221508855c48826aa0544a907f02b52515aabba5e16Yann Collet const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); 2223dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const BYTE* const dictBase = hc4->dictBase; 2233dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet U32 matchIndex; 22469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. int nbAttempts = maxNbAttempts; 2253dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet int delta = (int)(ip-iLowLimit); 226fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 227e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet 228508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* First Match */ 229fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. LZ4HC_Insert(hc4, ip); 2303dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet matchIndex = HashTable[LZ4HC_hashPtr(ip)]; 231fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 232e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet while ((matchIndex>=lowLimit) && (nbAttempts)) 233fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 234fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. nbAttempts--; 2353dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (matchIndex >= dictLimit) 236fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 237002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* matchPtr = base + matchIndex; 238002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) 239002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet if (LZ4_read32(matchPtr) == LZ4_read32(ip)) 240508855c48826aa0544a907f02b52515aabba5e16Yann Collet { 241002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit); 242002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet int back = 0; 243002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet 244002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet while ((ip+back>iLowLimit) 245002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet && (matchPtr+back > lowPrefixPtr) 246002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet && (ip[back-1] == matchPtr[back-1])) 247002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet back--; 248fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 249002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet mlt -= back; 250fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 251002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet if (mlt > longest) 252508855c48826aa0544a907f02b52515aabba5e16Yann Collet { 253002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet longest = (int)mlt; 254002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet *matchpos = matchPtr+back; 255002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet *startpos = ip+back; 256508855c48826aa0544a907f02b52515aabba5e16Yann Collet } 2573dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 2583dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 2593dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet else 2603dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet { 261002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* matchPtr = dictBase + matchIndex; 262002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet if (LZ4_read32(matchPtr) == LZ4_read32(ip)) 263fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 2643dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet size_t mlt; 265508855c48826aa0544a907f02b52515aabba5e16Yann Collet int back=0; 2663dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const BYTE* vLimit = ip + (dictLimit - matchIndex); 2673dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (vLimit > iHighLimit) vLimit = iHighLimit; 268002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet mlt = LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH; 2693dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if ((ip+mlt == vLimit) && (vLimit < iHighLimit)) 270326cada9fadeedccef8934e11144f343ecdcabcbYann Collet mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit); 271002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == matchPtr[back-1])) back--; 272508855c48826aa0544a907f02b52515aabba5e16Yann Collet mlt -= back; 2733dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; } 274fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 275fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 2762a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet matchIndex -= DELTANEXTU16(matchIndex); 277fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 278fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 279fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return longest; 280fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 281fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 282fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 283fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive; 284fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 2858a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#define LZ4HC_DEBUG 0 2868a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#if LZ4HC_DEBUG 2878a9fb8cf3229c9a704c982667c63ac440b8487baYann Colletstatic unsigned debug = 0; 2888a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#endif 289508855c48826aa0544a907f02b52515aabba5e16Yann Collet 290fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE int LZ4HC_encodeSequence ( 291508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** ip, 292508855c48826aa0544a907f02b52515aabba5e16Yann Collet BYTE** op, 293508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** anchor, 294508855c48826aa0544a907f02b52515aabba5e16Yann Collet int matchLength, 295508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE* const match, 296508855c48826aa0544a907f02b52515aabba5e16Yann Collet limitedOutput_directive limitedOutputBuffer, 297508855c48826aa0544a907f02b52515aabba5e16Yann Collet BYTE* oend) 298fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 299fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int length; 300fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* token; 301fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 3028a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#if LZ4HC_DEBUG 3038a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet if (debug) printf("literal : %u -- match : %u -- offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match)); 3048a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#endif 305e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet 30669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode Literal length */ 307fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. length = (int)(*ip - *anchor); 308fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. token = (*op)++; 309e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */ 310fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; } 311fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else *token = (BYTE)(length<<ML_BITS); 312fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 31369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Copy Literals */ 314326cada9fadeedccef8934e11144f343ecdcabcbYann Collet LZ4_wildCopy(*op, *anchor, (*op) + length); 315326cada9fadeedccef8934e11144f343ecdcabcbYann Collet *op += length; 316fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 31769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode Offset */ 318326cada9fadeedccef8934e11144f343ecdcabcbYann Collet LZ4_writeLE16(*op, (U16)(*ip-match)); *op += 2; 319fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 32069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode MatchLength */ 321fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. length = (int)(matchLength-MINMATCH); 322e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */ 323fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; } 324fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else *token += (BYTE)(length); 325fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 32669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Prepare next loop */ 327fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. *ip += matchLength; 328fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. *anchor = *ip; 329fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 330fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return 0; 331fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 332fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 333fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 334fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.static int LZ4HC_compress_generic ( 335508855c48826aa0544a907f02b52515aabba5e16Yann Collet void* ctxvoid, 336508855c48826aa0544a907f02b52515aabba5e16Yann Collet const char* source, 337508855c48826aa0544a907f02b52515aabba5e16Yann Collet char* dest, 338508855c48826aa0544a907f02b52515aabba5e16Yann Collet int inputSize, 339508855c48826aa0544a907f02b52515aabba5e16Yann Collet int maxOutputSize, 340508855c48826aa0544a907f02b52515aabba5e16Yann Collet int compressionLevel, 341508855c48826aa0544a907f02b52515aabba5e16Yann Collet limitedOutput_directive limit 342508855c48826aa0544a907f02b52515aabba5e16Yann Collet ) 343fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 344fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid; 345fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ip = (const BYTE*) source; 346fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* anchor = ip; 347fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const iend = ip + inputSize; 348fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const mflimit = iend - MFLIMIT; 349fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const matchlimit = (iend - LASTLITERALS); 350fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 351fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* op = (BYTE*) dest; 352fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* const oend = op + maxOutputSize; 353fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 354d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet unsigned maxNbAttempts; 355fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int ml, ml2, ml3, ml0; 356fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ref=NULL; 357fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* start2=NULL; 358fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ref2=NULL; 359fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* start3=NULL; 360fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ref3=NULL; 361fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* start0; 362fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ref0; 363fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 364fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 365d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet /* init */ 366c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet if (compressionLevel > g_maxCompressionLevel) compressionLevel = g_maxCompressionLevel; 367c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet if (compressionLevel < 1) compressionLevel = LZ4HC_compressionLevel_default; 368c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet maxNbAttempts = 1 << (compressionLevel-1); 369fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ctx->end += inputSize; 370fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 371fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip++; 372fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 37369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Main Loop */ 374fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. while (ip < mflimit) 375fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 37669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts); 377fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (!ml) { ip++; continue; } 378fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 37969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* saved, in case we would skip too much */ 380fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start0 = ip; 381fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref0 = ref; 382fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml0 = ml; 383fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 384fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search2: 385fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip+ml < mflimit) 38669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2, maxNbAttempts); 387fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else ml2 = ml; 388fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 38969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (ml2 == ml) /* No better match */ 390fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 391fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 392fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. continue; 393fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 394fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 395fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start0 < ip) 396fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 39769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (start2 < ip + ml0) /* empirical */ 398fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 399fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start0; 400fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref0; 401fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml0; 402fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 403fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 404fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 40569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Here, start0==ip */ 40669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if ((start2 - ip) < 3) /* First Match too small : removed */ 407fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 408fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml2; 409fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 410fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref =ref2; 411fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search2; 412fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 413fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 414fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search3: 41569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* 416508855c48826aa0544a907f02b52515aabba5e16Yann Collet * Currently we have : 417508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ml2 > ml1, and 418508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ip1+3 <= ip2 (usually < ip1+ml1) 419508855c48826aa0544a907f02b52515aabba5e16Yann Collet */ 420fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if ((start2 - ip) < OPTIMAL_ML) 421fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 422fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction; 423fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int new_ml = ml; 424fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; 425fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; 426fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. correction = new_ml - (int)(start2 - ip); 427fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (correction > 0) 428fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 429fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 430fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 431fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 432fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 433fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 43469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */ 435fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 436fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 + ml2 < mflimit) 43769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts); 438fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else ml3 = ml2; 439fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 44069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (ml3 == ml2) /* No better match : 2 sequences to encode */ 441fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 44269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* ip & ref are known; Now for ml */ 443fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 < ip+ml) ml = (int)(start2 - ip); 44469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Now, encode 2 sequences */ 445fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 446fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 447fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0; 448fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. continue; 449fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 450fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 45169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (start3 < ip+ml+3) /* Not enough space for match 2 : remove it */ 452fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 45369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (start3 >= (ip+ml)) /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ 454fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 455fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 < ip+ml) 456fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 457fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction = (int)(ip+ml - start2); 458fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 459fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 460fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 461fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ml2 < MINMATCH) 462fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 463fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 464fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 465fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 466fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 467fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 468fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 469fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 470fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start3; 471fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref3; 472fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml3; 473fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 474fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start0 = start2; 475fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref0 = ref2; 476fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml0 = ml2; 477fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search2; 478fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 479fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 480fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 481fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 482fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 483fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search3; 484fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 485fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 48669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* 487508855c48826aa0544a907f02b52515aabba5e16Yann Collet * OK, now we have 3 ascending matches; let's write at least the first one 488508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ip & ref are known; Now for ml 489508855c48826aa0544a907f02b52515aabba5e16Yann Collet */ 490fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 < ip+ml) 491fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 492fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if ((start2 - ip) < (int)ML_MASK) 493fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 494fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction; 495fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; 496fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; 497fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. correction = ml - (int)(start2 - ip); 498fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (correction > 0) 499fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 500fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 501fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 502fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 503fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 504fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 505fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else 506fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 507fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = (int)(start2 - ip); 508fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 509fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 510fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 511fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 512fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 513fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref2; 514fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml2; 515fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 516fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 517fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 518fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 519fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 520fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search3; 521fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 522fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 52369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode Last Literals */ 524fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. { 525fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int lastRun = (int)(iend - anchor); 52669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ 527fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 528fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else *op++ = (BYTE)(lastRun<<ML_BITS); 529fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. memcpy(op, anchor, iend - anchor); 530fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. op += iend-anchor; 531fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 532fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 53369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* End */ 534fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return (int) (((char*)op)-dest); 535fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 536fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 537fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 538e2a985f52444ad2e1438d2a71575185f31a08540Yann Colletint LZ4_sizeofStateHC(void) { return sizeof(LZ4HC_Data_Structure); } 539fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 540e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) 541fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 54269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */ 543e05088d0eb500d8d673e081929620e538df3d718Yann Collet LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)src); 544e05088d0eb500d8d673e081929620e538df3d718Yann Collet if (maxDstSize < LZ4_compressBound(srcSize)) 545e05088d0eb500d8d673e081929620e538df3d718Yann Collet return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput); 546be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet else 547e05088d0eb500d8d673e081929620e538df3d718Yann Collet return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, noLimit); 548fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 549fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 550e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) 551fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 552be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet LZ4HC_Data_Structure state; 553e05088d0eb500d8d673e081929620e538df3d718Yann Collet return LZ4_compress_HC_extStateHC(&state, src, dst, srcSize, maxDstSize, compressionLevel); 554fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 555fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 556fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 55765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet 558d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/************************************** 5592a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Streaming Functions 5602a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet**************************************/ 561d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* allocation */ 562d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletLZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); } 563be9d248851ecd712a8911526b009c5d0c948ee21Yann Colletint LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; } 564fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 565d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 566d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* initialization */ 567d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletvoid LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) 568fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 569a357f434f06de70e5d670b8669becccb09f4c7a6Yann Collet LZ4_STATIC_ASSERT(sizeof(LZ4HC_Data_Structure) <= sizeof(LZ4_streamHC_t)); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ 570d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->base = NULL; 571d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->compressionLevel = (unsigned)compressionLevel; 57269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 57369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 574d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize) 57569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ 57665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet LZ4HC_Data_Structure* ctxPtr = (LZ4HC_Data_Structure*) LZ4_streamHCPtr; 57761289dea1d94510a4d6386bc44c08d3d15083123Yann Collet if (dictSize > 64 KB) 57861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet { 57961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet dictionary += dictSize - 64 KB; 58061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet dictSize = 64 KB; 58161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet } 58265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet LZ4HC_init (ctxPtr, (const BYTE*)dictionary); 58365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if (dictSize >= 4) LZ4HC_Insert (ctxPtr, (const BYTE*)dictionary +(dictSize-3)); 58465ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->end = (const BYTE*)dictionary + dictSize; 58561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet return dictSize; 586d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 587d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 588d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 589d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* compression */ 590d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 59165ee6b09c4392814167e7a039d9312aabdb5119bYann Colletstatic void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newBlock) 59265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet{ 59365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if (ctxPtr->end >= ctxPtr->base + 4) 59465ee6b09c4392814167e7a039d9312aabdb5119bYann Collet LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */ 59565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet /* Only one memory segment for extDict, so any previous extDict is lost at this stage */ 59665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->lowLimit = ctxPtr->dictLimit; 59765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base); 59865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->dictBase = ctxPtr->base; 59965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->base = newBlock - ctxPtr->dictLimit; 60065ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->end = newBlock; 60165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ 60265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet} 60365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet 60465ee6b09c4392814167e7a039d9312aabdb5119bYann Colletstatic int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* ctxPtr, 605e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet const char* source, char* dest, 606e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet int inputSize, int maxOutputSize, limitedOutput_directive limit) 607e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet{ 608e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet /* auto-init if forgotten */ 60965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if (ctxPtr->base == NULL) 61065ee6b09c4392814167e7a039d9312aabdb5119bYann Collet LZ4HC_init (ctxPtr, (const BYTE*) source); 611e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 612508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check overflow */ 61365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) 614508855c48826aa0544a907f02b52515aabba5e16Yann Collet { 61565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit; 616508855c48826aa0544a907f02b52515aabba5e16Yann Collet if (dictSize > 64 KB) dictSize = 64 KB; 617508855c48826aa0544a907f02b52515aabba5e16Yann Collet 61865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet LZ4_loadDictHC((LZ4_streamHC_t*)ctxPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize); 619508855c48826aa0544a907f02b52515aabba5e16Yann Collet } 620508855c48826aa0544a907f02b52515aabba5e16Yann Collet 621508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check if blocks follow each other */ 622d6dc0a410d0be93551f247eeb871603d2db11c17Yann Collet if ((const BYTE*)source != ctxPtr->end) 623d6dc0a410d0be93551f247eeb871603d2db11c17Yann Collet LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source); 624e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 625508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check overlapping input/dictionary space */ 626e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet { 627e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet const BYTE* sourceEnd = (const BYTE*) source + inputSize; 62865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet const BYTE* dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; 62965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet const BYTE* dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; 6301c3e633c48766c58df949887297dc5838170a33fYann Collet if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd)) 631e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet { 6322b421e97d4e7cfbefdc007bf30133b0de7e7e14eYann Collet if (sourceEnd > dictEnd) sourceEnd = dictEnd; 63365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase); 63465ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit; 635e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet } 636e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet } 637e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 63865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit); 639e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet} 640e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 641e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize) 642d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 643be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet if (maxOutputSize < LZ4_compressBound(inputSize)) 644be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput); 645be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet else 646be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit); 647d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 648d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 649d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 650d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* dictionary saving */ 651d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 652d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize) 653d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 65461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*)LZ4_streamHCPtr; 65561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet int prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); 656d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet if (dictSize > 64 KB) dictSize = 64 KB; 65761289dea1d94510a4d6386bc44c08d3d15083123Yann Collet if (dictSize < 4) dictSize = 0; 65861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet if (dictSize > prefixSize) dictSize = prefixSize; 65981fdd9df23821d5db8331e66478e2617b470820cYann Collet memmove(safeBuffer, streamPtr->end - dictSize, dictSize); 66061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet { 66161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet U32 endIndex = (U32)(streamPtr->end - streamPtr->base); 66261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->end = (const BYTE*)safeBuffer + dictSize; 66361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->base = streamPtr->end - endIndex; 66461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->dictLimit = endIndex - dictSize; 66561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->lowLimit = endIndex - dictSize; 66695cc6cef6444b202a93ba414b7a9996eb2c72ca3Yann Collet if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit; 66761289dea1d94510a4d6386bc44c08d3d15083123Yann Collet } 668d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return dictSize; 669fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 670fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 671d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 672d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/*********************************** 6732a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Deprecated Functions 6742a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet***********************************/ 675be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated compression functions */ 676b805d581b97be95fcc000134a54aa7c591b3ef09Yann Collet/* These functions are planned to start generate warnings by r131 approximately */ 677e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); } 678e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); } 679e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } 680e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); } 681e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_withStateHC (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_HC_extStateHC (state, src, dst, srcSize, LZ4_compressBound(srcSize), 0); } 682e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_extStateHC (state, src, dst, srcSize, maxDstSize, 0); } 683e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2_withStateHC (void* state, const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } 684e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2_limitedOutput_withStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, maxDstSize, cLevel); } 685e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_continue (LZ4_streamHC_t* ctx, const char* src, char* dst, int srcSize) { return LZ4_compress_HC_continue (ctx, src, dst, srcSize, LZ4_compressBound(srcSize)); } 686e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_continue (ctx, src, dst, srcSize, maxDstSize); } 687be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet 688be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet 689be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated streaming functions */ 690e05088d0eb500d8d673e081929620e538df3d718Yann Collet/* These functions currently generate deprecation warnings */ 691d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; } 692d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 6931c3e633c48766c58df949887297dc5838170a33fYann Colletint LZ4_resetStreamStateHC(void* state, char* inputBuffer) 694d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 695d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */ 696d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet LZ4HC_init((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer); 6971c3e633c48766c58df949887297dc5838170a33fYann Collet ((LZ4HC_Data_Structure*)state)->inputBuffer = (BYTE*)inputBuffer; 698d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return 0; 699d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 700d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 7011c3e633c48766c58df949887297dc5838170a33fYann Colletvoid* LZ4_createHC (char* inputBuffer) 702d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 703326cada9fadeedccef8934e11144f343ecdcabcbYann Collet void* hc4 = ALLOCATOR(1, sizeof(LZ4HC_Data_Structure)); 704d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet LZ4HC_init ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer); 7051c3e633c48766c58df949887297dc5838170a33fYann Collet ((LZ4HC_Data_Structure*)hc4)->inputBuffer = (BYTE*)inputBuffer; 706d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return hc4; 707d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 708d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 709d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_freeHC (void* LZ4HC_Data) 710d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 711d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet FREEMEM(LZ4HC_Data); 712d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return (0); 713d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 714d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 715d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel) 716d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 717d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel, noLimit); 718d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 719fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 72069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel) 72169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ 72269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput); 72369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 724d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 725d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletchar* LZ4_slideInputBufferHC(void* LZ4HC_Data) 726d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 727d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data; 72865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet int dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB); 72965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet return (char*)(hc4->inputBuffer + dictSize); 730d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 731