update lz4, lz5 and some fixes in zstdmt

This commit is contained in:
Tino Reichardt
2016-11-20 16:30:46 +01:00
parent fe3a65bfbd
commit 94b2bf5dec
13 changed files with 2313 additions and 2189 deletions

View File

@@ -2,11 +2,11 @@
#define MY_VER_MINOR 04 #define MY_VER_MINOR 04
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "16.04 ZS" #define MY_VERSION_NUMBERS "16.04 ZS"
#define MY_VERSION "16.04 ZS" #define MY_VERSION "16.04 ZS"
#define MY_DATE "2016-10-16" #define MY_DATE "2016-11-20"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov, Tino Reichardt" #define MY_AUTHOR_NAME "Igor Pavlov, Tino Reichardt"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov" #define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov"

View File

@@ -2,10 +2,10 @@
#define MY_VER_MINOR 1 #define MY_VER_MINOR 1
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "1.1.0" #define MY_VERSION_NUMBERS "1.1.0"
#define MY_VERSION "1.1.0" #define MY_VERSION "1.1.0"
#define MY_DATE "2016-10-16" #define MY_DATE "2016-11-20"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Tino Reichardt" #define MY_AUTHOR_NAME "Tino Reichardt"
#define MY_COPYRIGHT "Copyright (c) 2016 Tino Reichardt" #define MY_COPYRIGHT "Copyright (c) 2016 Tino Reichardt"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/* /*
LZ4 - Fast LZ compression algorithm * LZ4 - Fast LZ compression algorithm
Header File * Header File
Copyright (C) 2011-2015, Yann Collet. * Copyright (C) 2011-2016, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
@@ -29,34 +29,79 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at : You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4 - LZ4 homepage : http://www.lz4.org
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c - LZ4 source repository : https://github.com/lz4/lz4
*/ */
#pragma once #ifndef LZ4_H_2983827168210
#define LZ4_H_2983827168210
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
/* /* --- Dependency --- */
* lz4.h provides block compression functions, and gives full buffer control to programmer. #include <stddef.h> /* size_t */
* If you need to generate inter-operable compressed data (respecting LZ4 frame specification),
* and can let the library handle its own memory, please use lz4frame.h instead.
/**
Introduction
LZ4 is lossless compression algorithm, providing compression speed at 400 MB/s per core,
scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
The LZ4 compression library provides in-memory compression and decompression functions.
Compression can be done in:
- a single step (described as Simple Functions)
- a single step, reusing a context (described in Advanced Functions)
- unbounded multiple steps (described as Streaming compression)
lz4.h provides block compression functions. It gives full buffer control to user.
Decompressing an lz4-compressed block also requires metadata (such as compressed size).
Each application is free to encode such metadata in whichever way it wants.
An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md),
take care of encoding standard metadata alongside LZ4-compressed blocks.
If your application requires interoperability, it's recommended to use it.
A library is provided to take care of it, see lz4frame.h.
*/ */
/************************************** /*^***************************************************************
* Version * Export parameters
**************************************/ *****************************************************************/
/*
* LZ4_DLL_EXPORT :
* Enable exporting of functions when building a Windows DLL
*/
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
# define LZ4LIB_API __declspec(dllexport)
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
# define LZ4LIB_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
#else
# define LZ4LIB_API
#endif
/*========== Version =========== */
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ #define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */ #define LZ4_VERSION_RELEASE 3 /* for tweaks, bug-fixes, or development */
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
int LZ4_versionNumber (void);
/************************************** #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
#define LZ4_QUOTE(str) #str
#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
LZ4LIB_API int LZ4_versionNumber (void);
LZ4LIB_API const char* LZ4_versionString (void);
/*-************************************
* Tuning parameter * Tuning parameter
**************************************/ **************************************/
/* /*!
* LZ4_MEMORY_USAGE : * LZ4_MEMORY_USAGE :
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
* Increasing memory usage improves compression ratio * Increasing memory usage improves compression ratio
@@ -66,15 +111,10 @@ int LZ4_versionNumber (void);
#define LZ4_MEMORY_USAGE 14 #define LZ4_MEMORY_USAGE 14
/************************************** /*-************************************
* Simple Functions * Simple Functions
**************************************/ **************************************/
/*! LZ4_compress_default() :
int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
/*
LZ4_compress_default() :
Compresses 'sourceSize' bytes from buffer 'source' Compresses 'sourceSize' bytes from buffer 'source'
into already allocated 'dest' buffer of size 'maxDestSize'. into already allocated 'dest' buffer of size 'maxDestSize'.
Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize). Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
@@ -86,9 +126,10 @@ LZ4_compress_default() :
sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
maxDestSize : full or partial size of buffer 'dest' (which must be already allocated) maxDestSize : full or partial size of buffer 'dest' (which must be already allocated)
return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize) return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
or 0 if compression fails or 0 if compression fails */
LZ4LIB_API int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
LZ4_decompress_safe() : /*! LZ4_decompress_safe() :
compressedSize : is the precise full size of the compressed block. compressedSize : is the precise full size of the compressed block.
maxDecompressedSize : is the size of destination buffer, which must be already allocated. maxDecompressedSize : is the size of destination buffer, which must be already allocated.
return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize) return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
@@ -97,15 +138,16 @@ LZ4_decompress_safe() :
This function is protected against buffer overflow exploits, including malicious data packets. This function is protected against buffer overflow exploits, including malicious data packets.
It never writes outside output buffer, nor reads outside input buffer. It never writes outside output buffer, nor reads outside input buffer.
*/ */
LZ4LIB_API int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
/************************************** /*-************************************
* Advanced Functions * Advanced Functions
**************************************/ **************************************/
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) #define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
/* /*!
LZ4_compressBound() : LZ4_compressBound() :
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
This function is primarily useful for memory allocation purposes (destination buffer size). This function is primarily useful for memory allocation purposes (destination buffer size).
@@ -115,9 +157,9 @@ LZ4_compressBound() :
return : maximum output size in a "worst case" scenario return : maximum output size in a "worst case" scenario
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
*/ */
int LZ4_compressBound(int inputSize); LZ4LIB_API int LZ4_compressBound(int inputSize);
/* /*!
LZ4_compress_fast() : LZ4_compress_fast() :
Same as LZ4_compress_default(), but allows to select an "acceleration" factor. Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
The larger the acceleration value, the faster the algorithm, but also the lesser the compression. The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
@@ -125,21 +167,21 @@ LZ4_compress_fast() :
An acceleration value of "1" is the same as regular LZ4_compress_default() An acceleration value of "1" is the same as regular LZ4_compress_default()
Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
*/ */
int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); LZ4LIB_API int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
/* /*!
LZ4_compress_fast_extState() : LZ4_compress_fast_extState() :
Same compression function, just using an externally allocated memory space to store compression state. Same compression function, just using an externally allocated memory space to store compression state.
Use LZ4_sizeofState() to know how much memory must be allocated, Use LZ4_sizeofState() to know how much memory must be allocated,
and allocate it on 8-bytes boundaries (using malloc() typically). and allocate it on 8-bytes boundaries (using malloc() typically).
Then, provide it as 'void* state' to compression function. Then, provide it as 'void* state' to compression function.
*/ */
int LZ4_sizeofState(void); LZ4LIB_API int LZ4_sizeofState(void);
int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration); LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
/* /*!
LZ4_compress_destSize() : LZ4_compress_destSize() :
Reverse the logic, by compressing as much data as possible from 'source' buffer Reverse the logic, by compressing as much data as possible from 'source' buffer
into already allocated buffer 'dest' of size 'targetDestSize'. into already allocated buffer 'dest' of size 'targetDestSize'.
@@ -150,10 +192,10 @@ LZ4_compress_destSize() :
return : Nb bytes written into 'dest' (necessarily <= targetDestSize) return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
or 0 if compression fails or 0 if compression fails
*/ */
int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); LZ4LIB_API int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize);
/* /*!
LZ4_decompress_fast() : LZ4_decompress_fast() :
originalSize : is the original and therefore uncompressed size originalSize : is the original and therefore uncompressed size
return : the number of bytes read from the source buffer (in other words, the compressed size) return : the number of bytes read from the source buffer (in other words, the compressed size)
@@ -164,9 +206,9 @@ LZ4_decompress_fast() :
However, it does not provide any protection against intentionally modified data stream (malicious input). However, it does not provide any protection against intentionally modified data stream (malicious input).
Use this function in trusted environment only (data to decode comes from a trusted source). Use this function in trusted environment only (data to decode comes from a trusted source).
*/ */
int LZ4_decompress_fast (const char* source, char* dest, int originalSize); LZ4LIB_API int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
/* /*!
LZ4_decompress_safe_partial() : LZ4_decompress_safe_partial() :
This function decompress a compressed block of size 'compressedSize' at position 'source' This function decompress a compressed block of size 'compressedSize' at position 'source'
into destination buffer 'dest' of size 'maxDecompressedSize'. into destination buffer 'dest' of size 'maxDecompressedSize'.
@@ -178,98 +220,73 @@ LZ4_decompress_safe_partial() :
If the source stream is detected malformed, the function will stop decoding and return a negative result. If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
*/ */
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); LZ4LIB_API int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
/*********************************************** /*-*********************************************
* Streaming Compression Functions * Streaming Compression Functions
***********************************************/ ***********************************************/
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
/* /*! LZ4_createStream() and LZ4_freeStream() :
* LZ4_stream_t * LZ4_createStream() will allocate and initialize an `LZ4_stream_t` structure.
* information structure to track an LZ4 stream. * LZ4_freeStream() releases its memory.
* important : init this structure content before first use !
* note : only allocated directly the structure if you are statically linking LZ4
* If you are using liblz4 as a DLL, please use below construction methods instead.
*/ */
typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
/* /*! LZ4_resetStream() :
* LZ4_resetStream * An LZ4_stream_t structure can be allocated once and re-used multiple times.
* Use this function to init an allocated LZ4_stream_t structure * Use this function to init an allocated `LZ4_stream_t` structure and start a new compression.
*/ */
void LZ4_resetStream (LZ4_stream_t* streamPtr); LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr);
/* /*! LZ4_loadDict() :
* LZ4_createStream will allocate and initialize an LZ4_stream_t structure * Use this function to load a static dictionary into LZ4_stream.
* LZ4_freeStream releases its memory. * Any previous data will be forgotten, only 'dictionary' will remain in memory.
* In the context of a DLL (liblz4), please use these methods rather than the static struct. * Loading a size of 0 is allowed.
* They are more future proof, in case of a change of LZ4_stream_t size. * Return : dictionary size, in bytes (necessarily <= 64 KB)
*/ */
LZ4_stream_t* LZ4_createStream(void); LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
int LZ4_freeStream (LZ4_stream_t* streamPtr);
/* /*! LZ4_compress_fast_continue() :
* LZ4_loadDict * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio.
* Use this function to load a static dictionary into LZ4_stream. * Important : Previous data blocks are assumed to still be present and unmodified !
* Any previous data will be forgotten, only 'dictionary' will remain in memory. * 'dst' buffer must be already allocated.
* Loading a size of 0 is allowed. * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
* Return : dictionary size, in bytes (necessarily <= 64 KB) * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
*/ */
int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration);
/* /*! LZ4_saveDict() :
* LZ4_compress_fast_continue * If previously compressed data block is not guaranteed to remain available at its memory location,
* Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio. * save it into a safer place (char* safeBuffer).
* Important : Previous data blocks are assumed to still be present and unmodified ! * Note : you don't need to call LZ4_loadDict() afterwards,
* 'dst' buffer must be already allocated. * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue().
* If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error.
* If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
*/ */
int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration); LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
/*
* LZ4_saveDict
* If previously compressed data block is not guaranteed to remain available at its memory location
* save it into a safer place (char* safeBuffer)
* Note : you don't need to call LZ4_loadDict() afterwards,
* dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue()
* Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error
*/
int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
/************************************************ /*-**********************************************
* Streaming Decompression Functions * Streaming Decompression Functions
* Bufferless synchronous API
************************************************/ ************************************************/
typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* incomplete type (defined later) */
#define LZ4_STREAMDECODESIZE_U64 4 /* creation / destruction of streaming decompression tracking structure */
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
/*
* LZ4_streamDecode_t /*! LZ4_setStreamDecode() :
* information structure to track an LZ4 stream. * Use this function to instruct where to find the dictionary.
* init this structure content using LZ4_setStreamDecode or memset() before first use ! * Setting a size of 0 is allowed (same effect as reset).
* * @return : 1 if OK, 0 if error
* In the context of a DLL (liblz4) please prefer usage of construction methods below.
* They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
* LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
* LZ4_freeStreamDecode releases its memory.
*/ */
LZ4_streamDecode_t* LZ4_createStreamDecode(void); LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
/* /*!
* LZ4_setStreamDecode LZ4_decompress_*_continue() :
* Use this function to instruct where to find the dictionary.
* Setting a size of 0 is allowed (same effect as reset).
* Return : 1 if OK, 0 if error
*/
int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
/*
*_continue() :
These decoding functions allow decompression of multiple blocks in "streaming" mode. These decoding functions allow decompression of multiple blocks in "streaming" mode.
Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
In the case of a ring buffers, decoding buffer must be either : In the case of a ring buffers, decoding buffer must be either :
@@ -285,37 +302,119 @@ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dicti
Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer, Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
and indicate where it is saved using LZ4_setStreamDecode() and indicate where it is saved using LZ4_setStreamDecode()
*/ */
int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
/* /*! LZ4_decompress_*_usingDict() :
Advanced decoding functions : * These decoding functions work the same as
*_usingDict() : * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue()
These decoding functions work the same as * They are stand-alone, and don't need an LZ4_streamDecode_t structure.
a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue() */
They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure. LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
*/ LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
/*^**********************************************
* !!!!!! STATIC LINKING ONLY !!!!!!
***********************************************/
/*-************************************
* Private definitions
**************************************
* Do not use these definitions.
* They are exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`.
* Using these definitions will expose code to API and/or ABI break in future versions of the library.
**************************************/
#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
/************************************** #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
#include <stdint.h>
typedef struct {
uint32_t hashTable[LZ4_HASH_SIZE_U32];
uint32_t currentOffset;
uint32_t initCheck;
const uint8_t* dictionary;
uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */
uint32_t dictSize;
} LZ4_stream_t_internal;
typedef struct {
const uint8_t* externalDict;
size_t extDictSize;
const uint8_t* prefixEnd;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
#else
typedef struct {
unsigned int hashTable[LZ4_HASH_SIZE_U32];
unsigned int currentOffset;
unsigned int initCheck;
const unsigned char* dictionary;
unsigned char* bufferStart; /* obsolete, used for slideInputBuffer */
unsigned int dictSize;
} LZ4_stream_t_internal;
typedef struct {
const unsigned char* externalDict;
size_t extDictSize;
const unsigned char* prefixEnd;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
#endif
/*!
* LZ4_stream_t :
* information structure to track an LZ4 stream.
* init this structure before first use.
* note : only use in association with static linking !
* this definition is not API/ABI safe,
* and may change in a future version !
*/
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long))
union LZ4_stream_u {
unsigned long long table[LZ4_STREAMSIZE_U64];
LZ4_stream_t_internal internal_donotuse;
} ; /* previously typedef'd to LZ4_stream_t */
/*!
* LZ4_streamDecode_t :
* information structure to track an LZ4 stream during decompression.
* init this structure using LZ4_setStreamDecode (or memset()) before first use
* note : only use in association with static linking !
* this definition is not API/ABI safe,
* and may change in a future version !
*/
#define LZ4_STREAMDECODESIZE_U64 4
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
union LZ4_streamDecode_u {
unsigned long long table[LZ4_STREAMDECODESIZE_U64];
LZ4_streamDecode_t_internal internal_donotuse;
} ; /* previously typedef'd to LZ4_streamDecode_t */
/*=************************************
* Obsolete Functions * Obsolete Functions
**************************************/ **************************************/
/* Deprecate Warnings */ /* Deprecation warnings */
/* Should these warnings messages be a problem, /* Should these warnings be a problem,
it is generally possible to disable them, it is generally possible to disable them,
with -Wno-deprecated-declarations for gcc typically with -Wno-deprecated-declarations for gcc
or _CRT_SECURE_NO_WARNINGS in Visual for example. or _CRT_SECURE_NO_WARNINGS in Visual.
You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */ Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */
#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK #ifdef LZ4_DISABLE_DEPRECATE_WARNINGS
# define LZ4_DEPRECATE_WARNING_DEFBLOCK # define LZ4_DEPRECATED(message) /* disable deprecation warnings */
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #else
# if (LZ4_GCC_VERSION >= 405) || defined(__clang__) # if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) # define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
# elif (LZ4_GCC_VERSION >= 301) # elif defined(__GNUC__) && (__GNUC__ >= 3)
# define LZ4_DEPRECATED(message) __attribute__((deprecated)) # define LZ4_DEPRECATED(message) __attribute__((deprecated))
# elif defined(_MSC_VER) # elif defined(_MSC_VER)
# define LZ4_DEPRECATED(message) __declspec(deprecated(message)) # define LZ4_DEPRECATED(message) __declspec(deprecated(message))
@@ -323,20 +422,19 @@ int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalS
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") # pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
# define LZ4_DEPRECATED(message) # define LZ4_DEPRECATED(message)
# endif # endif
#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */ #endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */
/* Obsolete compression functions */ /* Obsolete compression functions */
/* These functions are planned to start generate warnings by r131 approximately */ LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress (const char* source, char* dest, int sourceSize);
int LZ4_compress (const char* source, char* dest, int sourceSize); LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
/* Obsolete decompression functions */ /* Obsolete decompression functions */
/* These function names are completely deprecated and must no longer be used. /* These function names are completely deprecated and must no longer be used.
They are only provided here for compatibility with older programs. They are only provided in lz4.c for compatibility with older programs.
- LZ4_uncompress is the same as LZ4_decompress_fast - LZ4_uncompress is the same as LZ4_decompress_fast
- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
These function prototypes are now disabled; uncomment them only if you really need them. These function prototypes are now disabled; uncomment them only if you really need them.
@@ -358,3 +456,5 @@ LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* LZ4_H_2983827168210 */

