lz4hc.c revision 84b97f90b81195590700fb791b83165d9e8cc1cd
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 : 3184cedb4632ab87fbb108b4f7ed6e9ec164b6a4d4Przemyslaw Skibinski - LZ4 source repository : https://github.com/lz4/lz4 322a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 33fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.*/ 3494542d845884c922f809725807ecbd2cf7454aceYann Collet/* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */ 3569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 3669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 372c80138121550c719cb0a622f6a8a304d283960cYann Collet/* ************************************* 382a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Tuning Parameter 392c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/ 4069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 412c80138121550c719cb0a622f6a8a304d283960cYann Collet/*! 422c80138121550c719cb0a622f6a8a304d283960cYann Collet * HEAPMODE : 432c80138121550c719cb0a622f6a8a304d283960cYann Collet * Select how default compression function will allocate workplace memory, 442c80138121550c719cb0a622f6a8a304d283960cYann Collet * in stack (0:fastest), or in heap (1:requires malloc()). 452c80138121550c719cb0a622f6a8a304d283960cYann Collet * Since workplace is rather large, heap mode is recommended. 462c80138121550c719cb0a622f6a8a304d283960cYann Collet */ 4794542d845884c922f809725807ecbd2cf7454aceYann Collet#ifndef LZ4HC_HEAPMODE 4894542d845884c922f809725807ecbd2cf7454aceYann Collet# define LZ4HC_HEAPMODE 1 4994542d845884c922f809725807ecbd2cf7454aceYann Collet#endif 5069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 512c80138121550c719cb0a622f6a8a304d283960cYann Collet 522c80138121550c719cb0a622f6a8a304d283960cYann Collet/* ************************************* 5394542d845884c922f809725807ecbd2cf7454aceYann Collet* Dependency 542c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/ 5533dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet#include "lz4hc.h" 56fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 57fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 582c80138121550c719cb0a622f6a8a304d283960cYann Collet/* ************************************* 592a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Local Compiler Options 602c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/ 61326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#if defined(__GNUC__) 62326cada9fadeedccef8934e11144f343ecdcabcbYann Collet# pragma GCC diagnostic ignored "-Wunused-function" 63fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif 64fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 65326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#if defined (__clang__) 66326cada9fadeedccef8934e11144f343ecdcabcbYann Collet# pragma clang diagnostic ignored "-Wunused-function" 67fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif 68fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 69fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 702c80138121550c719cb0a622f6a8a304d283960cYann Collet/* ************************************* 712a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Common LZ4 definition 722c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/ 73326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#define LZ4_COMMONDEFS_ONLY 74326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#include "lz4.c" 75fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 76fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 772c80138121550c719cb0a622f6a8a304d283960cYann Collet/* ************************************* 782a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Local Constants 792c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/ 80fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH) 81fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 82fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 8369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./************************************** 842a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Local Macros 8569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/ 8685aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG)) 8785aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell/* #define DELTANEXTU16(p) chainTable[(p) & LZ4HC_MAXD_MASK] */ /* flexible, LZ4HC_MAXD dependent */ 882a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet#define DELTANEXTU16(p) chainTable[(U16)(p)] /* faster */ 89fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 90326cada9fadeedccef8934e11144f343ecdcabcbYann Colletstatic U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); } 91fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 92fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 93fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 94326cada9fadeedccef8934e11144f343ecdcabcbYann Collet/************************************** 952a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* HC Compression 96326cada9fadeedccef8934e11144f343ecdcabcbYann Collet**************************************/ 97874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Colletstatic void LZ4HC_init (LZ4HC_CCtx_internal* hc4, const BYTE* start) 98fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 99fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable)); 100fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); 101e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet hc4->nextToUpdate = 64 KB; 10265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet hc4->base = start - 64 KB; 10365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet hc4->end = start; 10465ee6b09c4392814167e7a039d9312aabdb5119bYann Collet hc4->dictBase = start - 64 KB; 105e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet hc4->dictLimit = 64 KB; 106e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet hc4->lowLimit = 64 KB; 107fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 108fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 109fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 11069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* Update chains up to ip (excluded) */ 111874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann ColletFORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE* ip) 112fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 1135871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet U16* const chainTable = hc4->chainTable; 1145871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet U32* const hashTable = hc4->hashTable; 115d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet const BYTE* const base = hc4->base; 1165871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet U32 const target = (U32)(ip - base); 117d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32 idx = hc4->nextToUpdate; 118fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 1195871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet while (idx < target) { 1205871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet U32 const h = LZ4HC_hashPtr(base+idx); 1215871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet size_t delta = idx - hashTable[h]; 122fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; 1232a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet DELTANEXTU16(idx) = (U16)delta; 1245871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet hashTable[h] = idx; 125d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet idx++; 126fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 1277ac18ad9dc5a5555f9129659c007fe9141e422b0Yann Collet 128d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet hc4->nextToUpdate = target; 129fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 130fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 131fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 132874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann ColletFORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_CCtx_internal* hc4, /* Index table will be updated */ 133508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE* ip, const BYTE* const iLimit, 134508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** matchpos, 135508855c48826aa0544a907f02b52515aabba5e16Yann Collet const int maxNbAttempts) 136fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 137fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. U16* const chainTable = hc4->chainTable; 138d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32* const HashTable = hc4->hashTable; 139d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet const BYTE* const base = hc4->base; 140e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet const BYTE* const dictBase = hc4->dictBase; 141e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet const U32 dictLimit = hc4->dictLimit; 142508855c48826aa0544a907f02b52515aabba5e16Yann Collet const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); 143e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet U32 matchIndex; 14469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. int nbAttempts=maxNbAttempts; 145d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet size_t ml=0; 146fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 147508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* HC4 match finder */ 148fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. LZ4HC_Insert(hc4, ip); 1493dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet matchIndex = HashTable[LZ4HC_hashPtr(ip)]; 150fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 1515871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet while ((matchIndex>=lowLimit) && (nbAttempts)) { 152fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. nbAttempts--; 1535871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (matchIndex >= dictLimit) { 15494542d845884c922f809725807ecbd2cf7454aceYann Collet const BYTE* const match = base + matchIndex; 1553dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (*(match+ml) == *(ip+ml) 156326cada9fadeedccef8934e11144f343ecdcabcbYann Collet && (LZ4_read32(match) == LZ4_read32(ip))) 1573dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet { 1585871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet size_t const mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH; 1593dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (mlt > ml) { ml = mlt; *matchpos = match; } 1603dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 1615871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet } else { 16294542d845884c922f809725807ecbd2cf7454aceYann Collet const BYTE* const match = dictBase + matchIndex; 1635871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (LZ4_read32(match) == LZ4_read32(ip)) { 1643dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet size_t mlt; 1653dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const BYTE* vLimit = ip + (dictLimit - matchIndex); 1663dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (vLimit > iLimit) vLimit = iLimit; 167326cada9fadeedccef8934e11144f343ecdcabcbYann Collet mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH; 1683dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if ((ip+mlt == vLimit) && (vLimit < iLimit)) 169326cada9fadeedccef8934e11144f343ecdcabcbYann Collet mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit); 1708a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; } /* virtual matchpos */ 1713dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 172fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 1732a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet matchIndex -= DELTANEXTU16(matchIndex); 174fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 175fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 176fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return (int)ml; 177fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 178fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 179fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 180d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletFORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( 181874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* hc4, 182002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const ip, 183002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const iLowLimit, 184002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const iHighLimit, 185508855c48826aa0544a907f02b52515aabba5e16Yann Collet int longest, 186508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** matchpos, 187508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** startpos, 188508855c48826aa0544a907f02b52515aabba5e16Yann Collet const int maxNbAttempts) 189fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 190d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U16* const chainTable = hc4->chainTable; 191d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet U32* const HashTable = hc4->hashTable; 192d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet const BYTE* const base = hc4->base; 1933dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const U32 dictLimit = hc4->dictLimit; 194002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* const lowPrefixPtr = base + dictLimit; 195508855c48826aa0544a907f02b52515aabba5e16Yann Collet const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); 1963dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const BYTE* const dictBase = hc4->dictBase; 1973dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet U32 matchIndex; 19869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. int nbAttempts = maxNbAttempts; 1993dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet int delta = (int)(ip-iLowLimit); 200fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 201e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet 202508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* First Match */ 203fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. LZ4HC_Insert(hc4, ip); 2043dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet matchIndex = HashTable[LZ4HC_hashPtr(ip)]; 205fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 2065871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet while ((matchIndex>=lowLimit) && (nbAttempts)) { 207fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. nbAttempts--; 2085871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (matchIndex >= dictLimit) { 209002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet const BYTE* matchPtr = base + matchIndex; 2105871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) { 2115871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (LZ4_read32(matchPtr) == LZ4_read32(ip)) { 212002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit); 213002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet int back = 0; 214002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet 2155871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet while ((ip+back > iLowLimit) 216002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet && (matchPtr+back > lowPrefixPtr) 217002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet && (ip[back-1] == matchPtr[back-1])) 218002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet back--; 219fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 220002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet mlt -= back; 221fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 2225871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (mlt > longest) { 223002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet longest = (int)mlt; 224002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet *matchpos = matchPtr+back; 225002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet *startpos = ip+back; 226508855c48826aa0544a907f02b52515aabba5e16Yann Collet } 2273dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet } 2285871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet } 2295871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet } else { 230258a5e7fa44825488fe4683f3a04c36fc944a23fYann Collet const BYTE* const matchPtr = dictBase + matchIndex; 2315871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (LZ4_read32(matchPtr) == LZ4_read32(ip)) { 2323dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet size_t mlt; 233508855c48826aa0544a907f02b52515aabba5e16Yann Collet int back=0; 2343dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet const BYTE* vLimit = ip + (dictLimit - matchIndex); 2353dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if (vLimit > iHighLimit) vLimit = iHighLimit; 236002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet mlt = LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH; 2373dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if ((ip+mlt == vLimit) && (vLimit < iHighLimit)) 238326cada9fadeedccef8934e11144f343ecdcabcbYann Collet mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit); 239002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == matchPtr[back-1])) back--; 240508855c48826aa0544a907f02b52515aabba5e16Yann Collet mlt -= back; 2413dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; } 242fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 243fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 2442a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet matchIndex -= DELTANEXTU16(matchIndex); 245fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 246fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 247fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return longest; 248fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 249fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 250fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 251fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive; 252fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 2538a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#define LZ4HC_DEBUG 0 2548a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#if LZ4HC_DEBUG 2558a9fb8cf3229c9a704c982667c63ac440b8487baYann Colletstatic unsigned debug = 0; 2568a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#endif 257508855c48826aa0544a907f02b52515aabba5e16Yann Collet 258fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE int LZ4HC_encodeSequence ( 259508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** ip, 260508855c48826aa0544a907f02b52515aabba5e16Yann Collet BYTE** op, 261508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE** anchor, 262508855c48826aa0544a907f02b52515aabba5e16Yann Collet int matchLength, 263508855c48826aa0544a907f02b52515aabba5e16Yann Collet const BYTE* const match, 264508855c48826aa0544a907f02b52515aabba5e16Yann Collet limitedOutput_directive limitedOutputBuffer, 265508855c48826aa0544a907f02b52515aabba5e16Yann Collet BYTE* oend) 266fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 267fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int length; 268fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* token; 269fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 2708a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#if LZ4HC_DEBUG 2718a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet if (debug) printf("literal : %u -- match : %u -- offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match)); 2728a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#endif 273e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet 27469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode Literal length */ 275fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. length = (int)(*ip - *anchor); 276fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. token = (*op)++; 277e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */ 278fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.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; } 279fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else *token = (BYTE)(length<<ML_BITS); 280fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 28169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Copy Literals */ 282326cada9fadeedccef8934e11144f343ecdcabcbYann Collet LZ4_wildCopy(*op, *anchor, (*op) + length); 283326cada9fadeedccef8934e11144f343ecdcabcbYann Collet *op += length; 284fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 28569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode Offset */ 286326cada9fadeedccef8934e11144f343ecdcabcbYann Collet LZ4_writeLE16(*op, (U16)(*ip-match)); *op += 2; 287fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 28869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode MatchLength */ 289fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. length = (int)(matchLength-MINMATCH); 290e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */ 29164f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet if (length>=(int)ML_MASK) { 29264f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet *token += ML_MASK; 29364f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet length -= ML_MASK; 29464f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } 29564f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet if (length > 254) { length-=255; *(*op)++ = 255; } 29664f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet *(*op)++ = (BYTE)length; 29764f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet } else { 29864f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet *token += (BYTE)(length); 29964f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet } 300fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 30169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Prepare next loop */ 302fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. *ip += matchLength; 303fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. *anchor = *ip; 304fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 305fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return 0; 306fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 307fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 308fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 309fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.static int LZ4HC_compress_generic ( 310874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* const ctx, 311c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet const char* const source, 312c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet char* const dest, 313c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet int const inputSize, 314c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet int const maxOutputSize, 315508855c48826aa0544a907f02b52515aabba5e16Yann Collet int compressionLevel, 316508855c48826aa0544a907f02b52515aabba5e16Yann Collet limitedOutput_directive limit 317508855c48826aa0544a907f02b52515aabba5e16Yann Collet ) 318fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 319fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ip = (const BYTE*) source; 320fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* anchor = ip; 321fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const iend = ip + inputSize; 322fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const mflimit = iend - MFLIMIT; 323fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const matchlimit = (iend - LASTLITERALS); 324fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 325fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* op = (BYTE*) dest; 326fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* const oend = op + maxOutputSize; 327fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 328d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet unsigned maxNbAttempts; 329fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int ml, ml2, ml3, ml0; 3305871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* ref = NULL; 3315871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* start2 = NULL; 3325871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* ref2 = NULL; 3335871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* start3 = NULL; 3345871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* ref3 = NULL; 335fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* start0; 336fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ref0; 337fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 338d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet /* init */ 3392cf32ef0f107d18c9779283b8bd1d56f0517dd39inikep if (compressionLevel > LZ4HC_MAX_CLEVEL) compressionLevel = LZ4HC_MAX_CLEVEL; 3402cf32ef0f107d18c9779283b8bd1d56f0517dd39inikep if (compressionLevel < 1) compressionLevel = LZ4HC_DEFAULT_CLEVEL; 341c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet maxNbAttempts = 1 << (compressionLevel-1); 342fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ctx->end += inputSize; 343fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 344fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip++; 345fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 34669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Main Loop */ 3475871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet while (ip < mflimit) { 34869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts); 349fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (!ml) { ip++; continue; } 350fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 35169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* saved, in case we would skip too much */ 352fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start0 = ip; 353fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref0 = ref; 354fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml0 = ml; 355fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 356fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search2: 357fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip+ml < mflimit) 358c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 0, matchlimit, ml, &ref2, &start2, maxNbAttempts); 359fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else ml2 = ml; 360fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 3615871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ml2 == ml) { /* No better match */ 362fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 363fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. continue; 364fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 365fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 3665871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start0 < ip) { 3675871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start2 < ip + ml0) { /* empirical */ 368fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start0; 369fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref0; 370fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml0; 371fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 372fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 373fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 37469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Here, start0==ip */ 3755871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((start2 - ip) < 3) { /* First Match too small : removed */ 376fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml2; 377fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 378fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref =ref2; 379fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search2; 380fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 381fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 382fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search3: 38369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* 384508855c48826aa0544a907f02b52515aabba5e16Yann Collet * Currently we have : 385508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ml2 > ml1, and 386508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ip1+3 <= ip2 (usually < ip1+ml1) 387508855c48826aa0544a907f02b52515aabba5e16Yann Collet */ 3885871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((start2 - ip) < OPTIMAL_ML) { 389fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction; 390fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int new_ml = ml; 391fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; 392fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; 393fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. correction = new_ml - (int)(start2 - ip); 3945871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (correction > 0) { 395fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 396fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 397fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 398fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 399fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 40069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */ 401fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 402fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 + ml2 < mflimit) 40369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts); 404fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else ml3 = ml2; 405fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 4065871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ml3 == ml2) { /* No better match : 2 sequences to encode */ 40769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* ip & ref are known; Now for ml */ 408fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 < ip+ml) ml = (int)(start2 - ip); 40969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Now, encode 2 sequences */ 410fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 411fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 412fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0; 413fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. continue; 414fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 415fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 4165871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start3 < ip+ml+3) { /* Not enough space for match 2 : remove it */ 4175871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start3 >= (ip+ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ 4185871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start2 < ip+ml) { 419fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction = (int)(ip+ml - start2); 420fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 421fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 422fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 4235871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ml2 < MINMATCH) { 424fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 425fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 426fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 427fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 428fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 429fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 430fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 431fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start3; 432fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref3; 433fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml3; 434fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 435fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start0 = start2; 436fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref0 = ref2; 437fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml0 = ml2; 438fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search2; 439fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 440fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 441fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 442fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 443fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 444fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search3; 445fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 446fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 44769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* 448508855c48826aa0544a907f02b52515aabba5e16Yann Collet * OK, now we have 3 ascending matches; let's write at least the first one 449508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ip & ref are known; Now for ml 450508855c48826aa0544a907f02b52515aabba5e16Yann Collet */ 4515871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start2 < ip+ml) { 4525871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((start2 - ip) < (int)ML_MASK) { 453fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction; 454fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; 455fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; 456fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. correction = ml - (int)(start2 - ip); 4575871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (correction > 0) { 458fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 459fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 460fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 461fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 4625871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet } else { 463fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = (int)(start2 - ip); 464fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 465fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 466fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 467fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 468fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 469fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref2; 470fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml2; 471fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 472fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 473fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 474fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 475fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 476fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search3; 477fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 478fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 47969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode Last Literals */ 4805871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet { int lastRun = (int)(iend - anchor); 48169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ 482fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 483fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else *op++ = (BYTE)(lastRun<<ML_BITS); 484fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. memcpy(op, anchor, iend - anchor); 485fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. op += iend-anchor; 486fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 487fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 48869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* End */ 489fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return (int) (((char*)op)-dest); 490fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 491fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 492fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 49394542d845884c922f809725807ecbd2cf7454aceYann Colletint LZ4_sizeofStateHC(void) { return sizeof(LZ4_streamHC_t); } 494fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 495e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) 496fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 497874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; 49869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */ 49985aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4HC_init (ctx, (const BYTE*)src); 500e05088d0eb500d8d673e081929620e538df3d718Yann Collet if (maxDstSize < LZ4_compressBound(srcSize)) 50185aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput); 502be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet else 50385aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, noLimit); 504fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 505fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 506e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) 507fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 50894542d845884c922f809725807ecbd2cf7454aceYann Collet#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 50984b97f90b81195590700fb791b83165d9e8cc1cdYann Collet LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); 5102c80138121550c719cb0a622f6a8a304d283960cYann Collet#else 51185aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHC_t state; 51285aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHC_t* const statePtr = &state; 5132c80138121550c719cb0a622f6a8a304d283960cYann Collet#endif 51494542d845884c922f809725807ecbd2cf7454aceYann Collet int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, maxDstSize, compressionLevel); 51594542d845884c922f809725807ecbd2cf7454aceYann Collet#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 5162c80138121550c719cb0a622f6a8a304d283960cYann Collet free(statePtr); 5172c80138121550c719cb0a622f6a8a304d283960cYann Collet#endif 5182c80138121550c719cb0a622f6a8a304d283960cYann Collet return cSize; 519fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 520fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 521fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 52265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet 523d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/************************************** 5242a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Streaming Functions 5252a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet**************************************/ 526d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* allocation */ 527d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletLZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); } 528be9d248851ecd712a8911526b009c5d0c948ee21Yann Colletint LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; } 529fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 530d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 531d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* initialization */ 532d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletvoid LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) 533fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 534874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= sizeof(size_t) * LZ4_STREAMHCSIZE_SIZET); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ 53585aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHCPtr->internal_donotuse.base = NULL; 53685aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHCPtr->internal_donotuse.compressionLevel = (unsigned)compressionLevel; 53769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 53869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 539d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize) 54069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ 541874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse; 5425871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (dictSize > 64 KB) { 54361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet dictionary += dictSize - 64 KB; 54461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet dictSize = 64 KB; 54561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet } 54665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet LZ4HC_init (ctxPtr, (const BYTE*)dictionary); 54765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if (dictSize >= 4) LZ4HC_Insert (ctxPtr, (const BYTE*)dictionary +(dictSize-3)); 54865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->end = (const BYTE*)dictionary + dictSize; 54961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet return dictSize; 550d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 551d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 552d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 553d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* compression */ 554d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 555874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Colletstatic void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock) 55665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet{ 5575871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ctxPtr->end >= ctxPtr->base + 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */ 55865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet /* Only one memory segment for extDict, so any previous extDict is lost at this stage */ 55965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->lowLimit = ctxPtr->dictLimit; 56065ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base); 56165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->dictBase = ctxPtr->base; 56265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->base = newBlock - ctxPtr->dictLimit; 56365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->end = newBlock; 56465ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ 56565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet} 56665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet 56785aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrellstatic int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr, 568e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet const char* source, char* dest, 569e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet int inputSize, int maxOutputSize, limitedOutput_directive limit) 570e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet{ 571874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse; 572e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet /* auto-init if forgotten */ 5735871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ctxPtr->base == NULL) LZ4HC_init (ctxPtr, (const BYTE*) source); 574e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 575508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check overflow */ 5765871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) { 57765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit; 578508855c48826aa0544a907f02b52515aabba5e16Yann Collet if (dictSize > 64 KB) dictSize = 64 KB; 57985aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize); 580508855c48826aa0544a907f02b52515aabba5e16Yann Collet } 581508855c48826aa0544a907f02b52515aabba5e16Yann Collet 582508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check if blocks follow each other */ 5835871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((const BYTE*)source != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source); 584e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 585508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check overlapping input/dictionary space */ 5865871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet { const BYTE* sourceEnd = (const BYTE*) source + inputSize; 5875871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; 5885871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; 5895871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd)) { 5902b421e97d4e7cfbefdc007bf30133b0de7e7e14eYann Collet if (sourceEnd > dictEnd) sourceEnd = dictEnd; 59165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase); 59265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit; 593e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet } 594e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet } 595e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 59665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit); 597e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet} 598e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 599e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize) 600d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 601be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet if (maxOutputSize < LZ4_compressBound(inputSize)) 60285aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput); 603be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet else 60485aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit); 605d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 606d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 607d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 608d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* dictionary saving */ 609d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 610d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize) 611d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 612874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse; 6135871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); 614d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet if (dictSize > 64 KB) dictSize = 64 KB; 61561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet if (dictSize < 4) dictSize = 0; 61661289dea1d94510a4d6386bc44c08d3d15083123Yann Collet if (dictSize > prefixSize) dictSize = prefixSize; 61781fdd9df23821d5db8331e66478e2617b470820cYann Collet memmove(safeBuffer, streamPtr->end - dictSize, dictSize); 6185871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet { U32 const endIndex = (U32)(streamPtr->end - streamPtr->base); 61961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->end = (const BYTE*)safeBuffer + dictSize; 62061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->base = streamPtr->end - endIndex; 62161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->dictLimit = endIndex - dictSize; 62261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->lowLimit = endIndex - dictSize; 62395cc6cef6444b202a93ba414b7a9996eb2c72ca3Yann Collet if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit; 62461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet } 625d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return dictSize; 626fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 627fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 628d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 629d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/*********************************** 6302a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Deprecated Functions 6312a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet***********************************/ 63294542d845884c922f809725807ecbd2cf7454aceYann Collet/* These functions currently generate deprecation warnings */ 633be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated compression functions */ 634e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); } 635e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); } 636e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } 637e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); } 638e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 639e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 640e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 641e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 642e05088d0eb500d8d673e081929620e538df3d718Yann 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)); } 643e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 644be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet 645be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet 646be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated streaming functions */ 647d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; } 648d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 6491c3e633c48766c58df949887297dc5838170a33fYann Colletint LZ4_resetStreamStateHC(void* state, char* inputBuffer) 650d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 651874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal *ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; 652d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */ 65385aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4HC_init(ctx, (const BYTE*)inputBuffer); 65485aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell ctx->inputBuffer = (BYTE*)inputBuffer; 655d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return 0; 656d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 657d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 6581c3e633c48766c58df949887297dc5838170a33fYann Colletvoid* LZ4_createHC (char* inputBuffer) 659d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 66085aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHC_t* hc4 = (LZ4_streamHC_t*)ALLOCATOR(1, sizeof(LZ4_streamHC_t)); 661aa1350e1399c808d2de83668249fff83fe70a24eYann Collet if (hc4 == NULL) return NULL; /* not enough memory */ 66285aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4HC_init (&hc4->internal_donotuse, (const BYTE*)inputBuffer); 66385aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell hc4->internal_donotuse.inputBuffer = (BYTE*)inputBuffer; 664d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return hc4; 665d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 666d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 66794542d845884c922f809725807ecbd2cf7454aceYann Colletint LZ4_freeHC (void* LZ4HC_Data) { FREEMEM(LZ4HC_Data); return 0; } 668d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 669d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel) 670d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 67185aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, 0, compressionLevel, noLimit); 672d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 673fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 67469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel) 67569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ 67685aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput); 67769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 678d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 679d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletchar* LZ4_slideInputBufferHC(void* LZ4HC_Data) 680d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 68194542d845884c922f809725807ecbd2cf7454aceYann Collet LZ4HC_CCtx_internal* const hc4 = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse; 68294542d845884c922f809725807ecbd2cf7454aceYann Collet int const dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB); 68365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet return (char*)(hc4->inputBuffer + dictSize); 684d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 685