mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 17:15:00 -06:00
Update LZ4 to version 1.9.4
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
LZ4 Library
|
||||
Copyright (c) 2011-2016, Yann Collet
|
||||
Copyright (c) 2011-2020, Yann Collet
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
@@ -2,16 +2,20 @@ LZ4 - Library Files
|
||||
================================
|
||||
|
||||
The `/lib` directory contains many files, but depending on project's objectives,
|
||||
not all of them are necessary.
|
||||
not all of them are required.
|
||||
Limited systems may want to reduce the nb of source files to include
|
||||
as a way to reduce binary size and dependencies.
|
||||
|
||||
#### Minimal LZ4 build
|
||||
Capabilities are added at the "level" granularity, detailed below.
|
||||
|
||||
#### Level 1 : Minimal LZ4 build
|
||||
|
||||
The minimum required is **`lz4.c`** and **`lz4.h`**,
|
||||
which provides the fast compression and decompression algorithms.
|
||||
They generate and decode data using the [LZ4 block format].
|
||||
|
||||
|
||||
#### High Compression variant
|
||||
#### Level 2 : High Compression variant
|
||||
|
||||
For more compression ratio at the cost of compression speed,
|
||||
the High Compression variant called **lz4hc** is available.
|
||||
@@ -20,7 +24,7 @@ This variant also compresses data using the [LZ4 block format],
|
||||
and depends on regular `lib/lz4.*` source files.
|
||||
|
||||
|
||||
#### Frame support, for interoperability
|
||||
#### Level 3 : Frame support, for interoperability
|
||||
|
||||
In order to produce compressed data compatible with `lz4` command line utility,
|
||||
it's necessary to use the [official interoperable frame format].
|
||||
@@ -28,14 +32,29 @@ This format is generated and decoded automatically by the **lz4frame** library.
|
||||
Its public API is described in `lib/lz4frame.h`.
|
||||
In order to work properly, lz4frame needs all other modules present in `/lib`,
|
||||
including, lz4 and lz4hc, and also **xxhash**.
|
||||
So it's necessary to include all `*.c` and `*.h` files present in `/lib`.
|
||||
So it's necessary to also include `xxhash.c` and `xxhash.h`.
|
||||
|
||||
|
||||
#### Level 4 : File compression operations
|
||||
|
||||
As a helper around file operations,
|
||||
the library has been recently extended with `lz4file.c` and `lz4file.h`
|
||||
(still considered experimental at the time of this writing).
|
||||
These helpers allow opening, reading, writing, and closing files
|
||||
using transparent LZ4 compression / decompression.
|
||||
As a consequence, using `lz4file` adds a dependency on `<stdio.h>`.
|
||||
|
||||
`lz4file` relies on `lz4frame` in order to produce compressed data
|
||||
conformant to the [LZ4 Frame format] specification.
|
||||
Consequently, to enable this capability,
|
||||
it's necessary to include all `*.c` and `*.h` files from `lib/` directory.
|
||||
|
||||
|
||||
#### Advanced / Experimental API
|
||||
|
||||
Definitions which are not guaranteed to remain stable in future versions,
|
||||
are protected behind macros, such as `LZ4_STATIC_LINKING_ONLY`.
|
||||
As the name strongly implies, these definitions should only be invoked
|
||||
As the name suggests, these definitions should only be invoked
|
||||
in the context of static linking ***only***.
|
||||
Otherwise, dependent application may fail on API or ABI break in the future.
|
||||
The associated symbols are also not exposed by the dynamic library by default.
|
||||
@@ -58,7 +77,7 @@ The following build macro can be selected to adjust source code behavior at comp
|
||||
Set to 65535 by default, which is the maximum value supported by lz4 format.
|
||||
Reducing maximum distance will reduce opportunities for LZ4 to find matches,
|
||||
hence will produce a worse compression ratio.
|
||||
However, a smaller max distance can allow compatibility with specific decoders using limited memory budget.
|
||||
Setting a smaller max distance could allow compatibility with specific decoders with limited memory budget.
|
||||
This build macro only influences the compressed output of the compressor.
|
||||
|
||||
- `LZ4_DISABLE_DEPRECATE_WARNINGS` : invoking a deprecated function will make the compiler generate a warning.
|
||||
@@ -69,15 +88,11 @@ The following build macro can be selected to adjust source code behavior at comp
|
||||
This build macro offers another project-specific method
|
||||
by defining `LZ4_DISABLE_DEPRECATE_WARNINGS` before including the LZ4 header files.
|
||||
|
||||
- `LZ4_USER_MEMORY_FUNCTIONS` : replace calls to <stdlib>'s `malloc`, `calloc` and `free`
|
||||
by user-defined functions, which must be called `LZ4_malloc()`, `LZ4_calloc()` and `LZ4_free()`.
|
||||
User functions must be available at link time.
|
||||
|
||||
- `LZ4_FORCE_SW_BITCOUNT` : by default, the compression algorithm tries to determine lengths
|
||||
by using bitcount instructions, generally implemented as fast single instructions in many cpus.
|
||||
In case the target cpus doesn't support it, or compiler intrinsic doesn't work, or feature bad performance,
|
||||
it's possible to use an optimized software path instead.
|
||||
This is achieved by setting this build macros .
|
||||
This is achieved by setting this build macros.
|
||||
In most cases, it's not expected to be necessary,
|
||||
but it can be legitimately considered for less common platforms.
|
||||
|
||||
@@ -85,6 +100,22 @@ The following build macro can be selected to adjust source code behavior at comp
|
||||
passed as argument to become a compression state is suitably aligned.
|
||||
This test can be disabled if it proves flaky, by setting this value to 0.
|
||||
|
||||
- `LZ4_USER_MEMORY_FUNCTIONS` : replace calls to `<stdlib,h>`'s `malloc()`, `calloc()` and `free()`
|
||||
by user-defined functions, which must be named `LZ4_malloc()`, `LZ4_calloc()` and `LZ4_free()`.
|
||||
User functions must be available at link time.
|
||||
|
||||
- `LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION` :
|
||||
Remove support of dynamic memory allocation.
|
||||
For more details, see description of this macro in `lib/lz4.c`.
|
||||
|
||||
- `LZ4_FREESTANDING` : by setting this build macro to 1,
|
||||
LZ4/HC removes dependencies on the C standard library,
|
||||
including allocation functions and `memmove()`, `memcpy()`, and `memset()`.
|
||||
This build macro is designed to help use LZ4/HC in restricted environments
|
||||
(embedded, bootloader, etc).
|
||||
For more details, see description of this macro in `lib/lz4.h`.
|
||||
|
||||
|
||||
|
||||
#### Amalgamation
|
||||
|
||||
@@ -101,7 +132,7 @@ All `*.h` files present in `/lib` remain necessary to compile `lz4_all.c`.
|
||||
|
||||
DLL can be created using MinGW+MSYS with the `make liblz4` command.
|
||||
This command creates `dll\liblz4.dll` and the import library `dll\liblz4.lib`.
|
||||
To override the `dlltool` command when cross-compiling on Linux, just set the `DLLTOOL` variable. Example of cross compilation on Linux with mingw-w64 64 bits:
|
||||
To override the `dlltool` command when cross-compiling on Linux, just set the `DLLTOOL` variable. Example of cross compilation on Linux with mingw-w64 64 bits:
|
||||
```
|
||||
make BUILD_STATIC=no CC=x86_64-w64-mingw32-gcc DLLTOOL=x86_64-w64-mingw32-dlltool OS=Windows_NT
|
||||
```
|
||||
@@ -127,6 +158,7 @@ Other files present in the directory are not source code. They are :
|
||||
- `README.md` : this file
|
||||
|
||||
[official interoperable frame format]: ../doc/lz4_Frame_format.md
|
||||
[LZ4 Frame format]: ../doc/lz4_Frame_format.md
|
||||
[LZ4 block format]: ../doc/lz4_Block_format.md
|
||||
|
||||
|
||||
|
||||
615
C/lz4/lz4.c
615
C/lz4/lz4.c
File diff suppressed because it is too large
Load Diff
160
C/lz4/lz4.h
160
C/lz4/lz4.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* LZ4 - Fast LZ compression algorithm
|
||||
* Header File
|
||||
* Copyright (C) 2011-present, Yann Collet.
|
||||
* Copyright (C) 2011-2020, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
@@ -97,36 +97,77 @@ extern "C" {
|
||||
# define LZ4LIB_API LZ4LIB_VISIBILITY
|
||||
#endif
|
||||
|
||||
/*! LZ4_FREESTANDING :
|
||||
* When this macro is set to 1, it enables "freestanding mode" that is
|
||||
* suitable for typical freestanding environment which doesn't support
|
||||
* standard C library.
|
||||
*
|
||||
* - LZ4_FREESTANDING is a compile-time switch.
|
||||
* - It requires the following macros to be defined:
|
||||
* LZ4_memcpy, LZ4_memmove, LZ4_memset.
|
||||
* - It only enables LZ4/HC functions which don't use heap.
|
||||
* All LZ4F_* functions are not supported.
|
||||
* - See tests/freestanding.c to check its basic setup.
|
||||
*/
|
||||
#if defined(LZ4_FREESTANDING) && (LZ4_FREESTANDING == 1)
|
||||
# define LZ4_HEAPMODE 0
|
||||
# define LZ4HC_HEAPMODE 0
|
||||
# define LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION 1
|
||||
# if !defined(LZ4_memcpy)
|
||||
# error "LZ4_FREESTANDING requires macro 'LZ4_memcpy'."
|
||||
# endif
|
||||
# if !defined(LZ4_memset)
|
||||
# error "LZ4_FREESTANDING requires macro 'LZ4_memset'."
|
||||
# endif
|
||||
# if !defined(LZ4_memmove)
|
||||
# error "LZ4_FREESTANDING requires macro 'LZ4_memmove'."
|
||||
# endif
|
||||
#elif ! defined(LZ4_FREESTANDING)
|
||||
# define LZ4_FREESTANDING 0
|
||||
#endif
|
||||
|
||||
|
||||
/*------ Version ------*/
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 3 /* for tweaks, bug-fixes, or development */
|
||||
#define LZ4_VERSION_RELEASE 4 /* for tweaks, bug-fixes, or development */
|
||||
|
||||
#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)
|
||||
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) /* requires v1.7.3+ */
|
||||
|
||||
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
|
||||
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version */
|
||||
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version; requires v1.3.0+ */
|
||||
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version; requires v1.7.5+ */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Tuning parameter
|
||||
**************************************/
|
||||
#define LZ4_MEMORY_USAGE_MIN 10
|
||||
#define LZ4_MEMORY_USAGE_DEFAULT 14
|
||||
#define LZ4_MEMORY_USAGE_MAX 20
|
||||
|
||||
/*!
|
||||
* LZ4_MEMORY_USAGE :
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
||||
* Increasing memory usage improves compression ratio.
|
||||
* Reduced memory usage may improve speed, thanks to better cache locality.
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; )
|
||||
* Increasing memory usage improves compression ratio, at the cost of speed.
|
||||
* Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality.
|
||||
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
||||
*/
|
||||
#ifndef LZ4_MEMORY_USAGE
|
||||
# define LZ4_MEMORY_USAGE 14
|
||||
# define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT
|
||||
#endif
|
||||
|
||||
#if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN)
|
||||
# error "LZ4_MEMORY_USAGE is too small !"
|
||||
#endif
|
||||
|
||||
#if (LZ4_MEMORY_USAGE > LZ4_MEMORY_USAGE_MAX)
|
||||
# error "LZ4_MEMORY_USAGE is too large !"
|
||||
#endif
|
||||
|
||||
/*-************************************
|
||||
* Simple Functions
|
||||
@@ -270,8 +311,25 @@ LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcS
|
||||
***********************************************/
|
||||
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
|
||||
|
||||
/**
|
||||
Note about RC_INVOKED
|
||||
|
||||
- RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio).
|
||||
https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros
|
||||
|
||||
- Since rc.exe is a legacy compiler, it truncates long symbol (> 30 chars)
|
||||
and reports warning "RC4011: identifier truncated".
|
||||
|
||||
- To eliminate the warning, we surround long preprocessor symbol with
|
||||
"#if !defined(RC_INVOKED) ... #endif" block that means
|
||||
"skip this block when rc.exe is trying to read it".
|
||||
*/
|
||||
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
|
||||
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
|
||||
#endif
|
||||
|
||||
/*! LZ4_resetStream_fast() : v1.9.0+
|
||||
* Use this to prepare an LZ4_stream_t for a new chain of dependent blocks
|
||||
@@ -355,8 +413,12 @@ typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */
|
||||
* creation / destruction of streaming decompression tracking context.
|
||||
* A tracking context can be re-used multiple times.
|
||||
*/
|
||||
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||
LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
|
||||
#endif
|
||||
|
||||
/*! LZ4_setStreamDecode() :
|
||||
* An LZ4_streamDecode_t context can be allocated once and re-used multiple times.
|
||||
@@ -406,7 +468,10 @@ LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
|
||||
* save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression,
|
||||
* then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity);
|
||||
LZ4LIB_API int
|
||||
LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode,
|
||||
const char* src, char* dst,
|
||||
int srcSize, int dstCapacity);
|
||||
|
||||
|
||||
/*! LZ4_decompress_*_usingDict() :
|
||||
@@ -417,7 +482,16 @@ LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecod
|
||||
* Performance tip : Decompression speed can be substantially increased
|
||||
* when dst == dictStart + dictSize.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize);
|
||||
LZ4LIB_API int
|
||||
LZ4_decompress_safe_usingDict(const char* src, char* dst,
|
||||
int srcSize, int dstCapacity,
|
||||
const char* dictStart, int dictSize);
|
||||
|
||||
LZ4LIB_API int
|
||||
LZ4_decompress_safe_partial_usingDict(const char* src, char* dst,
|
||||
int compressedSize,
|
||||
int targetOutputSize, int maxOutputSize,
|
||||
const char* dictStart, int dictSize);
|
||||
|
||||
#endif /* LZ4_H_2983827168210 */
|
||||
|
||||
@@ -496,13 +570,15 @@ LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const c
|
||||
* stream (and source buffer) must remain in-place / accessible / unchanged
|
||||
* through the completion of the first compression call on the stream.
|
||||
*/
|
||||
LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream);
|
||||
LZ4LIB_STATIC_API void
|
||||
LZ4_attach_dictionary(LZ4_stream_t* workingStream,
|
||||
const LZ4_stream_t* dictionaryStream);
|
||||
|
||||
|
||||
/*! In-place compression and decompression
|
||||
*
|
||||
* It's possible to have input and output sharing the same buffer,
|
||||
* for highly contrained memory environments.
|
||||
* for highly constrained memory environments.
|
||||
* In both cases, it requires input to lay at the end of the buffer,
|
||||
* and decompression to start at beginning of the buffer.
|
||||
* Buffer size must feature some margin, hence be larger than final size.
|
||||
@@ -592,38 +668,26 @@ LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const
|
||||
typedef unsigned int LZ4_u32;
|
||||
#endif
|
||||
|
||||
/*! LZ4_stream_t :
|
||||
* Never ever use below internal definitions directly !
|
||||
* These definitions are not API/ABI safe, and may change in future versions.
|
||||
* If you need static allocation, declare or allocate an LZ4_stream_t object.
|
||||
**/
|
||||
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
LZ4_u32 hashTable[LZ4_HASH_SIZE_U32];
|
||||
LZ4_u32 currentOffset;
|
||||
LZ4_u32 tableType;
|
||||
const LZ4_byte* dictionary;
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
LZ4_u32 currentOffset;
|
||||
LZ4_u32 tableType;
|
||||
LZ4_u32 dictSize;
|
||||
/* Implicit padding to ensure structure is aligned */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const LZ4_byte* externalDict;
|
||||
size_t extDictSize;
|
||||
const LZ4_byte* prefixEnd;
|
||||
size_t prefixSize;
|
||||
} LZ4_streamDecode_t_internal;
|
||||
|
||||
|
||||
/*! LZ4_stream_t :
|
||||
* Do not use below internal definitions directly !
|
||||
* Declare or allocate an LZ4_stream_t instead.
|
||||
* LZ4_stream_t can also be created using LZ4_createStream(), which is recommended.
|
||||
* The structure definition can be convenient for static allocation
|
||||
* (on stack, or as part of larger structure).
|
||||
* Init this structure with LZ4_initStream() before first use.
|
||||
* note : only use this definition in association with static linking !
|
||||
* this definition is not API/ABI safe, and may change in future versions.
|
||||
*/
|
||||
#define LZ4_STREAMSIZE 16416 /* static size, for inter-version compatibility */
|
||||
#define LZ4_STREAMSIZE_VOIDP (LZ4_STREAMSIZE / sizeof(void*))
|
||||
#define LZ4_STREAM_MINSIZE ((1UL << LZ4_MEMORY_USAGE) + 32) /* static size, for inter-version compatibility */
|
||||
union LZ4_stream_u {
|
||||
void* table[LZ4_STREAMSIZE_VOIDP];
|
||||
char minStateSize[LZ4_STREAM_MINSIZE];
|
||||
LZ4_stream_t_internal internal_donotuse;
|
||||
}; /* previously typedef'd to LZ4_stream_t */
|
||||
|
||||
@@ -641,21 +705,25 @@ union LZ4_stream_u {
|
||||
* In which case, the function will @return NULL.
|
||||
* Note2: An LZ4_stream_t structure guarantees correct alignment and size.
|
||||
* Note3: Before v1.9.0, use LZ4_resetStream() instead
|
||||
*/
|
||||
**/
|
||||
LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* buffer, size_t size);
|
||||
|
||||
|
||||
/*! LZ4_streamDecode_t :
|
||||
* information structure to track an LZ4 stream during decompression.
|
||||
* init this structure using LZ4_setStreamDecode() 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 + ((sizeof(void*)==16) ? 2 : 0) /*AS-400*/ )
|
||||
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
|
||||
* Never ever use below internal definitions directly !
|
||||
* These definitions are not API/ABI safe, and may change in future versions.
|
||||
* If you need static allocation, declare or allocate an LZ4_streamDecode_t object.
|
||||
**/
|
||||
typedef struct {
|
||||
const LZ4_byte* externalDict;
|
||||
const LZ4_byte* prefixEnd;
|
||||
size_t extDictSize;
|
||||
size_t prefixSize;
|
||||
} LZ4_streamDecode_t_internal;
|
||||
|
||||
#define LZ4_STREAMDECODE_MINSIZE 32
|
||||
union LZ4_streamDecode_u {
|
||||
unsigned long long table[LZ4_STREAMDECODESIZE_U64];
|
||||
char minStateSize[LZ4_STREAMDECODE_MINSIZE];
|
||||
LZ4_streamDecode_t_internal internal_donotuse;
|
||||
} ; /* previously typedef'd to LZ4_streamDecode_t */
|
||||
|
||||
|
||||
673
C/lz4/lz4frame.c
673
C/lz4/lz4frame.c
File diff suppressed because it is too large
Load Diff
175
C/lz4/lz4frame.h
175
C/lz4/lz4frame.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
LZ4 auto-framing library
|
||||
LZ4F - LZ4-Frame library
|
||||
Header File
|
||||
Copyright (C) 2011-2017, Yann Collet.
|
||||
Copyright (C) 2011-2020, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -39,7 +39,7 @@
|
||||
* LZ4F also offers streaming capabilities.
|
||||
*
|
||||
* lz4.h is not required when using lz4frame.h,
|
||||
* except to extract common constant such as LZ4_VERSION_NUMBER.
|
||||
* except to extract common constants such as LZ4_VERSION_NUMBER.
|
||||
* */
|
||||
|
||||
#ifndef LZ4F_H_09782039843
|
||||
@@ -54,12 +54,12 @@ extern "C" {
|
||||
|
||||
|
||||
/**
|
||||
Introduction
|
||||
|
||||
lz4frame.h implements LZ4 frame specification (doc/lz4_Frame_format.md).
|
||||
lz4frame.h provides frame compression functions that take care
|
||||
of encoding standard metadata alongside LZ4-compressed blocks.
|
||||
*/
|
||||
* Introduction
|
||||
*
|
||||
* lz4frame.h implements LZ4 frame specification: see doc/lz4_Frame_format.md .
|
||||
* LZ4 Frames are compatible with `lz4` CLI,
|
||||
* and designed to be interoperable with any system.
|
||||
**/
|
||||
|
||||
/*-***************************************************************
|
||||
* Compiler specifics
|
||||
@@ -210,7 +210,7 @@ LZ4FLIB_API int LZ4F_compressionLevel_max(void); /* v1.8.0+ */
|
||||
* Returns the maximum possible compressed size with LZ4F_compressFrame() given srcSize and preferences.
|
||||
* `preferencesPtr` is optional. It can be replaced by NULL, in which case, the function will assume default preferences.
|
||||
* Note : this result is only usable with LZ4F_compressFrame().
|
||||
* It may also be used with LZ4F_compressUpdate() _if no flush() operation_ is performed.
|
||||
* It may also be relevant to LZ4F_compressUpdate() _only if_ no flush() operation is ever performed.
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr);
|
||||
|
||||
@@ -230,7 +230,7 @@ LZ4FLIB_API size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
|
||||
* Advanced compression functions
|
||||
*************************************/
|
||||
typedef struct LZ4F_cctx_s LZ4F_cctx; /* incomplete type */
|
||||
typedef LZ4F_cctx* LZ4F_compressionContext_t; /* for compatibility with previous API version */
|
||||
typedef LZ4F_cctx* LZ4F_compressionContext_t; /* for compatibility with older APIs, prefer using LZ4F_cctx */
|
||||
|
||||
typedef struct {
|
||||
unsigned stableSrc; /* 1 == src content will remain present on future calls to LZ4F_compress(); skip copying src content within tmp buffer */
|
||||
@@ -243,20 +243,27 @@ typedef struct {
|
||||
LZ4FLIB_API unsigned LZ4F_getVersion(void);
|
||||
|
||||
/*! LZ4F_createCompressionContext() :
|
||||
* 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.
|
||||
* 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_cctx object.
|
||||
* If @return != zero, there was an error during context creation.
|
||||
* Object can release its memory using LZ4F_freeCompressionContext();
|
||||
*/
|
||||
* The first thing to do is to create a compressionContext object,
|
||||
* which will keep track of operation state during streaming compression.
|
||||
* This is achieved using LZ4F_createCompressionContext(), which takes as argument a version,
|
||||
* and a pointer to LZ4F_cctx*, to write the resulting pointer into.
|
||||
* @version provided MUST be LZ4F_VERSION. It is intended to track potential version mismatch, notably when using DLL.
|
||||
* The function provides a pointer to a fully allocated LZ4F_cctx object.
|
||||
* @cctxPtr MUST be != NULL.
|
||||
* If @return != zero, context creation failed.
|
||||
* A created compression context can be employed multiple times for consecutive streaming operations.
|
||||
* Once all streaming compression jobs are completed,
|
||||
* the state object can be released using LZ4F_freeCompressionContext().
|
||||
* Note1 : LZ4F_freeCompressionContext() is always successful. Its return value can be ignored.
|
||||
* Note2 : LZ4F_freeCompressionContext() works fine with NULL input pointers (do nothing).
|
||||
**/
|
||||
LZ4FLIB_API LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx** cctxPtr, unsigned version);
|
||||
LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx* cctx);
|
||||
|
||||
|
||||
/*---- Compression ----*/
|
||||
|
||||
#define LZ4F_HEADER_SIZE_MIN 7 /* LZ4 Frame header size can vary, depending on selected paramaters */
|
||||
#define LZ4F_HEADER_SIZE_MIN 7 /* LZ4 Frame header size can vary, depending on selected parameters */
|
||||
#define LZ4F_HEADER_SIZE_MAX 19
|
||||
|
||||
/* Size in bytes of a block header in little-endian format. Highest bit indicates if block data is uncompressed */
|
||||
@@ -301,8 +308,9 @@ LZ4FLIB_API size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t*
|
||||
* Important rule: dstCapacity MUST be large enough to ensure operation success even in worst case situations.
|
||||
* This value is provided by LZ4F_compressBound().
|
||||
* If this condition is not respected, LZ4F_compress() will fail (result is an errorCode).
|
||||
* LZ4F_compressUpdate() doesn't guarantee error recovery.
|
||||
* When an error occurs, compression context must be freed or resized.
|
||||
* After an error, the state is left in a UB state, and must be re-initialized or freed.
|
||||
* If previously an uncompressed block was written, buffered data is flushed
|
||||
* before appending compressed data is continued.
|
||||
* `cOptPtr` is optional : NULL can be provided, in which case all options are set to default.
|
||||
* @return : number of bytes written into `dstBuffer` (it can be zero, meaning input data was just buffered).
|
||||
* or an error code if it fails (which can be tested using LZ4F_isError())
|
||||
@@ -347,8 +355,12 @@ typedef struct LZ4F_dctx_s LZ4F_dctx; /* incomplete type */
|
||||
typedef LZ4F_dctx* LZ4F_decompressionContext_t; /* compatibility with previous API versions */
|
||||
|
||||
typedef struct {
|
||||
unsigned stableDst; /* pledges that last 64KB decompressed data will remain available unmodified. This optimization skips storage operations in tmp buffers. */
|
||||
unsigned reserved[3]; /* must be set to zero for forward compatibility */
|
||||
unsigned stableDst; /* pledges that last 64KB decompressed data will remain available unmodified between invocations.
|
||||
* This optimization skips storage operations in tmp buffers. */
|
||||
unsigned skipChecksums; /* disable checksum calculation and verification, even when one is present in frame, to save CPU time.
|
||||
* Setting this option to 1 once disables all checksums for the rest of the frame. */
|
||||
unsigned reserved1; /* must be set to zero for forward compatibility */
|
||||
unsigned reserved0; /* idem */
|
||||
} LZ4F_decompressOptions_t;
|
||||
|
||||
|
||||
@@ -356,9 +368,10 @@ typedef struct {
|
||||
|
||||
/*! LZ4F_createDecompressionContext() :
|
||||
* Create an LZ4F_dctx object, to track all decompression operations.
|
||||
* The version provided MUST be LZ4F_VERSION.
|
||||
* The function provides a pointer to an allocated and initialized LZ4F_dctx object.
|
||||
* The result is an errorCode, which can be tested using LZ4F_isError().
|
||||
* @version provided MUST be LZ4F_VERSION.
|
||||
* @dctxPtr MUST be valid.
|
||||
* The function fills @dctxPtr with the value of a pointer to an allocated and initialized LZ4F_dctx object.
|
||||
* The @return is an errorCode, which can be tested using LZ4F_isError().
|
||||
* dctx memory can be released using LZ4F_freeDecompressionContext();
|
||||
* Result of LZ4F_freeDecompressionContext() indicates current state of decompressionContext when being released.
|
||||
* That is, it should be == 0 if decompression has been completed fully and correctly.
|
||||
@@ -371,6 +384,8 @@ LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx* dctx);
|
||||
* Streaming decompression functions
|
||||
*************************************/
|
||||
|
||||
#define LZ4F_MAGICNUMBER 0x184D2204U
|
||||
#define LZ4F_MAGIC_SKIPPABLE_START 0x184D2A50U
|
||||
#define LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH 5
|
||||
|
||||
/*! LZ4F_headerSize() : v1.9.0+
|
||||
@@ -386,7 +401,7 @@ LZ4FLIB_API size_t LZ4F_headerSize(const void* src, size_t srcSize);
|
||||
|
||||
/*! LZ4F_getFrameInfo() :
|
||||
* This function extracts frame parameters (max blockSize, dictID, etc.).
|
||||
* Its usage is optional: user can call LZ4F_decompress() directly.
|
||||
* Its usage is optional: user can also invoke LZ4F_decompress() directly.
|
||||
*
|
||||
* Extracted information will fill an existing LZ4F_frameInfo_t structure.
|
||||
* This can be useful for allocation and dictionary identification purposes.
|
||||
@@ -427,9 +442,10 @@ LZ4FLIB_API size_t LZ4F_headerSize(const void* src, size_t srcSize);
|
||||
* note 1 : in case of error, dctx is not modified. Decoding operation can resume from beginning safely.
|
||||
* note 2 : frame parameters are *copied into* an already allocated LZ4F_frameInfo_t structure.
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
|
||||
LZ4F_frameInfo_t* frameInfoPtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr);
|
||||
LZ4FLIB_API size_t
|
||||
LZ4F_getFrameInfo(LZ4F_dctx* dctx,
|
||||
LZ4F_frameInfo_t* frameInfoPtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr);
|
||||
|
||||
/*! LZ4F_decompress() :
|
||||
* Call this function repetitively to regenerate data compressed in `srcBuffer`.
|
||||
@@ -462,10 +478,11 @@ LZ4FLIB_API size_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
|
||||
*
|
||||
* 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);
|
||||
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);
|
||||
|
||||
|
||||
/*! LZ4F_resetDecompressionContext() : added in v1.8.0
|
||||
@@ -529,6 +546,8 @@ extern "C" {
|
||||
ITEM(ERROR_headerChecksum_invalid) \
|
||||
ITEM(ERROR_contentChecksum_invalid) \
|
||||
ITEM(ERROR_frameDecoding_alreadyStarted) \
|
||||
ITEM(ERROR_compressionState_uninitialized) \
|
||||
ITEM(ERROR_parameter_null) \
|
||||
ITEM(ERROR_maxCode)
|
||||
|
||||
#define LZ4F_GENERATE_ENUM(ENUM) LZ4F_##ENUM,
|
||||
@@ -539,7 +558,31 @@ typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM)
|
||||
|
||||
LZ4FLIB_STATIC_API LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult);
|
||||
|
||||
LZ4FLIB_STATIC_API size_t LZ4F_getBlockSize(unsigned);
|
||||
|
||||
/*! LZ4F_getBlockSize() :
|
||||
* Return, in scalar format (size_t),
|
||||
* the maximum block size associated with blockSizeID.
|
||||
**/
|
||||
LZ4FLIB_STATIC_API size_t LZ4F_getBlockSize(LZ4F_blockSizeID_t blockSizeID);
|
||||
|
||||
/*! LZ4F_uncompressedUpdate() :
|
||||
* LZ4F_uncompressedUpdate() can be called repetitively to add as much data uncompressed data as necessary.
|
||||
* Important rule: dstCapacity MUST be large enough to store the entire source buffer as
|
||||
* no compression is done for this operation
|
||||
* If this condition is not respected, LZ4F_uncompressedUpdate() will fail (result is an errorCode).
|
||||
* After an error, the state is left in a UB state, and must be re-initialized or freed.
|
||||
* If previously a compressed block was written, buffered data is flushed
|
||||
* before appending uncompressed data is continued.
|
||||
* This is only supported when LZ4F_blockIndependent is used
|
||||
* `cOptPtr` is optional : NULL can be provided, in which case all options are set to default.
|
||||
* @return : number of bytes written into `dstBuffer` (it can be zero, meaning input data was just buffered).
|
||||
* or an error code if it fails (which can be tested using LZ4F_isError())
|
||||
*/
|
||||
LZ4FLIB_STATIC_API size_t
|
||||
LZ4F_uncompressedUpdate(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const void* srcBuffer, size_t srcSize,
|
||||
const LZ4F_compressOptions_t* cOptPtr);
|
||||
|
||||
/**********************************
|
||||
* Bulk processing dictionary API
|
||||
@@ -583,12 +626,12 @@ LZ4FLIB_STATIC_API void LZ4F_freeCDict(LZ4F_CDict* CDict);
|
||||
* but it's not recommended, as it's the only way to provide dictID in the frame header.
|
||||
* @return : number of bytes written into dstBuffer.
|
||||
* or an error code if it fails (can be tested using LZ4F_isError()) */
|
||||
LZ4FLIB_STATIC_API size_t LZ4F_compressFrame_usingCDict(
|
||||
LZ4F_cctx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
const LZ4F_CDict* cdict,
|
||||
const LZ4F_preferences_t* preferencesPtr);
|
||||
LZ4FLIB_STATIC_API size_t
|
||||
LZ4F_compressFrame_usingCDict(LZ4F_cctx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
const LZ4F_CDict* cdict,
|
||||
const LZ4F_preferences_t* preferencesPtr);
|
||||
|
||||
|
||||
/*! LZ4F_compressBegin_usingCDict() :
|
||||
@@ -598,23 +641,49 @@ LZ4FLIB_STATIC_API size_t LZ4F_compressFrame_usingCDict(
|
||||
* however, it's the only way to provide dictID in the frame header.
|
||||
* @return : number of bytes written into dstBuffer for the header,
|
||||
* or an error code (which can be tested using LZ4F_isError()) */
|
||||
LZ4FLIB_STATIC_API size_t LZ4F_compressBegin_usingCDict(
|
||||
LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const LZ4F_CDict* cdict,
|
||||
const LZ4F_preferences_t* prefsPtr);
|
||||
LZ4FLIB_STATIC_API size_t
|
||||
LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const LZ4F_CDict* cdict,
|
||||
const LZ4F_preferences_t* prefsPtr);
|
||||
|
||||
|
||||
/*! LZ4F_decompress_usingDict() :
|
||||
* Same as LZ4F_decompress(), using a predefined dictionary.
|
||||
* Dictionary is used "in place", without any preprocessing.
|
||||
* It must remain accessible throughout the entire frame decoding. */
|
||||
LZ4FLIB_STATIC_API size_t LZ4F_decompress_usingDict(
|
||||
LZ4F_dctx* dctxPtr,
|
||||
void* dstBuffer, size_t* dstSizePtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr,
|
||||
const void* dict, size_t dictSize,
|
||||
const LZ4F_decompressOptions_t* decompressOptionsPtr);
|
||||
** It must remain accessible throughout the entire frame decoding. */
|
||||
LZ4FLIB_STATIC_API size_t
|
||||
LZ4F_decompress_usingDict(LZ4F_dctx* dctxPtr,
|
||||
void* dstBuffer, size_t* dstSizePtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr,
|
||||
const void* dict, size_t dictSize,
|
||||
const LZ4F_decompressOptions_t* decompressOptionsPtr);
|
||||
|
||||
|
||||
/*! Custom memory allocation :
|
||||
* These prototypes make it possible to pass custom allocation/free functions.
|
||||
* LZ4F_customMem is provided at state creation time, using LZ4F_create*_advanced() listed below.
|
||||
* All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones.
|
||||
*/
|
||||
typedef void* (*LZ4F_AllocFunction) (void* opaqueState, size_t size);
|
||||
typedef void* (*LZ4F_CallocFunction) (void* opaqueState, size_t size);
|
||||
typedef void (*LZ4F_FreeFunction) (void* opaqueState, void* address);
|
||||
typedef struct {
|
||||
LZ4F_AllocFunction customAlloc;
|
||||
LZ4F_CallocFunction customCalloc; /* optional; when not defined, uses customAlloc + memset */
|
||||
LZ4F_FreeFunction customFree;
|
||||
void* opaqueState;
|
||||
} LZ4F_CustomMem;
|
||||
static
|
||||
#ifdef __GNUC__
|
||||
__attribute__((__unused__))
|
||||
#endif
|
||||
LZ4F_CustomMem const LZ4F_defaultCMem = { NULL, NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
|
||||
|
||||
LZ4FLIB_STATIC_API LZ4F_cctx* LZ4F_createCompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
|
||||
LZ4FLIB_STATIC_API LZ4F_dctx* LZ4F_createDecompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
|
||||
LZ4FLIB_STATIC_API LZ4F_CDict* LZ4F_createCDict_advanced(LZ4F_CustomMem customMem, const void* dictBuffer, size_t dictSize);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
LZ4 auto-framing library
|
||||
Header File for static linking only
|
||||
Copyright (C) 2011-2016, Yann Collet.
|
||||
Copyright (C) 2011-2020, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
|
||||
238
C/lz4/lz4hc.c
238
C/lz4/lz4hc.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
LZ4 HC - High Compression Mode of LZ4
|
||||
Copyright (C) 2011-2017, Yann Collet.
|
||||
Copyright (C) 2011-2020, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
* 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
|
||||
@@ -99,18 +99,20 @@ static void LZ4HC_clearTables (LZ4HC_CCtx_internal* hc4)
|
||||
|
||||
static void LZ4HC_init_internal (LZ4HC_CCtx_internal* hc4, const BYTE* start)
|
||||
{
|
||||
uptrval startingOffset = (uptrval)(hc4->end - hc4->base);
|
||||
if (startingOffset > 1 GB) {
|
||||
size_t const bufferSize = (size_t)(hc4->end - hc4->prefixStart);
|
||||
size_t newStartingOffset = bufferSize + hc4->dictLimit;
|
||||
assert(newStartingOffset >= bufferSize); /* check overflow */
|
||||
if (newStartingOffset > 1 GB) {
|
||||
LZ4HC_clearTables(hc4);
|
||||
startingOffset = 0;
|
||||
newStartingOffset = 0;
|
||||
}
|
||||
startingOffset += 64 KB;
|
||||
hc4->nextToUpdate = (U32) startingOffset;
|
||||
hc4->base = start - startingOffset;
|
||||
newStartingOffset += 64 KB;
|
||||
hc4->nextToUpdate = (U32)newStartingOffset;
|
||||
hc4->prefixStart = start;
|
||||
hc4->end = start;
|
||||
hc4->dictBase = start - startingOffset;
|
||||
hc4->dictLimit = (U32) startingOffset;
|
||||
hc4->lowLimit = (U32) startingOffset;
|
||||
hc4->dictStart = start;
|
||||
hc4->dictLimit = (U32)newStartingOffset;
|
||||
hc4->lowLimit = (U32)newStartingOffset;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,12 +121,15 @@ LZ4_FORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE* ip)
|
||||
{
|
||||
U16* const chainTable = hc4->chainTable;
|
||||
U32* const hashTable = hc4->hashTable;
|
||||
const BYTE* const base = hc4->base;
|
||||
U32 const target = (U32)(ip - base);
|
||||
const BYTE* const prefixPtr = hc4->prefixStart;
|
||||
U32 const prefixIdx = hc4->dictLimit;
|
||||
U32 const target = (U32)(ip - prefixPtr) + prefixIdx;
|
||||
U32 idx = hc4->nextToUpdate;
|
||||
assert(ip >= prefixPtr);
|
||||
assert(target >= prefixIdx);
|
||||
|
||||
while (idx < target) {
|
||||
U32 const h = LZ4HC_hashPtr(base+idx);
|
||||
U32 const h = LZ4HC_hashPtr(prefixPtr+idx-prefixIdx);
|
||||
size_t delta = idx - hashTable[h];
|
||||
if (delta>LZ4_DISTANCE_MAX) delta = LZ4_DISTANCE_MAX;
|
||||
DELTANEXTU16(chainTable, idx) = (U16)delta;
|
||||
@@ -193,15 +198,14 @@ LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, U32 const pattern32)
|
||||
BYTE const byte = (BYTE)(pattern >> bitOffset);
|
||||
if (*ip != byte) break;
|
||||
ip ++; bitOffset -= 8;
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
||||
return (unsigned)(ip - iStart);
|
||||
}
|
||||
|
||||
/* LZ4HC_reverseCountPattern() :
|
||||
* pattern must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!)
|
||||
* read using natural platform endianess */
|
||||
* read using natural platform endianness */
|
||||
static unsigned
|
||||
LZ4HC_reverseCountPattern(const BYTE* ip, const BYTE* const iLow, U32 pattern)
|
||||
{
|
||||
@@ -211,7 +215,7 @@ LZ4HC_reverseCountPattern(const BYTE* ip, const BYTE* const iLow, U32 pattern)
|
||||
if (LZ4_read32(ip-4) != pattern) break;
|
||||
ip -= 4;
|
||||
}
|
||||
{ const BYTE* bytePtr = (const BYTE*)(&pattern) + 3; /* works for any endianess */
|
||||
{ const BYTE* bytePtr = (const BYTE*)(&pattern) + 3; /* works for any endianness */
|
||||
while (likely(ip>iLow)) {
|
||||
if (ip[-1] != *bytePtr) break;
|
||||
ip--; bytePtr--;
|
||||
@@ -234,28 +238,28 @@ typedef enum { favorCompressionRatio=0, favorDecompressionSpeed } HCfavor_e;
|
||||
|
||||
LZ4_FORCE_INLINE int
|
||||
LZ4HC_InsertAndGetWiderMatch (
|
||||
LZ4HC_CCtx_internal* hc4,
|
||||
const BYTE* const ip,
|
||||
const BYTE* const iLowLimit,
|
||||
const BYTE* const iHighLimit,
|
||||
int longest,
|
||||
const BYTE** matchpos,
|
||||
const BYTE** startpos,
|
||||
const int maxNbAttempts,
|
||||
const int patternAnalysis,
|
||||
const int chainSwap,
|
||||
const dictCtx_directive dict,
|
||||
const HCfavor_e favorDecSpeed)
|
||||
LZ4HC_CCtx_internal* const hc4,
|
||||
const BYTE* const ip,
|
||||
const BYTE* const iLowLimit, const BYTE* const iHighLimit,
|
||||
int longest,
|
||||
const BYTE** matchpos,
|
||||
const BYTE** startpos,
|
||||
const int maxNbAttempts,
|
||||
const int patternAnalysis, const int chainSwap,
|
||||
const dictCtx_directive dict,
|
||||
const HCfavor_e favorDecSpeed)
|
||||
{
|
||||
U16* const chainTable = hc4->chainTable;
|
||||
U32* const HashTable = hc4->hashTable;
|
||||
const LZ4HC_CCtx_internal * const dictCtx = hc4->dictCtx;
|
||||
const BYTE* const base = hc4->base;
|
||||
const U32 dictLimit = hc4->dictLimit;
|
||||
const BYTE* const lowPrefixPtr = base + dictLimit;
|
||||
const U32 ipIndex = (U32)(ip - base);
|
||||
const U32 lowestMatchIndex = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX;
|
||||
const BYTE* const dictBase = hc4->dictBase;
|
||||
const BYTE* const prefixPtr = hc4->prefixStart;
|
||||
const U32 prefixIdx = hc4->dictLimit;
|
||||
const U32 ipIndex = (U32)(ip - prefixPtr) + prefixIdx;
|
||||
const int withinStartDistance = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex);
|
||||
const U32 lowestMatchIndex = (withinStartDistance) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX;
|
||||
const BYTE* const dictStart = hc4->dictStart;
|
||||
const U32 dictIdx = hc4->lowLimit;
|
||||
const BYTE* const dictEnd = dictStart + prefixIdx - dictIdx;
|
||||
int const lookBackLength = (int)(ip-iLowLimit);
|
||||
int nbAttempts = maxNbAttempts;
|
||||
U32 matchChainPos = 0;
|
||||
@@ -277,14 +281,13 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
assert(matchIndex < ipIndex);
|
||||
if (favorDecSpeed && (ipIndex - matchIndex < 8)) {
|
||||
/* do nothing */
|
||||
} else if (matchIndex >= dictLimit) { /* within current Prefix */
|
||||
const BYTE* const matchPtr = base + matchIndex;
|
||||
assert(matchPtr >= lowPrefixPtr);
|
||||
} else if (matchIndex >= prefixIdx) { /* within current Prefix */
|
||||
const BYTE* const matchPtr = prefixPtr + matchIndex - prefixIdx;
|
||||
assert(matchPtr < ip);
|
||||
assert(longest >= 1);
|
||||
if (LZ4_read16(iLowLimit + longest - 1) == LZ4_read16(matchPtr - lookBackLength + longest - 1)) {
|
||||
if (LZ4_read32(matchPtr) == pattern) {
|
||||
int const back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, lowPrefixPtr) : 0;
|
||||
int const back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, prefixPtr) : 0;
|
||||
matchLength = MINMATCH + (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit);
|
||||
matchLength -= back;
|
||||
if (matchLength > longest) {
|
||||
@@ -293,24 +296,25 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
*startpos = ip + back;
|
||||
} } }
|
||||
} else { /* lowestMatchIndex <= matchIndex < dictLimit */
|
||||
const BYTE* const matchPtr = dictBase + matchIndex;
|
||||
if (LZ4_read32(matchPtr) == pattern) {
|
||||
const BYTE* const dictStart = dictBase + hc4->lowLimit;
|
||||
const BYTE* const matchPtr = dictStart + (matchIndex - dictIdx);
|
||||
assert(matchIndex >= dictIdx);
|
||||
if ( likely(matchIndex <= prefixIdx - 4)
|
||||
&& (LZ4_read32(matchPtr) == pattern) ) {
|
||||
int back = 0;
|
||||
const BYTE* vLimit = ip + (dictLimit - matchIndex);
|
||||
const BYTE* vLimit = ip + (prefixIdx - matchIndex);
|
||||
if (vLimit > iHighLimit) vLimit = iHighLimit;
|
||||
matchLength = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
|
||||
if ((ip+matchLength == vLimit) && (vLimit < iHighLimit))
|
||||
matchLength += LZ4_count(ip+matchLength, lowPrefixPtr, iHighLimit);
|
||||
matchLength += LZ4_count(ip+matchLength, prefixPtr, iHighLimit);
|
||||
back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictStart) : 0;
|
||||
matchLength -= back;
|
||||
if (matchLength > longest) {
|
||||
longest = matchLength;
|
||||
*matchpos = base + matchIndex + back; /* virtual pos, relative to ip, to retrieve offset */
|
||||
*matchpos = prefixPtr - prefixIdx + matchIndex + back; /* virtual pos, relative to ip, to retrieve offset */
|
||||
*startpos = ip + back;
|
||||
} } }
|
||||
|
||||
if (chainSwap && matchLength==longest) { /* better match => select a better chain */
|
||||
if (chainSwap && matchLength==longest) { /* better match => select a better chain */
|
||||
assert(lookBackLength==0); /* search forward only */
|
||||
if (matchIndex + (U32)longest <= ipIndex) {
|
||||
int const kTrigger = 4;
|
||||
@@ -326,8 +330,7 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
distanceToNextMatch = candidateDist;
|
||||
matchChainPos = (U32)pos;
|
||||
accel = 1 << kTrigger;
|
||||
}
|
||||
}
|
||||
} }
|
||||
if (distanceToNextMatch > 1) {
|
||||
if (distanceToNextMatch > matchIndex) break; /* avoid overflow */
|
||||
matchIndex -= distanceToNextMatch;
|
||||
@@ -347,23 +350,24 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
repeat = rep_not;
|
||||
} }
|
||||
if ( (repeat == rep_confirmed) && (matchCandidateIdx >= lowestMatchIndex)
|
||||
&& LZ4HC_protectDictEnd(dictLimit, matchCandidateIdx) ) {
|
||||
const int extDict = matchCandidateIdx < dictLimit;
|
||||
const BYTE* const matchPtr = (extDict ? dictBase : base) + matchCandidateIdx;
|
||||
&& LZ4HC_protectDictEnd(prefixIdx, matchCandidateIdx) ) {
|
||||
const int extDict = matchCandidateIdx < prefixIdx;
|
||||
const BYTE* const matchPtr = (extDict ? dictStart - dictIdx : prefixPtr - prefixIdx) + matchCandidateIdx;
|
||||
if (LZ4_read32(matchPtr) == pattern) { /* good candidate */
|
||||
const BYTE* const dictStart = dictBase + hc4->lowLimit;
|
||||
const BYTE* const iLimit = extDict ? dictBase + dictLimit : iHighLimit;
|
||||
const BYTE* const iLimit = extDict ? dictEnd : iHighLimit;
|
||||
size_t forwardPatternLength = LZ4HC_countPattern(matchPtr+sizeof(pattern), iLimit, pattern) + sizeof(pattern);
|
||||
if (extDict && matchPtr + forwardPatternLength == iLimit) {
|
||||
U32 const rotatedPattern = LZ4HC_rotatePattern(forwardPatternLength, pattern);
|
||||
forwardPatternLength += LZ4HC_countPattern(lowPrefixPtr, iHighLimit, rotatedPattern);
|
||||
forwardPatternLength += LZ4HC_countPattern(prefixPtr, iHighLimit, rotatedPattern);
|
||||
}
|
||||
{ const BYTE* const lowestMatchPtr = extDict ? dictStart : lowPrefixPtr;
|
||||
{ const BYTE* const lowestMatchPtr = extDict ? dictStart : prefixPtr;
|
||||
size_t backLength = LZ4HC_reverseCountPattern(matchPtr, lowestMatchPtr, pattern);
|
||||
size_t currentSegmentLength;
|
||||
if (!extDict && matchPtr - backLength == lowPrefixPtr && hc4->lowLimit < dictLimit) {
|
||||
if (!extDict
|
||||
&& matchPtr - backLength == prefixPtr
|
||||
&& dictIdx < prefixIdx) {
|
||||
U32 const rotatedPattern = LZ4HC_rotatePattern((U32)(-(int)backLength), pattern);
|
||||
backLength += LZ4HC_reverseCountPattern(dictBase + dictLimit, dictStart, rotatedPattern);
|
||||
backLength += LZ4HC_reverseCountPattern(dictEnd, dictStart, rotatedPattern);
|
||||
}
|
||||
/* Limit backLength not go further than lowestMatchIndex */
|
||||
backLength = matchCandidateIdx - MAX(matchCandidateIdx - (U32)backLength, lowestMatchIndex);
|
||||
@@ -373,28 +377,28 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
if ( (currentSegmentLength >= srcPatternLength) /* current pattern segment large enough to contain full srcPatternLength */
|
||||
&& (forwardPatternLength <= srcPatternLength) ) { /* haven't reached this position yet */
|
||||
U32 const newMatchIndex = matchCandidateIdx + (U32)forwardPatternLength - (U32)srcPatternLength; /* best position, full pattern, might be followed by more match */
|
||||
if (LZ4HC_protectDictEnd(dictLimit, newMatchIndex))
|
||||
if (LZ4HC_protectDictEnd(prefixIdx, newMatchIndex))
|
||||
matchIndex = newMatchIndex;
|
||||
else {
|
||||
/* Can only happen if started in the prefix */
|
||||
assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict);
|
||||
matchIndex = dictLimit;
|
||||
assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict);
|
||||
matchIndex = prefixIdx;
|
||||
}
|
||||
} else {
|
||||
U32 const newMatchIndex = matchCandidateIdx - (U32)backLength; /* farthest position in current segment, will find a match of length currentSegmentLength + maybe some back */
|
||||
if (!LZ4HC_protectDictEnd(dictLimit, newMatchIndex)) {
|
||||
assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict);
|
||||
matchIndex = dictLimit;
|
||||
if (!LZ4HC_protectDictEnd(prefixIdx, newMatchIndex)) {
|
||||
assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict);
|
||||
matchIndex = prefixIdx;
|
||||
} else {
|
||||
matchIndex = newMatchIndex;
|
||||
if (lookBackLength==0) { /* no back possible */
|
||||
size_t const maxML = MIN(currentSegmentLength, srcPatternLength);
|
||||
if ((size_t)longest < maxML) {
|
||||
assert(base + matchIndex != ip);
|
||||
if ((size_t)(ip - base) - matchIndex > LZ4_DISTANCE_MAX) break;
|
||||
assert(prefixPtr - prefixIdx + matchIndex != ip);
|
||||
if ((size_t)(ip - prefixPtr) + prefixIdx - matchIndex > LZ4_DISTANCE_MAX) break;
|
||||
assert(maxML < 2 GB);
|
||||
longest = (int)maxML;
|
||||
*matchpos = base + matchIndex; /* virtual pos, relative to ip, to retrieve offset */
|
||||
*matchpos = prefixPtr - prefixIdx + matchIndex; /* virtual pos, relative to ip, to retrieve offset */
|
||||
*startpos = ip;
|
||||
}
|
||||
{ U32 const distToNextPattern = DELTANEXTU16(chainTable, matchIndex);
|
||||
@@ -413,12 +417,12 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
if ( dict == usingDictCtxHc
|
||||
&& nbAttempts > 0
|
||||
&& ipIndex - lowestMatchIndex < LZ4_DISTANCE_MAX) {
|
||||
size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->base);
|
||||
size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->prefixStart) + dictCtx->dictLimit;
|
||||
U32 dictMatchIndex = dictCtx->hashTable[LZ4HC_hashPtr(ip)];
|
||||
assert(dictEndOffset <= 1 GB);
|
||||
matchIndex = dictMatchIndex + lowestMatchIndex - (U32)dictEndOffset;
|
||||
while (ipIndex - matchIndex <= LZ4_DISTANCE_MAX && nbAttempts--) {
|
||||
const BYTE* const matchPtr = dictCtx->base + dictMatchIndex;
|
||||
const BYTE* const matchPtr = dictCtx->prefixStart - dictCtx->dictLimit + dictMatchIndex;
|
||||
|
||||
if (LZ4_read32(matchPtr) == pattern) {
|
||||
int mlt;
|
||||
@@ -426,11 +430,11 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
const BYTE* vLimit = ip + (dictEndOffset - dictMatchIndex);
|
||||
if (vLimit > iHighLimit) vLimit = iHighLimit;
|
||||
mlt = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
|
||||
back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictCtx->base + dictCtx->dictLimit) : 0;
|
||||
back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictCtx->prefixStart) : 0;
|
||||
mlt -= back;
|
||||
if (mlt > longest) {
|
||||
longest = mlt;
|
||||
*matchpos = base + matchIndex + back;
|
||||
*matchpos = prefixPtr - prefixIdx + matchIndex + back;
|
||||
*startpos = ip + back;
|
||||
} }
|
||||
|
||||
@@ -442,13 +446,13 @@ LZ4HC_InsertAndGetWiderMatch (
|
||||
return longest;
|
||||
}
|
||||
|
||||
LZ4_FORCE_INLINE
|
||||
int LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index table will be updated */
|
||||
const BYTE* const ip, const BYTE* const iLimit,
|
||||
const BYTE** matchpos,
|
||||
const int maxNbAttempts,
|
||||
const int patternAnalysis,
|
||||
const dictCtx_directive dict)
|
||||
LZ4_FORCE_INLINE int
|
||||
LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index table will be updated */
|
||||
const BYTE* const ip, const BYTE* const iLimit,
|
||||
const BYTE** matchpos,
|
||||
const int maxNbAttempts,
|
||||
const int patternAnalysis,
|
||||
const dictCtx_directive dict)
|
||||
{
|
||||
const BYTE* uselessPtr = ip;
|
||||
/* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos),
|
||||
@@ -751,7 +755,7 @@ _last_literals:
|
||||
} else {
|
||||
*op++ = (BYTE)(lastRunSize << ML_BITS);
|
||||
}
|
||||
memcpy(op, anchor, lastRunSize);
|
||||
LZ4_memcpy(op, anchor, lastRunSize);
|
||||
op += lastRunSize;
|
||||
}
|
||||
|
||||
@@ -884,13 +888,13 @@ LZ4HC_compress_generic_dictCtx (
|
||||
limitedOutput_directive limit
|
||||
)
|
||||
{
|
||||
const size_t position = (size_t)(ctx->end - ctx->base) - ctx->lowLimit;
|
||||
const size_t position = (size_t)(ctx->end - ctx->prefixStart) + (ctx->dictLimit - ctx->lowLimit);
|
||||
assert(ctx->dictCtx != NULL);
|
||||
if (position >= 64 KB) {
|
||||
ctx->dictCtx = NULL;
|
||||
return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
|
||||
} else if (position == 0 && *srcSizePtr > 4 KB) {
|
||||
memcpy(ctx, ctx->dictCtx, sizeof(LZ4HC_CCtx_internal));
|
||||
LZ4_memcpy(ctx, ctx->dictCtx, sizeof(LZ4HC_CCtx_internal));
|
||||
LZ4HC_setExternalDict(ctx, (const BYTE *)src);
|
||||
ctx->compressionLevel = (short)cLevel;
|
||||
return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
|
||||
@@ -953,13 +957,15 @@ int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int src
|
||||
|
||||
int LZ4_compress_HC(const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel)
|
||||
{
|
||||
int cSize;
|
||||
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
|
||||
LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)ALLOC(sizeof(LZ4_streamHC_t));
|
||||
if (statePtr==NULL) return 0;
|
||||
#else
|
||||
LZ4_streamHC_t state;
|
||||
LZ4_streamHC_t* const statePtr = &state;
|
||||
#endif
|
||||
int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel);
|
||||
cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel);
|
||||
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
|
||||
FREEMEM(statePtr);
|
||||
#endif
|
||||
@@ -982,6 +988,7 @@ int LZ4_compress_HC_destSize(void* state, const char* source, char* dest, int* s
|
||||
* Streaming Functions
|
||||
**************************************/
|
||||
/* allocation */
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
LZ4_streamHC_t* LZ4_createStreamHC(void)
|
||||
{
|
||||
LZ4_streamHC_t* const state =
|
||||
@@ -998,13 +1005,12 @@ int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr)
|
||||
FREEMEM(LZ4_streamHCPtr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size)
|
||||
{
|
||||
LZ4_streamHC_t* const LZ4_streamHCPtr = (LZ4_streamHC_t*)buffer;
|
||||
/* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
|
||||
LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= LZ4_STREAMHCSIZE);
|
||||
DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", buffer, (unsigned)size);
|
||||
/* check conditions */
|
||||
if (buffer == NULL) return NULL;
|
||||
@@ -1030,9 +1036,13 @@ void LZ4_resetStreamHC_fast (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLev
|
||||
if (LZ4_streamHCPtr->internal_donotuse.dirty) {
|
||||
LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr));
|
||||
} else {
|
||||
/* preserve end - base : can trigger clearTable's threshold */
|
||||
LZ4_streamHCPtr->internal_donotuse.end -= (uptrval)LZ4_streamHCPtr->internal_donotuse.base;
|
||||
LZ4_streamHCPtr->internal_donotuse.base = NULL;
|
||||
/* preserve end - prefixStart : can trigger clearTable's threshold */
|
||||
if (LZ4_streamHCPtr->internal_donotuse.end != NULL) {
|
||||
LZ4_streamHCPtr->internal_donotuse.end -= (uptrval)LZ4_streamHCPtr->internal_donotuse.prefixStart;
|
||||
} else {
|
||||
assert(LZ4_streamHCPtr->internal_donotuse.prefixStart == NULL);
|
||||
}
|
||||
LZ4_streamHCPtr->internal_donotuse.prefixStart = NULL;
|
||||
LZ4_streamHCPtr->internal_donotuse.dictCtx = NULL;
|
||||
}
|
||||
LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel);
|
||||
@@ -1083,14 +1093,14 @@ void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC
|
||||
static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock)
|
||||
{
|
||||
DEBUGLOG(4, "LZ4HC_setExternalDict(%p, %p)", ctxPtr, newBlock);
|
||||
if (ctxPtr->end >= ctxPtr->base + ctxPtr->dictLimit + 4)
|
||||
if (ctxPtr->end >= ctxPtr->prefixStart + 4)
|
||||
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 */
|
||||
ctxPtr->lowLimit = ctxPtr->dictLimit;
|
||||
ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
|
||||
ctxPtr->dictBase = ctxPtr->base;
|
||||
ctxPtr->base = newBlock - ctxPtr->dictLimit;
|
||||
ctxPtr->dictStart = ctxPtr->prefixStart;
|
||||
ctxPtr->dictLimit += (U32)(ctxPtr->end - ctxPtr->prefixStart);
|
||||
ctxPtr->prefixStart = newBlock;
|
||||
ctxPtr->end = newBlock;
|
||||
ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */
|
||||
|
||||
@@ -1109,11 +1119,11 @@ LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
|
||||
LZ4_streamHCPtr, src, *srcSizePtr, limit);
|
||||
assert(ctxPtr != NULL);
|
||||
/* auto-init if forgotten */
|
||||
if (ctxPtr->base == NULL) LZ4HC_init_internal (ctxPtr, (const BYTE*) src);
|
||||
if (ctxPtr->prefixStart == NULL) LZ4HC_init_internal (ctxPtr, (const BYTE*) src);
|
||||
|
||||
/* Check overflow */
|
||||
if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) {
|
||||
size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
|
||||
if ((size_t)(ctxPtr->end - ctxPtr->prefixStart) + ctxPtr->dictLimit > 2 GB) {
|
||||
size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->prefixStart);
|
||||
if (dictSize > 64 KB) dictSize = 64 KB;
|
||||
LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
|
||||
}
|
||||
@@ -1124,13 +1134,16 @@ LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
|
||||
|
||||
/* Check overlapping input/dictionary space */
|
||||
{ const BYTE* sourceEnd = (const BYTE*) src + *srcSizePtr;
|
||||
const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
|
||||
const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
|
||||
const BYTE* const dictBegin = ctxPtr->dictStart;
|
||||
const BYTE* const dictEnd = ctxPtr->dictStart + (ctxPtr->dictLimit - ctxPtr->lowLimit);
|
||||
if ((sourceEnd > dictBegin) && ((const BYTE*)src < dictEnd)) {
|
||||
if (sourceEnd > dictEnd) sourceEnd = dictEnd;
|
||||
ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
|
||||
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
|
||||
} }
|
||||
ctxPtr->lowLimit += (U32)(sourceEnd - ctxPtr->dictStart);
|
||||
ctxPtr->dictStart += (U32)(sourceEnd - ctxPtr->dictStart);
|
||||
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) {
|
||||
ctxPtr->lowLimit = ctxPtr->dictLimit;
|
||||
ctxPtr->dictStart = ctxPtr->prefixStart;
|
||||
} } }
|
||||
|
||||
return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit);
|
||||
}
|
||||
@@ -1158,7 +1171,7 @@ int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, const ch
|
||||
int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
|
||||
{
|
||||
LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
|
||||
int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
|
||||
int const prefixSize = (int)(streamPtr->end - streamPtr->prefixStart);
|
||||
DEBUGLOG(5, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize);
|
||||
assert(prefixSize >= 0);
|
||||
if (dictSize > 64 KB) dictSize = 64 KB;
|
||||
@@ -1166,12 +1179,13 @@ int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictS
|
||||
if (dictSize > prefixSize) dictSize = prefixSize;
|
||||
if (safeBuffer == NULL) assert(dictSize == 0);
|
||||
if (dictSize > 0)
|
||||
memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
|
||||
{ U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
|
||||
LZ4_memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
|
||||
{ U32 const endIndex = (U32)(streamPtr->end - streamPtr->prefixStart) + streamPtr->dictLimit;
|
||||
streamPtr->end = (const BYTE*)safeBuffer + dictSize;
|
||||
streamPtr->base = streamPtr->end - endIndex;
|
||||
streamPtr->prefixStart = streamPtr->end - dictSize;
|
||||
streamPtr->dictLimit = endIndex - (U32)dictSize;
|
||||
streamPtr->lowLimit = endIndex - (U32)dictSize;
|
||||
streamPtr->dictStart = streamPtr->prefixStart;
|
||||
if (streamPtr->nextToUpdate < streamPtr->dictLimit)
|
||||
streamPtr->nextToUpdate = streamPtr->dictLimit;
|
||||
}
|
||||
@@ -1199,7 +1213,7 @@ int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const char* src,
|
||||
|
||||
|
||||
/* Deprecated streaming functions */
|
||||
int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; }
|
||||
int LZ4_sizeofStreamStateHC(void) { return sizeof(LZ4_streamHC_t); }
|
||||
|
||||
/* state is presumed correctly sized, aka >= sizeof(LZ4_streamHC_t)
|
||||
* @return : 0 on success, !=0 if error */
|
||||
@@ -1211,6 +1225,7 @@ int LZ4_resetStreamStateHC(void* state, char* inputBuffer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
void* LZ4_createHC (const char* inputBuffer)
|
||||
{
|
||||
LZ4_streamHC_t* const hc4 = LZ4_createStreamHC();
|
||||
@@ -1225,6 +1240,7 @@ int LZ4_freeHC (void* LZ4HC_Data)
|
||||
FREEMEM(LZ4HC_Data);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int cLevel)
|
||||
{
|
||||
@@ -1238,11 +1254,11 @@ int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* src, c
|
||||
|
||||
char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
|
||||
{
|
||||
LZ4_streamHC_t *ctx = (LZ4_streamHC_t*)LZ4HC_Data;
|
||||
const BYTE *bufferStart = ctx->internal_donotuse.base + ctx->internal_donotuse.lowLimit;
|
||||
LZ4_streamHC_t* const ctx = (LZ4_streamHC_t*)LZ4HC_Data;
|
||||
const BYTE* bufferStart = ctx->internal_donotuse.prefixStart - ctx->internal_donotuse.dictLimit + ctx->internal_donotuse.lowLimit;
|
||||
LZ4_resetStreamHC_fast(ctx, ctx->internal_donotuse.compressionLevel);
|
||||
/* avoid const char * -> char * conversion warning :( */
|
||||
return (char *)(uptrval)bufferStart;
|
||||
return (char*)(uptrval)bufferStart;
|
||||
}
|
||||
|
||||
|
||||
@@ -1325,7 +1341,7 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
||||
{
|
||||
int retval = 0;
|
||||
#define TRAILING_LITERALS 3
|
||||
#ifdef LZ4HC_HEAPMODE
|
||||
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
|
||||
LZ4HC_optimal_t* const opt = (LZ4HC_optimal_t*)ALLOC(sizeof(LZ4HC_optimal_t) * (LZ4_OPT_NUM + TRAILING_LITERALS));
|
||||
#else
|
||||
LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* ~64 KB, which is a bit large for stack... */
|
||||
@@ -1343,7 +1359,7 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
||||
const BYTE* ovref = NULL;
|
||||
|
||||
/* init */
|
||||
#ifdef LZ4HC_HEAPMODE
|
||||
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
|
||||
if (opt == NULL) goto _return_label;
|
||||
#endif
|
||||
DEBUGLOG(5, "LZ4HC_compress_optimal(dst=%p, dstCapa=%u)", dst, (unsigned)dstCapacity);
|
||||
@@ -1575,7 +1591,7 @@ _last_literals:
|
||||
} else {
|
||||
*op++ = (BYTE)(lastRunSize << ML_BITS);
|
||||
}
|
||||
memcpy(op, anchor, lastRunSize);
|
||||
LZ4_memcpy(op, anchor, lastRunSize);
|
||||
op += lastRunSize;
|
||||
}
|
||||
|
||||
@@ -1608,7 +1624,7 @@ if (limit == fillOutput) {
|
||||
goto _last_literals;
|
||||
}
|
||||
_return_label:
|
||||
#ifdef LZ4HC_HEAPMODE
|
||||
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
|
||||
FREEMEM(opt);
|
||||
#endif
|
||||
return retval;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
LZ4 HC - High Compression Mode of LZ4
|
||||
Header File
|
||||
Copyright (C) 2011-2017, Yann Collet.
|
||||
Copyright (C) 2011-2020, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -198,14 +198,17 @@ LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, in
|
||||
#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
|
||||
|
||||
|
||||
/* Never ever use these definitions directly !
|
||||
* Declare or allocate an LZ4_streamHC_t instead.
|
||||
**/
|
||||
typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
|
||||
struct LZ4HC_CCtx_internal
|
||||
{
|
||||
LZ4_u32 hashTable[LZ4HC_HASHTABLESIZE];
|
||||
LZ4_u16 chainTable[LZ4HC_MAXD];
|
||||
const LZ4_byte* end; /* next block here to continue on current prefix */
|
||||
const LZ4_byte* base; /* All index relative to this position */
|
||||
const LZ4_byte* dictBase; /* alternate base for extDict */
|
||||
const LZ4_byte* prefixStart; /* Indexes relative to this position */
|
||||
const LZ4_byte* dictStart; /* alternate reference for extDict */
|
||||
LZ4_u32 dictLimit; /* below that point, need extDict */
|
||||
LZ4_u32 lowLimit; /* below that point, no more dict */
|
||||
LZ4_u32 nextToUpdate; /* index from which to continue dictionary update */
|
||||
@@ -216,20 +219,15 @@ struct LZ4HC_CCtx_internal
|
||||
const LZ4HC_CCtx_internal* dictCtx;
|
||||
};
|
||||
|
||||
|
||||
/* Do not use these definitions directly !
|
||||
* Declare or allocate an LZ4_streamHC_t instead.
|
||||
*/
|
||||
#define LZ4_STREAMHCSIZE 262200 /* static size, for inter-version compatibility */
|
||||
#define LZ4_STREAMHCSIZE_VOIDP (LZ4_STREAMHCSIZE / sizeof(void*))
|
||||
#define LZ4_STREAMHC_MINSIZE 262200 /* static size, for inter-version compatibility */
|
||||
union LZ4_streamHC_u {
|
||||
void* table[LZ4_STREAMHCSIZE_VOIDP];
|
||||
char minStateSize[LZ4_STREAMHC_MINSIZE];
|
||||
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.
|
||||
* This can be used to allocate statically, on state, or as part of a larger structure.
|
||||
* This can be used to allocate statically on stack, or as part of a larger structure.
|
||||
*
|
||||
* Such state **must** be initialized using LZ4_initStreamHC() before first use.
|
||||
*
|
||||
@@ -244,7 +242,7 @@ union LZ4_streamHC_u {
|
||||
* Required before first use of a statically allocated LZ4_streamHC_t.
|
||||
* Before v1.9.0 : use LZ4_resetStreamHC() instead
|
||||
*/
|
||||
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size);
|
||||
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC(void* buffer, size_t size);
|
||||
|
||||
|
||||
/*-************************************
|
||||
@@ -272,9 +270,11 @@ LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_comp
|
||||
* LZ4_slideInputBufferHC() will truncate the history of the stream, rather
|
||||
* than preserve a window-sized chunk of history.
|
||||
*/
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
|
||||
LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data);
|
||||
#endif
|
||||
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API 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") LZ4LIB_API int LZ4_sizeofStreamStateHC(void);
|
||||
@@ -305,7 +305,7 @@ LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionL
|
||||
* They should not be linked from DLL,
|
||||
* as there is no guarantee of API stability yet.
|
||||
* Prototypes will be promoted to "stable" status
|
||||
* after successfull usage in real-life scenarios.
|
||||
* after successful usage in real-life scenarios.
|
||||
***************************************************/
|
||||
#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
|
||||
#ifndef LZ4_HC_SLO_098092834
|
||||
|
||||
Reference in New Issue
Block a user