View File

File diff suppressed because it is too large Load Diff

View File

@@ -28,43 +28,65 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at : You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4 - LZ4 source repository : https://github.com/lz4/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/ */
/* LZ4F is a stand-alone API to create LZ4-compressed frames /* LZ4F is a stand-alone API to create LZ4-compressed frames
* fully conformant to specification v1.5.1. * conformant with specification v1.5.1.
* All related operations, including memory management, are handled by the library. * It also offers streaming capabilities.
* You don't need lz4.h when using lz4frame.h. * lz4.h is not required when using lz4frame.h.
* */ * */
#pragma once #ifndef LZ4F_H_09782039843
#define LZ4F_H_09782039843
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
/************************************** /* --- Dependency --- */
* Includes
**************************************/
#include <stddef.h> /* size_t */ #include <stddef.h> /* size_t */
/*-***************************************************************
* Compiler specifics
*****************************************************************/
/*!
* LZ4_DLL_EXPORT :
* Enable exporting of functions when building a Windows DLL
*/
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
# define LZ4FLIB_API __declspec(dllexport)
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
# define LZ4FLIB_API __declspec(dllimport)
#else
# define LZ4FLIB_API
#endif
/************************************** #if defined(_MSC_VER)
* Error management # define LZ4F_DEPRECATE(x) x /* __declspec(deprecated) x - only works with C++ */
* ************************************/ #elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
# define LZ4F_DEPRECATE(x) x __attribute__((deprecated))
#else
# define LZ4F_DEPRECATE(x) x /* no deprecation warning for this compiler */
#endif
/*-************************************
* Error management
**************************************/
typedef size_t LZ4F_errorCode_t; typedef size_t LZ4F_errorCode_t;
unsigned LZ4F_isError(LZ4F_errorCode_t code); LZ4FLIB_API unsigned LZ4F_isError(LZ4F_errorCode_t code);
const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /* return error code string; useful for debugging */ LZ4FLIB_API const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /* return error code string; useful for debugging */
/************************************** /*-************************************
* Frame compression types * Frame compression types
* ************************************/ **************************************/
//#define LZ4F_DISABLE_OBSOLETE_ENUMS /* #define LZ4F_DISABLE_OBSOLETE_ENUMS */ /* uncomment to disable obsolete enums */
#ifndef LZ4F_DISABLE_OBSOLETE_ENUMS #ifndef LZ4F_DISABLE_OBSOLETE_ENUMS
# define LZ4F_OBSOLETE_ENUM(x) ,x # define LZ4F_OBSOLETE_ENUM(x) , LZ4F_DEPRECATE(x) = LZ4F_##x
#else #else
# define LZ4F_OBSOLETE_ENUM(x) # define LZ4F_OBSOLETE_ENUM(x)
#endif #endif
@@ -75,30 +97,30 @@ typedef enum {
LZ4F_max256KB=5, LZ4F_max256KB=5,
LZ4F_max1MB=6, LZ4F_max1MB=6,
LZ4F_max4MB=7 LZ4F_max4MB=7
LZ4F_OBSOLETE_ENUM(max64KB = LZ4F_max64KB) LZ4F_OBSOLETE_ENUM(max64KB)
LZ4F_OBSOLETE_ENUM(max256KB = LZ4F_max256KB) LZ4F_OBSOLETE_ENUM(max256KB)
LZ4F_OBSOLETE_ENUM(max1MB = LZ4F_max1MB) LZ4F_OBSOLETE_ENUM(max1MB)
LZ4F_OBSOLETE_ENUM(max4MB = LZ4F_max4MB) LZ4F_OBSOLETE_ENUM(max4MB)
} LZ4F_blockSizeID_t; } LZ4F_blockSizeID_t;
typedef enum { typedef enum {
LZ4F_blockLinked=0, LZ4F_blockLinked=0,
LZ4F_blockIndependent LZ4F_blockIndependent
LZ4F_OBSOLETE_ENUM(blockLinked = LZ4F_blockLinked) LZ4F_OBSOLETE_ENUM(blockLinked)
LZ4F_OBSOLETE_ENUM(blockIndependent = LZ4F_blockIndependent) LZ4F_OBSOLETE_ENUM(blockIndependent)
} LZ4F_blockMode_t; } LZ4F_blockMode_t;
typedef enum { typedef enum {
LZ4F_noContentChecksum=0, LZ4F_noContentChecksum=0,
LZ4F_contentChecksumEnabled LZ4F_contentChecksumEnabled
LZ4F_OBSOLETE_ENUM(noContentChecksum = LZ4F_noContentChecksum) LZ4F_OBSOLETE_ENUM(noContentChecksum)
LZ4F_OBSOLETE_ENUM(contentChecksumEnabled = LZ4F_contentChecksumEnabled) LZ4F_OBSOLETE_ENUM(contentChecksumEnabled)
} LZ4F_contentChecksum_t; } LZ4F_contentChecksum_t;
typedef enum { typedef enum {
LZ4F_frame=0, LZ4F_frame=0,
LZ4F_skippableFrame LZ4F_skippableFrame
LZ4F_OBSOLETE_ENUM(skippableFrame = LZ4F_skippableFrame) LZ4F_OBSOLETE_ENUM(skippableFrame)
} LZ4F_frameType_t; } LZ4F_frameType_t;
#ifndef LZ4F_DISABLE_OBSOLETE_ENUMS #ifndef LZ4F_DISABLE_OBSOLETE_ENUMS
@@ -120,66 +142,72 @@ typedef struct {
typedef struct { typedef struct {
LZ4F_frameInfo_t frameInfo; LZ4F_frameInfo_t frameInfo;
int compressionLevel; /* 0 == default (fast mode); values above 16 count as 16; values below 0 count as 0 */ int compressionLevel; /* 0 == default (fast mode); values above 16 count as 16; values below 0 count as 0 */
unsigned autoFlush; /* 1 == always flush (reduce need for tmp buffer) */ unsigned autoFlush; /* 1 == always flush (reduce usage of tmp buffer) */
unsigned reserved[4]; /* must be zero for forward compatibility */ unsigned reserved[4]; /* must be zero for forward compatibility */
} LZ4F_preferences_t; } LZ4F_preferences_t;
/*********************************** /*-*********************************
* Simple compression function * Simple compression function
* *********************************/ ***********************************/
size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr); /*!LZ4F_compressFrameBound() :
* Returns the maximum possible size of a frame compressed with LZ4F_compressFrame() given srcSize content and preferences.
size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_preferences_t* preferencesPtr); * Note : this result is only usable with LZ4F_compressFrame(), not with multi-segments compression.
/* LZ4F_compressFrame()
* Compress an entire srcBuffer into a valid LZ4 frame, as defined by specification v1.5.1
* The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case.
* You can get the minimum value of dstMaxSize by using LZ4F_compressFrameBound()
* If this condition is not respected, LZ4F_compressFrame() will fail (result is an errorCode)
* The LZ4F_preferences_t structure is optional : you can provide NULL as argument. All preferences will be set to default.
* The result of the function is the number of bytes written into dstBuffer.
* The function outputs an error code if it fails (can be tested using LZ4F_isError())
*/ */
LZ4FLIB_API size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr);
/*!LZ4F_compressFrame() :
* Compress an entire srcBuffer into a valid LZ4 frame, as defined by specification v1.5.1
* An important rule is that dstBuffer MUST be large enough (dstCapacity) to store the result in worst case situation.
* This value is supplied by LZ4F_compressFrameBound().
* If this condition is not respected, LZ4F_compressFrame() will fail (result is an errorCode).
* The LZ4F_preferences_t structure is optional : you can provide NULL as argument. All preferences will be set to default.
* @return : number of bytes written into dstBuffer.
* or an error code if it fails (can be tested using LZ4F_isError())
*/
LZ4FLIB_API size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity, const void* srcBuffer, size_t srcSize, const LZ4F_preferences_t* preferencesPtr);
/********************************** /*-***********************************
* Advanced compression functions * Advanced compression functions
**********************************/ *************************************/
typedef struct LZ4F_cctx_s* LZ4F_compressionContext_t; /* must be aligned on 8-bytes */ typedef struct LZ4F_cctx_s LZ4F_cctx; /* incomplete type */
typedef LZ4F_cctx* LZ4F_compressionContext_t; /* for compatibility with previous API version */
typedef struct { typedef struct {
unsigned stableSrc; /* 1 == src content will remain available on future calls to LZ4F_compress(); avoid saving src content within tmp buffer as future dictionary */ unsigned stableSrc; /* 1 == src content will remain present on future calls to LZ4F_compress(); skip copying src content within tmp buffer */
unsigned reserved[3]; unsigned reserved[3];
} LZ4F_compressOptions_t; } LZ4F_compressOptions_t;
/* Resource Management */ /* Resource Management */
#define LZ4F_VERSION 100 #define LZ4F_VERSION 100
LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* cctxPtr, unsigned version); LZ4FLIB_API unsigned LZ4F_getVersion(void);
LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t cctx); LZ4FLIB_API LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx** cctxPtr, unsigned version);
LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx* cctx);
/* LZ4F_createCompressionContext() : /* LZ4F_createCompressionContext() :
* The first thing to do is to create a compressionContext object, which will be used in all compression operations. * The first thing to do is to create a compressionContext object, which will be used in all compression operations.
* This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure. * This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure.
* The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries. * The version provided MUST be LZ4F_VERSION. It is intended to track potential version mismatch, notably when using DLL.
* The function will provide a pointer to a fully allocated LZ4F_compressionContext_t object. * The function will provide a pointer to a fully allocated LZ4F_cctx object.
* If the result LZ4F_errorCode_t is not zero, there was an error during context creation. * If @return != zero, there was an error during context creation.
* Object can release its memory using LZ4F_freeCompressionContext(); * Object can release its memory using LZ4F_freeCompressionContext();
*/ */
/* Compression */ /* Compression */
size_t LZ4F_compressBegin(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t* prefsPtr); LZ4FLIB_API size_t LZ4F_compressBegin(LZ4F_cctx* cctx, void* dstBuffer, size_t dstCapacity, const LZ4F_preferences_t* prefsPtr);
/* LZ4F_compressBegin() : /* LZ4F_compressBegin() :
* will write the frame header into dstBuffer. * will write the frame header into dstBuffer.
* dstBuffer must be large enough to accommodate a header (dstMaxSize). Maximum header size is 15 bytes. * dstBuffer must be large enough to accommodate a header. Maximum header size is 15 bytes.
* The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all preferences will then be set to default. * `prefsPtr` is optional : you can provide NULL as argument, all preferences will then be set to default.
* The result of the function is the number of bytes written into dstBuffer for the header * @return : number of bytes written into dstBuffer for the header
* or an error code (can be tested using LZ4F_isError()) * or an error code (which can be tested using LZ4F_isError())
*/ */
size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* prefsPtr); LZ4FLIB_API size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* prefsPtr);
/* LZ4F_compressBound() : /* LZ4F_compressBound() :
* Provides the minimum size of Dst buffer given srcSize to handle worst case situations. * Provides the minimum size of Dst buffer given srcSize to handle worst case situations.
* Different preferences can produce different results. * Different preferences can produce different results.
@@ -187,46 +215,45 @@ size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* prefsPtr);
* This function includes frame termination cost (4 bytes, or 8 if frame checksum is enabled) * This function includes frame termination cost (4 bytes, or 8 if frame checksum is enabled)
*/ */
size_t LZ4F_compressUpdate(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_compressOptions_t* cOptPtr); LZ4FLIB_API size_t LZ4F_compressUpdate(LZ4F_cctx* cctx, void* dstBuffer, size_t dstCapacity, const void* srcBuffer, size_t srcSize, const LZ4F_compressOptions_t* cOptPtr);
/* LZ4F_compressUpdate() /* LZ4F_compressUpdate() :
* LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary. * LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary.
* The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case. * An important rule is that dstBuffer MUST be large enough (dstCapacity) to ensure compression completion even in worst case.
* You can get the minimum value of dstMaxSize by using LZ4F_compressBound(). * This value is provided by using LZ4F_compressBound().
* If this condition is not respected, LZ4F_compress() will fail (result is an errorCode). * If this condition is not respected, LZ4F_compress() will fail (result is an errorCode).
* LZ4F_compressUpdate() doesn't guarantee error recovery, so you have to reset compression context when an error occurs. * LZ4F_compressUpdate() doesn't guarantee error recovery. When an error occurs, compression context must be freed or resized.
* The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. * `cOptPtr` is optional : it's possible to provide NULL, all options will be set to default.
* The result of the function is the number of bytes written into dstBuffer : it can be zero, meaning input data was just buffered. * @return : number of bytes written into `dstBuffer` (it can be zero, meaning input data was just buffered).
* The function outputs an error code if it fails (can be tested using LZ4F_isError()) * or an error code if it fails (which can be tested using LZ4F_isError())
*/ */
size_t LZ4F_flush(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* cOptPtr); LZ4FLIB_API size_t LZ4F_flush(LZ4F_cctx* cctx, void* dstBuffer, size_t dstCapacity, const LZ4F_compressOptions_t* cOptPtr);
/* LZ4F_flush() /* LZ4F_flush() :
* Should you need to generate compressed data immediately, without waiting for the current block to be filled, * When data must be generated and sent immediately, without waiting for a block to be completely filled,
* you can call LZ4_flush(), which will immediately compress any remaining data buffered within cctx. * it's possible to call LZ4_flush(). It will immediately compress any data buffered within cctx.
* Note that dstMaxSize must be large enough to ensure the operation will be successful. * `dstCapacity` must be large enough to ensure the operation will be successful.
* LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. * `cOptPtr` is optional : it's possible to provide NULL, all options will be set to default.
* The result of the function is the number of bytes written into dstBuffer * @return : number of bytes written into dstBuffer (it can be zero, which means there was no data stored within cctx)
* (it can be zero, this means there was no data left within cctx) * or an error code if it fails (which can be tested using LZ4F_isError())
* The function outputs an error code if it fails (can be tested using LZ4F_isError())
*/ */
size_t LZ4F_compressEnd(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* cOptPtr); LZ4FLIB_API size_t LZ4F_compressEnd(LZ4F_cctx* cctx, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* cOptPtr);
/* LZ4F_compressEnd() /* LZ4F_compressEnd() :
* When you want to properly finish the compressed frame, just call LZ4F_compressEnd(). * To properly finish the compressed frame, invoke LZ4F_compressEnd().
* It will flush whatever data remained within compressionContext (like LZ4_flush()) * It will flush whatever data remained within `cctx` (like LZ4_flush())
* but also properly finalize the frame, with an endMark and a checksum. * and properly finalize the frame, with an endMark and a checksum.
* The result of the function is the number of bytes written into dstBuffer (necessarily >= 4 (endMark), or 8 if optional frame checksum is enabled) * `cOptPtr` is optional : it's possible to provide NULL, all options will be set to default.
* The function outputs an error code if it fails (can be tested using LZ4F_isError()) * @return : number of bytes written into dstBuffer (necessarily >= 4 (endMark), or 8 if optional frame checksum is enabled)
* The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. * or an error code if it fails (which can be tested using LZ4F_isError())
* A successful call to LZ4F_compressEnd() makes cctx available again for next compression task. * A successful call to LZ4F_compressEnd() makes `cctx` available again for another compression task.
*/ */
/*********************************** /*-*********************************
* Decompression functions * Decompression functions
***********************************/ ***********************************/
typedef struct LZ4F_dctx_s LZ4F_dctx; /* incomplete type */
typedef struct LZ4F_dctx_s* LZ4F_decompressionContext_t; /* must be aligned on 8-bytes */ typedef LZ4F_dctx* LZ4F_decompressionContext_t; /* compatibility with previous API versions */
typedef struct { typedef struct {
unsigned stableDst; /* guarantee that decompressed data will still be there on next function calls (avoid storage into tmp buffers) */ unsigned stableDst; /* guarantee that decompressed data will still be there on next function calls (avoid storage into tmp buffers) */
@@ -236,11 +263,8 @@ typedef struct {
/* Resource management */ /* Resource management */
LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* dctxPtr, unsigned version); /*!LZ4F_createDecompressionContext() :
LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t dctx); * Create an LZ4F_decompressionContext_t object, which will be used to track all decompression operations.
/* LZ4F_createDecompressionContext() :
* The first thing to do is to create an LZ4F_decompressionContext_t object, which will be used in all decompression operations.
* This is achieved using LZ4F_createDecompressionContext().
* The version provided MUST be LZ4F_VERSION. It is intended to track potential breaking differences between different versions. * The version provided MUST be LZ4F_VERSION. It is intended to track potential breaking differences between different versions.
* The function will provide a pointer to a fully allocated and initialized LZ4F_decompressionContext_t object. * The function will provide a pointer to a fully allocated and initialized LZ4F_decompressionContext_t object.
* The result is an errorCode, which can be tested using LZ4F_isError(). * The result is an errorCode, which can be tested using LZ4F_isError().
@@ -248,56 +272,60 @@ LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t dctx)
* The result of LZ4F_freeDecompressionContext() is indicative of the current state of decompressionContext when being released. * The result of LZ4F_freeDecompressionContext() is indicative of the current state of decompressionContext when being released.
* That is, it should be == 0 if decompression has been completed fully and correctly. * That is, it should be == 0 if decompression has been completed fully and correctly.
*/ */
LZ4FLIB_API LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx** dctxPtr, unsigned version);
LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx* const dctx);
/* Decompression */ /*====== Decompression ======*/
size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t dctx, /*!LZ4F_getFrameInfo() :
LZ4F_frameInfo_t* frameInfoPtr,
const void* srcBuffer, size_t* srcSizePtr);
/* LZ4F_getFrameInfo()
* This function decodes frame header information (such as max blockSize, frame checksum, etc.). * This function decodes frame header information (such as max blockSize, frame checksum, etc.).
* Its usage is optional : you can start by calling directly LZ4F_decompress() instead. * Its usage is optional. The objective is to extract frame header information, typically for allocation purposes.
* The objective is to extract frame header information, typically for allocation purposes. * A header size is variable and can length from 7 to 15 bytes. It's possible to provide more input bytes than that.
* LZ4F_getFrameInfo() can also be used anytime *after* starting decompression, on any valid LZ4F_decompressionContext_t. * The number of bytes consumed from srcBuffer will be updated within *srcSizePtr (necessarily <= original value).
* The result is *copied* into an existing LZ4F_frameInfo_t structure which must be already allocated. * Decompression must resume from this point (srcBuffer + *srcSizePtr).
* The number of bytes read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value). * Note that LZ4F_getFrameInfo() can also be used anytime *after* decompression is started, in which case 0 input byte can be enough.
* The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for next call, * Frame header info is *copied into* an already allocated LZ4F_frameInfo_t structure.
* or an error code which can be tested using LZ4F_isError() * @return : an hint about how many srcSize bytes LZ4F_decompress() expects for next call,
* (typically, when there is not enough src bytes to fully decode the frame header) * or an error code which can be tested using LZ4F_isError()
* You are expected to resume decompression from where it stopped (srcBuffer + *srcSizePtr) * (typically, when there is not enough src bytes to fully decode the frame header)
*/ */
LZ4FLIB_API size_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
LZ4F_frameInfo_t* frameInfoPtr,
const void* srcBuffer, size_t* srcSizePtr);
size_t LZ4F_decompress(LZ4F_decompressionContext_t dctx, /*!LZ4F_decompress() :
void* dstBuffer, size_t* dstSizePtr, * Call this function repetitively to regenerate data compressed within `srcBuffer`.
const void* srcBuffer, size_t* srcSizePtr, * The function will attempt to decode up to *srcSizePtr bytes from srcBuffer, into dstBuffer of capacity *dstSizePtr.
const LZ4F_decompressOptions_t* dOptPtr);
/* LZ4F_decompress()
* Call this function repetitively to regenerate data compressed within srcBuffer.
* The function will attempt to decode *srcSizePtr bytes from srcBuffer, into dstBuffer of maximum size *dstSizePtr.
* *
* The number of bytes regenerated into dstBuffer will be provided within *dstSizePtr (necessarily <= original value). * The number of bytes regenerated into dstBuffer will be provided within *dstSizePtr (necessarily <= original value).
* *
* The number of bytes read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value). * The number of bytes read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value).
* If number of bytes read is < number of bytes provided, then decompression operation is not completed. * Number of bytes read can be < number of bytes provided, meaning there is some more data to decode.
* It typically happens when dstBuffer is not large enough to contain all decoded data. * It typically happens when dstBuffer is not large enough to contain all decoded data.
* LZ4F_decompress() must be called again, starting from where it stopped (srcBuffer + *srcSizePtr) * Remaining data will have to be presented again in a subsequent invocation.
* The function will check this condition, and refuse to continue if it is not respected.
* *
* dstBuffer is supposed to be flushed between each call to the function, since its content will be overwritten. * `dstBuffer` content is expected to be flushed between each invocation, as its content will be overwritten.
* dst arguments can be changed at will with each consecutive call to the function. * `dstBuffer` can be changed at will between each consecutive function invocation.
* *
* The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for next call. * @return is an hint of how many `srcSize` bytes LZ4F_decompress() expects for next call.
* Schematically, it's the size of the current (or remaining) compressed block + header of next block. * Schematically, it's the size of the current (or remaining) compressed block + header of next block.
* Respecting the hint provides some boost to performance, since it does skip intermediate buffers. * Respecting the hint provides some boost to performance, since it does skip intermediate buffers.
* This is just a hint, you can always provide any srcSize you want. * This is just a hint though, it's always possible to provide any srcSize.
* When a frame is fully decoded, the function result will be 0 (no more data expected). * When a frame is fully decoded, @return will be 0 (no more data expected).
* If decompression failed, function result is an error code, which can be tested using LZ4F_isError(). * If decompression failed, @return is an error code, which can be tested using LZ4F_isError().
* *
* After a frame is fully decoded, dctx can be used again to decompress another frame. * After a frame is fully decoded, dctx can be used again to decompress another frame.
*/ */
LZ4FLIB_API size_t LZ4F_decompress(LZ4F_dctx* dctx,
void* dstBuffer, size_t* dstSizePtr,
const void* srcBuffer, size_t* srcSizePtr,
const LZ4F_decompressOptions_t* dOptPtr);
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* LZ4F_H_09782039843 */

View File

@@ -29,31 +29,28 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at : You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4 - LZ4 source repository : https://github.com/lz4/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/ */
#pragma once #ifndef LZ4FRAME_STATIC_H_0398209384
#define LZ4FRAME_STATIC_H_0398209384
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
/* lz4frame_static.h should be used solely in the context of static linking. /* lz4frame_static.h should be used solely in the context of static linking.
* It contains definitions which may still change overtime. * It contains definitions which are not stable and may change in the future.
* Never use it in the context of DLL linking. * Never use it in the context of DLL linking.
* */ * */
/************************************** /* --- Dependency --- */
* Includes
**************************************/
#include "lz4frame.h" #include "lz4frame.h"
/************************************** /* --- Error List --- */
* Error management
* ************************************/
#define LZ4F_LIST_ERRORS(ITEM) \ #define LZ4F_LIST_ERRORS(ITEM) \
ITEM(OK_NoError) ITEM(ERROR_GENERIC) \ ITEM(OK_NoError) ITEM(ERROR_GENERIC) \
ITEM(ERROR_maxBlockSize_invalid) ITEM(ERROR_blockMode_invalid) ITEM(ERROR_contentChecksumFlag_invalid) \ ITEM(ERROR_maxBlockSize_invalid) ITEM(ERROR_blockMode_invalid) ITEM(ERROR_contentChecksumFlag_invalid) \
@@ -67,15 +64,19 @@ extern "C" {
ITEM(ERROR_headerChecksum_invalid) ITEM(ERROR_contentChecksum_invalid) \ ITEM(ERROR_headerChecksum_invalid) ITEM(ERROR_contentChecksum_invalid) \
ITEM(ERROR_maxCode) ITEM(ERROR_maxCode)
//#define LZ4F_DISABLE_OLD_ENUMS #define LZ4F_DISABLE_OLD_ENUMS /* comment to enable deprecated enums */
#ifndef LZ4F_DISABLE_OLD_ENUMS #ifndef LZ4F_DISABLE_OLD_ENUMS
#define LZ4F_GENERATE_ENUM(ENUM) LZ4F_##ENUM, ENUM = LZ4F_##ENUM, # define LZ4F_GENERATE_ENUM(ENUM) LZ4F_##ENUM, ENUM = LZ4F_##ENUM,
#else #else
#define LZ4F_GENERATE_ENUM(ENUM) LZ4F_##ENUM, # define LZ4F_GENERATE_ENUM(ENUM) LZ4F_##ENUM,
#endif #endif
typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM) } LZ4F_errorCodes; /* enum is exposed, to handle specific errors; compare function result to -enum value */ typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM) } LZ4F_errorCodes; /* enum is exposed, to handle specific errors; compare function result to -enum value */
LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult);
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* LZ4FRAME_STATIC_H_0398209384 */

