1fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet./* 22a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet LZ4 HC - High Compression Mode of LZ4 38b233b228dbda484d1d545c5a3ecaf06aef3e930Yann Collet Copyright (C) 2011-2016, 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)) 871833be1cf0e545f8b24bb4a786e274a9e419e280Przemyslaw Skibinski#define DELTANEXTMAXD(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)); 101312d88249feee4c1b7511ac9fffce10ed6802ba7Przemyslaw Skibinski 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. 308c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski#include "lz4opt.h" 309fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 310c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinskistatic int LZ4HC_compress_hashChain ( 311874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* const ctx, 312c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet const char* const source, 313c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet char* const dest, 314c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet int const inputSize, 315c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet int const maxOutputSize, 316e3fee94742f9027aa2d27fae6458ce285889552ePrzemyslaw Skibinski unsigned maxNbAttempts, 317508855c48826aa0544a907f02b52515aabba5e16Yann Collet limitedOutput_directive limit 318508855c48826aa0544a907f02b52515aabba5e16Yann Collet ) 319fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 320fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* ip = (const BYTE*) source; 321fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* anchor = ip; 322fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const iend = ip + inputSize; 323fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const mflimit = iend - MFLIMIT; 324fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. const BYTE* const matchlimit = (iend - LASTLITERALS); 325fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 326fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* op = (BYTE*) dest; 327fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. BYTE* const oend = op + maxOutputSize; 328fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 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 */ 339fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ctx->end += inputSize; 340fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 341fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip++; 342fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 34369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Main Loop */ 3445871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet while (ip < mflimit) { 34569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts); 346fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (!ml) { ip++; continue; } 347fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 34869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* saved, in case we would skip too much */ 349fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start0 = ip; 350fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref0 = ref; 351fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml0 = ml; 352fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 353fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search2: 354fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip+ml < mflimit) 355c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 0, matchlimit, ml, &ref2, &start2, maxNbAttempts); 356fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else ml2 = ml; 357fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 3585871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ml2 == ml) { /* No better match */ 359fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 360fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. continue; 361fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 362fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 3635871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start0 < ip) { 3645871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start2 < ip + ml0) { /* empirical */ 365fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start0; 366fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref0; 367fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml0; 368fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 369fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 370fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 37169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Here, start0==ip */ 3725871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((start2 - ip) < 3) { /* First Match too small : removed */ 373fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml2; 374fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 375fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref =ref2; 376fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search2; 377fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 378fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 379fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search3: 38069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* 381508855c48826aa0544a907f02b52515aabba5e16Yann Collet * Currently we have : 382508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ml2 > ml1, and 383508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ip1+3 <= ip2 (usually < ip1+ml1) 384508855c48826aa0544a907f02b52515aabba5e16Yann Collet */ 3855871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((start2 - ip) < OPTIMAL_ML) { 386fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction; 387fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int new_ml = ml; 388fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; 389fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; 390fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. correction = new_ml - (int)(start2 - ip); 3915871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (correction > 0) { 392fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 393fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 394fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 395fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 396fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 39769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */ 398fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 399fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 + ml2 < mflimit) 40069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts); 401fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else ml3 = ml2; 402fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 4035871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ml3 == ml2) { /* No better match : 2 sequences to encode */ 40469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* ip & ref are known; Now for ml */ 405fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (start2 < ip+ml) ml = (int)(start2 - ip); 40669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Now, encode 2 sequences */ 407fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 408fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 409fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0; 410fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. continue; 411fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 412fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 4135871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start3 < ip+ml+3) { /* Not enough space for match 2 : remove it */ 4145871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start3 >= (ip+ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ 4155871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start2 < ip+ml) { 416fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction = (int)(ip+ml - start2); 417fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 418fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 419fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 4205871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ml2 < MINMATCH) { 421fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 422fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 423fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 424fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 425fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 426fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 427fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 428fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start3; 429fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref3; 430fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml3; 431fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 432fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start0 = start2; 433fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref0 = ref2; 434fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml0 = ml2; 435fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search2; 436fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 437fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 438fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 439fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 440fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 441fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search3; 442fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 443fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 44469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* 445508855c48826aa0544a907f02b52515aabba5e16Yann Collet * OK, now we have 3 ascending matches; let's write at least the first one 446508855c48826aa0544a907f02b52515aabba5e16Yann Collet * ip & ref are known; Now for ml 447508855c48826aa0544a907f02b52515aabba5e16Yann Collet */ 4485871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (start2 < ip+ml) { 4495871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((start2 - ip) < (int)ML_MASK) { 450fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. int correction; 451fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; 452fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; 453fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. correction = ml - (int)(start2 - ip); 4545871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (correction > 0) { 455fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 += correction; 456fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 += correction; 457fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 -= correction; 458fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 4595871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet } else { 460fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = (int)(start2 - ip); 461fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 462fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 463fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; 464fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 465fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ip = start2; 466fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref = ref2; 467fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml = ml2; 468fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 469fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. start2 = start3; 470fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ref2 = ref3; 471fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. ml2 = ml3; 472fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 473fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. goto _Search3; 474fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 475fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 47669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* Encode Last Literals */ 4775871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet { int lastRun = (int)(iend - anchor); 47869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ 479fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 480fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. else *op++ = (BYTE)(lastRun<<ML_BITS); 481fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. memcpy(op, anchor, iend - anchor); 482fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. op += iend-anchor; 483fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. } 484fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 48569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. /* End */ 486fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. return (int) (((char*)op)-dest); 487fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 488fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 4891c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinskistatic int LZ4HC_getSearchNum(int compressionLevel) 4901c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski{ 4911c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski switch (compressionLevel) { 4921c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski default: return 0; /* unused */ 4931c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski case 11: return 128; 4941c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski case 12: return 1<<10; 4951c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski } 4961c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski} 497fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 498c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinskistatic int LZ4HC_compress_generic ( 499c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski LZ4HC_CCtx_internal* const ctx, 500c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski const char* const source, 501c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski char* const dest, 502c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski int const inputSize, 503c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski int const maxOutputSize, 504c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski int compressionLevel, 505c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski limitedOutput_directive limit 506c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski ) 507c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski{ 50852cac9a97342641315c76cfb861206d6acd631a8Yann Collet if (compressionLevel < 1) compressionLevel = LZ4HC_CLEVEL_DEFAULT; 509e3fee94742f9027aa2d27fae6458ce285889552ePrzemyslaw Skibinski if (compressionLevel > 9) { 510c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski switch (compressionLevel) { 511e3fee94742f9027aa2d27fae6458ce285889552ePrzemyslaw Skibinski case 10: return LZ4HC_compress_hashChain(ctx, source, dest, inputSize, maxOutputSize, 1 << (16-1), limit); 5121c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski case 11: ctx->searchNum = LZ4HC_getSearchNum(compressionLevel); return LZ4HC_compress_optimal(ctx, source, dest, inputSize, maxOutputSize, limit, 128, 0); 5132113ead176e0032c7ba04aa93f3bcc3d04ba6142Przemyslaw Skibinski default: 5141c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski case 12: ctx->searchNum = LZ4HC_getSearchNum(compressionLevel); return LZ4HC_compress_optimal(ctx, source, dest, inputSize, maxOutputSize, limit, LZ4_OPT_NUM, 1); 515c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski } 516c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski } 517e3fee94742f9027aa2d27fae6458ce285889552ePrzemyslaw Skibinski return LZ4HC_compress_hashChain(ctx, source, dest, inputSize, maxOutputSize, 1 << (compressionLevel-1), limit); 518c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski} 519c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski 520c1ef7a177fae1f5435f191cbdebb0c59fb81d8ffPrzemyslaw Skibinski 52194542d845884c922f809725807ecbd2cf7454aceYann Colletint LZ4_sizeofStateHC(void) { return sizeof(LZ4_streamHC_t); } 522fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 523e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) 524fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 525874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; 52669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */ 52785aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4HC_init (ctx, (const BYTE*)src); 528e05088d0eb500d8d673e081929620e538df3d718Yann Collet if (maxDstSize < LZ4_compressBound(srcSize)) 52985aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput); 530be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet else 53185aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, noLimit); 532fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 533fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 534e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) 535fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 53694542d845884c922f809725807ecbd2cf7454aceYann Collet#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 53784b97f90b81195590700fb791b83165d9e8cc1cdYann Collet LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); 5382c80138121550c719cb0a622f6a8a304d283960cYann Collet#else 53985aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHC_t state; 54085aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHC_t* const statePtr = &state; 5412c80138121550c719cb0a622f6a8a304d283960cYann Collet#endif 54294542d845884c922f809725807ecbd2cf7454aceYann Collet int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, maxDstSize, compressionLevel); 54394542d845884c922f809725807ecbd2cf7454aceYann Collet#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 5442c80138121550c719cb0a622f6a8a304d283960cYann Collet free(statePtr); 5452c80138121550c719cb0a622f6a8a304d283960cYann Collet#endif 5462c80138121550c719cb0a622f6a8a304d283960cYann Collet return cSize; 547fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 548fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 549fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 55065ee6b09c4392814167e7a039d9312aabdb5119bYann Collet 551d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/************************************** 5522a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Streaming Functions 5532a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet**************************************/ 554d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* allocation */ 555d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletLZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); } 556be9d248851ecd712a8911526b009c5d0c948ee21Yann Colletint LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; } 557fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 558d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 559d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* initialization */ 560d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletvoid LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) 561fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{ 562874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= sizeof(size_t) * LZ4_STREAMHCSIZE_SIZET); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ 56385aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHCPtr->internal_donotuse.base = NULL; 56485aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHCPtr->internal_donotuse.compressionLevel = (unsigned)compressionLevel; 5651c80b9af4edf94f93582d40bae0856d13eacbf11Przemyslaw Skibinski LZ4_streamHCPtr->internal_donotuse.searchNum = LZ4HC_getSearchNum(compressionLevel); 56669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 56769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 568d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize) 56969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ 570874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse; 5715871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (dictSize > 64 KB) { 57261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet dictionary += dictSize - 64 KB; 57361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet dictSize = 64 KB; 57461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet } 57565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet LZ4HC_init (ctxPtr, (const BYTE*)dictionary); 57665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->end = (const BYTE*)dictionary + dictSize; 57712aae846b3006d7cd76a1197992eab1a0e995466Przemyslaw Skibinski if (ctxPtr->compressionLevel >= LZ4HC_CLEVEL_OPT_MIN) 57812aae846b3006d7cd76a1197992eab1a0e995466Przemyslaw Skibinski LZ4HC_updateBinTree(ctxPtr, ctxPtr->end - MFLIMIT, ctxPtr->end - LASTLITERALS); 57912aae846b3006d7cd76a1197992eab1a0e995466Przemyslaw Skibinski else 58012aae846b3006d7cd76a1197992eab1a0e995466Przemyslaw Skibinski if (dictSize >= 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); 58161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet return dictSize; 582d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 583d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 584d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 585d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* compression */ 586d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 587874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Colletstatic void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock) 58865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet{ 58952cac9a97342641315c76cfb861206d6acd631a8Yann Collet if (ctxPtr->compressionLevel >= LZ4HC_CLEVEL_OPT_MIN) 5904f050b68d817776e3c1fac6c449b5f2b2adfbcb9Przemyslaw Skibinski LZ4HC_updateBinTree(ctxPtr, ctxPtr->end - MFLIMIT, ctxPtr->end - LASTLITERALS); 5914f050b68d817776e3c1fac6c449b5f2b2adfbcb9Przemyslaw Skibinski else 5924f050b68d817776e3c1fac6c449b5f2b2adfbcb9Przemyslaw Skibinski if (ctxPtr->end >= ctxPtr->base + 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */ 593838ed341f94aa68c0bce8ee181e33a87274d2202Przemyslaw Skibinski 59465ee6b09c4392814167e7a039d9312aabdb5119bYann Collet /* Only one memory segment for extDict, so any previous extDict is lost at this stage */ 59565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->lowLimit = ctxPtr->dictLimit; 59665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base); 59765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->dictBase = ctxPtr->base; 59865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->base = newBlock - ctxPtr->dictLimit; 59965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->end = newBlock; 600312d88249feee4c1b7511ac9fffce10ed6802ba7Przemyslaw Skibinski ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ 60165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet} 60265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet 60385aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrellstatic int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr, 604e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet const char* source, char* dest, 605e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet int inputSize, int maxOutputSize, limitedOutput_directive limit) 606e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet{ 607874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse; 608e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet /* auto-init if forgotten */ 6095871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if (ctxPtr->base == NULL) LZ4HC_init (ctxPtr, (const BYTE*) source); 610e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 611508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check overflow */ 6125871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) { 61365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit; 614508855c48826aa0544a907f02b52515aabba5e16Yann Collet if (dictSize > 64 KB) dictSize = 64 KB; 61585aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize); 616508855c48826aa0544a907f02b52515aabba5e16Yann Collet } 617508855c48826aa0544a907f02b52515aabba5e16Yann Collet 618508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check if blocks follow each other */ 6195871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((const BYTE*)source != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source); 620e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 621508855c48826aa0544a907f02b52515aabba5e16Yann Collet /* Check overlapping input/dictionary space */ 6225871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet { const BYTE* sourceEnd = (const BYTE*) source + inputSize; 6235871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; 6245871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; 6255871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd)) { 6262b421e97d4e7cfbefdc007bf30133b0de7e7e14eYann Collet if (sourceEnd > dictEnd) sourceEnd = dictEnd; 62765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase); 62865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit; 629e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet } 630e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet } 631e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 63265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit); 633e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet} 634e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet 635e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize) 636d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 637be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet if (maxOutputSize < LZ4_compressBound(inputSize)) 63885aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput); 639be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet else 64085aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit); 641d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 642d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 643d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 644d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* dictionary saving */ 645d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 646d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize) 647d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 648874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse; 6495871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); 650d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet if (dictSize > 64 KB) dictSize = 64 KB; 65161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet if (dictSize < 4) dictSize = 0; 65261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet if (dictSize > prefixSize) dictSize = prefixSize; 65381fdd9df23821d5db8331e66478e2617b470820cYann Collet memmove(safeBuffer, streamPtr->end - dictSize, dictSize); 6545871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet { U32 const endIndex = (U32)(streamPtr->end - streamPtr->base); 65561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->end = (const BYTE*)safeBuffer + dictSize; 65661289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->base = streamPtr->end - endIndex; 65761289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->dictLimit = endIndex - dictSize; 65861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet streamPtr->lowLimit = endIndex - dictSize; 65995cc6cef6444b202a93ba414b7a9996eb2c72ca3Yann Collet if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit; 66061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet } 661d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return dictSize; 662fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} 663fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 664d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 665d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/*********************************** 6662a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet* Deprecated Functions 6672a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet***********************************/ 66894542d845884c922f809725807ecbd2cf7454aceYann Collet/* These functions currently generate deprecation warnings */ 669be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated compression functions */ 670e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); } 671e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); } 672e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } 673e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); } 674e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 675e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 676e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 677e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 678e05088d0eb500d8d673e081929620e538df3d718Yann 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)); } 679e05088d0eb500d8d673e081929620e538df3d718Yann 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); } 680be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet 681be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet 682be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated streaming functions */ 683d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; } 684d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 6851c3e633c48766c58df949887297dc5838170a33fYann Colletint LZ4_resetStreamStateHC(void* state, char* inputBuffer) 686d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 687874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet LZ4HC_CCtx_internal *ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; 688d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */ 68985aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4HC_init(ctx, (const BYTE*)inputBuffer); 69085aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell ctx->inputBuffer = (BYTE*)inputBuffer; 691d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return 0; 692d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 693d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 6941c3e633c48766c58df949887297dc5838170a33fYann Colletvoid* LZ4_createHC (char* inputBuffer) 695d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 69685aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4_streamHC_t* hc4 = (LZ4_streamHC_t*)ALLOCATOR(1, sizeof(LZ4_streamHC_t)); 697aa1350e1399c808d2de83668249fff83fe70a24eYann Collet if (hc4 == NULL) return NULL; /* not enough memory */ 69885aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell LZ4HC_init (&hc4->internal_donotuse, (const BYTE*)inputBuffer); 69985aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell hc4->internal_donotuse.inputBuffer = (BYTE*)inputBuffer; 700d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet return hc4; 701d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 702d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 70394542d845884c922f809725807ecbd2cf7454aceYann Colletint LZ4_freeHC (void* LZ4HC_Data) { FREEMEM(LZ4HC_Data); return 0; } 704d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 705d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel) 706d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 70785aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, 0, compressionLevel, noLimit); 708d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 709fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet. 71069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel) 71169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ 71285aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput); 71369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 714d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet 715d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletchar* LZ4_slideInputBufferHC(void* LZ4HC_Data) 716d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{ 71794542d845884c922f809725807ecbd2cf7454aceYann Collet LZ4HC_CCtx_internal* const hc4 = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse; 71894542d845884c922f809725807ecbd2cf7454aceYann Collet int const dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB); 71965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet return (char*)(hc4->inputBuffer + dictSize); 720d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet} 721