1b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet./*
2b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   LZ4 - Fast LZ compression algorithm
3c071852bed418d68e56fcce41bd2de6bccc48b4eYann Collet   Copyright (C) 2011-2015, Yann Collet.
4b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
6b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   Redistribution and use in source and binary forms, with or without
7b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   modification, are permitted provided that the following conditions are
8b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   met:
9b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
10b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.       * Redistributions of source code must retain the above copyright
11b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   notice, this list of conditions and the following disclaimer.
12b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.       * Redistributions in binary form must reproduce the above
13b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   copyright notice, this list of conditions and the following disclaimer
14b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   in the documentation and/or other materials provided with the
15b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   distribution.
16b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
17b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
29b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   You can contact the author at :
30c071852bed418d68e56fcce41bd2de6bccc48b4eYann Collet   - LZ4 source repository : http://code.google.com/p/lz4
31c071852bed418d68e56fcce41bd2de6bccc48b4eYann Collet   - LZ4 source mirror : https://github.com/Cyan4973/lz4
32b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.   - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
33b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.*/
34b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
358907f6c7a55a26d51700166a9496f504296ee126Yann Collet
366875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
376875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.   Tuning parameters
386875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
396875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./*
406875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet. * HEAPMODE :
416875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet. * Select how default compression functions will allocate memory for their hash table,
428907f6c7a55a26d51700166a9496f504296ee126Yann Collet * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
436875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet. */
44b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define HEAPMODE 0
45b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
468907f6c7a55a26d51700166a9496f504296ee126Yann Collet/*
478907f6c7a55a26d51700166a9496f504296ee126Yann Collet * CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS :
4862bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * By default, the source code expects the compiler to correctly optimize
4962bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * 4-bytes and 8-bytes read on architectures able to handle it efficiently.
5062bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * This is not always the case. In some circumstances (ARM notably),
5162bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * the compiler will issue cautious code even when target is able to correctly handle unaligned memory accesses.
5262bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet *
5362bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * You can force the compiler to use unaligned memory access by uncommenting the line below.
5462bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * One of the below scenarios will happen :
5562bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * 1 - Your target CPU correctly handle unaligned access, and was not well optimized by compiler (good case).
5662bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet *     You will witness large performance improvements (+50% and up).
5762bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet *     Keep the line uncommented and send a word to upstream (https://groups.google.com/forum/#!forum/lz4c)
5862bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet *     The goal is to automatically detect such situations by adding your target CPU within an exception list.
593772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet * 2 - Your target CPU correctly handle unaligned access, and was already already optimized by compiler
6062bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet *     No change will be experienced.
6162bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * 3 - Your target CPU inefficiently handle unaligned access.
6262bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet *     You will experience a performance loss. Comment back the line.
6362bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * 4 - Your target CPU does not handle unaligned access.
6462bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet *     Program will crash.
653772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet * If uncommenting results in better performance (case 1)
669bc8681601164defee5cc35aa5bc7e1109ba077dYann Collet * please report your configuration to upstream (https://groups.google.com/forum/#!forum/lz4c)
673772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet * An automatic detection macro will be added to match your case within future versions of the library.
688907f6c7a55a26d51700166a9496f504296ee126Yann Collet */
698907f6c7a55a26d51700166a9496f504296ee126Yann Collet/* #define CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS 1 */
708907f6c7a55a26d51700166a9496f504296ee126Yann Collet
71b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
726875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
736875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.   CPU Feature Detection
746875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
756875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./*
76f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet * Automated efficient unaligned memory access detection
77f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet * Based on known hardware architectures
7862bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * This list will be updated thanks to feedbacks
796875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet. */
808907f6c7a55a26d51700166a9496f504296ee126Yann Collet#if defined(CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS) \
818907f6c7a55a26d51700166a9496f504296ee126Yann Collet    || defined(__ARM_FEATURE_UNALIGNED) \
828907f6c7a55a26d51700166a9496f504296ee126Yann Collet    || defined(__i386__) || defined(__x86_64__) \
839bb0d842f061f8ac80884949f9065540be15ddafYann Collet    || defined(_M_IX86) || defined(_M_X64) \
849bb0d842f061f8ac80884949f9065540be15ddafYann Collet    || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) \
859bb0d842f061f8ac80884949f9065540be15ddafYann Collet    || (defined(_M_ARM) && (_M_ARM >= 7))
868907f6c7a55a26d51700166a9496f504296ee126Yann Collet#  define LZ4_UNALIGNED_ACCESS 1
87b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#else
888907f6c7a55a26d51700166a9496f504296ee126Yann Collet#  define LZ4_UNALIGNED_ACCESS 0
89b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
90b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
9162bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet/*
9262bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * LZ4_FORCE_SW_BITCOUNT
9362bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet * Define this parameter if your target system or compiler does not support hardware bit count
9462bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet */
956875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#if defined(_MSC_VER) && defined(_WIN32_WCE)   /* Visual Studio for Windows CE does not support Hardware bit count */
96b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#  define LZ4_FORCE_SW_BITCOUNT
97b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
98b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
99b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1006875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
1018907f6c7a55a26d51700166a9496f504296ee126Yann Collet   Compiler Options
1026875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
1036875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
104b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet./* "restrict" is a known keyword */
105b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#else
1066875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#  define restrict /* Disable restrict */
107b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
108b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1096875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#ifdef _MSC_VER    /* Visual Studio */
1101de37fe6eabc2b3b7804134311d37155ababb230Yann Collet#  define FORCE_INLINE static __forceinline
11162bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet#  include <intrin.h>
1126875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
113c071852bed418d68e56fcce41bd2de6bccc48b4eYann Collet#  pragma warning(disable : 4293)        /* disable: C4293: too large shift (32-bits) */
1141de37fe6eabc2b3b7804134311d37155ababb230Yann Collet#else
1151e7c898533406da8a170dc0e951989bdc448c024Yann Collet#  if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
1161e7c898533406da8a170dc0e951989bdc448c024Yann Collet#    ifdef __GNUC__
1171e7c898533406da8a170dc0e951989bdc448c024Yann Collet#      define FORCE_INLINE static inline __attribute__((always_inline))
1181e7c898533406da8a170dc0e951989bdc448c024Yann Collet#    else
1191e7c898533406da8a170dc0e951989bdc448c024Yann Collet#      define FORCE_INLINE static inline
1201e7c898533406da8a170dc0e951989bdc448c024Yann Collet#    endif
1211de37fe6eabc2b3b7804134311d37155ababb230Yann Collet#  else
1221e7c898533406da8a170dc0e951989bdc448c024Yann Collet#    define FORCE_INLINE static
1231e7c898533406da8a170dc0e951989bdc448c024Yann Collet#  endif   /* __STDC_VERSION__ */
1241e7c898533406da8a170dc0e951989bdc448c024Yann Collet#endif  /* _MSC_VER */
1251de37fe6eabc2b3b7804134311d37155ababb230Yann Collet
126b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
127b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
128b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
129b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
130b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#else
131b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#  define expect(expr,value)    (expr)
132b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
133b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
134b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define likely(expr)     expect((expr) != 0, 1)
135b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define unlikely(expr)   expect((expr) != 0, 0)
136b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
137b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1386875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
1396875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.   Memory routines
1406875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
1416875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#include <stdlib.h>   /* malloc, calloc, free */
142b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define ALLOCATOR(n,s) calloc(n,s)
143b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define FREEMEM        free
1446875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#include <string.h>   /* memset, memcpy */
145b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define MEM_INIT       memset
146b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
147b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1486875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
1496875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.   Includes
1506875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
151b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#include "lz4.h"
152b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
153b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1546875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
1556875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.   Basic Types
1566875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
1576875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
158b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.# include <stdint.h>
159b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef  uint8_t BYTE;
160b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef uint16_t U16;
161b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef uint32_t U32;
162b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef  int32_t S32;
163b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef uint64_t U64;
164b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#else
165b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef unsigned char       BYTE;
166b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef unsigned short      U16;
167b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef unsigned int        U32;
168b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef   signed int        S32;
169b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.  typedef unsigned long long  U64;
170b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
171b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
172b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1738907f6c7a55a26d51700166a9496f504296ee126Yann Collet/**************************************
1748907f6c7a55a26d51700166a9496f504296ee126Yann Collet   Reading and writing into memory
1758907f6c7a55a26d51700166a9496f504296ee126Yann Collet**************************************/
176f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet#define STEPSIZE sizeof(size_t)
177f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet
1788907f6c7a55a26d51700166a9496f504296ee126Yann Colletstatic unsigned LZ4_64bits(void) { return sizeof(void*)==8; }
179b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1808907f6c7a55a26d51700166a9496f504296ee126Yann Colletstatic unsigned LZ4_isLittleEndian(void)
1818907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
1828907f6c7a55a26d51700166a9496f504296ee126Yann Collet    const union { U32 i; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental  */
1838907f6c7a55a26d51700166a9496f504296ee126Yann Collet    return one.c[0];
1848907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
185b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1863772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet
1878907f6c7a55a26d51700166a9496f504296ee126Yann Colletstatic U16 LZ4_readLE16(const void* memPtr)
1888907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
1898907f6c7a55a26d51700166a9496f504296ee126Yann Collet    if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian()))
1908907f6c7a55a26d51700166a9496f504296ee126Yann Collet        return *(U16*)memPtr;
1919bb0d842f061f8ac80884949f9065540be15ddafYann Collet    else
1928907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
1938907f6c7a55a26d51700166a9496f504296ee126Yann Collet        const BYTE* p = memPtr;
1948907f6c7a55a26d51700166a9496f504296ee126Yann Collet        return (U16)((U16)p[0] + (p[1]<<8));
1958907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
1968907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
1978907f6c7a55a26d51700166a9496f504296ee126Yann Collet
1988907f6c7a55a26d51700166a9496f504296ee126Yann Colletstatic void LZ4_writeLE16(void* memPtr, U16 value)
1998907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
2008907f6c7a55a26d51700166a9496f504296ee126Yann Collet    if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian()))
2018907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
2028907f6c7a55a26d51700166a9496f504296ee126Yann Collet        *(U16*)memPtr = value;
2038907f6c7a55a26d51700166a9496f504296ee126Yann Collet        return;
2048907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
2059bb0d842f061f8ac80884949f9065540be15ddafYann Collet    else
2068907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
2078907f6c7a55a26d51700166a9496f504296ee126Yann Collet        BYTE* p = memPtr;
2088907f6c7a55a26d51700166a9496f504296ee126Yann Collet        p[0] = (BYTE) value;
2098907f6c7a55a26d51700166a9496f504296ee126Yann Collet        p[1] = (BYTE)(value>>8);
2108907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
2118907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
2128907f6c7a55a26d51700166a9496f504296ee126Yann Collet
213f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet
2143772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Colletstatic U16 LZ4_read16(const void* memPtr)
2158907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
216f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    if (LZ4_UNALIGNED_ACCESS)
217f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        return *(U16*)memPtr;
218f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    else
219f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    {
220f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        U16 val16;
221f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        memcpy(&val16, memPtr, 2);
222f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        return val16;
2238907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
2248907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
2258907f6c7a55a26d51700166a9496f504296ee126Yann Collet
226f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Colletstatic U32 LZ4_read32(const void* memPtr)
2278907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
2288907f6c7a55a26d51700166a9496f504296ee126Yann Collet    if (LZ4_UNALIGNED_ACCESS)
229f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        return *(U32*)memPtr;
2309bb0d842f061f8ac80884949f9065540be15ddafYann Collet    else
2318907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
232f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        U32 val32;
233f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        memcpy(&val32, memPtr, 4);
234f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        return val32;
235f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    }
236f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet}
237f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet
2383772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Colletstatic U64 LZ4_read64(const void* memPtr)
2398907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
2403772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet    if (LZ4_UNALIGNED_ACCESS)
2418907f6c7a55a26d51700166a9496f504296ee126Yann Collet        return *(U64*)memPtr;
2429bb0d842f061f8ac80884949f9065540be15ddafYann Collet    else
2438907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
2443772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        U64 val64;
2453772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        memcpy(&val64, memPtr, 8);
2463772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        return val64;
2478907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
2488907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
2498907f6c7a55a26d51700166a9496f504296ee126Yann Collet
2503772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Colletstatic size_t LZ4_read_ARCH(const void* p)
251f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet{
252f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    if (LZ4_64bits())
2533772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        return (size_t)LZ4_read64(p);
254f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    else
2553772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        return (size_t)LZ4_read32(p);
256f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet}
257f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet
258f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet
259f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Colletstatic void LZ4_copy4(void* dstPtr, const void* srcPtr)
2608907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
261f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    if (LZ4_UNALIGNED_ACCESS)
262f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    {
263f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        *(U32*)dstPtr = *(U32*)srcPtr;
264f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        return;
265f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    }
266f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    memcpy(dstPtr, srcPtr, 4);
2678907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
2688907f6c7a55a26d51700166a9496f504296ee126Yann Collet
2698907f6c7a55a26d51700166a9496f504296ee126Yann Colletstatic void LZ4_copy8(void* dstPtr, const void* srcPtr)
2708907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
2711e7c898533406da8a170dc0e951989bdc448c024Yann Collet#if GCC_VERSION!=409  /* disabled on GCC 4.9, as it generates invalid opcode (crash) */
2728907f6c7a55a26d51700166a9496f504296ee126Yann Collet    if (LZ4_UNALIGNED_ACCESS)
2738907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
2748907f6c7a55a26d51700166a9496f504296ee126Yann Collet        if (LZ4_64bits())
2758907f6c7a55a26d51700166a9496f504296ee126Yann Collet            *(U64*)dstPtr = *(U64*)srcPtr;
2768907f6c7a55a26d51700166a9496f504296ee126Yann Collet        else
2778907f6c7a55a26d51700166a9496f504296ee126Yann Collet            ((U32*)dstPtr)[0] = ((U32*)srcPtr)[0],
2788907f6c7a55a26d51700166a9496f504296ee126Yann Collet            ((U32*)dstPtr)[1] = ((U32*)srcPtr)[1];
2798907f6c7a55a26d51700166a9496f504296ee126Yann Collet        return;
2808907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
28117f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet#endif
282f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    memcpy(dstPtr, srcPtr, 8);
2838907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
284b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
285f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */
286f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Colletstatic void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
2878907f6c7a55a26d51700166a9496f504296ee126Yann Collet{
288f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    BYTE* d = dstPtr;
289f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    const BYTE* s = srcPtr;
290f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    BYTE* e = dstEnd;
291f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e);
2928907f6c7a55a26d51700166a9496f504296ee126Yann Collet}
2938907f6c7a55a26d51700166a9496f504296ee126Yann Collet
294b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
2956875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
296aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet   Common Constants
2976875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
298b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define MINMATCH 4
299b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
300b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define COPYLENGTH 8
301b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define LASTLITERALS 5
302b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define MFLIMIT (COPYLENGTH+MINMATCH)
3036875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.static const int LZ4_minLength = (MFLIMIT+1);
3046875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.
305aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet#define KB *(1 <<10)
306aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet#define MB *(1 <<20)
3076875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.#define GB *(1U<<30)
308b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
309b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define MAXD_LOG 16
310b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
311b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
312b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define ML_BITS  4
313b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define ML_MASK  ((1U<<ML_BITS)-1)
314b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define RUN_BITS (8-ML_BITS)
315b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#define RUN_MASK ((1U<<RUN_BITS)-1)
316b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
317b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
3186875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./**************************************
319aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet   Common Utils
3206875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.**************************************/
321eb82dd9e2dfe2aa1748128a38d143be9a5889793Yann Collet#define LZ4_STATIC_ASSERT(c)    { enum { LZ4_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
322b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
323b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
3248907f6c7a55a26d51700166a9496f504296ee126Yann Collet/********************************
325aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet   Common functions
3268907f6c7a55a26d51700166a9496f504296ee126Yann Collet********************************/
327f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Colletstatic unsigned LZ4_NbCommonBytes (register size_t val)
328b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
3293772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet    if (LZ4_isLittleEndian())
3308907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
3313772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        if (LZ4_64bits())
3323772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        {
3333772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
3343772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            unsigned long r = 0;
3353772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            _BitScanForward64( &r, (U64)val );
3363772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (int)(r>>3);
3373772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
3383772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (__builtin_ctzll((U64)val) >> 3);
3393772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       else
3403772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
3413772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
3423772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       endif
3433772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        }
3443772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        else /* 32 bits */
3453772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        {
3463772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
3473772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            unsigned long r;
3483772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            _BitScanForward( &r, (U32)val );
3493772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (int)(r>>3);
3503772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
3513772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (__builtin_ctz((U32)val) >> 3);
3523772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       else
3533772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
3543772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
3553772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       endif
3563772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        }
3578907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
3583772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet    else   /* Big Endian CPU */
3598907f6c7a55a26d51700166a9496f504296ee126Yann Collet    {
3603772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        if (LZ4_64bits())
3613772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        {
3623772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
3633772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            unsigned long r = 0;
3643772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            _BitScanReverse64( &r, val );
3653772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (unsigned)(r>>3);
3663772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
3673772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (__builtin_clzll(val) >> 3);
3683772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       else
3693772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            unsigned r;
3703772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
3713772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
3723772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            r += (!val);
3733772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return r;
3743772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       endif
3753772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        }
3763772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        else /* 32 bits */
3773772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        {
3783772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
3793772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            unsigned long r = 0;
38055a6b23fae7a4f74ee8e06af1e9c19f56d1a2135Yann Collet            _BitScanReverse( &r, (unsigned long)val );
3813772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (unsigned)(r>>3);
3823772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
3833772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return (__builtin_clz(val) >> 3);
3843772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       else
3853772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            unsigned r;
3863772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
3873772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            r += (!val);
3883772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet            return r;
3893772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet#       endif
3903772fa21a143a55a8297a81ebf037d57a7ce82f1Yann Collet        }
3918907f6c7a55a26d51700166a9496f504296ee126Yann Collet    }
392b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
393b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
394aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Colletstatic unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit)
395aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet{
396aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    const BYTE* const pStart = pIn;
397aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
398aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    while (likely(pIn<pInLimit-(STEPSIZE-1)))
399aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    {
400aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet        size_t diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
401aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet        if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; }
402aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet        pIn += LZ4_NbCommonBytes(diff);
403aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet        return (unsigned)(pIn - pStart);
404aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    }
405533f1743d3c416c5e391d72cfbb9deca6fa8ff35Yann Collet
406aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    if (LZ4_64bits()) if ((pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; }
407aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; }
408aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
409aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    return (unsigned)(pIn - pStart);
410aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet}
411aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
412aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
413aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet#ifndef LZ4_COMMONDEFS_ONLY
414aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet/**************************************
415533f1743d3c416c5e391d72cfbb9deca6fa8ff35Yann Collet   Local Constants
416aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet**************************************/
417aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet#define LZ4_HASHLOG   (LZ4_MEMORY_USAGE-2)
418aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet#define HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
41917f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet#define HASH_SIZE_U32 (1 << LZ4_HASHLOG)       /* required as macro for static allocation */
420aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
42117f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Colletstatic const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1));
42217f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Colletstatic const U32 LZ4_skipTrigger = 6;  /* Increase this value ==> compression run slower on incompressible data */
423aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
424aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
425aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet/**************************************
426aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet   Local Utils
427aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet**************************************/
428aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Colletint LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
429aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Colletint LZ4_compressBound(int isize)  { return LZ4_COMPRESSBOUND(isize); }
430aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
431aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
432aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet/**************************************
433aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet   Local Structures and types
434aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet**************************************/
435aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collettypedef struct {
436aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    U32 hashTable[HASH_SIZE_U32];
437aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    U32 currentOffset;
438aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    U32 initCheck;
439aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    const BYTE* dictionary;
440aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    const BYTE* bufferStart;
441aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet    U32 dictSize;
442aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet} LZ4_stream_t_internal;
443aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
444aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collettypedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
445aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collettypedef enum { byPtr, byU32, byU16 } tableType_t;
446aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
447aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collettypedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
448aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collettypedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
449aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
450aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collettypedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
451aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collettypedef enum { full = 0, partial = 1 } earlyEnd_directive;
452aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
453aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
454aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
455aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet/********************************
456aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet   Compression functions
457aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet********************************/
458b996d28d5863199d4b041e3c8aca9e2a8d05c287yann.collet.
4598907f6c7a55a26d51700166a9496f504296ee126Yann Colletstatic U32 LZ4_hashSequence(U32 sequence, tableType_t tableType)
460b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
461b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    if (tableType == byU16)
462b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1)));
463b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    else
464b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));
465b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
466b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
467f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Colletstatic U32 LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(LZ4_read32(p), tableType); }
468b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
469c0e2826e4f7787381ac37489d46160d454ef068cYann Colletstatic void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
470b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
471b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    switch (tableType)
472b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    {
4735c8b0e40733c0461df72a4839435657587f90d91Yann Collet    case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; }
4748907f6c7a55a26d51700166a9496f504296ee126Yann Collet    case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; }
4758907f6c7a55a26d51700166a9496f504296ee126Yann Collet    case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; }
476b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    }
477b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
478b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
479c0e2826e4f7787381ac37489d46160d454ef068cYann Colletstatic void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
480b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
481b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    U32 h = LZ4_hashPosition(p, tableType);
482b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
483b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
484b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
485c0e2826e4f7787381ac37489d46160d454ef068cYann Colletstatic const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
486b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
487b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }
488b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }
4896875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; }   /* default, to ensure a return */
490b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
491b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
492c0e2826e4f7787381ac37489d46160d454ef068cYann Colletstatic const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
493b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
494b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    U32 h = LZ4_hashPosition(p, tableType);
495b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
496b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
497b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
4987059704c6a01be9b47220509fdea83c4e3dfbb6dYann Colletstatic int LZ4_compress_generic(
499b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                 void* ctx,
500b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                 const char* source,
501b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                 char* dest,
502b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                 int inputSize,
503b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                 int maxOutputSize,
504267fbd3d3412ca9a94d96a07adaaa450edd4a1d8Yann Collet                 limitedOutput_directive outputLimited,
505b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                 tableType_t tableType,
506fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet                 dict_directive dict,
507fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet                 dictIssue_directive dictIssue)
508b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
5096499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx;
510b870ca1164a338cb7afb14f080a42c139377200aYann Collet
511b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    const BYTE* ip = (const BYTE*) source;
512c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    const BYTE* base;
513b870ca1164a338cb7afb14f080a42c139377200aYann Collet    const BYTE* lowLimit;
514fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet    const BYTE* const lowRefLimit = ip - dictPtr->dictSize;
515b870ca1164a338cb7afb14f080a42c139377200aYann Collet    const BYTE* const dictionary = dictPtr->dictionary;
516b870ca1164a338cb7afb14f080a42c139377200aYann Collet    const BYTE* const dictEnd = dictionary + dictPtr->dictSize;
517b870ca1164a338cb7afb14f080a42c139377200aYann Collet    const size_t dictDelta = dictEnd - (const BYTE*)source;
518b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    const BYTE* anchor = (const BYTE*) source;
519b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    const BYTE* const iend = ip + inputSize;
520b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    const BYTE* const mflimit = iend - MFLIMIT;
521b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    const BYTE* const matchlimit = iend - LASTLITERALS;
522b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
523b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    BYTE* op = (BYTE*) dest;
52469a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet    BYTE* const olimit = op + maxOutputSize;
525b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
526b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    U32 forwardH;
52769a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet    size_t refDelta=0;
528b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
5296875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* Init conditions */
530c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0;          /* Unsupported input size, too large (or negative) */
531c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    switch(dict)
532c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    {
533c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    case noDict:
534c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    default:
535b870ca1164a338cb7afb14f080a42c139377200aYann Collet        base = (const BYTE*)source;
536b870ca1164a338cb7afb14f080a42c139377200aYann Collet        lowLimit = (const BYTE*)source;
537b870ca1164a338cb7afb14f080a42c139377200aYann Collet        break;
538c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    case withPrefix64k:
539052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet        base = (const BYTE*)source - dictPtr->currentOffset;
540130c2191b3cf94237c94df2395f05b79c2e68259Yann Collet        lowLimit = (const BYTE*)source - dictPtr->dictSize;
541c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        break;
542052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    case usingExtDict:
543b870ca1164a338cb7afb14f080a42c139377200aYann Collet        base = (const BYTE*)source - dictPtr->currentOffset;
544b870ca1164a338cb7afb14f080a42c139377200aYann Collet        lowLimit = (const BYTE*)source;
545b870ca1164a338cb7afb14f080a42c139377200aYann Collet        break;
546c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    }
54717f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet    if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0;   /* Size too large (not within 64K limit) */
548b00f7a053658a719a440c702e4123e0349f035e9Yann Collet    if (inputSize<LZ4_minLength) goto _last_literals;                  /* Input too small, no compression (all literals) */
549b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
5506875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* First Byte */
551b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    LZ4_putPosition(ip, ctx, tableType, base);
552b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    ip++; forwardH = LZ4_hashPosition(ip, tableType);
553b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
5546875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* Main Loop */
555b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    for ( ; ; )
556b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    {
5575c8b0e40733c0461df72a4839435657587f90d91Yann Collet        const BYTE* match;
558b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        BYTE* token;
5595a19390c32e8dbb37c189523065381c82d59e450Yann Collet        {
5606499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet            const BYTE* forwardIp = ip;
5616499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet            unsigned step=1;
56217f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet            unsigned searchMatchNb = (1U << LZ4_skipTrigger);
563b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
5645a19390c32e8dbb37c189523065381c82d59e450Yann Collet            /* Find a match */
5655a19390c32e8dbb37c189523065381c82d59e450Yann Collet            do {
5665a19390c32e8dbb37c189523065381c82d59e450Yann Collet                U32 h = forwardH;
5675a19390c32e8dbb37c189523065381c82d59e450Yann Collet                ip = forwardIp;
5685a19390c32e8dbb37c189523065381c82d59e450Yann Collet                forwardIp += step;
56917f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet                step = searchMatchNb++ >> LZ4_skipTrigger;
570b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
5716499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet                if (unlikely(forwardIp > mflimit)) goto _last_literals;
5725a19390c32e8dbb37c189523065381c82d59e450Yann Collet
5735c8b0e40733c0461df72a4839435657587f90d91Yann Collet                match = LZ4_getPositionOnHash(h, ctx, tableType, base);
574fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet                if (dict==usingExtDict)
57569a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet                {
5765c8b0e40733c0461df72a4839435657587f90d91Yann Collet                    if (match<(const BYTE*)source)
5775a19390c32e8dbb37c189523065381c82d59e450Yann Collet                    {
5785a19390c32e8dbb37c189523065381c82d59e450Yann Collet                        refDelta = dictDelta;
5795a19390c32e8dbb37c189523065381c82d59e450Yann Collet                        lowLimit = dictionary;
5805a19390c32e8dbb37c189523065381c82d59e450Yann Collet                    }
5815a19390c32e8dbb37c189523065381c82d59e450Yann Collet                    else
5825a19390c32e8dbb37c189523065381c82d59e450Yann Collet                    {
5835a19390c32e8dbb37c189523065381c82d59e450Yann Collet                        refDelta = 0;
5845a19390c32e8dbb37c189523065381c82d59e450Yann Collet                        lowLimit = (const BYTE*)source;
5855a19390c32e8dbb37c189523065381c82d59e450Yann Collet                    }
58669a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet                }
5875a19390c32e8dbb37c189523065381c82d59e450Yann Collet                forwardH = LZ4_hashPosition(forwardIp, tableType);
5885a19390c32e8dbb37c189523065381c82d59e450Yann Collet                LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
589b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
5905c8b0e40733c0461df72a4839435657587f90d91Yann Collet            } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
5915c8b0e40733c0461df72a4839435657587f90d91Yann Collet                || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
5925c8b0e40733c0461df72a4839435657587f90d91Yann Collet                || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
5935a19390c32e8dbb37c189523065381c82d59e450Yann Collet        }
594b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
5956875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* Catch up */
5965c8b0e40733c0461df72a4839435657587f90d91Yann Collet        while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; }
597b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
598b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        {
599c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            /* Encode Literal length */
60091901668c47dbff4c943a680b6b6710927164e25Yann Collet            unsigned litLength = (unsigned)(ip - anchor);
601c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            token = op++;
602fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet            if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)))
603fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet                return 0;   /* Check output limit */
604c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            if (litLength>=RUN_MASK)
605c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            {
606c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                int len = (int)litLength-RUN_MASK;
607c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                *token=(RUN_MASK<<ML_BITS);
608c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                for(; len >= 255 ; len-=255) *op++ = 255;
609c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                *op++ = (BYTE)len;
610c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            }
611c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            else *token = (BYTE)(litLength<<ML_BITS);
612c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
613c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            /* Copy Literals */
614f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet            LZ4_wildCopy(op, anchor, op+litLength);
615f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet            op+=litLength;
616c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        }
617b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
618b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet._next_match:
6196875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* Encode Offset */
6205c8b0e40733c0461df72a4839435657587f90d91Yann Collet        LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
621b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
6226875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* Encode MatchLength */
623b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        {
624b870ca1164a338cb7afb14f080a42c139377200aYann Collet            unsigned matchLength;
625b870ca1164a338cb7afb14f080a42c139377200aYann Collet
626052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet            if ((dict==usingExtDict) && (lowLimit==dictionary))
627b870ca1164a338cb7afb14f080a42c139377200aYann Collet            {
6286499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet                const BYTE* limit;
6295c8b0e40733c0461df72a4839435657587f90d91Yann Collet                match += refDelta;
6305c8b0e40733c0461df72a4839435657587f90d91Yann Collet                limit = ip + (dictEnd-match);
631b870ca1164a338cb7afb14f080a42c139377200aYann Collet                if (limit > matchlimit) limit = matchlimit;
6325c8b0e40733c0461df72a4839435657587f90d91Yann Collet                matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit);
633b870ca1164a338cb7afb14f080a42c139377200aYann Collet                ip += MINMATCH + matchLength;
634b870ca1164a338cb7afb14f080a42c139377200aYann Collet                if (ip==limit)
635b870ca1164a338cb7afb14f080a42c139377200aYann Collet                {
636b870ca1164a338cb7afb14f080a42c139377200aYann Collet                    unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit);
637b870ca1164a338cb7afb14f080a42c139377200aYann Collet                    matchLength += more;
638b870ca1164a338cb7afb14f080a42c139377200aYann Collet                    ip += more;
639b870ca1164a338cb7afb14f080a42c139377200aYann Collet                }
640b870ca1164a338cb7afb14f080a42c139377200aYann Collet            }
641b870ca1164a338cb7afb14f080a42c139377200aYann Collet            else
642b870ca1164a338cb7afb14f080a42c139377200aYann Collet            {
6435c8b0e40733c0461df72a4839435657587f90d91Yann Collet                matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
644b870ca1164a338cb7afb14f080a42c139377200aYann Collet                ip += MINMATCH + matchLength;
645b870ca1164a338cb7afb14f080a42c139377200aYann Collet            }
646b870ca1164a338cb7afb14f080a42c139377200aYann Collet
647ba31d6cb5a66c20d160d40210a5ab3cfe0825fe3Yann Collet            if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit)))
648ba31d6cb5a66c20d160d40210a5ab3cfe0825fe3Yann Collet                return 0;    /* Check output limit */
649c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            if (matchLength>=ML_MASK)
650c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            {
651c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                *token += ML_MASK;
652c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                matchLength -= ML_MASK;
6535a19390c32e8dbb37c189523065381c82d59e450Yann Collet                for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; }
654c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                if (matchLength >= 255) { matchLength-=255; *op++ = 255; }
655c0e2826e4f7787381ac37489d46160d454ef068cYann Collet                *op++ = (BYTE)matchLength;
656c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            }
657c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            else *token += (BYTE)(matchLength);
658b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        }
659c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
660c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        anchor = ip;
661b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
6626875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* Test end of chunk */
663c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        if (ip > mflimit) break;
664b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
6656875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* Fill table */
666b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        LZ4_putPosition(ip-2, ctx, tableType, base);
667b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
6686875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* Test next position */
6695c8b0e40733c0461df72a4839435657587f90d91Yann Collet        match = LZ4_getPosition(ip, ctx, tableType, base);
670fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        if (dict==usingExtDict)
671b870ca1164a338cb7afb14f080a42c139377200aYann Collet        {
6725c8b0e40733c0461df72a4839435657587f90d91Yann Collet            if (match<(const BYTE*)source)
673b870ca1164a338cb7afb14f080a42c139377200aYann Collet            {
67469a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet                refDelta = dictDelta;
675b870ca1164a338cb7afb14f080a42c139377200aYann Collet                lowLimit = dictionary;
676b870ca1164a338cb7afb14f080a42c139377200aYann Collet            }
67769a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet            else
67869a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet            {
67969a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet                refDelta = 0;
68069a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet                lowLimit = (const BYTE*)source;
68169a439aea10e77f85fc2e97dd4af65986ea3c6fdYann Collet            }
682b870ca1164a338cb7afb14f080a42c139377200aYann Collet        }
683b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        LZ4_putPosition(ip, ctx, tableType, base);
6845c8b0e40733c0461df72a4839435657587f90d91Yann Collet        if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
6855c8b0e40733c0461df72a4839435657587f90d91Yann Collet            && (match+MAX_DISTANCE>=ip)
6865c8b0e40733c0461df72a4839435657587f90d91Yann Collet            && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) )
687f40e3767065520db32afccfd3927e94fbf86d83bYann Collet        { token=op++; *token=0; goto _next_match; }
688b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
6896875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* Prepare next loop */
690c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        forwardH = LZ4_hashPosition(++ip, tableType);
691b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    }
692b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
693b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet._last_literals:
6946875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* Encode Last Literals */
695b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    {
696b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        int lastRun = (int)(iend - anchor);
697fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        if ((outputLimited) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize))
698fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet            return 0;   /* Check output limit */
699b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun >= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
700b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        else *op++ = (BYTE)(lastRun<<ML_BITS);
701b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        memcpy(op, anchor, iend - anchor);
702b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        op += iend-anchor;
703b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    }
704b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
7056875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* End */
706b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    return (int) (((char*)op)-dest);
707b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
708b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
709b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
710b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.int LZ4_compress(const char* source, char* dest, int inputSize)
711b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
712b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#if (HEAPMODE)
7138907f6c7a55a26d51700166a9496f504296ee126Yann Collet    void* ctx = ALLOCATOR(LZ4_STREAMSIZE_U64, 8);   /* Aligned on 8-bytes boundaries */
714b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#else
7158907f6c7a55a26d51700166a9496f504296ee126Yann Collet    U64 ctx[LZ4_STREAMSIZE_U64] = {0};      /* Ensure data is aligned on 8-bytes boundaries */
716b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
717b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    int result;
718b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
71917f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet    if (inputSize < LZ4_64Klimit)
720fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue);
721b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    else
7228907f6c7a55a26d51700166a9496f504296ee126Yann Collet        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
723b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
724b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#if (HEAPMODE)
725b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    FREEMEM(ctx);
726b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
727b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    return result;
728b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
729b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
730b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
731b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
732b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#if (HEAPMODE)
733f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet    void* ctx = ALLOCATOR(LZ4_STREAMSIZE_U64, 8);   /* Aligned on 8-bytes boundaries */
734b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#else
7358907f6c7a55a26d51700166a9496f504296ee126Yann Collet    U64 ctx[LZ4_STREAMSIZE_U64] = {0};      /* Ensure data is aligned on 8-bytes boundaries */
736b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
737b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    int result;
738b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
73917f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet    if (inputSize < LZ4_64Klimit)
740fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue);
741b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    else
7428907f6c7a55a26d51700166a9496f504296ee126Yann Collet        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
743b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
744b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#if (HEAPMODE)
745b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    FREEMEM(ctx);
746b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.#endif
747b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    return result;
748b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
749b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
750b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
751267fbd3d3412ca9a94d96a07adaaa450edd4a1d8Yann Collet/*****************************************
75290b6b9e6788452973e1828eb1758e24fa2f7ccb1Yann Collet   Experimental : Streaming functions
753267fbd3d3412ca9a94d96a07adaaa450edd4a1d8Yann Collet*****************************************/
754b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
75577d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet/*
75677d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet * LZ4_initStream
75777d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet * Use this function once, to init a newly allocated LZ4_stream_t structure
75877d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet * Return : 1 if OK, 0 if error
75977d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet */
76077d918824e181bfab4b5e3760f768b49be8b01c6Yann Colletvoid LZ4_resetStream (LZ4_stream_t* LZ4_stream)
76177d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet{
76277d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet    MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
76377d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet}
76477d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet
76572c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann ColletLZ4_stream_t* LZ4_createStream(void)
766e0d9f849468f12368e9113cd4efe194806b22730Yann Collet{
7678907f6c7a55a26d51700166a9496f504296ee126Yann Collet    LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64);
76897a32a310e5e52c5a81087585e9e7c6d18176080Yann Collet    LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal));    /* A compilation error here means LZ4_STREAMSIZE is not large enough */
76977d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet    LZ4_resetStream(lz4s);
770e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    return lz4s;
771e0d9f849468f12368e9113cd4efe194806b22730Yann Collet}
772e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
77372c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Colletint LZ4_freeStream (LZ4_stream_t* LZ4_stream)
774e0d9f849468f12368e9113cd4efe194806b22730Yann Collet{
775e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    FREEMEM(LZ4_stream);
776e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    return (0);
777e0d9f849468f12368e9113cd4efe194806b22730Yann Collet}
778e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
779e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
78077d918824e181bfab4b5e3760f768b49be8b01c6Yann Colletint LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
781052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet{
7826499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
783052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    const BYTE* p = (const BYTE*)dictionary;
784052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    const BYTE* const dictEnd = p + dictSize;
785052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    const BYTE* base;
786052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet
78777d918824e181bfab4b5e3760f768b49be8b01c6Yann Collet    if (dict->initCheck) LZ4_resetStream(LZ4_dict);                         /* Uninitialized structure detected */
788052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet
789052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    if (dictSize < MINMATCH)
790052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    {
791130c2191b3cf94237c94df2395f05b79c2e68259Yann Collet        dict->dictionary = NULL;
792052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet        dict->dictSize = 0;
79397a32a310e5e52c5a81087585e9e7c6d18176080Yann Collet        return 0;
794052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    }
795052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet
796052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    if (p <= dictEnd - 64 KB) p = dictEnd - 64 KB;
797052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    base = p - dict->currentOffset;
798052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    dict->dictionary = p;
799052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    dict->dictSize = (U32)(dictEnd - p);
800052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    dict->currentOffset += dict->dictSize;
801052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet
802052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    while (p <= dictEnd-MINMATCH)
803052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    {
804052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet        LZ4_putPosition(p, dict, byU32, base);
805052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet        p+=3;
806052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    }
807052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet
80897a32a310e5e52c5a81087585e9e7c6d18176080Yann Collet    return dict->dictSize;
809052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet}
810052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet
811052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet
812f9c0666803ef64a2e591a7baeb26dd941bb6c9b8Yann Colletstatic void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
813b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
814ff48dfe244b5474990365738c0230710c4b79132Yann Collet    if ((LZ4_dict->currentOffset > 0x80000000) ||
815130c2191b3cf94237c94df2395f05b79c2e68259Yann Collet        ((size_t)LZ4_dict->currentOffset > (size_t)src))   /* address space overflow */
816c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    {
817c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        /* rescale hash table */
818c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        U32 delta = LZ4_dict->currentOffset - 64 KB;
819fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
820c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        int i;
821c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        for (i=0; i<HASH_SIZE_U32; i++)
822c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        {
823c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
824c0e2826e4f7787381ac37489d46160d454ef068cYann Collet            else LZ4_dict->hashTable[i] -= delta;
825c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        }
826c0e2826e4f7787381ac37489d46160d454ef068cYann Collet        LZ4_dict->currentOffset = 64 KB;
827fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB;
828fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize;
829c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    }
830b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
831b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
832b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
83374ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann ColletFORCE_INLINE int LZ4_compress_continue_generic (void* LZ4_stream, const char* source, char* dest, int inputSize,
83474ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet                                                int maxOutputSize, limitedOutput_directive limit)
835e0d9f849468f12368e9113cd4efe194806b22730Yann Collet{
8366499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream;
837e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
838e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
839130c2191b3cf94237c94df2395f05b79c2e68259Yann Collet    const BYTE* smallest = (const BYTE*) source;
8406499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    if (streamPtr->initCheck) return 0;   /* Uninitialized structure detected */
84174ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd;
842e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    LZ4_renormDictT(streamPtr, smallest);
843e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
8446499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    /* Check overlapping input/dictionary space */
8456499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    {
8466499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet        const BYTE* sourceEnd = (const BYTE*) source + inputSize;
8476499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet        if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd))
8486499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet        {
849f40e3767065520db32afccfd3927e94fbf86d83bYann Collet            streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
8506499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet            if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
8516499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet            if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
852571ef3b3a4660dc30843da1cd930ab492bd808d8Yann Collet            streamPtr->dictionary = dictEnd - streamPtr->dictSize;
8536499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet        }
8546499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    }
8556499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet
85674ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    /* prefix mode : source data follows dictionary */
857e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    if (dictEnd == (const BYTE*)source)
858e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    {
859f40e3767065520db32afccfd3927e94fbf86d83bYann Collet        int result;
86074ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet        if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
861fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet            result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, dictSmall);
862f40e3767065520db32afccfd3927e94fbf86d83bYann Collet        else
863fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet            result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, noDictIssue);
864e0d9f849468f12368e9113cd4efe194806b22730Yann Collet        streamPtr->dictSize += (U32)inputSize;
865e0d9f849468f12368e9113cd4efe194806b22730Yann Collet        streamPtr->currentOffset += (U32)inputSize;
866e0d9f849468f12368e9113cd4efe194806b22730Yann Collet        return result;
867e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    }
868e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
86974ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    /* external dictionary mode */
870e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    {
871f40e3767065520db32afccfd3927e94fbf86d83bYann Collet        int result;
87274ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet        if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
873fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet            result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, dictSmall);
874f40e3767065520db32afccfd3927e94fbf86d83bYann Collet        else
875fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet            result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, noDictIssue);
876e0d9f849468f12368e9113cd4efe194806b22730Yann Collet        streamPtr->dictionary = (const BYTE*)source;
877e0d9f849468f12368e9113cd4efe194806b22730Yann Collet        streamPtr->dictSize = (U32)inputSize;
878e0d9f849468f12368e9113cd4efe194806b22730Yann Collet        streamPtr->currentOffset += (U32)inputSize;
879e0d9f849468f12368e9113cd4efe194806b22730Yann Collet        return result;
880e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    }
881e0d9f849468f12368e9113cd4efe194806b22730Yann Collet}
882e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
88377d918824e181bfab4b5e3760f768b49be8b01c6Yann Colletint LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize)
88474ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet{
88574ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, 0, notLimited);
88674ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet}
887e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
88877d918824e181bfab4b5e3760f768b49be8b01c6Yann Colletint LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize)
88974ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet{
89074ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput);
891e0d9f849468f12368e9113cd4efe194806b22730Yann Collet}
892e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
893e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
89472c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet/* Hidden debug function, to force separate dictionary mode */
8950b8513a15d2e09dd10edcdd57655f39355d80658Yann Colletint LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize)
8967059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet{
8976499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict;
898e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    int result;
899e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
900e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
901e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    const BYTE* smallest = dictEnd;
902e0d9f849468f12368e9113cd4efe194806b22730Yann Collet    if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
9036499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest);
904e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
905fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet    result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue);
906b870ca1164a338cb7afb14f080a42c139377200aYann Collet
907b870ca1164a338cb7afb14f080a42c139377200aYann Collet    streamPtr->dictionary = (const BYTE*)source;
908b870ca1164a338cb7afb14f080a42c139377200aYann Collet    streamPtr->dictSize = (U32)inputSize;
909b870ca1164a338cb7afb14f080a42c139377200aYann Collet    streamPtr->currentOffset += (U32)inputSize;
910b870ca1164a338cb7afb14f080a42c139377200aYann Collet
911b870ca1164a338cb7afb14f080a42c139377200aYann Collet    return result;
912b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
913b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
914c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
91577d918824e181bfab4b5e3760f768b49be8b01c6Yann Colletint LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
9167059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet{
9176499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
9187059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet    const BYTE* previousDictEnd = dict->dictionary + dict->dictSize;
9197059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet
9207059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet    if ((U32)dictSize > 64 KB) dictSize = 64 KB;   /* useless to define a dictionary > 64 KB */
9217059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet    if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize;
9227059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet
923414cfb9b952e76dfdd86106e94071f77e50b00f2Yann Collet    memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
9247059704c6a01be9b47220509fdea83c4e3dfbb6dYann Collet
925052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    dict->dictionary = (const BYTE*)safeBuffer;
926052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet    dict->dictSize = (U32)dictSize;
927c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
9282b4cdd0e3108a6626d4346346647c44be7b8cff6Yann Collet    return dictSize;
929b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
930b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
931b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
932c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
9336875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./****************************
9346875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.   Decompression functions
9356875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.****************************/
9366875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet./*
9376875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet. * This generic decompression function cover all use cases.
938414cfb9b952e76dfdd86106e94071f77e50b00f2Yann Collet * It shall be instantiated several times, using different sets of directives
9396875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet. * Note that it is essential this generic function is really inlined,
940414cfb9b952e76dfdd86106e94071f77e50b00f2Yann Collet * in order to remove useless branches during compilation optimization.
9416875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet. */
9421de37fe6eabc2b3b7804134311d37155ababb230Yann ColletFORCE_INLINE int LZ4_decompress_generic(
943ba70bf71c84517a1cebc21bbbcc6314cbeb4373cYann Collet                 const char* const source,
944ba70bf71c84517a1cebc21bbbcc6314cbeb4373cYann Collet                 char* const dest,
9456875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                 int inputSize,
9466875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                 int outputSize,         /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */
947b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
9486875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                 int endOnInput,         /* endOnOutputSize, endOnInputSize */
9496875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                 int partialDecoding,    /* full, partial */
950aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                 int targetOutputSize,   /* only used if partialDecoding==partial */
951052c6bba9977f2c15da09b0be435c5b0c37309a3Yann Collet                 int dict,               /* noDict, withPrefix64k, usingExtDict */
9520ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                 const BYTE* const lowPrefix,  /* == dest if dict == noDict */
9530ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                 const BYTE* const dictStart,  /* only if dict==usingExtDict */
9540ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                 const size_t dictSize         /* note : = 0 if noDict */
955b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                 )
956b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
9576875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* Local Variables */
958b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    const BYTE* restrict ip = (const BYTE*) source;
959b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    const BYTE* const iend = ip + inputSize;
960b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
961b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    BYTE* op = (BYTE*) dest;
962b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    BYTE* const oend = op + outputSize;
963b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    BYTE* cpy;
964b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    BYTE* oexit = op + targetOutputSize;
9650ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    const BYTE* const lowLimit = lowPrefix - dictSize;
966b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
9671de37fe6eabc2b3b7804134311d37155ababb230Yann Collet    const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
9687ec4badc36b99602901329c0cb8f22fbcfd71318Yann Collet    const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4};
9697ec4badc36b99602901329c0cb8f22fbcfd71318Yann Collet    const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
970b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
97172c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet    const int safeDecode = (endOnInput==endOnInputSize);
97272c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet    const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
973fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet
974b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
9756875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* Special cases */
97672c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet    if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT;                         /* targetOutputSize too high => decode everything */
97772c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet    if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1;  /* Empty output buffer */
9786875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
979b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
9801de37fe6eabc2b3b7804134311d37155ababb230Yann Collet
9816875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* Main Loop */
982b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    while (1)
983b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    {
984b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        unsigned token;
985b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        size_t length;
9860ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        const BYTE* match;
987b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
9880ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        /* get literal length */
989b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        token = *ip++;
990b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        if ((length=(token>>ML_BITS)) == RUN_MASK)
991b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        {
992999693d8830483e72341ef628acf91cfc83080f7Yann Collet            unsigned s;
993999693d8830483e72341ef628acf91cfc83080f7Yann Collet            do
9941de37fe6eabc2b3b7804134311d37155ababb230Yann Collet            {
9951de37fe6eabc2b3b7804134311d37155ababb230Yann Collet                s = *ip++;
9961de37fe6eabc2b3b7804134311d37155ababb230Yann Collet                length += s;
9971de37fe6eabc2b3b7804134311d37155ababb230Yann Collet            }
998999693d8830483e72341ef628acf91cfc83080f7Yann Collet            while (likely((endOnInput)?ip<iend-RUN_MASK:1) && (s==255));
9990ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error;   /* overflow detection */
10000ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error;   /* overflow detection */
1001b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        }
1002b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
10036875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* copy literals */
1004b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        cpy = op+length;
1005b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
1006b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            || ((!endOnInput) && (cpy>oend-COPYLENGTH)))
1007b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        {
1008b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            if (partialDecoding)
1009b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            {
10106875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                if (cpy > oend) goto _output_error;                           /* Error : write attempt beyond end of output buffer */
10116875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                if ((endOnInput) && (ip+length > iend)) goto _output_error;   /* Error : read attempt beyond end of input buffer */
1012b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            }
1013b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            else
1014b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            {
10156875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                if ((!endOnInput) && (cpy != oend)) goto _output_error;       /* Error : block decoding must stop exactly there */
10166875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.                if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error;   /* Error : input must be consumed */
1017b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            }
1018b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            memcpy(op, ip, length);
1019b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            ip += length;
1020b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            op += length;
102172c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet            break;     /* Necessarily EOF, due to parsing restrictions */
1022b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        }
1023f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        LZ4_wildCopy(op, ip, cpy);
1024f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        ip += length; op = cpy;
1025b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
10266875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* get offset */
10278907f6c7a55a26d51700166a9496f504296ee126Yann Collet        match = cpy - LZ4_readLE16(ip); ip+=2;
10280ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error;   /* Error : offset outside destination buffer */
1029b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
10306875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* get matchlength */
10318907f6c7a55a26d51700166a9496f504296ee126Yann Collet        length = token & ML_MASK;
10328907f6c7a55a26d51700166a9496f504296ee126Yann Collet        if (length == ML_MASK)
1033b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        {
10341de37fe6eabc2b3b7804134311d37155ababb230Yann Collet            unsigned s;
10351de37fe6eabc2b3b7804134311d37155ababb230Yann Collet            do
1036b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.            {
103725ad4ec4789bfe9a3a67d0e190bd6c7f37b3bef4Yann Collet                if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
10381de37fe6eabc2b3b7804134311d37155ababb230Yann Collet                s = *ip++;
1039b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.                length += s;
10401de37fe6eabc2b3b7804134311d37155ababb230Yann Collet            } while (s==255);
10410ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error;   /* overflow detection */
1042b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        }
10437ec4badc36b99602901329c0cb8f22fbcfd71318Yann Collet        length += MINMATCH;
1044b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1045aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet        /* check external dictionary */
10460ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        if ((dict==usingExtDict) && (match < lowPrefix))
1047aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet        {
10480ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error;   /* doesn't respect parsing restriction */
1049aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet
10500ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            if (length <= (size_t)(lowPrefix-match))
1051aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet            {
10520ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                /* match can be copied as a single segment from external dictionary */
10530ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                match = dictEnd - (lowPrefix-match);
10540ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                memcpy(op, match, length);
10557ec4badc36b99602901329c0cb8f22fbcfd71318Yann Collet                op += length;
1056aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet            }
1057aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet            else
1058aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet            {
10590ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                /* match encompass external dictionary and current segment */
10600ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                size_t copySize = (size_t)(lowPrefix-match);
1061aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                memcpy(op, dictEnd - copySize, copySize);
1062aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                op += copySize;
10637ec4badc36b99602901329c0cb8f22fbcfd71318Yann Collet                copySize = length - copySize;
10640ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                if (copySize > (size_t)(op-lowPrefix))   /* overlap within current segment */
1065aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                {
1066c70d9d627ba01771868be2e649bf85d44a07aeadYann Collet                    BYTE* const endOfMatch = op + copySize;
10670ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                    const BYTE* copyFrom = lowPrefix;
1068c70d9d627ba01771868be2e649bf85d44a07aeadYann Collet                    while (op < endOfMatch) *op++ = *copyFrom++;
1069aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                }
1070aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                else
1071aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                {
10720ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                    memcpy(op, lowPrefix, copySize);
1073aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                    op += copySize;
1074aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet                }
1075aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet            }
1076aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet            continue;
1077aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet        }
1078aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet
10796875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        /* copy repeated sequence */
10807ec4badc36b99602901329c0cb8f22fbcfd71318Yann Collet        cpy = op + length;
108162bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet        if (unlikely((op-match)<8))
1082b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        {
10830ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            const size_t dec64 = dec64table[op-match];
10840ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            op[0] = match[0];
10850ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            op[1] = match[1];
10860ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            op[2] = match[2];
10870ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            op[3] = match[3];
10880ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            match += dec32table[op-match];
10898907f6c7a55a26d51700166a9496f504296ee126Yann Collet            LZ4_copy4(op+4, match);
10900ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet            op += 8; match -= dec64;
10918907f6c7a55a26d51700166a9496f504296ee126Yann Collet        } else { LZ4_copy8(op, match); op+=8; match+=8; }
1092b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
10937ec4badc36b99602901329c0cb8f22fbcfd71318Yann Collet        if (unlikely(cpy>oend-12))
1094b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        {
1095f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet            if (cpy > oend-LASTLITERALS) goto _output_error;    /* Error : last LASTLITERALS bytes must be literals */
109687b244ba764ac6e1ce2688ae648533ce5a050141Yann Collet            if (op < oend-8)
109787b244ba764ac6e1ce2688ae648533ce5a050141Yann Collet            {
109887b244ba764ac6e1ce2688ae648533ce5a050141Yann Collet                LZ4_wildCopy(op, match, oend-8);
109962bd444d9ba41f6f4fbd012d46e3d985c4c3a5e4Yann Collet                match += (oend-8) - op;
110087b244ba764ac6e1ce2688ae648533ce5a050141Yann Collet                op = oend-8;
110187b244ba764ac6e1ce2688ae648533ce5a050141Yann Collet            }
1102f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet            while (op<cpy) *op++ = *match++;
1103b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.        }
1104f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet        else
1105f9ddcd47799cb98dc2e4c1791aa7b1b22d86417cYann Collet            LZ4_wildCopy(op, match, cpy);
11066875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.        op=cpy;   /* correction */
1107b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    }
1108b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
11096875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* end of decoding */
1110b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    if (endOnInput)
11116875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.       return (int) (((char*)op)-dest);     /* Nb of output bytes decoded */
1112b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    else
11136875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.       return (int) (((char*)ip)-source);   /* Nb of input bytes read */
1114b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
11156875c27f71d5eb85b54e742f75df5e7232c035dfyann.collet.    /* Overflow error detected */
1116b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet._output_error:
1117b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.    return (int) (-(((char*)ip)-source))-1;
1118b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
1119b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1120b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
112172c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Colletint LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
1122aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet{
11230ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0);
1124aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet}
1125aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet
112672c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Colletint LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize)
1127b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
11280ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0);
1129b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
1130b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1131f40e3767065520db32afccfd3927e94fbf86d83bYann Colletint LZ4_decompress_fast(const char* source, char* dest, int originalSize)
1132b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
11330ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB);
1134b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
1135b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
11360ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet
1137f40e3767065520db32afccfd3927e94fbf86d83bYann Collet/* streaming decompression functions */
1138f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1139f40e3767065520db32afccfd3927e94fbf86d83bYann Collettypedef struct
1140b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
11410ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    BYTE* externalDict;
11420ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    size_t extDictSize;
11430ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    BYTE* prefixEnd;
11440ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    size_t prefixSize;
1145f40e3767065520db32afccfd3927e94fbf86d83bYann Collet} LZ4_streamDecode_t_internal;
1146f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1147f40e3767065520db32afccfd3927e94fbf86d83bYann Collet/*
1148f40e3767065520db32afccfd3927e94fbf86d83bYann Collet * If you prefer dynamic allocation methods,
1149f40e3767065520db32afccfd3927e94fbf86d83bYann Collet * LZ4_createStreamDecode()
1150f40e3767065520db32afccfd3927e94fbf86d83bYann Collet * provides a pointer (void*) towards an initialized LZ4_streamDecode_t structure.
1151f40e3767065520db32afccfd3927e94fbf86d83bYann Collet */
115272c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann ColletLZ4_streamDecode_t* LZ4_createStreamDecode(void)
1153f40e3767065520db32afccfd3927e94fbf86d83bYann Collet{
11548907f6c7a55a26d51700166a9496f504296ee126Yann Collet    LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(sizeof(U64), LZ4_STREAMDECODESIZE_U64);
1155f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    return lz4s;
1156b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
1157b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
115872c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Colletint LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
115972c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet{
116072c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet    FREEMEM(LZ4_stream);
116172c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet    return 0;
116272c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet}
116372c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet
1164f40e3767065520db32afccfd3927e94fbf86d83bYann Collet/*
116572c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Collet * LZ4_setStreamDecode
1166f40e3767065520db32afccfd3927e94fbf86d83bYann Collet * Use this function to instruct where to find the dictionary
1167f40e3767065520db32afccfd3927e94fbf86d83bYann Collet * This function is not necessary if previous data is still available where it was decoded.
1168f40e3767065520db32afccfd3927e94fbf86d83bYann Collet * Loading a size of 0 is allowed (same effect as no dictionary).
1169f40e3767065520db32afccfd3927e94fbf86d83bYann Collet * Return : 1 if OK, 0 if error
1170f40e3767065520db32afccfd3927e94fbf86d83bYann Collet */
117172c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Colletint LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize)
1172b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.{
1173f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
11740ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    lz4sd->prefixSize = (size_t) dictSize;
11750ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    lz4sd->prefixEnd = (BYTE*) dictionary + dictSize;
11760ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    lz4sd->externalDict = NULL;
11770ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    lz4sd->extDictSize  = 0;
1178f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    return 1;
1179b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.}
1180b4bb2abaae96fc64eb20085b0f8dc0c8d5827818yann.collet.
1181f40e3767065520db32afccfd3927e94fbf86d83bYann Collet/*
1182f40e3767065520db32afccfd3927e94fbf86d83bYann Collet*_continue() :
1183f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    These decoding functions allow decompression of multiple blocks in "streaming" mode.
1184f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    Previously decoded blocks must still be available at the memory position where they were decoded.
118574ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    If it's not possible, save the relevant part of decoded data into a safe buffer,
11860ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    and indicate where it stands using LZ4_setStreamDecode()
1187f40e3767065520db32afccfd3927e94fbf86d83bYann Collet*/
118872c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Colletint LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize)
118911c3c319d86723ab678cb8c20b503b3c81546f5cYann Collet{
1190f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
1191f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    int result;
1192f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
11930ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    if (lz4sd->prefixEnd == (BYTE*)dest)
119474ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    {
11950ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
11960ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        endOnInputSize, full, 0,
11970ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
11980ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        if (result <= 0) return result;
11990ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixSize += result;
12000ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixEnd  += result;
120174ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    }
120274ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    else
120374ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    {
12040ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->extDictSize = lz4sd->prefixSize;
12050ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
12060ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
12070ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        endOnInputSize, full, 0,
12080ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
12090ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        if (result <= 0) return result;
12100ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixSize = result;
12110ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixEnd  = (BYTE*)dest + result;
121274ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    }
1213f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1214f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    return result;
1215f40e3767065520db32afccfd3927e94fbf86d83bYann Collet}
1216f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
121772c08b333139ac5173f5cc7a810a21fa6a14f9b9Yann Colletint LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize)
1218f40e3767065520db32afccfd3927e94fbf86d83bYann Collet{
1219f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
1220f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    int result;
1221f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
12220ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    if (lz4sd->prefixEnd == (BYTE*)dest)
122374ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    {
12240ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        result = LZ4_decompress_generic(source, dest, 0, originalSize,
12250ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        endOnOutputSize, full, 0,
12260ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
12270ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        if (result <= 0) return result;
12280ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixSize += originalSize;
12290ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixEnd  += originalSize;
123074ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    }
123174ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    else
123274ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    {
12330ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->extDictSize = lz4sd->prefixSize;
12340ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize;
12350ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        result = LZ4_decompress_generic(source, dest, 0, originalSize,
12360ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        endOnOutputSize, full, 0,
12370ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet                                        usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
12380ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        if (result <= 0) return result;
12390ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixSize = originalSize;
12400ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet        lz4sd->prefixEnd  = (BYTE*)dest + originalSize;
124174ec7c3129e87dd6fd2684bfeace5bb29d7c7453Yann Collet    }
1242f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1243f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    return result;
1244f40e3767065520db32afccfd3927e94fbf86d83bYann Collet}
1245f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1246f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1247f40e3767065520db32afccfd3927e94fbf86d83bYann Collet/*
1248f40e3767065520db32afccfd3927e94fbf86d83bYann ColletAdvanced decoding functions :
1249f40e3767065520db32afccfd3927e94fbf86d83bYann Collet*_usingDict() :
1250f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    These decoding functions work the same as "_continue" ones,
1251f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    the dictionary must be explicitly provided within parameters
1252f40e3767065520db32afccfd3927e94fbf86d83bYann Collet*/
1253f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
12541f54033b335245e34cacca9aec294a87eb5ade9aYann ColletFORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize)
12551f54033b335245e34cacca9aec294a87eb5ade9aYann Collet{
12566330f77dc54e5ba6dbc826587fa7eb2a3ae5d4c5Yann Collet    if (dictSize==0)
125714995232b861761e640f692e5a8395de8002e340Yann Collet        return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0);
125814995232b861761e640f692e5a8395de8002e340Yann Collet    if (dictStart+dictSize == dest)
125914995232b861761e640f692e5a8395de8002e340Yann Collet    {
126014995232b861761e640f692e5a8395de8002e340Yann Collet        if (dictSize >= (int)(64 KB - 1))
126114995232b861761e640f692e5a8395de8002e340Yann Collet            return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0);
126214995232b861761e640f692e5a8395de8002e340Yann Collet        return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
126314995232b861761e640f692e5a8395de8002e340Yann Collet    }
12640ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize);
12651f54033b335245e34cacca9aec294a87eb5ade9aYann Collet}
12661f54033b335245e34cacca9aec294a87eb5ade9aYann Collet
1267f40e3767065520db32afccfd3927e94fbf86d83bYann Colletint LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1268f40e3767065520db32afccfd3927e94fbf86d83bYann Collet{
12691f54033b335245e34cacca9aec294a87eb5ade9aYann Collet    return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);
127011c3c319d86723ab678cb8c20b503b3c81546f5cYann Collet}
127111c3c319d86723ab678cb8c20b503b3c81546f5cYann Collet
127211c3c319d86723ab678cb8c20b503b3c81546f5cYann Colletint LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
127311c3c319d86723ab678cb8c20b503b3c81546f5cYann Collet{
12741f54033b335245e34cacca9aec294a87eb5ade9aYann Collet    return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize);
12751f54033b335245e34cacca9aec294a87eb5ade9aYann Collet}
12761f54033b335245e34cacca9aec294a87eb5ade9aYann Collet
12771f54033b335245e34cacca9aec294a87eb5ade9aYann Collet/* debug function */
12781f54033b335245e34cacca9aec294a87eb5ade9aYann Colletint LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
12791f54033b335245e34cacca9aec294a87eb5ade9aYann Collet{
12800ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize);
128111c3c319d86723ab678cb8c20b503b3c81546f5cYann Collet}
1282aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet
1283aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet
1284f40e3767065520db32afccfd3927e94fbf86d83bYann Collet/***************************************************
1285f40e3767065520db32afccfd3927e94fbf86d83bYann Collet    Obsolete Functions
1286f40e3767065520db32afccfd3927e94fbf86d83bYann Collet***************************************************/
1287aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet/*
1288e0d9f849468f12368e9113cd4efe194806b22730Yann ColletThese function names are deprecated and should no longer be used.
1289e0d9f849468f12368e9113cd4efe194806b22730Yann ColletThey are only provided here for compatibility with older user programs.
1290e0d9f849468f12368e9113cd4efe194806b22730Yann Collet- LZ4_uncompress is totally equivalent to LZ4_decompress_fast
1291e0d9f849468f12368e9113cd4efe194806b22730Yann Collet- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe
1292aad35dcdc7106052edae3e4c30983bc0492021c1Yann Collet*/
1293b996d28d5863199d4b041e3c8aca9e2a8d05c287yann.collet.int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
1294b996d28d5863199d4b041e3c8aca9e2a8d05c287yann.collet.int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
1295c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
1296e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
129790b6b9e6788452973e1828eb1758e24fa2f7ccb1Yann Collet/* Obsolete Streaming functions */
1298c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
12990b8513a15d2e09dd10edcdd57655f39355d80658Yann Colletint LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
1300e0d9f849468f12368e9113cd4efe194806b22730Yann Collet
1301f9c0666803ef64a2e591a7baeb26dd941bb6c9b8Yann Colletstatic void LZ4_init(LZ4_stream_t_internal* lz4ds, const BYTE* base)
1302c0e2826e4f7787381ac37489d46160d454ef068cYann Collet{
1303999693d8830483e72341ef628acf91cfc83080f7Yann Collet    MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE);
1304c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    lz4ds->bufferStart = base;
1305c0e2826e4f7787381ac37489d46160d454ef068cYann Collet}
1306c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
1307c0e2826e4f7787381ac37489d46160d454ef068cYann Colletint LZ4_resetStreamState(void* state, const char* inputBuffer)
1308c0e2826e4f7787381ac37489d46160d454ef068cYann Collet{
1309c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    if ((((size_t)state) & 3) != 0) return 1;   /* Error : pointer is not aligned on 4-bytes boundary */
13106499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_init((LZ4_stream_t_internal*)state, (const BYTE*)inputBuffer);
1311c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    return 0;
1312c0e2826e4f7787381ac37489d46160d454ef068cYann Collet}
1313c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
1314c0e2826e4f7787381ac37489d46160d454ef068cYann Colletvoid* LZ4_create (const char* inputBuffer)
1315c0e2826e4f7787381ac37489d46160d454ef068cYann Collet{
13168907f6c7a55a26d51700166a9496f504296ee126Yann Collet    void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64);
13176499a94b2426edd506f425c20e661bf399c3e5e7Yann Collet    LZ4_init ((LZ4_stream_t_internal*)lz4ds, (const BYTE*)inputBuffer);
1318c0e2826e4f7787381ac37489d46160d454ef068cYann Collet    return lz4ds;
1319c0e2826e4f7787381ac37489d46160d454ef068cYann Collet}
1320c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
1321c0e2826e4f7787381ac37489d46160d454ef068cYann Colletchar* LZ4_slideInputBuffer (void* LZ4_Data)
1322c0e2826e4f7787381ac37489d46160d454ef068cYann Collet{
1323a18d8b1e2cc3e3b72d62237d334bd0d3c28a891bYann Collet    LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data;
1324a18d8b1e2cc3e3b72d62237d334bd0d3c28a891bYann Collet    int dictSize = LZ4_saveDict((LZ4_stream_t*)ctx, (char*)ctx->bufferStart, 64 KB);
1325a18d8b1e2cc3e3b72d62237d334bd0d3c28a891bYann Collet    return (char*)(ctx->bufferStart + dictSize);
1326c0e2826e4f7787381ac37489d46160d454ef068cYann Collet}
1327c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
1328f40e3767065520db32afccfd3927e94fbf86d83bYann Collet/*  Obsolete compresson functions using User-allocated state */
13290b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet
13300b8513a15d2e09dd10edcdd57655f39355d80658Yann Colletint LZ4_sizeofState() { return LZ4_STREAMSIZE; }
13310b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet
13320b8513a15d2e09dd10edcdd57655f39355d80658Yann Colletint LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize)
13330b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet{
13340b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet    if (((size_t)(state)&3) != 0) return 0;   /* Error : state is not aligned on 4-bytes boundary */
13351de37fe6eabc2b3b7804134311d37155ababb230Yann Collet    MEM_INIT(state, 0, LZ4_STREAMSIZE);
13360b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet
133717f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet    if (inputSize < LZ4_64Klimit)
1338fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue);
13390b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet    else
13408907f6c7a55a26d51700166a9496f504296ee126Yann Collet        return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
13410b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet}
13420b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet
13430b8513a15d2e09dd10edcdd57655f39355d80658Yann Colletint LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize)
13440b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet{
13450b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet    if (((size_t)(state)&3) != 0) return 0;   /* Error : state is not aligned on 4-bytes boundary */
13461de37fe6eabc2b3b7804134311d37155ababb230Yann Collet    MEM_INIT(state, 0, LZ4_STREAMSIZE);
13470b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet
134817f5eaeb9e846a0e8065b6d6316b620927ab90e2Yann Collet    if (inputSize < LZ4_64Klimit)
1349fbb74077036504cf9fa4414bda28b9ec4ad9bfd5Yann Collet        return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue);
13500b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet    else
13518907f6c7a55a26d51700166a9496f504296ee126Yann Collet        return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
13520b8513a15d2e09dd10edcdd57655f39355d80658Yann Collet}
1353c0e2826e4f7787381ac37489d46160d454ef068cYann Collet
135490b6b9e6788452973e1828eb1758e24fa2f7ccb1Yann Collet/* Obsolete streaming decompression functions */
1355f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1356f40e3767065520db32afccfd3927e94fbf86d83bYann Colletint LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
1357f40e3767065520db32afccfd3927e94fbf86d83bYann Collet{
13580ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
1359f40e3767065520db32afccfd3927e94fbf86d83bYann Collet}
1360f40e3767065520db32afccfd3927e94fbf86d83bYann Collet
1361f40e3767065520db32afccfd3927e94fbf86d83bYann Colletint LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
1362f40e3767065520db32afccfd3927e94fbf86d83bYann Collet{
13630ec5a9e45892bf3ce92f11c4305644966abbb796Yann Collet    return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
1364f40e3767065520db32afccfd3927e94fbf86d83bYann Collet}
1365aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
1366aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet#endif   /* LZ4_COMMONDEFS_ONLY */
1367aa1246bbf1d1fe19e9cbe8a8b64716528ed2a751Yann Collet
1368