View File

@@ -28,27 +28,36 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at : You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4 - LZ4 source repository : https://github.com/lz4/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/ */
/* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */
/* *************************************
/**************************************
* Tuning Parameter * Tuning Parameter
**************************************/ ***************************************/
static const int LZ4HC_compressionLevel_default = 9;
/*!
* HEAPMODE :
* Select how default compression function will allocate workplace memory,
* in stack (0:fastest), or in heap (1:requires malloc()).
* Since workplace is rather large, heap mode is recommended.
*/
#ifndef LZ4HC_HEAPMODE
# define LZ4HC_HEAPMODE 1
#endif
/************************************** /* *************************************
* Includes * Dependency
**************************************/ ***************************************/
#include "lz4hc.h" #include "lz4hc.h"
/************************************** /* *************************************
* Local Compiler Options * Local Compiler Options
**************************************/ ***************************************/
#if defined(__GNUC__) #if defined(__GNUC__)
# pragma GCC diagnostic ignored "-Wunused-function" # pragma GCC diagnostic ignored "-Wunused-function"
#endif #endif
@@ -58,52 +67,24 @@ static const int LZ4HC_compressionLevel_default = 9;
#endif #endif
/************************************** /* *************************************
* Common LZ4 definition * Common LZ4 definition
**************************************/ ***************************************/
#define LZ4_COMMONDEFS_ONLY #define LZ4_COMMONDEFS_ONLY
#include "lz4.c" #include "lz4.c"
/************************************** /* *************************************
* Local Constants * Local Constants
**************************************/ ***************************************/
#define DICTIONARY_LOGSIZE 16
#define MAXD (1<<DICTIONARY_LOGSIZE)
#define MAXD_MASK (MAXD - 1)
#define HASH_LOG (DICTIONARY_LOGSIZE-1)
#define HASHTABLESIZE (1 << HASH_LOG)
#define HASH_MASK (HASHTABLESIZE - 1)
#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH) #define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
static const int g_maxCompressionLevel = 16;
/**************************************
* Local Types
**************************************/
typedef struct
{
U32 hashTable[HASHTABLESIZE];
U16 chainTable[MAXD];
const BYTE* end; /* next block here to continue on current prefix */
const BYTE* base; /* All index relative to this position */
const BYTE* dictBase; /* alternate base for extDict */
BYTE* inputBuffer; /* deprecated */
U32 dictLimit; /* below that point, need extDict */
U32 lowLimit; /* below that point, no more dict */
U32 nextToUpdate; /* index from which to continue dictionary update */
U32 compressionLevel;
} LZ4HC_Data_Structure;
/************************************** /**************************************
* Local Macros * Local Macros
**************************************/ **************************************/
#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG)) #define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG))
//#define DELTANEXTU16(p) chainTable[(p) & MAXD_MASK] /* flexible, MAXD dependent */ /* #define DELTANEXTU16(p) chainTable[(p) & LZ4HC_MAXD_MASK] */ /* flexible, LZ4HC_MAXD dependent */
#define DELTANEXTU16(p) chainTable[(U16)(p)] /* faster */ #define DELTANEXTU16(p) chainTable[(U16)(p)] /* faster */
static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); } static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); }
@@ -113,7 +94,7 @@ static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)
/************************************** /**************************************
* HC Compression * HC Compression
**************************************/ **************************************/
static void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start) static void LZ4HC_init (LZ4HC_CCtx_internal* hc4, const BYTE* start)
{ {
MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable)); MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
@@ -127,21 +108,20 @@ static void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start)
/* Update chains up to ip (excluded) */ /* Update chains up to ip (excluded) */
FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip) FORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE* ip)
{ {
U16* chainTable = hc4->chainTable; U16* const chainTable = hc4->chainTable;
U32* HashTable = hc4->hashTable; U32* const hashTable = hc4->hashTable;
const BYTE* const base = hc4->base; const BYTE* const base = hc4->base;
const U32 target = (U32)(ip - base); U32 const target = (U32)(ip - base);
U32 idx = hc4->nextToUpdate; U32 idx = hc4->nextToUpdate;
while(idx < target) while (idx < target) {
{ U32 const h = LZ4HC_hashPtr(base+idx);
U32 h = LZ4HC_hashPtr(base+idx); size_t delta = idx - hashTable[h];
size_t delta = idx - HashTable[h];
if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
DELTANEXTU16(idx) = (U16)delta; DELTANEXTU16(idx) = (U16)delta;
HashTable[h] = idx; hashTable[h] = idx;
idx++; idx++;
} }
@@ -149,7 +129,7 @@ FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
} }
FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* Index table will be updated */ FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_CCtx_internal* hc4, /* Index table will be updated */
const BYTE* ip, const BYTE* const iLimit, const BYTE* ip, const BYTE* const iLimit,
const BYTE** matchpos, const BYTE** matchpos,
const int maxNbAttempts) const int maxNbAttempts)
@@ -161,7 +141,6 @@ FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* I
const U32 dictLimit = hc4->dictLimit; const U32 dictLimit = hc4->dictLimit;
const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
U32 matchIndex; U32 matchIndex;
const BYTE* match;
int nbAttempts=maxNbAttempts; int nbAttempts=maxNbAttempts;
size_t ml=0; size_t ml=0;
@@ -169,24 +148,19 @@ FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* I
LZ4HC_Insert(hc4, ip); LZ4HC_Insert(hc4, ip);
matchIndex = HashTable[LZ4HC_hashPtr(ip)]; matchIndex = HashTable[LZ4HC_hashPtr(ip)];
while ((matchIndex>=lowLimit) && (nbAttempts)) while ((matchIndex>=lowLimit) && (nbAttempts)) {
{
nbAttempts--; nbAttempts--;
if (matchIndex >= dictLimit) if (matchIndex >= dictLimit) {
{ const BYTE* const match = base + matchIndex;
match = base + matchIndex;
if (*(match+ml) == *(ip+ml) if (*(match+ml) == *(ip+ml)
&& (LZ4_read32(match) == LZ4_read32(ip))) && (LZ4_read32(match) == LZ4_read32(ip)))
{ {
size_t mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH; size_t const mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
if (mlt > ml) { ml = mlt; *matchpos = match; } if (mlt > ml) { ml = mlt; *matchpos = match; }
} }
} } else {
else const BYTE* const match = dictBase + matchIndex;
{ if (LZ4_read32(match) == LZ4_read32(ip)) {
match = dictBase + matchIndex;
if (LZ4_read32(match) == LZ4_read32(ip))
{
size_t mlt; size_t mlt;
const BYTE* vLimit = ip + (dictLimit - matchIndex); const BYTE* vLimit = ip + (dictLimit - matchIndex);
if (vLimit > iLimit) vLimit = iLimit; if (vLimit > iLimit) vLimit = iLimit;
@@ -204,7 +178,7 @@ FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* I
FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (
LZ4HC_Data_Structure* hc4, LZ4HC_CCtx_internal* hc4,
const BYTE* const ip, const BYTE* const ip,
const BYTE* const iLowLimit, const BYTE* const iLowLimit,
const BYTE* const iHighLimit, const BYTE* const iHighLimit,
@@ -229,38 +203,32 @@ FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (
LZ4HC_Insert(hc4, ip); LZ4HC_Insert(hc4, ip);
matchIndex = HashTable[LZ4HC_hashPtr(ip)]; matchIndex = HashTable[LZ4HC_hashPtr(ip)];
while ((matchIndex>=lowLimit) && (nbAttempts)) while ((matchIndex>=lowLimit) && (nbAttempts)) {
{
nbAttempts--; nbAttempts--;
if (matchIndex >= dictLimit) if (matchIndex >= dictLimit) {
{
const BYTE* matchPtr = base + matchIndex; const BYTE* matchPtr = base + matchIndex;
if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) {
if (LZ4_read32(matchPtr) == LZ4_read32(ip)) if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
{
int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit); int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit);
int back = 0; int back = 0;
while ((ip+back>iLowLimit) while ((ip+back > iLowLimit)
&& (matchPtr+back > lowPrefixPtr) && (matchPtr+back > lowPrefixPtr)
&& (ip[back-1] == matchPtr[back-1])) && (ip[back-1] == matchPtr[back-1]))
back--; back--;
mlt -= back; mlt -= back;
if (mlt > longest) if (mlt > longest) {
{
longest = (int)mlt; longest = (int)mlt;
*matchpos = matchPtr+back; *matchpos = matchPtr+back;
*startpos = ip+back; *startpos = ip+back;
} }
} }
} }
else } else {
{ const BYTE* const matchPtr = dictBase + matchIndex;
const BYTE* matchPtr = dictBase + matchIndex; if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
if (LZ4_read32(matchPtr) == LZ4_read32(ip))
{
size_t mlt; size_t mlt;
int back=0; int back=0;
const BYTE* vLimit = ip + (dictLimit - matchIndex); const BYTE* vLimit = ip + (dictLimit - matchIndex);
@@ -320,8 +288,15 @@ FORCE_INLINE int LZ4HC_encodeSequence (
/* Encode MatchLength */ /* Encode MatchLength */
length = (int)(matchLength-MINMATCH); length = (int)(matchLength-MINMATCH);
if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */ if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */
if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; } if (length>=(int)ML_MASK) {
else *token += (BYTE)(length); *token += ML_MASK;
length -= ML_MASK;
for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; }
if (length > 254) { length-=255; *(*op)++ = 255; }
*(*op)++ = (BYTE)length;
} else {
*token += (BYTE)(length);
}
/* Prepare next loop */ /* Prepare next loop */
*ip += matchLength; *ip += matchLength;
@@ -332,16 +307,15 @@ FORCE_INLINE int LZ4HC_encodeSequence (
static int LZ4HC_compress_generic ( static int LZ4HC_compress_generic (
void* ctxvoid, LZ4HC_CCtx_internal* const ctx,
const char* source, const char* const source,
char* dest, char* const dest,
int inputSize, int const inputSize,
int maxOutputSize, int const maxOutputSize,
int compressionLevel, int compressionLevel,
limitedOutput_directive limit limitedOutput_directive limit
) )
{ {
LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid;
const BYTE* ip = (const BYTE*) source; const BYTE* ip = (const BYTE*) source;
const BYTE* anchor = ip; const BYTE* anchor = ip;
const BYTE* const iend = ip + inputSize; const BYTE* const iend = ip + inputSize;
@@ -353,26 +327,24 @@ static int LZ4HC_compress_generic (
unsigned maxNbAttempts; unsigned maxNbAttempts;
int ml, ml2, ml3, ml0; int ml, ml2, ml3, ml0;
const BYTE* ref=NULL; const BYTE* ref = NULL;
const BYTE* start2=NULL; const BYTE* start2 = NULL;
const BYTE* ref2=NULL; const BYTE* ref2 = NULL;
const BYTE* start3=NULL; const BYTE* start3 = NULL;
const BYTE* ref3=NULL; const BYTE* ref3 = NULL;
const BYTE* start0; const BYTE* start0;
const BYTE* ref0; const BYTE* ref0;
/* init */ /* init */
if (compressionLevel > g_maxCompressionLevel) compressionLevel = g_maxCompressionLevel; if (compressionLevel > LZ4HC_MAX_CLEVEL) compressionLevel = LZ4HC_MAX_CLEVEL;
if (compressionLevel < 1) compressionLevel = LZ4HC_compressionLevel_default; if (compressionLevel < 1) compressionLevel = LZ4HC_DEFAULT_CLEVEL;
maxNbAttempts = 1 << (compressionLevel-1); maxNbAttempts = 1 << (compressionLevel-1);
ctx->end += inputSize; ctx->end += inputSize;
ip++; ip++;
/* Main Loop */ /* Main Loop */
while (ip < mflimit) while (ip < mflimit) {
{
ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts); ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts);
if (!ml) { ip++; continue; } if (!ml) { ip++; continue; }
@@ -383,19 +355,16 @@ static int LZ4HC_compress_generic (
_Search2: _Search2:
if (ip+ml < mflimit) if (ip+ml < mflimit)
ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2, maxNbAttempts); ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 0, matchlimit, ml, &ref2, &start2, maxNbAttempts);
else ml2 = ml; else ml2 = ml;
if (ml2 == ml) /* No better match */ if (ml2 == ml) { /* No better match */
{
if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
continue; continue;
} }
if (start0 < ip) if (start0 < ip) {
{ if (start2 < ip + ml0) { /* empirical */
if (start2 < ip + ml0) /* empirical */
{
ip = start0; ip = start0;
ref = ref0; ref = ref0;
ml = ml0; ml = ml0;
@@ -403,8 +372,7 @@ _Search2:
} }
/* Here, start0==ip */ /* Here, start0==ip */
if ((start2 - ip) < 3) /* First Match too small : removed */ if ((start2 - ip) < 3) { /* First Match too small : removed */
{
ml = ml2; ml = ml2;
ip = start2; ip = start2;
ref =ref2; ref =ref2;
@@ -417,15 +385,13 @@ _Search3:
* ml2 > ml1, and * ml2 > ml1, and
* ip1+3 <= ip2 (usually < ip1+ml1) * ip1+3 <= ip2 (usually < ip1+ml1)
*/ */
if ((start2 - ip) < OPTIMAL_ML) if ((start2 - ip) < OPTIMAL_ML) {
{
int correction; int correction;
int new_ml = ml; int new_ml = ml;
if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
correction = new_ml - (int)(start2 - ip); correction = new_ml - (int)(start2 - ip);
if (correction > 0) if (correction > 0) {
{
start2 += correction; start2 += correction;
ref2 += correction; ref2 += correction;
ml2 -= correction; ml2 -= correction;
@@ -437,8 +403,7 @@ _Search3:
ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts); ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts);
else ml3 = ml2; else ml3 = ml2;
if (ml3 == ml2) /* No better match : 2 sequences to encode */ if (ml3 == ml2) { /* No better match : 2 sequences to encode */
{
/* ip & ref are known; Now for ml */ /* ip & ref are known; Now for ml */
if (start2 < ip+ml) ml = (int)(start2 - ip); if (start2 < ip+ml) ml = (int)(start2 - ip);
/* Now, encode 2 sequences */ /* Now, encode 2 sequences */
@@ -448,18 +413,14 @@ _Search3:
continue; continue;
} }
if (start3 < ip+ml+3) /* Not enough space for match 2 : remove it */ if (start3 < ip+ml+3) { /* Not enough space for match 2 : remove it */
{ if (start3 >= (ip+ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */
if (start3 >= (ip+ml)) /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ if (start2 < ip+ml) {
{
if (start2 < ip+ml)
{
int correction = (int)(ip+ml - start2); int correction = (int)(ip+ml - start2);
start2 += correction; start2 += correction;
ref2 += correction; ref2 += correction;
ml2 -= correction; ml2 -= correction;
if (ml2 < MINMATCH) if (ml2 < MINMATCH) {
{
start2 = start3; start2 = start3;
ref2 = ref3; ref2 = ref3;
ml2 = ml3; ml2 = ml3;
@@ -487,23 +448,18 @@ _Search3:
* OK, now we have 3 ascending matches; let's write at least the first one * OK, now we have 3 ascending matches; let's write at least the first one
* ip & ref are known; Now for ml * ip & ref are known; Now for ml
*/ */
if (start2 < ip+ml) if (start2 < ip+ml) {
{ if ((start2 - ip) < (int)ML_MASK) {
if ((start2 - ip) < (int)ML_MASK)
{
int correction; int correction;
if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
correction = ml - (int)(start2 - ip); correction = ml - (int)(start2 - ip);
if (correction > 0) if (correction > 0) {
{
start2 += correction; start2 += correction;
ref2 += correction; ref2 += correction;
ml2 -= correction; ml2 -= correction;
} }
} } else {
else
{
ml = (int)(start2 - ip); ml = (int)(start2 - ip);
} }
} }
@@ -521,8 +477,7 @@ _Search3:
} }
/* Encode Last Literals */ /* Encode Last Literals */
{ { int lastRun = (int)(iend - anchor);
int lastRun = (int)(iend - anchor);
if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
else *op++ = (BYTE)(lastRun<<ML_BITS); else *op++ = (BYTE)(lastRun<<ML_BITS);
@@ -535,22 +490,32 @@ _Search3:
} }
int LZ4_sizeofStateHC(void) { return sizeof(LZ4HC_Data_Structure); } int LZ4_sizeofStateHC(void) { return sizeof(LZ4_streamHC_t); }
int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel)
{ {
LZ4HC_CCtx_internal* ctx = &((LZ4_streamHC_t*)state)->internal_donotuse;
if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */ if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */
LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)src); LZ4HC_init (ctx, (const BYTE*)src);
if (maxDstSize < LZ4_compressBound(srcSize)) if (maxDstSize < LZ4_compressBound(srcSize))
return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput); return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput);
else else
return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, noLimit); return LZ4HC_compress_generic (ctx, src, dst, srcSize, maxDstSize, compressionLevel, noLimit);
} }
int LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) int LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel)
{ {
LZ4HC_Data_Structure state; #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
return LZ4_compress_HC_extStateHC(&state, src, dst, srcSize, maxDstSize, compressionLevel); LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t));
#else
LZ4_streamHC_t state;
LZ4_streamHC_t* const statePtr = &state;
#endif
int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, maxDstSize, compressionLevel);
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
free(statePtr);
#endif
return cSize;
} }
@@ -566,16 +531,15 @@ int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_st
/* initialization */ /* initialization */
void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel)
{ {
LZ4_STATIC_ASSERT(sizeof(LZ4HC_Data_Structure) <= sizeof(LZ4_streamHC_t)); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= sizeof(size_t) * LZ4_STREAMHCSIZE_SIZET); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->base = NULL; LZ4_streamHCPtr->internal_donotuse.base = NULL;
((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->compressionLevel = (unsigned)compressionLevel; LZ4_streamHCPtr->internal_donotuse.compressionLevel = (unsigned)compressionLevel;
} }
int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize) int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize)
{ {
LZ4HC_Data_Structure* ctxPtr = (LZ4HC_Data_Structure*) LZ4_streamHCPtr; LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
if (dictSize > 64 KB) if (dictSize > 64 KB) {
{
dictionary += dictSize - 64 KB; dictionary += dictSize - 64 KB;
dictSize = 64 KB; dictSize = 64 KB;
} }
@@ -588,10 +552,9 @@ int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int
/* compression */ /* compression */
static void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newBlock) static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock)
{ {
if (ctxPtr->end >= ctxPtr->base + 4) if (ctxPtr->end >= ctxPtr->base + 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */
LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */
/* Only one memory segment for extDict, so any previous extDict is lost at this stage */ /* Only one memory segment for extDict, so any previous extDict is lost at this stage */
ctxPtr->lowLimit = ctxPtr->dictLimit; ctxPtr->lowLimit = ctxPtr->dictLimit;
ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base); ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
@@ -601,34 +564,29 @@ static void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newB
ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */
} }
static int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* ctxPtr, static int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
const char* source, char* dest, const char* source, char* dest,
int inputSize, int maxOutputSize, limitedOutput_directive limit) int inputSize, int maxOutputSize, limitedOutput_directive limit)
{ {
LZ4HC_CCtx_internal* ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
/* auto-init if forgotten */ /* auto-init if forgotten */
if (ctxPtr->base == NULL) if (ctxPtr->base == NULL) LZ4HC_init (ctxPtr, (const BYTE*) source);
LZ4HC_init (ctxPtr, (const BYTE*) source);
/* Check overflow */ /* Check overflow */
if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) {
{
size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit; size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
if (dictSize > 64 KB) dictSize = 64 KB; if (dictSize > 64 KB) dictSize = 64 KB;
LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
LZ4_loadDictHC((LZ4_streamHC_t*)ctxPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
} }
/* Check if blocks follow each other */ /* Check if blocks follow each other */
if ((const BYTE*)source != ctxPtr->end) if ((const BYTE*)source != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source);
LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source);
/* Check overlapping input/dictionary space */ /* Check overlapping input/dictionary space */
{ { const BYTE* sourceEnd = (const BYTE*) source + inputSize;
const BYTE* sourceEnd = (const BYTE*) source + inputSize; const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
const BYTE* dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
const BYTE* dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd)) {
if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd))
{
if (sourceEnd > dictEnd) sourceEnd = dictEnd; if (sourceEnd > dictEnd) sourceEnd = dictEnd;
ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase); ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit; if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
@@ -641,9 +599,9 @@ static int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* ctxPtr,
int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize) int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize)
{ {
if (maxOutputSize < LZ4_compressBound(inputSize)) if (maxOutputSize < LZ4_compressBound(inputSize))
return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput); return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput);
else else
return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit); return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit);
} }
@@ -651,14 +609,13 @@ int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* sourc
int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize) int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
{ {
LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*)LZ4_streamHCPtr; LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
int prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
if (dictSize > 64 KB) dictSize = 64 KB; if (dictSize > 64 KB) dictSize = 64 KB;
if (dictSize < 4) dictSize = 0; if (dictSize < 4) dictSize = 0;
if (dictSize > prefixSize) dictSize = prefixSize; if (dictSize > prefixSize) dictSize = prefixSize;
memmove(safeBuffer, streamPtr->end - dictSize, dictSize); memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
{ { U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
U32 endIndex = (U32)(streamPtr->end - streamPtr->base);
streamPtr->end = (const BYTE*)safeBuffer + dictSize; streamPtr->end = (const BYTE*)safeBuffer + dictSize;
streamPtr->base = streamPtr->end - endIndex; streamPtr->base = streamPtr->end - endIndex;
streamPtr->dictLimit = endIndex - dictSize; streamPtr->dictLimit = endIndex - dictSize;
@@ -672,8 +629,8 @@ int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictS
/*********************************** /***********************************
* Deprecated Functions * Deprecated Functions
***********************************/ ***********************************/
/* These functions currently generate deprecation warnings */
/* Deprecated compression functions */ /* Deprecated compression functions */
/* These functions are planned to start generate warnings by r131 approximately */
int LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); } int LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); }
int LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); } int LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); }
int LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } int LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); }
@@ -687,45 +644,41 @@ int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const char* src,
/* Deprecated streaming functions */ /* Deprecated streaming functions */
/* These functions currently generate deprecation warnings */
int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; } int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; }
int LZ4_resetStreamStateHC(void* state, char* inputBuffer) int LZ4_resetStreamStateHC(void* state, char* inputBuffer)
{ {
LZ4HC_CCtx_internal *ctx = &((LZ4_streamHC_t*)state)->internal_donotuse;
if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */ if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */
LZ4HC_init((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer); LZ4HC_init(ctx, (const BYTE*)inputBuffer);
((LZ4HC_Data_Structure*)state)->inputBuffer = (BYTE*)inputBuffer; ctx->inputBuffer = (BYTE*)inputBuffer;
return 0; return 0;
} }
void* LZ4_createHC (char* inputBuffer) void* LZ4_createHC (char* inputBuffer)
{ {
void* hc4 = ALLOCATOR(1, sizeof(LZ4HC_Data_Structure)); LZ4_streamHC_t* hc4 = (LZ4_streamHC_t*)ALLOCATOR(1, sizeof(LZ4_streamHC_t));
if (hc4 == NULL) return NULL; /* not enough memory */ if (hc4 == NULL) return NULL; /* not enough memory */
LZ4HC_init ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer); LZ4HC_init (&hc4->internal_donotuse, (const BYTE*)inputBuffer);
((LZ4HC_Data_Structure*)hc4)->inputBuffer = (BYTE*)inputBuffer; hc4->internal_donotuse.inputBuffer = (BYTE*)inputBuffer;
return hc4; return hc4;
} }
int LZ4_freeHC (void* LZ4HC_Data) int LZ4_freeHC (void* LZ4HC_Data) { FREEMEM(LZ4HC_Data); return 0; }
{
FREEMEM(LZ4HC_Data);
return (0);
}
int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel) int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel)
{ {
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel, noLimit); return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, 0, compressionLevel, noLimit);
} }
int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel) int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
{ {
return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput); return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
} }
char* LZ4_slideInputBufferHC(void* LZ4HC_Data) char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
{ {
LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data; LZ4HC_CCtx_internal* const hc4 = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse;
int dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB); int const dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB);
return (char*)(hc4->inputBuffer + dictSize); return (char*)(hc4->inputBuffer + dictSize);
} }

