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