extlz4 0.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.ja.md +7 -0
- data/README.md +3 -3
- data/contrib/lz4/Makefile.inc +87 -0
- data/contrib/lz4/NEWS +7 -0
- data/contrib/lz4/README.md +1 -1
- data/contrib/lz4/lib/README.md +3 -5
- data/contrib/lz4/lib/liblz4-dll.rc.in +35 -0
- data/contrib/lz4/lib/lz4.c +296 -182
- data/contrib/lz4/lib/lz4.h +125 -40
- data/contrib/lz4/lib/lz4frame.c +30 -6
- data/contrib/lz4/lib/lz4frame.h +11 -2
- data/contrib/lz4/lib/lz4hc.c +93 -30
- data/contrib/lz4/lib/lz4hc.h +3 -0
- data/contrib/lz4/ossfuzz/Makefile +74 -0
- data/contrib/lz4/ossfuzz/compress_frame_fuzzer.c +42 -0
- data/contrib/lz4/ossfuzz/compress_fuzzer.c +51 -0
- data/contrib/lz4/ossfuzz/compress_hc_fuzzer.c +57 -0
- data/contrib/lz4/ossfuzz/decompress_frame_fuzzer.c +67 -0
- data/contrib/lz4/ossfuzz/decompress_fuzzer.c +58 -0
- data/contrib/lz4/ossfuzz/fuzz.h +48 -0
- data/contrib/lz4/ossfuzz/fuzz_helpers.h +94 -0
- data/contrib/lz4/ossfuzz/lz4_helpers.c +51 -0
- data/contrib/lz4/ossfuzz/lz4_helpers.h +13 -0
- data/contrib/lz4/ossfuzz/ossfuzz.sh +23 -0
- data/contrib/lz4/ossfuzz/round_trip_frame_fuzzer.c +39 -0
- data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +50 -0
- data/contrib/lz4/ossfuzz/round_trip_hc_fuzzer.c +39 -0
- data/contrib/lz4/ossfuzz/round_trip_stream_fuzzer.c +302 -0
- data/contrib/lz4/ossfuzz/standaloneengine.c +74 -0
- data/contrib/lz4/ossfuzz/travisoss.sh +21 -0
- data/ext/blockapi.c +3 -3
- data/ext/hashargs.c +1 -1
- data/lib/extlz4.rb +5 -1
- data/lib/extlz4/version.rb +1 -1
- data/test/common.rb +2 -2
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47cf5cc7a6110b9745b7c8fb44241bb63cec270c72a71de4d5d874f5bb054823
|
4
|
+
data.tar.gz: f2a7d26bc96f2df6ffe99db799d1c199bceb75f5e5ad01f959bca5ce48ef19ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e906586be02470ae4b18fe625e15af59d958c05b71e74eb74eb5f9f767279cc04a1411bc134743c2d572d2dea4c99f7c44bfbda0618208c79c6fc3c3e2eeb64
|
7
|
+
data.tar.gz: 17962b5b4e648ef9aa4f1629c8673197ee1f9d2222ef0ddf90ce0e9513b4b5f135cc1452b36cd1d734b3dff8efc5b2318b795bb88fc0d73f05c14d75affdd508
|
data/HISTORY.ja.md
CHANGED
data/README.md
CHANGED
@@ -194,13 +194,13 @@ p src2 == data # => true
|
|
194
194
|
- author: dearblue (mailto:dearblue@users.noreply.github.com)
|
195
195
|
- project page: <https://github.com/dearblue/ruby-extlz4>
|
196
196
|
- how to install: `gem install extlz4`
|
197
|
-
- version: 0.3
|
197
|
+
- version: 0.3.1
|
198
198
|
- product quality: technical preview
|
199
199
|
- licensing: [2 clause BSD License](LICENSE)
|
200
200
|
- dependency gems: none
|
201
201
|
- dependency external c libraries: none
|
202
202
|
- bundled external c libraries (git submodules):
|
203
203
|
- [lz4](https://github.com/lz4/lz4)
|
204
|
-
[version 1.9.
|
205
|
-
under [2 clause BSD license](https://github.com/lz4/lz4/blob/v1.9.
|
204
|
+
[version 1.9.2](https://github.com/lz4/lz4/tree/v1.9.2)
|
205
|
+
under [2 clause BSD license](https://github.com/lz4/lz4/blob/v1.9.2/LICENSE)
|
206
206
|
by [Yann Collet](https://github.com/Cyan4973)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
ifeq ($(V), 1)
|
2
|
+
Q =
|
3
|
+
else
|
4
|
+
Q = @
|
5
|
+
endif
|
6
|
+
|
7
|
+
TARGET_OS ?= $(shell uname)
|
8
|
+
ifeq ($(TARGET_OS),)
|
9
|
+
TARGET_OS ?= $(OS)
|
10
|
+
endif
|
11
|
+
|
12
|
+
ifneq (,$(filter Windows%,$(TARGET_OS)))
|
13
|
+
LIBLZ4 = liblz4-$(LIBVER_MAJOR)
|
14
|
+
LIBLZ4_EXP = liblz4.lib
|
15
|
+
WINBASED = yes
|
16
|
+
else
|
17
|
+
LIBLZ4_EXP = liblz4.dll.a
|
18
|
+
ifneq (,$(filter MINGW%,$(TARGET_OS)))
|
19
|
+
LIBLZ4 = liblz4
|
20
|
+
WINBASED = yes
|
21
|
+
else
|
22
|
+
ifneq (,$(filter MSYS%,$(TARGET_OS)))
|
23
|
+
LIBLZ4 = msys-lz4-$(LIBVER_MAJOR)
|
24
|
+
WINBASED = yes
|
25
|
+
else
|
26
|
+
ifneq (,$(filter CYGWIN%,$(TARGET_OS)))
|
27
|
+
LIBLZ4 = cyglz4-$(LIBVER_MAJOR)
|
28
|
+
WINBASED = yes
|
29
|
+
else
|
30
|
+
LIBLZ4 = liblz4.$(SHARED_EXT_VER)
|
31
|
+
WINBASED = no
|
32
|
+
EXT =
|
33
|
+
endif
|
34
|
+
endif
|
35
|
+
endif
|
36
|
+
endif
|
37
|
+
|
38
|
+
ifeq ($(WINBASED),yes)
|
39
|
+
EXT = .exe
|
40
|
+
WINDRES = windres
|
41
|
+
endif
|
42
|
+
|
43
|
+
#determine if dev/nul based on host environment
|
44
|
+
ifneq (,$(filter MINGW% MSYS% CYGWIN%,$(shell uname)))
|
45
|
+
VOID := /dev/null
|
46
|
+
else
|
47
|
+
ifneq (,$(filter Windows%,$(OS)))
|
48
|
+
VOID := nul
|
49
|
+
else
|
50
|
+
VOID := /dev/null
|
51
|
+
endif
|
52
|
+
endif
|
53
|
+
|
54
|
+
ifneq (,$(filter Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku MidnightBSD MINGW% CYGWIN% MSYS%,$(shell uname)))
|
55
|
+
POSIX_ENV = Yes
|
56
|
+
else
|
57
|
+
POSIX_ENV = No
|
58
|
+
endif
|
59
|
+
|
60
|
+
# Avoid symlinks when targetting Windows or building on a Windows host
|
61
|
+
ifeq ($(WINBASED),yes)
|
62
|
+
LN_S = cp -p
|
63
|
+
LN_SF = cp -p
|
64
|
+
else
|
65
|
+
ifneq (,$(filter MINGW% MSYS% CYGWIN%,$(shell uname)))
|
66
|
+
LN_S = cp -p
|
67
|
+
LN_SF = cp -p
|
68
|
+
else
|
69
|
+
ifneq (,$(filter Windows%,$(OS)))
|
70
|
+
LN_S = cp -p
|
71
|
+
LN_SF = cp -p
|
72
|
+
else
|
73
|
+
LN_S = ln -s
|
74
|
+
LN_SF = ln -sf
|
75
|
+
endif
|
76
|
+
endif
|
77
|
+
endif
|
78
|
+
|
79
|
+
ifneq (,$(filter $(shell uname),SunOS))
|
80
|
+
INSTALL ?= ginstall
|
81
|
+
else
|
82
|
+
INSTALL ?= install
|
83
|
+
endif
|
84
|
+
|
85
|
+
INSTALL_PROGRAM ?= $(INSTALL) -m 755
|
86
|
+
INSTALL_DATA ?= $(INSTALL) -m 644
|
87
|
+
INSTALL_DIR ?= $(INSTALL) -d -m 755
|
data/contrib/lz4/NEWS
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
v1.9.1
|
2
|
+
fix : decompression functions were reading a few bytes beyond input size (introduced in v1.9.0, reported by @ppodolsky and @danlark1)
|
3
|
+
api : fix : lz4frame initializers compatibility with c++, reported by @degski
|
4
|
+
cli : added command --list, based on a patch by @gabrielstedman
|
5
|
+
build: improved Windows build, by @JPeterMugaas
|
6
|
+
build: AIX, by Norman Green
|
7
|
+
|
1
8
|
v1.9.0
|
2
9
|
perf: large decompression speed improvement on x86/x64 (up to +20%) by @djwatson
|
3
10
|
api : changed : _destSize() compression variants are promoted to stable API
|
data/contrib/lz4/README.md
CHANGED
@@ -68,7 +68,7 @@ in single-thread mode.
|
|
68
68
|
| [Zstandard] 1.4.0 -1 | 2.883 | 515 MB/s | 1380 MB/s |
|
69
69
|
| LZF v3.6 | 2.073 | 415 MB/s | 910 MB/s |
|
70
70
|
| [zlib] deflate 1.2.11 -1| 2.730 | 100 MB/s | 415 MB/s |
|
71
|
-
|**LZ4 HC -9 (v1.
|
71
|
+
|**LZ4 HC -9 (v1.9.0)** |**2.721**| 41 MB/s | **4900 MB/s** |
|
72
72
|
| [zlib] deflate 1.2.11 -6| 3.099 | 36 MB/s | 445 MB/s |
|
73
73
|
|
74
74
|
[zlib]: http://www.zlib.net/
|
data/contrib/lz4/lib/README.md
CHANGED
@@ -56,8 +56,8 @@ The following build macro can be selected at compilation time :
|
|
56
56
|
- `LZ4_DISTANCE_MAX` : control the maximum offset that the compressor will allow.
|
57
57
|
Set to 65535 by default, which is the maximum value supported by lz4 format.
|
58
58
|
Reducing maximum distance will reduce opportunities for LZ4 to find matches,
|
59
|
-
hence will produce worse
|
60
|
-
However, a smaller max distance
|
59
|
+
hence will produce a worse compression ratio.
|
60
|
+
However, a smaller max distance can allow compatibility with specific decoders using limited memory budget.
|
61
61
|
This build macro only influences the compressed output of the compressor.
|
62
62
|
|
63
63
|
- `LZ4_DISABLE_DEPRECATE_WARNINGS` : invoking a deprecated function will make the compiler generate a warning.
|
@@ -74,9 +74,7 @@ The following build macro can be selected at compilation time :
|
|
74
74
|
lz4 source code can be amalgamated into a single file.
|
75
75
|
One can combine all source code into `lz4_all.c` by using following command:
|
76
76
|
```
|
77
|
-
cat lz4.c > lz4_all.c
|
78
|
-
cat lz4hc.c >> lz4_all.c
|
79
|
-
cat lz4frame.c >> lz4_all.c
|
77
|
+
cat lz4.c lz4hc.c lz4frame.c > lz4_all.c
|
80
78
|
```
|
81
79
|
(`cat` file order is important) then compile `lz4_all.c`.
|
82
80
|
All `*.h` files present in `/lib` remain necessary to compile `lz4_all.c`.
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#include <windows.h>
|
2
|
+
|
3
|
+
// DLL version information.
|
4
|
+
1 VERSIONINFO
|
5
|
+
FILEVERSION @LIBVER_MAJOR@,@LIBVER_MINOR@,@LIBVER_PATCH@,0
|
6
|
+
PRODUCTVERSION @LIBVER_MAJOR@,@LIBVER_MINOR@,@LIBVER_PATCH@,0
|
7
|
+
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
8
|
+
#ifdef _DEBUG
|
9
|
+
FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
|
10
|
+
#else
|
11
|
+
FILEFLAGS 0
|
12
|
+
#endif
|
13
|
+
FILEOS VOS_NT_WINDOWS32
|
14
|
+
FILETYPE VFT_DLL
|
15
|
+
FILESUBTYPE VFT2_UNKNOWN
|
16
|
+
BEGIN
|
17
|
+
BLOCK "StringFileInfo"
|
18
|
+
BEGIN
|
19
|
+
BLOCK "040904B0"
|
20
|
+
BEGIN
|
21
|
+
VALUE "CompanyName", "Yann Collet"
|
22
|
+
VALUE "FileDescription", "Extremely fast compression"
|
23
|
+
VALUE "FileVersion", "@LIBVER_MAJOR@.@LIBVER_MINOR@.@LIBVER_PATCH@.0"
|
24
|
+
VALUE "InternalName", "@LIBLZ4@"
|
25
|
+
VALUE "LegalCopyright", "Copyright (C) 2013-2016, Yann Collet"
|
26
|
+
VALUE "OriginalFilename", "@LIBLZ4@.dll"
|
27
|
+
VALUE "ProductName", "LZ4"
|
28
|
+
VALUE "ProductVersion", "@LIBVER_MAJOR@.@LIBVER_MINOR@.@LIBVER_PATCH@.0"
|
29
|
+
END
|
30
|
+
END
|
31
|
+
BLOCK "VarFileInfo"
|
32
|
+
BEGIN
|
33
|
+
VALUE "Translation", 0x0409, 1200
|
34
|
+
END
|
35
|
+
END
|
data/contrib/lz4/lib/lz4.c
CHANGED
@@ -98,8 +98,15 @@
|
|
98
98
|
# define LZ4_SRC_INCLUDED 1
|
99
99
|
#endif
|
100
100
|
|
101
|
+
#ifndef LZ4_STATIC_LINKING_ONLY
|
101
102
|
#define LZ4_STATIC_LINKING_ONLY
|
103
|
+
#endif
|
104
|
+
|
105
|
+
#ifndef LZ4_DISABLE_DEPRECATE_WARNINGS
|
102
106
|
#define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */
|
107
|
+
#endif
|
108
|
+
|
109
|
+
#define LZ4_STATIC_LINKING_ONLY /* LZ4_DISTANCE_MAX */
|
103
110
|
#include "lz4.h"
|
104
111
|
/* see also "memory routines" below */
|
105
112
|
|
@@ -130,7 +137,7 @@
|
|
130
137
|
#endif /* LZ4_FORCE_INLINE */
|
131
138
|
|
132
139
|
/* LZ4_FORCE_O2_GCC_PPC64LE and LZ4_FORCE_O2_INLINE_GCC_PPC64LE
|
133
|
-
*
|
140
|
+
* gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy8,
|
134
141
|
* together with a simple 8-byte copy loop as a fall-back path.
|
135
142
|
* However, this optimization hurts the decompression speed by >30%,
|
136
143
|
* because the execution does not go to the optimized loop
|
@@ -138,10 +145,10 @@
|
|
138
145
|
* before going to the fall-back path become useless overhead.
|
139
146
|
* This optimization happens only with the -O3 flag, and -O2 generates
|
140
147
|
* a simple 8-byte copy loop.
|
141
|
-
* With gcc on ppc64le, all of the LZ4_decompress_* and
|
148
|
+
* With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy8
|
142
149
|
* functions are annotated with __attribute__((optimize("O2"))),
|
143
|
-
* and also
|
144
|
-
* of
|
150
|
+
* and also LZ4_wildCopy8 is forcibly inlined, so that the O2 attribute
|
151
|
+
* of LZ4_wildCopy8 does not affect the compression speed.
|
145
152
|
*/
|
146
153
|
#if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__) && !defined(__clang__)
|
147
154
|
# define LZ4_FORCE_O2_GCC_PPC64LE __attribute__((optimize("O2")))
|
@@ -176,6 +183,60 @@
|
|
176
183
|
#define MEM_INIT(p,v,s) memset((p),(v),(s))
|
177
184
|
|
178
185
|
|
186
|
+
/*-************************************
|
187
|
+
* Common Constants
|
188
|
+
**************************************/
|
189
|
+
#define MINMATCH 4
|
190
|
+
|
191
|
+
#define WILDCOPYLENGTH 8
|
192
|
+
#define LASTLITERALS 5 /* see ../doc/lz4_Block_format.md#parsing-restrictions */
|
193
|
+
#define MFLIMIT 12 /* see ../doc/lz4_Block_format.md#parsing-restrictions */
|
194
|
+
#define MATCH_SAFEGUARD_DISTANCE ((2*WILDCOPYLENGTH) - MINMATCH) /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */
|
195
|
+
#define FASTLOOP_SAFE_DISTANCE 64
|
196
|
+
static const int LZ4_minLength = (MFLIMIT+1);
|
197
|
+
|
198
|
+
#define KB *(1 <<10)
|
199
|
+
#define MB *(1 <<20)
|
200
|
+
#define GB *(1U<<30)
|
201
|
+
|
202
|
+
#define LZ4_DISTANCE_ABSOLUTE_MAX 65535
|
203
|
+
#if (LZ4_DISTANCE_MAX > LZ4_DISTANCE_ABSOLUTE_MAX) /* max supported by LZ4 format */
|
204
|
+
# error "LZ4_DISTANCE_MAX is too big : must be <= 65535"
|
205
|
+
#endif
|
206
|
+
|
207
|
+
#define ML_BITS 4
|
208
|
+
#define ML_MASK ((1U<<ML_BITS)-1)
|
209
|
+
#define RUN_BITS (8-ML_BITS)
|
210
|
+
#define RUN_MASK ((1U<<RUN_BITS)-1)
|
211
|
+
|
212
|
+
|
213
|
+
/*-************************************
|
214
|
+
* Error detection
|
215
|
+
**************************************/
|
216
|
+
#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=1)
|
217
|
+
# include <assert.h>
|
218
|
+
#else
|
219
|
+
# ifndef assert
|
220
|
+
# define assert(condition) ((void)0)
|
221
|
+
# endif
|
222
|
+
#endif
|
223
|
+
|
224
|
+
#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use after variable declarations */
|
225
|
+
|
226
|
+
#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2)
|
227
|
+
# include <stdio.h>
|
228
|
+
static int g_debuglog_enable = 1;
|
229
|
+
# define DEBUGLOG(l, ...) { \
|
230
|
+
if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \
|
231
|
+
fprintf(stderr, __FILE__ ": "); \
|
232
|
+
fprintf(stderr, __VA_ARGS__); \
|
233
|
+
fprintf(stderr, " \n"); \
|
234
|
+
} }
|
235
|
+
#else
|
236
|
+
# define DEBUGLOG(l, ...) {} /* disabled */
|
237
|
+
#endif
|
238
|
+
|
239
|
+
|
179
240
|
/*-************************************
|
180
241
|
* Types
|
181
242
|
**************************************/
|
@@ -295,7 +356,7 @@ static void LZ4_writeLE16(void* memPtr, U16 value)
|
|
295
356
|
|
296
357
|
/* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */
|
297
358
|
LZ4_FORCE_O2_INLINE_GCC_PPC64LE
|
298
|
-
void
|
359
|
+
void LZ4_wildCopy8(void* dstPtr, const void* srcPtr, void* dstEnd)
|
299
360
|
{
|
300
361
|
BYTE* d = (BYTE*)dstPtr;
|
301
362
|
const BYTE* s = (const BYTE*)srcPtr;
|
@@ -311,6 +372,11 @@ static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3};
|
|
311
372
|
#ifndef LZ4_FAST_DEC_LOOP
|
312
373
|
# if defined(__i386__) || defined(__x86_64__)
|
313
374
|
# define LZ4_FAST_DEC_LOOP 1
|
375
|
+
# elif defined(__aarch64__) && !defined(__clang__)
|
376
|
+
/* On aarch64, we disable this optimization for clang because on certain
|
377
|
+
* mobile chipsets and clang, it reduces performance. For more information
|
378
|
+
* refer to https://github.com/lz4/lz4/pull/707. */
|
379
|
+
# define LZ4_FAST_DEC_LOOP 1
|
314
380
|
# else
|
315
381
|
# define LZ4_FAST_DEC_LOOP 0
|
316
382
|
# endif
|
@@ -336,7 +402,7 @@ LZ4_memcpy_using_offset_base(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, con
|
|
336
402
|
srcPtr += 8;
|
337
403
|
}
|
338
404
|
|
339
|
-
|
405
|
+
LZ4_wildCopy8(dstPtr, srcPtr, dstEnd);
|
340
406
|
}
|
341
407
|
|
342
408
|
/* customized variant of memcpy, which can overwrite up to 32 bytes beyond dstEnd
|
@@ -352,29 +418,35 @@ LZ4_wildCopy32(void* dstPtr, const void* srcPtr, void* dstEnd)
|
|
352
418
|
do { memcpy(d,s,16); memcpy(d+16,s+16,16); d+=32; s+=32; } while (d<e);
|
353
419
|
}
|
354
420
|
|
421
|
+
/* LZ4_memcpy_using_offset() presumes :
|
422
|
+
* - dstEnd >= dstPtr + MINMATCH
|
423
|
+
* - there is at least 8 bytes available to write after dstEnd */
|
355
424
|
LZ4_FORCE_O2_INLINE_GCC_PPC64LE void
|
356
425
|
LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset)
|
357
426
|
{
|
358
427
|
BYTE v[8];
|
428
|
+
|
429
|
+
assert(dstEnd >= dstPtr + MINMATCH);
|
430
|
+
LZ4_write32(dstPtr, 0); /* silence an msan warning when offset==0 */
|
431
|
+
|
359
432
|
switch(offset) {
|
360
433
|
case 1:
|
361
434
|
memset(v, *srcPtr, 8);
|
362
|
-
|
435
|
+
break;
|
363
436
|
case 2:
|
364
437
|
memcpy(v, srcPtr, 2);
|
365
438
|
memcpy(&v[2], srcPtr, 2);
|
366
439
|
memcpy(&v[4], &v[0], 4);
|
367
|
-
|
440
|
+
break;
|
368
441
|
case 4:
|
369
442
|
memcpy(v, srcPtr, 4);
|
370
443
|
memcpy(&v[4], srcPtr, 4);
|
371
|
-
|
444
|
+
break;
|
372
445
|
default:
|
373
446
|
LZ4_memcpy_using_offset_base(dstPtr, srcPtr, dstEnd, offset);
|
374
447
|
return;
|
375
448
|
}
|
376
449
|
|
377
|
-
copy_loop:
|
378
450
|
memcpy(dstPtr, v, 8);
|
379
451
|
dstPtr += 8;
|
380
452
|
while (dstPtr < dstEnd) {
|
@@ -385,63 +457,6 @@ LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const si
|
|
385
457
|
#endif
|
386
458
|
|
387
459
|
|
388
|
-
/*-************************************
|
389
|
-
* Common Constants
|
390
|
-
**************************************/
|
391
|
-
#define MINMATCH 4
|
392
|
-
|
393
|
-
#define WILDCOPYLENGTH 8
|
394
|
-
#define LASTLITERALS 5 /* see ../doc/lz4_Block_format.md#parsing-restrictions */
|
395
|
-
#define MFLIMIT 12 /* see ../doc/lz4_Block_format.md#parsing-restrictions */
|
396
|
-
#define MATCH_SAFEGUARD_DISTANCE ((2*WILDCOPYLENGTH) - MINMATCH) /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */
|
397
|
-
#define FASTLOOP_SAFE_DISTANCE 64
|
398
|
-
static const int LZ4_minLength = (MFLIMIT+1);
|
399
|
-
|
400
|
-
#define KB *(1 <<10)
|
401
|
-
#define MB *(1 <<20)
|
402
|
-
#define GB *(1U<<30)
|
403
|
-
|
404
|
-
#ifndef LZ4_DISTANCE_MAX /* can be user - defined at compile time */
|
405
|
-
# define LZ4_DISTANCE_MAX 65535
|
406
|
-
#endif
|
407
|
-
|
408
|
-
#if (LZ4_DISTANCE_MAX > 65535) /* max supported by LZ4 format */
|
409
|
-
# error "LZ4_DISTANCE_MAX is too big : must be <= 65535"
|
410
|
-
#endif
|
411
|
-
|
412
|
-
#define ML_BITS 4
|
413
|
-
#define ML_MASK ((1U<<ML_BITS)-1)
|
414
|
-
#define RUN_BITS (8-ML_BITS)
|
415
|
-
#define RUN_MASK ((1U<<RUN_BITS)-1)
|
416
|
-
|
417
|
-
|
418
|
-
/*-************************************
|
419
|
-
* Error detection
|
420
|
-
**************************************/
|
421
|
-
#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=1)
|
422
|
-
# include <assert.h>
|
423
|
-
#else
|
424
|
-
# ifndef assert
|
425
|
-
# define assert(condition) ((void)0)
|
426
|
-
# endif
|
427
|
-
#endif
|
428
|
-
|
429
|
-
#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use after variable declarations */
|
430
|
-
|
431
|
-
#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2)
|
432
|
-
# include <stdio.h>
|
433
|
-
static int g_debuglog_enable = 1;
|
434
|
-
# define DEBUGLOG(l, ...) { \
|
435
|
-
if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \
|
436
|
-
fprintf(stderr, __FILE__ ": "); \
|
437
|
-
fprintf(stderr, __VA_ARGS__); \
|
438
|
-
fprintf(stderr, " \n"); \
|
439
|
-
} }
|
440
|
-
#else
|
441
|
-
# define DEBUGLOG(l, ...) {} /* disabled */
|
442
|
-
#endif
|
443
|
-
|
444
|
-
|
445
460
|
/*-************************************
|
446
461
|
* Common functions
|
447
462
|
**************************************/
|
@@ -454,7 +469,7 @@ static unsigned LZ4_NbCommonBytes (reg_t val)
|
|
454
469
|
_BitScanForward64( &r, (U64)val );
|
455
470
|
return (int)(r>>3);
|
456
471
|
# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
|
457
|
-
return (__builtin_ctzll((U64)val) >> 3
|
472
|
+
return (unsigned)__builtin_ctzll((U64)val) >> 3;
|
458
473
|
# else
|
459
474
|
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
|
460
475
|
0, 3, 1, 3, 1, 4, 2, 7,
|
@@ -472,7 +487,7 @@ static unsigned LZ4_NbCommonBytes (reg_t val)
|
|
472
487
|
_BitScanForward( &r, (U32)val );
|
473
488
|
return (int)(r>>3);
|
474
489
|
# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
|
475
|
-
return (__builtin_ctz((U32)val) >> 3
|
490
|
+
return (unsigned)__builtin_ctz((U32)val) >> 3;
|
476
491
|
# else
|
477
492
|
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
|
478
493
|
3, 2, 2, 1, 3, 2, 0, 1,
|
@@ -488,7 +503,7 @@ static unsigned LZ4_NbCommonBytes (reg_t val)
|
|
488
503
|
_BitScanReverse64( &r, val );
|
489
504
|
return (unsigned)(r>>3);
|
490
505
|
# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
|
491
|
-
return (__builtin_clzll((U64)val) >> 3
|
506
|
+
return (unsigned)__builtin_clzll((U64)val) >> 3;
|
492
507
|
# else
|
493
508
|
static const U32 by32 = sizeof(val)*4; /* 32 on 64 bits (goal), 16 on 32 bits.
|
494
509
|
Just to avoid some static analyzer complaining about shift by 32 on 32-bits target.
|
@@ -505,7 +520,7 @@ static unsigned LZ4_NbCommonBytes (reg_t val)
|
|
505
520
|
_BitScanReverse( &r, (unsigned long)val );
|
506
521
|
return (unsigned)(r>>3);
|
507
522
|
# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
|
508
|
-
return (__builtin_clz((U32)val) >> 3
|
523
|
+
return (unsigned)__builtin_clz((U32)val) >> 3;
|
509
524
|
# else
|
510
525
|
unsigned r;
|
511
526
|
if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
|
@@ -600,9 +615,11 @@ int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
|
|
600
615
|
extern "C" {
|
601
616
|
#endif
|
602
617
|
|
603
|
-
int LZ4_compress_forceExtDict (LZ4_stream_t*
|
618
|
+
int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize);
|
604
619
|
|
605
|
-
int LZ4_decompress_safe_forceExtDict(const char*
|
620
|
+
int LZ4_decompress_safe_forceExtDict(const char* source, char* dest,
|
621
|
+
int compressedSize, int maxOutputSize,
|
622
|
+
const void* dictStart, size_t dictSize);
|
606
623
|
|
607
624
|
#if defined (__cplusplus)
|
608
625
|
}
|
@@ -637,6 +654,18 @@ LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tab
|
|
637
654
|
return LZ4_hash4(LZ4_read32(p), tableType);
|
638
655
|
}
|
639
656
|
|
657
|
+
static void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType)
|
658
|
+
{
|
659
|
+
switch (tableType)
|
660
|
+
{
|
661
|
+
default: /* fallthrough */
|
662
|
+
case clearedTable: { /* illegal! */ assert(0); return; }
|
663
|
+
case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = NULL; return; }
|
664
|
+
case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = 0; return; }
|
665
|
+
case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = 0; return; }
|
666
|
+
}
|
667
|
+
}
|
668
|
+
|
640
669
|
static void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType)
|
641
670
|
{
|
642
671
|
switch (tableType)
|
@@ -697,18 +726,19 @@ static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, tableType
|
|
697
726
|
{ const U16* const hashTable = (const U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */
|
698
727
|
}
|
699
728
|
|
700
|
-
LZ4_FORCE_INLINE const BYTE*
|
701
|
-
|
702
|
-
|
729
|
+
LZ4_FORCE_INLINE const BYTE*
|
730
|
+
LZ4_getPosition(const BYTE* p,
|
731
|
+
const void* tableBase, tableType_t tableType,
|
732
|
+
const BYTE* srcBase)
|
703
733
|
{
|
704
734
|
U32 const h = LZ4_hashPosition(p, tableType);
|
705
735
|
return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
|
706
736
|
}
|
707
737
|
|
708
|
-
LZ4_FORCE_INLINE void
|
709
|
-
|
710
|
-
|
711
|
-
|
738
|
+
LZ4_FORCE_INLINE void
|
739
|
+
LZ4_prepareTable(LZ4_stream_t_internal* const cctx,
|
740
|
+
const int inputSize,
|
741
|
+
const tableType_t tableType) {
|
712
742
|
/* If compression failed during the previous step, then the context
|
713
743
|
* is marked as dirty, therefore, it has to be fully reset.
|
714
744
|
*/
|
@@ -723,9 +753,10 @@ LZ4_FORCE_INLINE void LZ4_prepareTable(
|
|
723
753
|
* out if it's safe to leave as is or whether it needs to be reset.
|
724
754
|
*/
|
725
755
|
if (cctx->tableType != clearedTable) {
|
756
|
+
assert(inputSize >= 0);
|
726
757
|
if (cctx->tableType != tableType
|
727
|
-
|| (tableType == byU16 && cctx->currentOffset + inputSize >= 0xFFFFU)
|
728
|
-
|| (tableType == byU32 && cctx->currentOffset > 1 GB)
|
758
|
+
|| ((tableType == byU16) && cctx->currentOffset + (unsigned)inputSize >= 0xFFFFU)
|
759
|
+
|| ((tableType == byU32) && cctx->currentOffset > 1 GB)
|
729
760
|
|| tableType == byPtr
|
730
761
|
|| inputSize >= 4 KB)
|
731
762
|
{
|
@@ -805,9 +836,9 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
|
805
836
|
DEBUGLOG(5, "LZ4_compress_generic: srcSize=%i, tableType=%u", inputSize, tableType);
|
806
837
|
/* If init conditions are not met, we don't have to mark stream
|
807
838
|
* as having dirty context, since no action was taken yet */
|
808
|
-
if (outputDirective == fillOutput && maxOutputSize < 1) return 0;
|
809
|
-
if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */
|
810
|
-
if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
|
839
|
+
if (outputDirective == fillOutput && maxOutputSize < 1) { return 0; } /* Impossible to store anything */
|
840
|
+
if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) { return 0; } /* Unsupported inputSize, too large (or negative) */
|
841
|
+
if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) { return 0; } /* Size too large (not within 64K limit) */
|
811
842
|
if (tableType==byPtr) assert(dictDirective==noDict); /* only supported use case with byPtr */
|
812
843
|
assert(acceleration >= 1);
|
813
844
|
|
@@ -835,6 +866,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
|
835
866
|
for ( ; ; ) {
|
836
867
|
const BYTE* match;
|
837
868
|
BYTE* token;
|
869
|
+
const BYTE* filledIp;
|
838
870
|
|
839
871
|
/* Find a match */
|
840
872
|
if (tableType == byPtr) {
|
@@ -903,10 +935,14 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
|
903
935
|
forwardH = LZ4_hashPosition(forwardIp, tableType);
|
904
936
|
LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType);
|
905
937
|
|
906
|
-
|
938
|
+
DEBUGLOG(7, "candidate at pos=%u (offset=%u \n", matchIndex, current - matchIndex);
|
939
|
+
if ((dictIssue == dictSmall) && (matchIndex < prefixIdxLimit)) { continue; } /* match outside of valid area */
|
907
940
|
assert(matchIndex < current);
|
908
|
-
if ((tableType != byU16)
|
909
|
-
|
941
|
+
if ( ((tableType != byU16) || (LZ4_DISTANCE_MAX < LZ4_DISTANCE_ABSOLUTE_MAX))
|
942
|
+
&& (matchIndex+LZ4_DISTANCE_MAX < current)) {
|
943
|
+
continue;
|
944
|
+
} /* too far */
|
945
|
+
assert((current - matchIndex) <= LZ4_DISTANCE_MAX); /* match now expected within distance */
|
910
946
|
|
911
947
|
if (LZ4_read32(match) == LZ4_read32(ip)) {
|
912
948
|
if (maybe_extMem) offset = current - matchIndex;
|
@@ -917,15 +953,16 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
|
917
953
|
}
|
918
954
|
|
919
955
|
/* Catch up */
|
956
|
+
filledIp = ip;
|
920
957
|
while (((ip>anchor) & (match > lowLimit)) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; }
|
921
958
|
|
922
959
|
/* Encode Literals */
|
923
960
|
{ unsigned const litLength = (unsigned)(ip - anchor);
|
924
961
|
token = op++;
|
925
962
|
if ((outputDirective == limitedOutput) && /* Check output buffer overflow */
|
926
|
-
(unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)) )
|
963
|
+
(unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)) ) {
|
927
964
|
return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */
|
928
|
-
|
965
|
+
}
|
929
966
|
if ((outputDirective == fillOutput) &&
|
930
967
|
(unlikely(op + (litLength+240)/255 /* litlen */ + litLength /* literals */ + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit))) {
|
931
968
|
op--;
|
@@ -940,7 +977,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
|
940
977
|
else *token = (BYTE)(litLength<<ML_BITS);
|
941
978
|
|
942
979
|
/* Copy Literals */
|
943
|
-
|
980
|
+
LZ4_wildCopy8(op, anchor, op+litLength);
|
944
981
|
op+=litLength;
|
945
982
|
DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i",
|
946
983
|
(int)(anchor-(const BYTE*)source), litLength, (int)(ip-(const BYTE*)source));
|
@@ -996,12 +1033,26 @@ _next_match:
|
|
996
1033
|
}
|
997
1034
|
|
998
1035
|
if ((outputDirective) && /* Check output buffer overflow */
|
999
|
-
(unlikely(op + (1 + LASTLITERALS) + (matchCode
|
1036
|
+
(unlikely(op + (1 + LASTLITERALS) + (matchCode+240)/255 > olimit)) ) {
|
1000
1037
|
if (outputDirective == fillOutput) {
|
1001
1038
|
/* Match description too long : reduce it */
|
1002
|
-
U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) -
|
1039
|
+
U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 1 - LASTLITERALS) * 255;
|
1003
1040
|
ip -= matchCode - newMatchCode;
|
1041
|
+
assert(newMatchCode < matchCode);
|
1004
1042
|
matchCode = newMatchCode;
|
1043
|
+
if (unlikely(ip <= filledIp)) {
|
1044
|
+
/* We have already filled up to filledIp so if ip ends up less than filledIp
|
1045
|
+
* we have positions in the hash table beyond the current position. This is
|
1046
|
+
* a problem if we reuse the hash table. So we have to remove these positions
|
1047
|
+
* from the hash table.
|
1048
|
+
*/
|
1049
|
+
const BYTE* ptr;
|
1050
|
+
DEBUGLOG(5, "Clearing %u positions", (U32)(filledIp - ip));
|
1051
|
+
for (ptr = ip; ptr <= filledIp; ++ptr) {
|
1052
|
+
U32 const h = LZ4_hashPosition(ptr, tableType);
|
1053
|
+
LZ4_clearHash(h, cctx->hashTable, tableType);
|
1054
|
+
}
|
1055
|
+
}
|
1005
1056
|
} else {
|
1006
1057
|
assert(outputDirective == limitedOutput);
|
1007
1058
|
return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */
|
@@ -1021,6 +1072,8 @@ _next_match:
|
|
1021
1072
|
} else
|
1022
1073
|
*token += (BYTE)(matchCode);
|
1023
1074
|
}
|
1075
|
+
/* Ensure we have enough space for the last literals. */
|
1076
|
+
assert(!(outputDirective == fillOutput && op + 1 + LASTLITERALS > olimit));
|
1024
1077
|
|
1025
1078
|
anchor = ip;
|
1026
1079
|
|
@@ -1070,7 +1123,7 @@ _next_match:
|
|
1070
1123
|
LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType);
|
1071
1124
|
assert(matchIndex < current);
|
1072
1125
|
if ( ((dictIssue==dictSmall) ? (matchIndex >= prefixIdxLimit) : 1)
|
1073
|
-
&& ((tableType==byU16) ? 1 : (matchIndex+LZ4_DISTANCE_MAX >= current))
|
1126
|
+
&& (((tableType==byU16) && (LZ4_DISTANCE_MAX == LZ4_DISTANCE_ABSOLUTE_MAX)) ? 1 : (matchIndex+LZ4_DISTANCE_MAX >= current))
|
1074
1127
|
&& (LZ4_read32(match) == LZ4_read32(ip)) ) {
|
1075
1128
|
token=op++;
|
1076
1129
|
*token=0;
|
@@ -1137,7 +1190,7 @@ int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int
|
|
1137
1190
|
return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration);
|
1138
1191
|
}
|
1139
1192
|
} else {
|
1140
|
-
if (inputSize < LZ4_64Klimit) {
|
1193
|
+
if (inputSize < LZ4_64Klimit) {
|
1141
1194
|
return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
|
1142
1195
|
} else {
|
1143
1196
|
const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32;
|
@@ -1300,12 +1353,12 @@ static size_t LZ4_stream_t_alignment(void)
|
|
1300
1353
|
LZ4_stream_t* LZ4_initStream (void* buffer, size_t size)
|
1301
1354
|
{
|
1302
1355
|
DEBUGLOG(5, "LZ4_initStream");
|
1303
|
-
if (buffer == NULL) return NULL;
|
1304
|
-
if (size < sizeof(LZ4_stream_t)) return NULL;
|
1356
|
+
if (buffer == NULL) { return NULL; }
|
1357
|
+
if (size < sizeof(LZ4_stream_t)) { return NULL; }
|
1305
1358
|
#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 :
|
1306
1359
|
it reports an aligment of 8-bytes,
|
1307
1360
|
while actually aligning LZ4_stream_t on 4 bytes. */
|
1308
|
-
if (((size_t)buffer) & (LZ4_stream_t_alignment() - 1)) return NULL;
|
1361
|
+
if (((size_t)buffer) & (LZ4_stream_t_alignment() - 1)) { return NULL; } /* alignment check */
|
1309
1362
|
#endif
|
1310
1363
|
MEM_INIT(buffer, 0, sizeof(LZ4_stream_t));
|
1311
1364
|
return (LZ4_stream_t*)buffer;
|
@@ -1355,18 +1408,18 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
|
|
1355
1408
|
* there are only valid offsets in the window, which allows an optimization
|
1356
1409
|
* in LZ4_compress_fast_continue() where it uses noDictIssue even when the
|
1357
1410
|
* dictionary isn't a full 64k. */
|
1358
|
-
|
1359
|
-
if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
|
1360
|
-
base = dictEnd - 64 KB - dict->currentOffset;
|
1361
|
-
dict->dictionary = p;
|
1362
|
-
dict->dictSize = (U32)(dictEnd - p);
|
1363
1411
|
dict->currentOffset += 64 KB;
|
1364
|
-
dict->tableType = tableType;
|
1365
1412
|
|
1366
1413
|
if (dictSize < (int)HASH_UNIT) {
|
1367
1414
|
return 0;
|
1368
1415
|
}
|
1369
1416
|
|
1417
|
+
if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
|
1418
|
+
base = dictEnd - dict->currentOffset;
|
1419
|
+
dict->dictionary = p;
|
1420
|
+
dict->dictSize = (U32)(dictEnd - p);
|
1421
|
+
dict->tableType = tableType;
|
1422
|
+
|
1370
1423
|
while (p <= dictEnd-HASH_UNIT) {
|
1371
1424
|
LZ4_putPosition(p, dict->hashTable, tableType, base);
|
1372
1425
|
p+=3;
|
@@ -1375,26 +1428,37 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
|
|
1375
1428
|
return (int)dict->dictSize;
|
1376
1429
|
}
|
1377
1430
|
|
1378
|
-
void LZ4_attach_dictionary(LZ4_stream_t
|
1431
|
+
void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream) {
|
1432
|
+
const LZ4_stream_t_internal* dictCtx = dictionaryStream == NULL ? NULL :
|
1433
|
+
&(dictionaryStream->internal_donotuse);
|
1434
|
+
|
1435
|
+
DEBUGLOG(4, "LZ4_attach_dictionary (%p, %p, size %u)",
|
1436
|
+
workingStream, dictionaryStream,
|
1437
|
+
dictCtx != NULL ? dictCtx->dictSize : 0);
|
1438
|
+
|
1379
1439
|
/* Calling LZ4_resetStream_fast() here makes sure that changes will not be
|
1380
1440
|
* erased by subsequent calls to LZ4_resetStream_fast() in case stream was
|
1381
1441
|
* marked as having dirty context, e.g. requiring full reset.
|
1382
1442
|
*/
|
1383
|
-
LZ4_resetStream_fast(
|
1443
|
+
LZ4_resetStream_fast(workingStream);
|
1384
1444
|
|
1385
|
-
if (
|
1445
|
+
if (dictCtx != NULL) {
|
1386
1446
|
/* If the current offset is zero, we will never look in the
|
1387
1447
|
* external dictionary context, since there is no value a table
|
1388
1448
|
* entry can take that indicate a miss. In that case, we need
|
1389
1449
|
* to bump the offset to something non-zero.
|
1390
1450
|
*/
|
1391
|
-
if (
|
1392
|
-
|
1451
|
+
if (workingStream->internal_donotuse.currentOffset == 0) {
|
1452
|
+
workingStream->internal_donotuse.currentOffset = 64 KB;
|
1453
|
+
}
|
1454
|
+
|
1455
|
+
/* Don't actually attach an empty dictionary.
|
1456
|
+
*/
|
1457
|
+
if (dictCtx->dictSize == 0) {
|
1458
|
+
dictCtx = NULL;
|
1393
1459
|
}
|
1394
|
-
working_stream->internal_donotuse.dictCtx = &(dictionary_stream->internal_donotuse);
|
1395
|
-
} else {
|
1396
|
-
working_stream->internal_donotuse.dictCtx = NULL;
|
1397
1460
|
}
|
1461
|
+
workingStream->internal_donotuse.dictCtx = dictCtx;
|
1398
1462
|
}
|
1399
1463
|
|
1400
1464
|
|
@@ -1429,7 +1493,7 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream,
|
|
1429
1493
|
|
1430
1494
|
DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i)", inputSize);
|
1431
1495
|
|
1432
|
-
if (streamPtr->dirty) return 0;
|
1496
|
+
if (streamPtr->dirty) { return 0; } /* Uninitialized structure detected */
|
1433
1497
|
LZ4_renormDictT(streamPtr, inputSize); /* avoid index overflow */
|
1434
1498
|
if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
|
1435
1499
|
|
@@ -1526,8 +1590,8 @@ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
|
|
1526
1590
|
LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse;
|
1527
1591
|
const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize;
|
1528
1592
|
|
1529
|
-
if ((U32)dictSize > 64 KB) dictSize = 64 KB;
|
1530
|
-
if ((U32)dictSize > dict->dictSize) dictSize = (int)dict->dictSize;
|
1593
|
+
if ((U32)dictSize > 64 KB) { dictSize = 64 KB; } /* useless to define a dictionary > 64 KB */
|
1594
|
+
if ((U32)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; }
|
1531
1595
|
|
1532
1596
|
memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
|
1533
1597
|
|
@@ -1601,7 +1665,7 @@ LZ4_decompress_generic(
|
|
1601
1665
|
const size_t dictSize /* note : = 0 if noDict */
|
1602
1666
|
)
|
1603
1667
|
{
|
1604
|
-
if (src == NULL) return -1;
|
1668
|
+
if (src == NULL) { return -1; }
|
1605
1669
|
|
1606
1670
|
{ const BYTE* ip = (const BYTE*) src;
|
1607
1671
|
const BYTE* const iend = ip + srcSize;
|
@@ -1630,20 +1694,26 @@ LZ4_decompress_generic(
|
|
1630
1694
|
|
1631
1695
|
/* Special cases */
|
1632
1696
|
assert(lowPrefix <= op);
|
1633
|
-
if ((endOnInput) && (unlikely(outputSize==0)))
|
1634
|
-
|
1635
|
-
|
1697
|
+
if ((endOnInput) && (unlikely(outputSize==0))) {
|
1698
|
+
/* Empty output buffer */
|
1699
|
+
if (partialDecoding) return 0;
|
1700
|
+
return ((srcSize==1) && (*ip==0)) ? 0 : -1;
|
1701
|
+
}
|
1702
|
+
if ((!endOnInput) && (unlikely(outputSize==0))) { return (*ip==0 ? 1 : -1); }
|
1703
|
+
if ((endOnInput) && unlikely(srcSize==0)) { return -1; }
|
1636
1704
|
|
1637
1705
|
/* Currently the fast loop shows a regression on qualcomm arm chips. */
|
1638
1706
|
#if LZ4_FAST_DEC_LOOP
|
1639
|
-
if ((oend - op) < FASTLOOP_SAFE_DISTANCE)
|
1707
|
+
if ((oend - op) < FASTLOOP_SAFE_DISTANCE) {
|
1708
|
+
DEBUGLOG(6, "skip fast decode loop");
|
1640
1709
|
goto safe_decode;
|
1710
|
+
}
|
1641
1711
|
|
1642
1712
|
/* Fast loop : decode sequences as long as output < iend-FASTLOOP_SAFE_DISTANCE */
|
1643
1713
|
while (1) {
|
1644
1714
|
/* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */
|
1645
1715
|
assert(oend - op >= FASTLOOP_SAFE_DISTANCE);
|
1646
|
-
|
1716
|
+
if (endOnInput) { assert(ip < iend); }
|
1647
1717
|
token = *ip++;
|
1648
1718
|
length = token >> ML_BITS; /* literal length */
|
1649
1719
|
|
@@ -1653,46 +1723,53 @@ LZ4_decompress_generic(
|
|
1653
1723
|
if (length == RUN_MASK) {
|
1654
1724
|
variable_length_error error = ok;
|
1655
1725
|
length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error);
|
1656
|
-
if (error == initial_error) goto _output_error;
|
1657
|
-
if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error;
|
1658
|
-
if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error;
|
1726
|
+
if (error == initial_error) { goto _output_error; }
|
1727
|
+
if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */
|
1728
|
+
if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */
|
1659
1729
|
|
1660
1730
|
/* copy literals */
|
1661
1731
|
cpy = op+length;
|
1662
1732
|
LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
|
1663
|
-
if (
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
}
|
1668
|
-
|
1733
|
+
if (endOnInput) { /* LZ4_decompress_safe() */
|
1734
|
+
if ((cpy>oend-32) || (ip+length>iend-32)) { goto safe_literal_copy; }
|
1735
|
+
LZ4_wildCopy32(op, ip, cpy);
|
1736
|
+
} else { /* LZ4_decompress_fast() */
|
1737
|
+
if (cpy>oend-8) { goto safe_literal_copy; }
|
1738
|
+
LZ4_wildCopy8(op, ip, cpy); /* LZ4_decompress_fast() cannot copy more than 8 bytes at a time :
|
1739
|
+
* it doesn't know input length, and only relies on end-of-block properties */
|
1740
|
+
}
|
1669
1741
|
ip += length; op = cpy;
|
1670
1742
|
} else {
|
1671
1743
|
cpy = op+length;
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1744
|
+
if (endOnInput) { /* LZ4_decompress_safe() */
|
1745
|
+
DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length);
|
1746
|
+
/* We don't need to check oend, since we check it once for each loop below */
|
1747
|
+
if (ip > iend-(16 + 1/*max lit + offset + nextToken*/)) { goto safe_literal_copy; }
|
1748
|
+
/* Literals can only be 14, but hope compilers optimize if we copy by a register size */
|
1749
|
+
memcpy(op, ip, 16);
|
1750
|
+
} else { /* LZ4_decompress_fast() */
|
1751
|
+
/* LZ4_decompress_fast() cannot copy more than 8 bytes at a time :
|
1752
|
+
* it doesn't know input length, and relies on end-of-block properties */
|
1753
|
+
memcpy(op, ip, 8);
|
1754
|
+
if (length > 8) { memcpy(op+8, ip+8, 8); }
|
1755
|
+
}
|
1679
1756
|
ip += length; op = cpy;
|
1680
1757
|
}
|
1681
1758
|
|
1682
1759
|
/* get offset */
|
1683
1760
|
offset = LZ4_readLE16(ip); ip+=2;
|
1684
1761
|
match = op - offset;
|
1762
|
+
assert(match <= op);
|
1685
1763
|
|
1686
1764
|
/* get matchlength */
|
1687
1765
|
length = token & ML_MASK;
|
1688
1766
|
|
1689
|
-
if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */
|
1690
|
-
|
1691
1767
|
if (length == ML_MASK) {
|
1692
1768
|
variable_length_error error = ok;
|
1769
|
+
if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */
|
1693
1770
|
length += read_variable_length(&ip, iend - LASTLITERALS + 1, endOnInput, 0, &error);
|
1694
|
-
if (error != ok) goto _output_error;
|
1695
|
-
if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error;
|
1771
|
+
if (error != ok) { goto _output_error; }
|
1772
|
+
if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */
|
1696
1773
|
length += MINMATCH;
|
1697
1774
|
if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) {
|
1698
1775
|
goto safe_match_copy;
|
@@ -1704,8 +1781,12 @@ LZ4_decompress_generic(
|
|
1704
1781
|
}
|
1705
1782
|
|
1706
1783
|
/* Fastpath check: Avoids a branch in LZ4_wildCopy32 if true */
|
1707
|
-
if (
|
1784
|
+
if ((dict == withPrefix64k) || (match >= lowPrefix)) {
|
1708
1785
|
if (offset >= 8) {
|
1786
|
+
assert(match >= lowPrefix);
|
1787
|
+
assert(match <= op);
|
1788
|
+
assert(op + 18 <= oend);
|
1789
|
+
|
1709
1790
|
memcpy(op, match, 8);
|
1710
1791
|
memcpy(op+8, match+8, 8);
|
1711
1792
|
memcpy(op+16, match+16, 2);
|
@@ -1713,12 +1794,15 @@ LZ4_decompress_generic(
|
|
1713
1794
|
continue;
|
1714
1795
|
} } }
|
1715
1796
|
|
1797
|
+
if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */
|
1716
1798
|
/* match starting within external dictionary */
|
1717
1799
|
if ((dict==usingExtDict) && (match < lowPrefix)) {
|
1718
1800
|
if (unlikely(op+length > oend-LASTLITERALS)) {
|
1719
|
-
if (partialDecoding)
|
1720
|
-
|
1721
|
-
|
1801
|
+
if (partialDecoding) {
|
1802
|
+
length = MIN(length, (size_t)(oend-op)); /* reach end of buffer */
|
1803
|
+
} else {
|
1804
|
+
goto _output_error; /* end-of-block condition violated */
|
1805
|
+
} }
|
1722
1806
|
|
1723
1807
|
if (length <= (size_t)(lowPrefix-match)) {
|
1724
1808
|
/* match fits entirely within external dictionary : just copy */
|
@@ -1733,7 +1817,7 @@ LZ4_decompress_generic(
|
|
1733
1817
|
if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */
|
1734
1818
|
BYTE* const endOfMatch = op + restSize;
|
1735
1819
|
const BYTE* copyFrom = lowPrefix;
|
1736
|
-
while (op < endOfMatch) *op++ = *copyFrom++;
|
1820
|
+
while (op < endOfMatch) { *op++ = *copyFrom++; }
|
1737
1821
|
} else {
|
1738
1822
|
memcpy(op, lowPrefix, restSize);
|
1739
1823
|
op += restSize;
|
@@ -1806,11 +1890,11 @@ LZ4_decompress_generic(
|
|
1806
1890
|
|
1807
1891
|
/* decode literal length */
|
1808
1892
|
if (length == RUN_MASK) {
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error;
|
1813
|
-
if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error;
|
1893
|
+
variable_length_error error = ok;
|
1894
|
+
length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error);
|
1895
|
+
if (error == initial_error) { goto _output_error; }
|
1896
|
+
if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */
|
1897
|
+
if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */
|
1814
1898
|
}
|
1815
1899
|
|
1816
1900
|
/* copy literals */
|
@@ -1822,23 +1906,52 @@ LZ4_decompress_generic(
|
|
1822
1906
|
if ( ((endOnInput) && ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) )
|
1823
1907
|
|| ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) )
|
1824
1908
|
{
|
1909
|
+
/* We've either hit the input parsing restriction or the output parsing restriction.
|
1910
|
+
* If we've hit the input parsing condition then this must be the last sequence.
|
1911
|
+
* If we've hit the output parsing condition then we are either using partialDecoding
|
1912
|
+
* or we've hit the output parsing condition.
|
1913
|
+
*/
|
1825
1914
|
if (partialDecoding) {
|
1826
|
-
|
1827
|
-
|
1915
|
+
/* Since we are partial decoding we may be in this block because of the output parsing
|
1916
|
+
* restriction, which is not valid since the output buffer is allowed to be undersized.
|
1917
|
+
*/
|
1918
|
+
assert(endOnInput);
|
1919
|
+
/* If we're in this block because of the input parsing condition, then we must be on the
|
1920
|
+
* last sequence (or invalid), so we must check that we exactly consume the input.
|
1921
|
+
*/
|
1922
|
+
if ((ip+length>iend-(2+1+LASTLITERALS)) && (ip+length != iend)) { goto _output_error; }
|
1923
|
+
assert(ip+length <= iend);
|
1924
|
+
/* We are finishing in the middle of a literals segment.
|
1925
|
+
* Break after the copy.
|
1926
|
+
*/
|
1927
|
+
if (cpy > oend) {
|
1928
|
+
cpy = oend;
|
1929
|
+
assert(op<=oend);
|
1930
|
+
length = (size_t)(oend-op);
|
1931
|
+
}
|
1932
|
+
assert(ip+length <= iend);
|
1828
1933
|
} else {
|
1829
|
-
|
1830
|
-
|
1934
|
+
/* We must be on the last sequence because of the parsing limitations so check
|
1935
|
+
* that we exactly regenerate the original size (must be exact when !endOnInput).
|
1936
|
+
*/
|
1937
|
+
if ((!endOnInput) && (cpy != oend)) { goto _output_error; }
|
1938
|
+
/* We must be on the last sequence (or invalid) because of the parsing limitations
|
1939
|
+
* so check that we exactly consume the input and don't overrun the output buffer.
|
1940
|
+
*/
|
1941
|
+
if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) { goto _output_error; }
|
1831
1942
|
}
|
1832
|
-
|
1943
|
+
memmove(op, ip, length); /* supports overlapping memory regions, which only matters for in-place decompression scenarios */
|
1833
1944
|
ip += length;
|
1834
1945
|
op += length;
|
1835
|
-
|
1836
|
-
|
1946
|
+
/* Necessarily EOF when !partialDecoding. When partialDecoding
|
1947
|
+
* it is EOF if we've either filled the output buffer or hit
|
1948
|
+
* the input parsing restriction.
|
1949
|
+
*/
|
1950
|
+
if (!partialDecoding || (cpy == oend) || (ip == iend)) {
|
1837
1951
|
break;
|
1838
1952
|
}
|
1839
|
-
|
1840
1953
|
} else {
|
1841
|
-
|
1954
|
+
LZ4_wildCopy8(op, ip, cpy); /* may overwrite up to WILDCOPYLENGTH beyond cpy */
|
1842
1955
|
ip += length; op = cpy;
|
1843
1956
|
}
|
1844
1957
|
|
@@ -1850,13 +1963,6 @@ LZ4_decompress_generic(
|
|
1850
1963
|
length = token & ML_MASK;
|
1851
1964
|
|
1852
1965
|
_copy_match:
|
1853
|
-
if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */
|
1854
|
-
if (!partialDecoding) {
|
1855
|
-
assert(oend > op);
|
1856
|
-
assert(oend - op >= 4);
|
1857
|
-
LZ4_write32(op, 0); /* silence an msan warning when offset==0; costs <1%; */
|
1858
|
-
} /* note : when partialDecoding, there is no guarantee that at least 4 bytes remain available in output buffer */
|
1859
|
-
|
1860
1966
|
if (length == ML_MASK) {
|
1861
1967
|
variable_length_error error = ok;
|
1862
1968
|
length += read_variable_length(&ip, iend - LASTLITERALS + 1, endOnInput, 0, &error);
|
@@ -1868,6 +1974,7 @@ LZ4_decompress_generic(
|
|
1868
1974
|
#if LZ4_FAST_DEC_LOOP
|
1869
1975
|
safe_match_copy:
|
1870
1976
|
#endif
|
1977
|
+
if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */
|
1871
1978
|
/* match starting within external dictionary */
|
1872
1979
|
if ((dict==usingExtDict) && (match < lowPrefix)) {
|
1873
1980
|
if (unlikely(op+length > oend-LASTLITERALS)) {
|
@@ -1895,6 +2002,7 @@ LZ4_decompress_generic(
|
|
1895
2002
|
} }
|
1896
2003
|
continue;
|
1897
2004
|
}
|
2005
|
+
assert(match >= lowPrefix);
|
1898
2006
|
|
1899
2007
|
/* copy match within block */
|
1900
2008
|
cpy = op + length;
|
@@ -1906,16 +2014,17 @@ LZ4_decompress_generic(
|
|
1906
2014
|
const BYTE* const matchEnd = match + mlen;
|
1907
2015
|
BYTE* const copyEnd = op + mlen;
|
1908
2016
|
if (matchEnd > op) { /* overlap copy */
|
1909
|
-
while (op < copyEnd) *op++ = *match++;
|
2017
|
+
while (op < copyEnd) { *op++ = *match++; }
|
1910
2018
|
} else {
|
1911
2019
|
memcpy(op, match, mlen);
|
1912
2020
|
}
|
1913
2021
|
op = copyEnd;
|
1914
|
-
if (op==oend) break;
|
2022
|
+
if (op == oend) { break; }
|
1915
2023
|
continue;
|
1916
2024
|
}
|
1917
2025
|
|
1918
2026
|
if (unlikely(offset<8)) {
|
2027
|
+
LZ4_write32(op, 0); /* silence msan warning when offset==0 */
|
1919
2028
|
op[0] = match[0];
|
1920
2029
|
op[1] = match[1];
|
1921
2030
|
op[2] = match[2];
|
@@ -1931,25 +2040,26 @@ LZ4_decompress_generic(
|
|
1931
2040
|
|
1932
2041
|
if (unlikely(cpy > oend-MATCH_SAFEGUARD_DISTANCE)) {
|
1933
2042
|
BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH-1);
|
1934
|
-
if (cpy > oend-LASTLITERALS) goto _output_error;
|
2043
|
+
if (cpy > oend-LASTLITERALS) { goto _output_error; } /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
|
1935
2044
|
if (op < oCopyLimit) {
|
1936
|
-
|
2045
|
+
LZ4_wildCopy8(op, match, oCopyLimit);
|
1937
2046
|
match += oCopyLimit - op;
|
1938
2047
|
op = oCopyLimit;
|
1939
2048
|
}
|
1940
|
-
while (op < cpy) *op++ = *match++;
|
2049
|
+
while (op < cpy) { *op++ = *match++; }
|
1941
2050
|
} else {
|
1942
2051
|
memcpy(op, match, 8);
|
1943
|
-
if (length > 16)
|
2052
|
+
if (length > 16) { LZ4_wildCopy8(op+8, match+8, cpy); }
|
1944
2053
|
}
|
1945
2054
|
op = cpy; /* wildcopy correction */
|
1946
2055
|
}
|
1947
2056
|
|
1948
2057
|
/* end of decoding */
|
1949
|
-
if (endOnInput)
|
2058
|
+
if (endOnInput) {
|
1950
2059
|
return (int) (((char*)op)-dst); /* Nb of output bytes decoded */
|
1951
|
-
|
2060
|
+
} else {
|
1952
2061
|
return (int) (((const char*)ip)-src); /* Nb of input bytes read */
|
2062
|
+
}
|
1953
2063
|
|
1954
2064
|
/* Overflow error detected */
|
1955
2065
|
_output_error:
|
@@ -2064,7 +2174,7 @@ LZ4_streamDecode_t* LZ4_createStreamDecode(void)
|
|
2064
2174
|
|
2065
2175
|
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
|
2066
2176
|
{
|
2067
|
-
if (LZ4_stream == NULL) return 0;
|
2177
|
+
if (LZ4_stream == NULL) { return 0; } /* support free on NULL */
|
2068
2178
|
FREEMEM(LZ4_stream);
|
2069
2179
|
return 0;
|
2070
2180
|
}
|
@@ -2199,18 +2309,22 @@ int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressed
|
|
2199
2309
|
if (dictSize==0)
|
2200
2310
|
return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize);
|
2201
2311
|
if (dictStart+dictSize == dest) {
|
2202
|
-
if (dictSize >= 64 KB - 1)
|
2312
|
+
if (dictSize >= 64 KB - 1) {
|
2203
2313
|
return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize);
|
2204
|
-
|
2314
|
+
}
|
2315
|
+
assert(dictSize >= 0);
|
2316
|
+
return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, (size_t)dictSize);
|
2205
2317
|
}
|
2206
|
-
|
2318
|
+
assert(dictSize >= 0);
|
2319
|
+
return LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, dictStart, (size_t)dictSize);
|
2207
2320
|
}
|
2208
2321
|
|
2209
2322
|
int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
|
2210
2323
|
{
|
2211
2324
|
if (dictSize==0 || dictStart+dictSize == dest)
|
2212
2325
|
return LZ4_decompress_fast(source, dest, originalSize);
|
2213
|
-
|
2326
|
+
assert(dictSize >= 0);
|
2327
|
+
return LZ4_decompress_fast_extDict(source, dest, originalSize, dictStart, (size_t)dictSize);
|
2214
2328
|
}
|
2215
2329
|
|
2216
2330
|
|
@@ -2222,9 +2336,9 @@ int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, in
|
|
2222
2336
|
{
|
2223
2337
|
return LZ4_compress_default(source, dest, inputSize, maxOutputSize);
|
2224
2338
|
}
|
2225
|
-
int LZ4_compress(const char*
|
2339
|
+
int LZ4_compress(const char* src, char* dest, int srcSize)
|
2226
2340
|
{
|
2227
|
-
return LZ4_compress_default(
|
2341
|
+
return LZ4_compress_default(src, dest, srcSize, LZ4_compressBound(srcSize));
|
2228
2342
|
}
|
2229
2343
|
int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize)
|
2230
2344
|
{
|