View File

@@ -1,7 +1,7 @@
/* /*
LZ4 HC - High Compression Mode of LZ4 LZ4 HC - High Compression Mode of LZ4
Header File Header File
Copyright (C) 2011-2015, Yann Collet. Copyright (C) 2011-2016, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -28,107 +28,91 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at : You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4 - LZ4 source repository : https://github.com/lz4/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/ */
#pragma once #ifndef LZ4_HC_H_19834876238432
#define LZ4_HC_H_19834876238432
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
/***************************** /* --- Dependency --- */
* Includes /* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */
*****************************/ #include "lz4.h" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */
#include <stddef.h> /* size_t */
/************************************** /* --- Useful constants --- */
* Block Compression #define LZ4HC_MIN_CLEVEL 3
**************************************/ #define LZ4HC_DEFAULT_CLEVEL 9
int LZ4_compress_HC (const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel); #define LZ4HC_MAX_CLEVEL 16
/*
LZ4_compress_HC :
Destination buffer 'dst' must be already allocated. /*-************************************
Compression completion is guaranteed if 'dst' buffer is sized to handle worst circumstances (data not compressible) * Block Compression
Worst size evaluation is provided by function LZ4_compressBound() (see "lz4.h") **************************************/
srcSize : Max supported value is LZ4_MAX_INPUT_SIZE (see "lz4.h") /*! LZ4_compress_HC() :
compressionLevel : Recommended values are between 4 and 9, although any value between 0 and 16 will work. * Compress data from `src` into `dst`, using the more powerful but slower "HC" algorithm.
0 means "use default value" (see lz4hc.c). * `dst` must be already allocated.
Values >16 behave the same as 16. * Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h")
return : the number of bytes written into buffer 'dst' * Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h")
or 0 if compression fails. * `compressionLevel` : Recommended values are between 4 and 9, although any value between 1 and LZ4HC_MAX_CLEVEL will work.
*/ * Values >LZ4HC_MAX_CLEVEL behave the same as 16.
* @return : the number of bytes written into 'dst'
* or 0 if compression fails.
*/
LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
/* Note : /* Note :
Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license) * Decompression functions are provided within "lz4.h" (BSD license)
*/ */
int LZ4_sizeofStateHC(void); /*! LZ4_compress_HC_extStateHC() :
int LZ4_compress_HC_extStateHC(void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel); * Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`.
/* * `state` size is provided by LZ4_sizeofStateHC().
LZ4_compress_HC_extStateHC() : * Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() will do properly).
Use this function if you prefer to manually allocate memory for compression tables. */
To know how much memory must be allocated for the compression tables, use : LZ4LIB_API int LZ4_compress_HC_extStateHC(void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel);
int LZ4_sizeofStateHC(); LZ4LIB_API int LZ4_sizeofStateHC(void);
Allocated memory must be aligned on 8-bytes boundaries (which a normal malloc() will do properly).
The allocated memory can then be provided to the compression functions using 'void* state' parameter.
LZ4_compress_HC_extStateHC() is equivalent to previously described function.
It just uses externally allocated memory for stateHC.
*/
/************************************** /*-************************************
* Streaming Compression * Streaming Compression
**************************************/ * Bufferless synchronous API
#define LZ4_STREAMHCSIZE 262192 **************************************/
#define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t)) typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */
typedef struct { size_t table[LZ4_STREAMHCSIZE_SIZET]; } LZ4_streamHC_t;
/*
LZ4_streamHC_t
This structure allows static allocation of LZ4 HC streaming state.
State must then be initialized using LZ4_resetStreamHC() before first use.
Static allocation should only be used in combination with static linking. /*! LZ4_createStreamHC() and LZ4_freeStreamHC() :
If you want to use LZ4 as a DLL, please use construction functions below, which are future-proof. * These functions create and release memory for LZ4 HC streaming state.
*/ * Newly created states are automatically initialized.
* Existing states can be re-used several times, using LZ4_resetStreamHC().
* These methods are API and ABI stable, they can be used in combination with a DLL.
*/
LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void);
LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel);
LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize);
LZ4_streamHC_t* LZ4_createStreamHC(void); LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr, const char* src, char* dst, int srcSize, int maxDstSize);
int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
/*
These functions create and release memory for LZ4 HC streaming state.
Newly created states are already initialized.
Existing state space can be re-used anytime using LZ4_resetStreamHC().
If you use LZ4 as a DLL, use these functions instead of static structure allocation,
to avoid size mismatch between different versions.
*/
void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel); LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize);
int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr, const char* src, char* dst, int srcSize, int maxDstSize);
int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
/* /*
These functions compress data in successive blocks of any size, using previous blocks as dictionary. These functions compress data in successive blocks of any size, using previous blocks as dictionary.
One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks. One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks.
There is an exception for ring buffers, which can be smaller 64 KB. There is an exception for ring buffers, which can be smaller than 64 KB.
Such case is automatically detected and correctly handled by LZ4_compress_HC_continue(). Ring buffers scenario is automatically detected and handled by LZ4_compress_HC_continue().
Before starting compression, state must be properly initialized, using LZ4_resetStreamHC(). Before starting compression, state must be properly initialized, using LZ4_resetStreamHC().
A first "fictional block" can then be designated as initial dictionary, using LZ4_loadDictHC() (Optional). A first "fictional block" can then be designated as initial dictionary, using LZ4_loadDictHC() (Optional).
Then, use LZ4_compress_HC_continue() to compress each successive block. Then, use LZ4_compress_HC_continue() to compress each successive block.
It works like LZ4_compress_HC(), but use previous memory blocks as dictionary to improve compression.
Previous memory blocks (including initial dictionary when present) must remain accessible and unmodified during compression. Previous memory blocks (including initial dictionary when present) must remain accessible and unmodified during compression.
As a reminder, size 'dst' buffer to handle worst cases, using LZ4_compressBound(), to ensure success of compression operation. 'dst' buffer should be sized to handle worst case scenarios, using LZ4_compressBound(), to ensure operation success.
If, for any reason, previous data blocks can't be preserved unmodified in memory during next compression block, If, for any reason, previous data blocks can't be preserved unmodified in memory during next compression block,
you must save it to a safer memory space, using LZ4_saveDictHC(). you must save it to a safer memory space, using LZ4_saveDictHC().
@@ -136,50 +120,100 @@ int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSi
*/ */
/*-******************************************
* !!!!! STATIC LINKING ONLY !!!!!
*******************************************/
/************************************** /*-*************************************
* PRIVATE DEFINITIONS :
* Do not use these definitions.
* They are exposed to allow static allocation of `LZ4_streamHC_t`.
* Using these definitions makes the code vulnerable to potential API break when upgrading LZ4
**************************************/
#define LZ4HC_DICTIONARY_LOGSIZE 16
#define LZ4HC_MAXD (1<<LZ4HC_DICTIONARY_LOGSIZE)
#define LZ4HC_MAXD_MASK (LZ4HC_MAXD - 1)
#define LZ4HC_HASH_LOG (LZ4HC_DICTIONARY_LOGSIZE-1)
#define LZ4HC_HASHTABLESIZE (1 << LZ4HC_HASH_LOG)
#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
#include <stdint.h>
typedef struct
{
uint32_t hashTable[LZ4HC_HASHTABLESIZE];
uint16_t chainTable[LZ4HC_MAXD];
const uint8_t* end; /* next block here to continue on current prefix */
const uint8_t* base; /* All index relative to this position */
const uint8_t* dictBase; /* alternate base for extDict */
uint8_t* inputBuffer; /* deprecated */
uint32_t dictLimit; /* below that point, need extDict */
uint32_t lowLimit; /* below that point, no more dict */
uint32_t nextToUpdate; /* index from which to continue dictionary update */
uint32_t compressionLevel;
} LZ4HC_CCtx_internal;
#else
typedef struct
{
unsigned int hashTable[LZ4HC_HASHTABLESIZE];
unsigned short chainTable[LZ4HC_MAXD];
const unsigned char* end; /* next block here to continue on current prefix */
const unsigned char* base; /* All index relative to this position */
const unsigned char* dictBase; /* alternate base for extDict */
unsigned char* inputBuffer; /* deprecated */
unsigned int dictLimit; /* below that point, need extDict */
unsigned int lowLimit; /* below that point, no more dict */
unsigned int nextToUpdate; /* index from which to continue dictionary update */
unsigned int compressionLevel;
} LZ4HC_CCtx_internal;
#endif
#define LZ4_STREAMHCSIZE 262192
#define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t))
union LZ4_streamHC_u {
size_t table[LZ4_STREAMHCSIZE_SIZET];
LZ4HC_CCtx_internal internal_donotuse;
}; /* previously typedef'd to LZ4_streamHC_t */
/*
LZ4_streamHC_t :
This structure allows static allocation of LZ4 HC streaming state.
State must be initialized using LZ4_resetStreamHC() before first use.
Static allocation shall only be used in combination with static linking.
When invoking LZ4 from a DLL, use create/free functions instead, which are API and ABI stable.
*/
/*-************************************
* Deprecated Functions * Deprecated Functions
**************************************/ **************************************/
/* Deprecate Warnings */ /* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */
/* Should these warnings messages be a problem,
it is generally possible to disable them,
with -Wno-deprecated-declarations for gcc
or _CRT_SECURE_NO_WARNINGS in Visual for example.
You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
# define LZ4_DEPRECATE_WARNING_DEFBLOCK
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
# if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
# elif (LZ4_GCC_VERSION >= 301)
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
# elif defined(_MSC_VER)
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
# else
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
# define LZ4_DEPRECATED(message)
# endif
#endif // LZ4_DEPRECATE_WARNING_DEFBLOCK
/* compression functions */ /* deprecated compression functions */
/* these functions are planned to trigger warning messages by r131 approximately */ /* these functions will trigger warning messages in future releases */
int LZ4_compressHC (const char* source, char* dest, int inputSize); LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC (const char* source, char* dest, int inputSize);
int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel); LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel);
int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize); LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize);
int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel); LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel);
int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize); LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize);
int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize); LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
/* Streaming functions following the older model; should no longer be used */ /* Deprecated Streaming functions using older model; should no longer be used */
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") void* LZ4_createHC (char* inputBuffer); LZ4_DEPRECATED("use LZ4_createStreamHC() instead") void* LZ4_createHC (char* inputBuffer);
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") char* LZ4_slideInputBufferHC (void* LZ4HC_Data); LZ4_DEPRECATED("use LZ4_saveDictHC() instead") char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") int LZ4_freeHC (void* LZ4HC_Data); LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") int LZ4_freeHC (void* LZ4HC_Data);
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel); LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") int LZ4_sizeofStreamStateHC(void); LZ4_DEPRECATED("use LZ4_createStreamHC() instead") int LZ4_sizeofStreamStateHC(void);
LZ4_DEPRECATED("use LZ4_resetStreamHC() instead") int LZ4_resetStreamStateHC(void* state, char* inputBuffer); LZ4_DEPRECATED("use LZ4_resetStreamHC() instead") int LZ4_resetStreamStateHC(void* state, char* inputBuffer);
@@ -187,3 +221,5 @@ LZ4_DEPRECATED("use LZ4_resetStreamHC() instead") int LZ4_resetStreamStateHC(
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* LZ4_HC_H_19834876238432 */

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/* /*
xxHash - Extremely Fast Hash algorithm xxHash - Extremely Fast Hash algorithm
Header File Header File
Copyright (C) 2012-2015, Yann Collet. Copyright (C) 2012-2016, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
@@ -64,129 +64,230 @@ XXH64 13.8 GB/s 1.9 GB/s
XXH32 6.8 GB/s 6.0 GB/s XXH32 6.8 GB/s 6.0 GB/s
*/ */
#pragma once #ifndef XXHASH_H_5627135585666179
#define XXHASH_H_5627135585666179 1
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
/***************************** /* ****************************
* Definitions * Definitions
*****************************/ ******************************/
#include <stddef.h> /* size_t */ #include <stddef.h> /* size_t */
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
/***************************** /* ****************************
* Namespace Emulation * API modifier
*****************************/ ******************************/
/* Motivations : /** XXH_PRIVATE_API
* This is useful to include xxhash functions in `static` mode
* in order to inline them, and remove their symbol from the public list.
* Methodology :
* #define XXH_PRIVATE_API
* #include "xxhash.h"
* `xxhash.c` is automatically included.
* It's not useful to compile and link it as a separate module.
*/
#ifdef XXH_PRIVATE_API
# ifndef XXH_STATIC_LINKING_ONLY
# define XXH_STATIC_LINKING_ONLY
# endif
# if defined(__GNUC__)
# define XXH_PUBLIC_API static __inline __attribute__((unused))
# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
# define XXH_PUBLIC_API static inline
# elif defined(_MSC_VER)
# define XXH_PUBLIC_API static __inline
# else
# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */
# endif
#else
# define XXH_PUBLIC_API /* do nothing */
#endif /* XXH_PRIVATE_API */
If you need to include xxHash into your library, /*!XXH_NAMESPACE, aka Namespace Emulation :
but wish to avoid xxHash symbols to be present on your library interface
in an effort to avoid potential name collision if another library also includes xxHash,
you can use XXH_NAMESPACE, which will automatically prefix any symbol from xxHash If you want to include _and expose_ xxHash functions from within your own library,
with the value of XXH_NAMESPACE (so avoid to keep it NULL, and avoid numeric values). but also want to avoid symbol collisions with other libraries which may also include xxHash,
Note that no change is required within the calling program : you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
it can still call xxHash functions using their regular name. with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values).
They will be automatically translated by this header.
Note that no change is required within the calling program as long as it includes `xxhash.h` :
regular symbol name will be automatically translated by this header.
*/ */
#ifdef XXH_NAMESPACE #ifdef XXH_NAMESPACE
# define XXH_CAT(A,B) A##B # define XXH_CAT(A,B) A##B
# define XXH_NAME2(A,B) XXH_CAT(A,B) # define XXH_NAME2(A,B) XXH_CAT(A,B)
# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
#endif #endif
/***************************** /* *************************************
* Simple Hash Functions * Version
*****************************/ ***************************************/
#define XXH_VERSION_MAJOR 0
#define XXH_VERSION_MINOR 6
#define XXH_VERSION_RELEASE 2
#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
XXH_PUBLIC_API unsigned XXH_versionNumber (void);
unsigned int XXH32 (const void* input, size_t length, unsigned seed);
unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed);
/* /*-**********************************************************************
XXH32() : * 32-bits hash
************************************************************************/
typedef unsigned int XXH32_hash_t;
/*! XXH32() :
Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
The memory between input & input+length must be valid (allocated and read-accessible). The memory between input & input+length must be valid (allocated and read-accessible).
"seed" can be used to alter the result predictably. "seed" can be used to alter the result predictably.
This function successfully passes all SMHasher tests. Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */
Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
XXH64() :
Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
Faster on 64-bits systems. Slower on 32-bits systems.
*/
/*====== Streaming ======*/
typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
/***************************** XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
* Advanced Hash Functions XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
*****************************/
typedef struct { long long ll[ 6]; } XXH32_state_t;
typedef struct { long long ll[11]; } XXH64_state_t;
/* /*
These structures allow static allocation of XXH states. These functions generate the xxHash of an input provided in multiple segments.
States must then be initialized using XXHnn_reset() before first use. Note that, for small input, they are slower than single-call functions, due to state management.
For small input, prefer `XXH32()` and `XXH64()` .
If you prefer dynamic allocation, please refer to functions below. XXH state must first be allocated, using XXH*_createState() .
*/
XXH32_state_t* XXH32_createState(void); Start a new hash by initializing state with a seed, using XXH*_reset().
XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
XXH64_state_t* XXH64_createState(void); Then, feed the hash state by calling XXH*_update() as many times as necessary.
XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); Obviously, input must be allocated and read accessible.
/*
These functions create and release memory for XXH state.
States must then be initialized using XXHnn_reset() before first use.
*/
XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed);
XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
unsigned int XXH32_digest (const XXH32_state_t* statePtr);
XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
unsigned long long XXH64_digest (const XXH64_state_t* statePtr);
/*
These functions calculate the xxHash of an input provided in multiple smaller packets,
as opposed to an input provided as a single block.
XXH state space must first be allocated, using either static or dynamic method provided above.
Start a new hash by initializing state with a seed, using XXHnn_reset().
Then, feed the hash state by calling XXHnn_update() as many times as necessary.
Obviously, input must be valid, meaning allocated and read accessible.
The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
Finally, you can produce a hash anytime, by using XXHnn_digest(). Finally, a hash value can be produced anytime, by using XXH*_digest().
This function returns the final nn-bits hash. This function returns the nn-bits hash as an int or long long.
You can nonetheless continue feeding the hash state with more input,
and therefore get some new hashes, by calling again XXHnn_digest().
When you are done, don't forget to free XXH state space, using typically XXHnn_freeState(). It's still possible to continue inserting input into the hash state after a digest,
and generate some new hashes later on, by calling again XXH*_digest().
When done, free XXH state space if it was allocated dynamically.
*/ */
/*====== Canonical representation ======*/
typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
* The canonical representation uses human-readable write convention, aka big-endian (large digits first).
* These functions allow transformation of hash result into and from its canonical format.
* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
*/
#ifndef XXH_NO_LONG_LONG
/*-**********************************************************************
* 64-bits hash
************************************************************************/
typedef unsigned long long XXH64_hash_t;
/*! XXH64() :
Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
"seed" can be used to alter the result predictably.
This function runs faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
*/
XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
/*====== Streaming ======*/
typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
/*====== Canonical representation ======*/
typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
#endif /* XXH_NO_LONG_LONG */
#ifdef XXH_STATIC_LINKING_ONLY
/* ================================================================================================
This section contains definitions which are not guaranteed to remain stable.
They may change in future versions, becoming incompatible with a different version of the library.
They shall only be used with static linking.
Never use these definitions in association with dynamic linking !
=================================================================================================== */
/* These definitions are only meant to allow allocation of XXH state
statically, on stack, or in a struct for example.
Do not use members directly. */
struct XXH32_state_s {
unsigned total_len_32;
unsigned large_len;
unsigned v1;
unsigned v2;
unsigned v3;
unsigned v4;
unsigned mem32[4]; /* buffer defined as U32 for alignment */
unsigned memsize;
unsigned reserved; /* never read nor write, will be removed in a future version */
}; /* typedef'd to XXH32_state_t */
#ifndef XXH_NO_LONG_LONG
struct XXH64_state_s {
unsigned long long total_len;
unsigned long long v1;
unsigned long long v2;
unsigned long long v3;
unsigned long long v4;
unsigned long long mem64[4]; /* buffer defined as U64 for alignment */
unsigned memsize;
unsigned reserved[2]; /* never read nor write, will be removed in a future version */
}; /* typedef'd to XXH64_state_t */
#endif
# ifdef XXH_PRIVATE_API
# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */
# endif
#endif /* XXH_STATIC_LINKING_ONLY */
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* XXHASH_H_5627135585666179 */

