lz4hc.c revision 874f3e095b1d64ab3545a3f2a3f7403a44ebb3bb
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.*/
34fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
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 */
472c80138121550c719cb0a622f6a8a304d283960cYann Collet#define LZ4HC_HEAPMODE 0
4869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
492c80138121550c719cb0a622f6a8a304d283960cYann Collet
502c80138121550c719cb0a622f6a8a304d283960cYann Collet/* *************************************
512a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  Includes
522c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/
5333dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet#include "lz4hc.h"
54fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
55fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
562c80138121550c719cb0a622f6a8a304d283960cYann Collet/* *************************************
572a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  Local Compiler Options
582c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/
59326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#if defined(__GNUC__)
60326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#  pragma GCC diagnostic ignored "-Wunused-function"
61fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
62fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
63326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#if defined (__clang__)
64326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#  pragma clang diagnostic ignored "-Wunused-function"
65fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
66fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
67fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
682c80138121550c719cb0a622f6a8a304d283960cYann Collet/* *************************************
692a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  Common LZ4 definition
702c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/
71326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#define LZ4_COMMONDEFS_ONLY
72326cada9fadeedccef8934e11144f343ecdcabcbYann Collet#include "lz4.c"
73fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
74fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
752c80138121550c719cb0a622f6a8a304d283960cYann Collet/* *************************************
762a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  Local Constants
772c80138121550c719cb0a622f6a8a304d283960cYann Collet***************************************/
78fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
79fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
80fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
8169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
822a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  Local Macros
8369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
8485aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell#define HASH_FUNCTION(i)       (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG))
8585aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell/* #define DELTANEXTU16(p)        chainTable[(p) & LZ4HC_MAXD_MASK] */   /* flexible, LZ4HC_MAXD dependent */
862a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet#define DELTANEXTU16(p)        chainTable[(U16)(p)]   /* faster */
87fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
88326cada9fadeedccef8934e11144f343ecdcabcbYann Colletstatic U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); }
89fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
90fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
91fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
92326cada9fadeedccef8934e11144f343ecdcabcbYann Collet/**************************************
932a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  HC Compression
94326cada9fadeedccef8934e11144f343ecdcabcbYann Collet**************************************/
95874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Colletstatic void LZ4HC_init (LZ4HC_CCtx_internal* hc4, const BYTE* start)
96fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
97fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
98fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
99e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->nextToUpdate = 64 KB;
10065ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    hc4->base = start - 64 KB;
10165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    hc4->end = start;
10265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    hc4->dictBase = start - 64 KB;
103e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->dictLimit = 64 KB;
104e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->lowLimit = 64 KB;
105fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
106fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
107fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
10869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* Update chains up to ip (excluded) */
109874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann ColletFORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE* ip)
110fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
1115871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    U16* const chainTable = hc4->chainTable;
1125871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    U32* const hashTable  = hc4->hashTable;
113d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* const base = hc4->base;
1145871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    U32 const target = (U32)(ip - base);
115d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32 idx = hc4->nextToUpdate;
116fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
1175871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    while (idx < target) {
1185871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        U32 const h = LZ4HC_hashPtr(base+idx);
1195871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        size_t delta = idx - hashTable[h];
120fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
1212a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet        DELTANEXTU16(idx) = (U16)delta;
1225871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        hashTable[h] = idx;
123d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        idx++;
124fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
1257ac18ad9dc5a5555f9129659c007fe9141e422b0Yann Collet
126d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    hc4->nextToUpdate = target;
127fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
128fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
129fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
130874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann ColletFORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_CCtx_internal* hc4,   /* Index table will be updated */
131508855c48826aa0544a907f02b52515aabba5e16Yann Collet                                               const BYTE* ip, const BYTE* const iLimit,
132508855c48826aa0544a907f02b52515aabba5e16Yann Collet                                               const BYTE** matchpos,
133508855c48826aa0544a907f02b52515aabba5e16Yann Collet                                               const int maxNbAttempts)
134fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
135fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    U16* const chainTable = hc4->chainTable;
136d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32* const HashTable = hc4->hashTable;
137d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* const base = hc4->base;
138e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    const BYTE* const dictBase = hc4->dictBase;
139e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    const U32 dictLimit = hc4->dictLimit;
140508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
141e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    U32 matchIndex;
142d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* match;
14369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    int nbAttempts=maxNbAttempts;
144d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    size_t ml=0;
145fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
146508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* HC4 match finder */
147fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    LZ4HC_Insert(hc4, ip);
1483dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    matchIndex = HashTable[LZ4HC_hashPtr(ip)];
149fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
1505871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    while ((matchIndex>=lowLimit) && (nbAttempts)) {
151fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        nbAttempts--;
1525871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if (matchIndex >= dictLimit) {
1533dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            match = base + matchIndex;
1543dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            if (*(match+ml) == *(ip+ml)
155326cada9fadeedccef8934e11144f343ecdcabcbYann Collet                && (LZ4_read32(match) == LZ4_read32(ip)))
1563dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            {
1575871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet                size_t const mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
1583dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if (mlt > ml) { ml = mlt; *matchpos = match; }
1593dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            }
1605871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        } else {
1613dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            match = dictBase + matchIndex;
1625871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            if (LZ4_read32(match) == LZ4_read32(ip)) {
1633dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                size_t mlt;
1643dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                const BYTE* vLimit = ip + (dictLimit - matchIndex);
1653dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if (vLimit > iLimit) vLimit = iLimit;
166326cada9fadeedccef8934e11144f343ecdcabcbYann Collet                mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH;
1673dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if ((ip+mlt == vLimit) && (vLimit < iLimit))
168326cada9fadeedccef8934e11144f343ecdcabcbYann Collet                    mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit);
1698a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet                if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; }   /* virtual matchpos */
1703dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            }
171fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
1722a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet        matchIndex -= DELTANEXTU16(matchIndex);
173fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
174fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
175fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int)ml;
176fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
177fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
178fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
179d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletFORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (
180874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4HC_CCtx_internal* hc4,
181002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet    const BYTE* const ip,
182002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet    const BYTE* const iLowLimit,
183002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet    const BYTE* const iHighLimit,
184508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int longest,
185508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** matchpos,
186508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** startpos,
187508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const int maxNbAttempts)
188fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
189d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U16* const chainTable = hc4->chainTable;
190d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32* const HashTable = hc4->hashTable;
191d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* const base = hc4->base;
1923dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    const U32 dictLimit = hc4->dictLimit;
193002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet    const BYTE* const lowPrefixPtr = base + dictLimit;
194508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
1953dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    const BYTE* const dictBase = hc4->dictBase;
1963dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    U32   matchIndex;
19769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    int nbAttempts = maxNbAttempts;
1983dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    int delta = (int)(ip-iLowLimit);
199fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
200e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet
201508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* First Match */
202fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    LZ4HC_Insert(hc4, ip);
2033dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    matchIndex = HashTable[LZ4HC_hashPtr(ip)];
204fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
2055871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    while ((matchIndex>=lowLimit) && (nbAttempts)) {
206fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        nbAttempts--;
2075871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if (matchIndex >= dictLimit) {
208002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet            const BYTE* matchPtr = base + matchIndex;
2095871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) {
2105871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet                if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
211002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                    int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit);
212002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                    int back = 0;
213002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet
2145871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet                    while ((ip+back > iLowLimit)
215002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                           && (matchPtr+back > lowPrefixPtr)
216002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                           && (ip[back-1] == matchPtr[back-1]))
217002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                            back--;
218fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
219002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                    mlt -= back;
220fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
2215871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet                    if (mlt > longest) {
222002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                        longest = (int)mlt;
223002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                        *matchpos = matchPtr+back;
224002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                        *startpos = ip+back;
225508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    }
2263dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                }
2275871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            }
2285871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        } else {
229258a5e7fa44825488fe4683f3a04c36fc944a23fYann Collet            const BYTE* const matchPtr = dictBase + matchIndex;
2305871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
2313dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                size_t mlt;
232508855c48826aa0544a907f02b52515aabba5e16Yann Collet                int back=0;
2333dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                const BYTE* vLimit = ip + (dictLimit - matchIndex);
2343dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if (vLimit > iHighLimit) vLimit = iHighLimit;
235002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                mlt = LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
2363dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if ((ip+mlt == vLimit) && (vLimit < iHighLimit))
237326cada9fadeedccef8934e11144f343ecdcabcbYann Collet                    mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit);
238002ec60f0feadc07a25a6f18a7b2b4ace3c1b718Yann Collet                while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == matchPtr[back-1])) back--;
239508855c48826aa0544a907f02b52515aabba5e16Yann Collet                mlt -= back;
2403dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; }
241fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
242fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
2432a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet        matchIndex -= DELTANEXTU16(matchIndex);
244fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
245fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
246fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return longest;
247fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
248fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
249fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
250fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
251fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
2528a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#define LZ4HC_DEBUG 0
2538a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#if LZ4HC_DEBUG
2548a9fb8cf3229c9a704c982667c63ac440b8487baYann Colletstatic unsigned debug = 0;
2558a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#endif
256508855c48826aa0544a907f02b52515aabba5e16Yann Collet
257fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE int LZ4HC_encodeSequence (
258508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** ip,
259508855c48826aa0544a907f02b52515aabba5e16Yann Collet    BYTE** op,
260508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** anchor,
261508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int matchLength,
262508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE* const match,
263508855c48826aa0544a907f02b52515aabba5e16Yann Collet    limitedOutput_directive limitedOutputBuffer,
264508855c48826aa0544a907f02b52515aabba5e16Yann Collet    BYTE* oend)
265fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
266fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    int length;
267fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    BYTE* token;
268fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
2698a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#if LZ4HC_DEBUG
2708a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet    if (debug) printf("literal : %u  --  match : %u  --  offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match));
2718a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet#endif
272e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet
27369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode Literal length */
274fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    length = (int)(*ip - *anchor);
275fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    token = (*op)++;
276e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1;   /* Check output limit */
277fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.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; }
278fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    else *token = (BYTE)(length<<ML_BITS);
279fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
28069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Copy Literals */
281326cada9fadeedccef8934e11144f343ecdcabcbYann Collet    LZ4_wildCopy(*op, *anchor, (*op) + length);
282326cada9fadeedccef8934e11144f343ecdcabcbYann Collet    *op += length;
283fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
28469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode Offset */
285326cada9fadeedccef8934e11144f343ecdcabcbYann Collet    LZ4_writeLE16(*op, (U16)(*ip-match)); *op += 2;
286fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
28769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode MatchLength */
288fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    length = (int)(matchLength-MINMATCH);
289e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1;   /* Check output limit */
29064f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet    if (length>=(int)ML_MASK) {
29164f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet        *token += ML_MASK;
29264f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet        length -= ML_MASK;
29364f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet        for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; }
29464f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet        if (length > 254) { length-=255; *(*op)++ = 255; }
29564f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet        *(*op)++ = (BYTE)length;
29664f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet    } else {
29764f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet        *token += (BYTE)(length);
29864f556e610b68e6781e05d2d6470ebf8b8dff45cYann Collet    }
299fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
30069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Prepare next loop */
301fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    *ip += matchLength;
302fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    *anchor = *ip;
303fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
304fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return 0;
305fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
306fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
307fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
308fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.static int LZ4HC_compress_generic (
309874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4HC_CCtx_internal* const ctx,
310c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet    const char* const source,
311c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet    char* const dest,
312c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet    int const inputSize,
313c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet    int const maxOutputSize,
314508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int compressionLevel,
315508855c48826aa0544a907f02b52515aabba5e16Yann Collet    limitedOutput_directive limit
316508855c48826aa0544a907f02b52515aabba5e16Yann Collet    )
317fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
318fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* ip = (const BYTE*) source;
319fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* anchor = ip;
320fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* const iend = ip + inputSize;
321fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* const mflimit = iend - MFLIMIT;
322fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* const matchlimit = (iend - LASTLITERALS);
323fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
324fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    BYTE* op = (BYTE*) dest;
325fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    BYTE* const oend = op + maxOutputSize;
326fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
327d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    unsigned maxNbAttempts;
328fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    int   ml, ml2, ml3, ml0;
3295871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    const BYTE* ref = NULL;
3305871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    const BYTE* start2 = NULL;
3315871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    const BYTE* ref2 = NULL;
3325871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    const BYTE* start3 = NULL;
3335871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    const BYTE* ref3 = NULL;
334fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* start0;
335fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* ref0;
336fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
337d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    /* init */
3382cf32ef0f107d18c9779283b8bd1d56f0517dd39inikep    if (compressionLevel > LZ4HC_MAX_CLEVEL) compressionLevel = LZ4HC_MAX_CLEVEL;
3392cf32ef0f107d18c9779283b8bd1d56f0517dd39inikep    if (compressionLevel < 1) compressionLevel = LZ4HC_DEFAULT_CLEVEL;
340c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet    maxNbAttempts = 1 << (compressionLevel-1);
341fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    ctx->end += inputSize;
342fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
343fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    ip++;
344fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
34569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Main Loop */
3465871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    while (ip < mflimit) {
34769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts);
348fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (!ml) { ip++; continue; }
349fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
35069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /* saved, in case we would skip too much */
351fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        start0 = ip;
352fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ref0 = ref;
353fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ml0 = ml;
354fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
355fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search2:
356fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (ip+ml < mflimit)
357c7ab95faa5aabec7e2c01e66ce164865d7c79bbfYann Collet            ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 0, matchlimit, ml, &ref2, &start2, maxNbAttempts);
358fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        else ml2 = ml;
359fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
3605871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if (ml2 == ml) { /* No better match */
361fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
362fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            continue;
363fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
364fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
3655871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if (start0 < ip) {
3665871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            if (start2 < ip + ml0) {  /* empirical */
367fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ip = start0;
368fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref = ref0;
369fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml = ml0;
370fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
371fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
372fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
37369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /* Here, start0==ip */
3745871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if ((start2 - ip) < 3) {  /* First Match too small : removed */
375fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ml = ml2;
376fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ip = start2;
377fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ref =ref2;
378fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            goto _Search2;
379fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
380fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
381fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search3:
38269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /*
383508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * Currently we have :
384508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * ml2 > ml1, and
385508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * ip1+3 <= ip2 (usually < ip1+ml1)
386508855c48826aa0544a907f02b52515aabba5e16Yann Collet        */
3875871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if ((start2 - ip) < OPTIMAL_ML) {
388fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            int correction;
389fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            int new_ml = ml;
390fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
391fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
392fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            correction = new_ml - (int)(start2 - ip);
3935871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            if (correction > 0) {
394fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                start2 += correction;
395fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref2 += correction;
396fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml2 -= correction;
397fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
398fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
39969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */
400fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
401fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (start2 + ml2 < mflimit)
40269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts);
403fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        else ml3 = ml2;
404fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
4055871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if (ml3 == ml2) {  /* No better match : 2 sequences to encode */
40669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            /* ip & ref are known; Now for ml */
407fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (start2 < ip+ml)  ml = (int)(start2 - ip);
40869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            /* Now, encode 2 sequences */
409fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
410fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ip = start2;
411fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0;
412fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            continue;
413fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
414fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
4155871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if (start3 < ip+ml+3) {  /* Not enough space for match 2 : remove it */
4165871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            if (start3 >= (ip+ml)) {  /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */
4175871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet                if (start2 < ip+ml) {
418fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    int correction = (int)(ip+ml - start2);
419fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    start2 += correction;
420fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ref2 += correction;
421fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ml2 -= correction;
4225871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet                    if (ml2 < MINMATCH) {
423fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                        start2 = start3;
424fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                        ref2 = ref3;
425fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                        ml2 = ml3;
426fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    }
427fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                }
428fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
429fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
430fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ip  = start3;
431fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref = ref3;
432fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml  = ml3;
433fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
434fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                start0 = start2;
435fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref0 = ref2;
436fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml0 = ml2;
437fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                goto _Search2;
438fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
439fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
440fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            start2 = start3;
441fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ref2 = ref3;
442fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ml2 = ml3;
443fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            goto _Search3;
444fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
445fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
44669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /*
447508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * OK, now we have 3 ascending matches; let's write at least the first one
448508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * ip & ref are known; Now for ml
449508855c48826aa0544a907f02b52515aabba5e16Yann Collet        */
4505871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if (start2 < ip+ml) {
4515871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            if ((start2 - ip) < (int)ML_MASK) {
452fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                int correction;
453fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
454fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
455fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                correction = ml - (int)(start2 - ip);
4565871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet                if (correction > 0) {
457fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    start2 += correction;
458fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ref2 += correction;
459fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ml2 -= correction;
460fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                }
4615871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet            } else {
462fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml = (int)(start2 - ip);
463fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
464fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
465fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
466fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
467fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ip = start2;
468fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ref = ref2;
469fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ml = ml2;
470fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
471fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        start2 = start3;
472fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ref2 = ref3;
473fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ml2 = ml3;
474fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
475fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        goto _Search3;
476fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
477fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
47869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode Last Literals */
4795871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    {   int lastRun = (int)(iend - anchor);
48069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0;  /* Check output limit */
481fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
482fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        else *op++ = (BYTE)(lastRun<<ML_BITS);
483fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        memcpy(op, anchor, iend - anchor);
484fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        op += iend-anchor;
485fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
486fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
48769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* End */
488fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int) (((char*)op)-dest);
489fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
490fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
491fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
492874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Colletint LZ4_sizeofStateHC(void) { return sizeof(LZ4HC_CCtx_internal); }
493fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
494e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel)
495fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
496874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4HC_CCtx_internal* ctx = &((LZ4_streamHC_t*)state)->internal_donotuse;
49769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0;   /* Error : state is not aligned for pointers (32 or 64 bits) */
49885aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    LZ4HC_init (ctx, (const BYTE*)src);
499e05088d0eb500d8d673e081929620e538df3d718Yann Collet    if (maxDstSize < LZ4_compressBound(srcSize))
50085aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell        return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput);
501be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet    else
50285aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell        return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, noLimit);
503fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
504fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
505e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel)
506fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
5072c80138121550c719cb0a622f6a8a304d283960cYann Collet#if LZ4HC_HEAPMODE==1
50885aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    LZ4_streamHC_t* statePtr = malloc(sizeof(LZ4_streamHC_t));
5092c80138121550c719cb0a622f6a8a304d283960cYann Collet#else
51085aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    LZ4_streamHC_t state;
51185aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    LZ4_streamHC_t* const statePtr = &state;
5122c80138121550c719cb0a622f6a8a304d283960cYann Collet#endif
5132c80138121550c719cb0a622f6a8a304d283960cYann Collet    int cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, maxDstSize, compressionLevel);
5142c80138121550c719cb0a622f6a8a304d283960cYann Collet#if LZ4HC_HEAPMODE==1
5152c80138121550c719cb0a622f6a8a304d283960cYann Collet    free(statePtr);
5162c80138121550c719cb0a622f6a8a304d283960cYann Collet#endif
5172c80138121550c719cb0a622f6a8a304d283960cYann Collet    return cSize;
518fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
519fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
520fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
52165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet
522d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/**************************************
5232a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  Streaming Functions
5242a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet**************************************/
525d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* allocation */
526d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletLZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); }
527be9d248851ecd712a8911526b009c5d0c948ee21Yann Colletint             LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; }
528fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
529d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
530d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* initialization */
531d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletvoid LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel)
532fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
533874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= sizeof(size_t) * LZ4_STREAMHCSIZE_SIZET);   /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
53485aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    LZ4_streamHCPtr->internal_donotuse.base = NULL;
53585aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    LZ4_streamHCPtr->internal_donotuse.compressionLevel = (unsigned)compressionLevel;
53669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.}
53769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
538d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize)
53969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{
540874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
5415871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    if (dictSize > 64 KB) {
54261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        dictionary += dictSize - 64 KB;
54361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        dictSize = 64 KB;
54461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    }
54565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    LZ4HC_init (ctxPtr, (const BYTE*)dictionary);
54665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    if (dictSize >= 4) LZ4HC_Insert (ctxPtr, (const BYTE*)dictionary +(dictSize-3));
54765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    ctxPtr->end = (const BYTE*)dictionary + dictSize;
54861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    return dictSize;
549d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
550d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
551d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
552d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* compression */
553d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
554874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Colletstatic void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock)
55565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet{
5565871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    if (ctxPtr->end >= ctxPtr->base + 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3);   /* Referencing remaining dictionary content */
55765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    /* Only one memory segment for extDict, so any previous extDict is lost at this stage */
55865ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    ctxPtr->lowLimit  = ctxPtr->dictLimit;
55965ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
56065ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    ctxPtr->dictBase  = ctxPtr->base;
56165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    ctxPtr->base = newBlock - ctxPtr->dictLimit;
56265ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    ctxPtr->end  = newBlock;
56365ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    ctxPtr->nextToUpdate = ctxPtr->dictLimit;   /* match referencing will resume from there */
56465ee6b09c4392814167e7a039d9312aabdb5119bYann Collet}
56565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet
56685aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrellstatic int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
567e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet                                            const char* source, char* dest,
568e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet                                            int inputSize, int maxOutputSize, limitedOutput_directive limit)
569e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet{
570874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
571e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    /* auto-init if forgotten */
5725871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    if (ctxPtr->base == NULL) LZ4HC_init (ctxPtr, (const BYTE*) source);
573e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
574508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* Check overflow */
5755871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) {
57665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet        size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
577508855c48826aa0544a907f02b52515aabba5e16Yann Collet        if (dictSize > 64 KB) dictSize = 64 KB;
57885aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell        LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
579508855c48826aa0544a907f02b52515aabba5e16Yann Collet    }
580508855c48826aa0544a907f02b52515aabba5e16Yann Collet
581508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* Check if blocks follow each other */
5825871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    if ((const BYTE*)source != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source);
583e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
584508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* Check overlapping input/dictionary space */
5855871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    {   const BYTE* sourceEnd = (const BYTE*) source + inputSize;
5865871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
5875871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        const BYTE* const dictEnd   = ctxPtr->dictBase + ctxPtr->dictLimit;
5885871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet        if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd)) {
5892b421e97d4e7cfbefdc007bf30133b0de7e7e14eYann Collet            if (sourceEnd > dictEnd) sourceEnd = dictEnd;
59065ee6b09c4392814167e7a039d9312aabdb5119bYann Collet            ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
59165ee6b09c4392814167e7a039d9312aabdb5119bYann Collet            if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
592e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet        }
593e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    }
594e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
59565ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit);
596e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet}
597e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
598e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize)
599d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
600be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet    if (maxOutputSize < LZ4_compressBound(inputSize))
60185aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell        return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput);
602be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet    else
60385aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell        return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit);
604d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
605d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
606d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
607d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* dictionary saving */
608d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
609d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
610d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
611874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
6125871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
613d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    if (dictSize > 64 KB) dictSize = 64 KB;
61461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    if (dictSize < 4) dictSize = 0;
61561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    if (dictSize > prefixSize) dictSize = prefixSize;
61681fdd9df23821d5db8331e66478e2617b470820cYann Collet    memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
6175871585b6a28c6582d1626b8d07bb1a53a4cbd9dYann Collet    {   U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
61861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->end = (const BYTE*)safeBuffer + dictSize;
61961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->base = streamPtr->end - endIndex;
62061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->dictLimit = endIndex - dictSize;
62161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->lowLimit = endIndex - dictSize;
62295cc6cef6444b202a93ba414b7a9996eb2c72ca3Yann Collet        if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit;
62361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    }
624d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return dictSize;
625fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
626fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
627d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
628d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/***********************************
6292a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet*  Deprecated Functions
6302a974d73c35476eb66275dd0d9448a6efa51bf56Yann Collet***********************************/
631be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated compression functions */
632b805d581b97be95fcc000134a54aa7c591b3ef09Yann Collet/* These functions are planned to start generate warnings by r131 approximately */
633e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); }
634e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); }
635e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); }
636e05088d0eb500d8d673e081929620e538df3d718Yann Colletint LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); }
637e05088d0eb500d8d673e081929620e538df3d718Yann 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); }
638e05088d0eb500d8d673e081929620e538df3d718Yann 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); }
639e05088d0eb500d8d673e081929620e538df3d718Yann 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); }
640e05088d0eb500d8d673e081929620e538df3d718Yann 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); }
641e05088d0eb500d8d673e081929620e538df3d718Yann 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)); }
642e05088d0eb500d8d673e081929620e538df3d718Yann 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); }
643be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet
644be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet
645be9d248851ecd712a8911526b009c5d0c948ee21Yann Collet/* Deprecated streaming functions */
646e05088d0eb500d8d673e081929620e538df3d718Yann Collet/* These functions currently generate deprecation warnings */
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
667d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_freeHC (void* LZ4HC_Data)
668d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
669d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    FREEMEM(LZ4HC_Data);
670d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return (0);
671d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
672d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
673d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel)
674d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
67585aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, 0, compressionLevel, noLimit);
676d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
677fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
67869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
67969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{
68085aeb0e4bb9c0b8dd6f6caa00ac2d9c7a4452660Nick Terrell    return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
68169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.}
682d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
683d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletchar* LZ4_slideInputBufferHC(void* LZ4HC_Data)
684d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
685874f3e095b1d64ab3545a3f2a3f7403a44ebb3bbYann Collet    LZ4HC_CCtx_internal* hc4 = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse;
68665ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    int dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB);
68765ee6b09c4392814167e7a039d9312aabdb5119bYann Collet    return (char*)(hc4->inputBuffer + dictSize);
688d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
689