View File

@@ -35,13 +35,26 @@ You can contact the author at :
/************************************** /**************************************
* Tuning parameters * Tuning parameters
**************************************/ **************************************/
/* Unaligned memory access is automatically enabled for "common" CPU, such as x86. /* XXH_FORCE_MEMORY_ACCESS
* For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected. * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
* If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance. * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
* You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32). * The below switch allow to select different access method for improved performance.
* Method 0 (default) : use `memcpy()`. Safe and portable.
* Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
* This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
* Method 2 : direct access. This method is portable but violate C standard.
* It can generate buggy code on targets which generate assembly depending on alignment.
* But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
* See http://stackoverflow.com/a/32095106/646947 for details.
* Prefer these methods in priority order (0 > 1 > 2)
*/ */
#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
# define XXH_USE_UNALIGNED_ACCESS 1 # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
# define XXH_FORCE_MEMORY_ACCESS 2
# elif defined(__INTEL_COMPILER) || \
(defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
# define XXH_FORCE_MEMORY_ACCESS 1
# endif
#endif #endif
/* XXH_ACCEPT_NULL_INPUT_POINTER : /* XXH_ACCEPT_NULL_INPUT_POINTER :
@@ -55,12 +68,21 @@ You can contact the author at :
* By default, xxHash library provides endian-independant Hash values, based on little-endian convention. * By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
* Results are therefore identical for little-endian and big-endian CPU. * Results are therefore identical for little-endian and big-endian CPU.
* This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
* Should endian-independance be of no importance for your application, you may set the #define below to 1. * Should endian-independance be of no importance for your application, you may set the #define below to 1,
* It will improve speed for Big-endian CPU. * to improve speed for Big-endian CPU.
* This option has no impact on Little_Endian CPU. * This option has no impact on Little_Endian CPU.
*/ */
#define XXH_FORCE_NATIVE_FORMAT 0 #define XXH_FORCE_NATIVE_FORMAT 0
/* XXH_USELESS_ALIGN_BRANCH :
* This is a minor performance trick, only useful with lots of very small keys.
* It means : don't make a test between aligned/unaligned, because performance will be the same.
* It saves one initial branch per hash.
*/
#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
# define XXH_USELESS_ALIGN_BRANCH 1
#endif
/************************************** /**************************************
* Compiler Specific Options * Compiler Specific Options
@@ -113,20 +135,43 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
typedef unsigned long long U64; typedef unsigned long long U64;
#endif #endif
#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
/* currently only defined for gcc and icc */
typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign;
static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
#else
/* portable and safe solution. Generally efficient.
* see : http://stackoverflow.com/a/32095106/646947
*/
static U32 XXH_read32(const void* memPtr) static U32 XXH_read32(const void* memPtr)
{ {
U32 val32; U32 val;
memcpy(&val32, memPtr, 4); memcpy(&val, memPtr, sizeof(val));
return val32; return val;
} }
static U64 XXH_read64(const void* memPtr) static U64 XXH_read64(const void* memPtr)
{ {
U64 val64; U64 val;
memcpy(&val64, memPtr, 8); memcpy(&val, memPtr, sizeof(val));
return val64; return val;
} }
#endif // XXH_FORCE_DIRECT_MEMORY_ACCESS
/****************************************** /******************************************
@@ -175,8 +220,10 @@ static U64 XXH_swap64 (U64 x)
* Architecture Macros * Architecture Macros
***************************************/ ***************************************/
typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
#ifndef XXH_CPU_LITTLE_ENDIAN /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example using a compiler switch */
static const int one = 1; /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example one the compiler command line */
#ifndef XXH_CPU_LITTLE_ENDIAN
static const int one = 1;
# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one)) # define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one))
#endif #endif
@@ -315,7 +362,7 @@ FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH
} }
unsigned XXH32 (const void* input, size_t len, unsigned seed) unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
{ {
#if 0 #if 0
/* Simple version, good for code maintenance, but unfortunately slow for small inputs */ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
@@ -326,7 +373,7 @@ unsigned XXH32 (const void* input, size_t len, unsigned seed)
#else #else
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
# if !defined(XXH_USE_UNALIGNED_ACCESS) # if !defined(XXH_USELESS_ALIGN_BRANCH)
if ((((size_t)input) & 3) == 0) /* Input is 4-bytes aligned, leverage the speed benefit */ if ((((size_t)input) & 3) == 0) /* Input is 4-bytes aligned, leverage the speed benefit */
{ {
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
@@ -466,7 +513,7 @@ unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed
#else #else
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
# if !defined(XXH_USE_UNALIGNED_ACCESS) # if !defined(XXH_USELESS_ALIGN_BRANCH)
if ((((size_t)input) & 7)==0) /* Input is aligned, let's leverage the speed advantage */ if ((((size_t)input) & 7)==0) /* Input is aligned, let's leverage the speed advantage */
{ {
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
@@ -538,7 +585,7 @@ XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
/*** Hash feed ***/ /*** Hash feed ***/
XXH_errorcode XXH32_reset(XXH32_state_t* state_in, U32 seed) XXH_errorcode XXH32_reset(XXH32_state_t* state_in, unsigned int seed)
{ {
XXH_istate32_t* state = (XXH_istate32_t*) state_in; XXH_istate32_t* state = (XXH_istate32_t*) state_in;
state->seed = seed; state->seed = seed;
@@ -708,7 +755,7 @@ FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endiane
} }
U32 XXH32_digest (const XXH32_state_t* state_in) unsigned int XXH32_digest (const XXH32_state_t* state_in)
{ {
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;

View File

@@ -15,6 +15,7 @@
#include <stdlib.h> #include <stdlib.h>
#define ZSTD_STATIC_LINKING_ONLY #define ZSTD_STATIC_LINKING_ONLY
//#define DEBUGME
#include "zstd.h" #include "zstd.h"
#include "mem.h" #include "mem.h"
@@ -114,12 +115,20 @@ ZSTDMT_CCtx *ZSTDMT_createCCtx(int threads, int level, int inputsize)
if (inputsize) if (inputsize)
ctx->inputsize = inputsize; ctx->inputsize = inputsize;
else { else {
/* XXX - windowlog */ const int mb[] = { #ifndef DEBUGME
2, 2, 4, 4, 6, 6, 6, /* 1 - 7 */ const int windowLog[] = {
8, 8, 8, 8, 8, 8, 8, /* 8 - 14 */ 0, 19, 19, 20, 20, 20, 21, 21,
16, 16, 16, 16, 16, 16, 16, 16 /* 15 - 22 */ 21, 21, 21, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 25, 26, 27
}; };
ctx->inputsize = 1024 * 1024 * mb[level - 1]; ctx->inputsize = 1 << (windowLog[level] + 1);
#else
const int mb[] = { 0, 1, 1, 1, 2, 2, 2,
3, 3, 3, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5
};
ctx->inputsize = 1024 * 1024 * mb[level];
#endif
} }
/* setup ctx */ /* setup ctx */