extlz4 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -4
- data/bin/extlz4 +1 -1
- data/contrib/lz4/NEWS +36 -0
- data/contrib/lz4/README.md +11 -12
- data/contrib/lz4/build/README.md +55 -0
- data/contrib/lz4/build/VS2010/datagen/datagen.vcxproj +169 -0
- data/contrib/lz4/build/VS2010/frametest/frametest.vcxproj +176 -0
- data/contrib/lz4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +180 -0
- data/contrib/lz4/build/VS2010/fullbench/fullbench.vcxproj +176 -0
- data/contrib/lz4/build/VS2010/fuzzer/fuzzer.vcxproj +173 -0
- data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.rc +51 -0
- data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.vcxproj +179 -0
- data/contrib/lz4/build/VS2010/liblz4/liblz4.vcxproj +175 -0
- data/contrib/lz4/build/VS2010/lz4.sln +98 -0
- data/contrib/lz4/build/VS2010/lz4/lz4.rc +51 -0
- data/contrib/lz4/build/VS2010/lz4/lz4.vcxproj +189 -0
- data/contrib/lz4/build/VS2017/datagen/datagen.vcxproj +173 -0
- data/contrib/lz4/build/VS2017/frametest/frametest.vcxproj +180 -0
- data/contrib/lz4/build/VS2017/fullbench-dll/fullbench-dll.vcxproj +184 -0
- data/contrib/lz4/build/VS2017/fullbench/fullbench.vcxproj +180 -0
- data/contrib/lz4/build/VS2017/fuzzer/fuzzer.vcxproj +177 -0
- data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.rc +51 -0
- data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.vcxproj +183 -0
- data/contrib/lz4/build/VS2017/liblz4/liblz4.vcxproj +179 -0
- data/contrib/lz4/build/VS2017/lz4.sln +103 -0
- data/contrib/lz4/build/VS2017/lz4/lz4.rc +51 -0
- data/contrib/lz4/build/VS2017/lz4/lz4.vcxproj +164 -0
- data/contrib/lz4/build/cmake/CMakeLists.txt +235 -0
- data/contrib/lz4/lib/README.md +27 -10
- data/contrib/lz4/lib/lz4.c +327 -230
- data/contrib/lz4/lib/lz4.h +80 -70
- data/contrib/lz4/lib/lz4frame.c +93 -54
- data/contrib/lz4/lib/lz4frame.h +22 -14
- data/contrib/lz4/lib/lz4hc.c +192 -115
- data/contrib/lz4/lib/lz4hc.h +15 -40
- data/contrib/lz4/ossfuzz/Makefile +12 -8
- data/contrib/lz4/ossfuzz/compress_frame_fuzzer.c +11 -5
- data/contrib/lz4/ossfuzz/compress_fuzzer.c +9 -2
- data/contrib/lz4/ossfuzz/compress_hc_fuzzer.c +10 -3
- data/contrib/lz4/ossfuzz/decompress_frame_fuzzer.c +11 -3
- data/contrib/lz4/ossfuzz/decompress_fuzzer.c +6 -2
- data/contrib/lz4/ossfuzz/fuzz_data_producer.c +77 -0
- data/contrib/lz4/ossfuzz/fuzz_data_producer.h +36 -0
- data/contrib/lz4/ossfuzz/round_trip_frame_fuzzer.c +8 -4
- data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +9 -2
- data/contrib/lz4/ossfuzz/round_trip_hc_fuzzer.c +7 -2
- data/contrib/lz4/ossfuzz/travisoss.sh +6 -1
- data/contrib/lz4/tmp +0 -0
- data/contrib/lz4/tmpsparse +0 -0
- data/ext/extlz4.c +2 -0
- data/ext/extlz4.h +5 -0
- data/ext/hashargs.c +1 -1
- data/ext/hashargs.h +1 -1
- data/gemstub.rb +3 -14
- data/lib/extlz4.rb +0 -2
- data/lib/extlz4/oldstream.rb +1 -1
- metadata +40 -25
- data/lib/extlz4/version.rb +0 -3
data/contrib/lz4/lib/lz4frame.h
CHANGED
@@ -66,17 +66,22 @@ extern "C" {
|
|
66
66
|
*****************************************************************/
|
67
67
|
/* LZ4_DLL_EXPORT :
|
68
68
|
* Enable exporting of functions when building a Windows DLL
|
69
|
-
*
|
69
|
+
* LZ4FLIB_VISIBILITY :
|
70
70
|
* Control library symbols visibility.
|
71
71
|
*/
|
72
|
+
#ifndef LZ4FLIB_VISIBILITY
|
73
|
+
# if defined(__GNUC__) && (__GNUC__ >= 4)
|
74
|
+
# define LZ4FLIB_VISIBILITY __attribute__ ((visibility ("default")))
|
75
|
+
# else
|
76
|
+
# define LZ4FLIB_VISIBILITY
|
77
|
+
# endif
|
78
|
+
#endif
|
72
79
|
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
|
73
|
-
# define LZ4FLIB_API __declspec(dllexport)
|
80
|
+
# define LZ4FLIB_API __declspec(dllexport) LZ4FLIB_VISIBILITY
|
74
81
|
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
|
75
|
-
# define LZ4FLIB_API __declspec(dllimport)
|
76
|
-
#elif defined(__GNUC__) && (__GNUC__ >= 4)
|
77
|
-
# define LZ4FLIB_API __attribute__ ((__visibility__ ("default")))
|
82
|
+
# define LZ4FLIB_API __declspec(dllimport) LZ4FLIB_VISIBILITY
|
78
83
|
#else
|
79
|
-
# define LZ4FLIB_API
|
84
|
+
# define LZ4FLIB_API LZ4FLIB_VISIBILITY
|
80
85
|
#endif
|
81
86
|
|
82
87
|
#ifdef LZ4F_DISABLE_DEPRECATE_WARNINGS
|
@@ -103,7 +108,7 @@ LZ4FLIB_API const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /**< return
|
|
103
108
|
|
104
109
|
/*-************************************
|
105
110
|
* Frame compression types
|
106
|
-
|
111
|
+
************************************* */
|
107
112
|
/* #define LZ4F_ENABLE_OBSOLETE_ENUMS // uncomment to enable obsolete enums */
|
108
113
|
#ifdef LZ4F_ENABLE_OBSOLETE_ENUMS
|
109
114
|
# define LZ4F_OBSOLETE_ENUM(x) , LZ4F_DEPRECATE(x) = LZ4F_##x
|
@@ -113,7 +118,8 @@ LZ4FLIB_API const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /**< return
|
|
113
118
|
|
114
119
|
/* The larger the block size, the (slightly) better the compression ratio,
|
115
120
|
* though there are diminishing returns.
|
116
|
-
* Larger blocks also increase memory usage on both compression and decompression sides.
|
121
|
+
* Larger blocks also increase memory usage on both compression and decompression sides.
|
122
|
+
*/
|
117
123
|
typedef enum {
|
118
124
|
LZ4F_default=0,
|
119
125
|
LZ4F_max64KB=4,
|
@@ -284,7 +290,7 @@ LZ4FLIB_API size_t LZ4F_compressBegin(LZ4F_cctx* cctx,
|
|
284
290
|
* @return is always the same for a srcSize and prefsPtr.
|
285
291
|
* prefsPtr is optional : when NULL is provided, preferences will be set to cover worst case scenario.
|
286
292
|
* tech details :
|
287
|
-
* @return includes the possibility that internal buffer might already be filled by up to (blockSize-1) bytes.
|
293
|
+
* @return if automatic flushing is not enabled, includes the possibility that internal buffer might already be filled by up to (blockSize-1) bytes.
|
288
294
|
* It also includes frame footer (ending + checksum), since it might be generated by LZ4F_compressEnd().
|
289
295
|
* @return doesn't include frame header, as it was already generated by LZ4F_compressBegin().
|
290
296
|
*/
|
@@ -376,7 +382,7 @@ LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx* dctx);
|
|
376
382
|
* note : Frame header size is variable, but is guaranteed to be
|
377
383
|
* >= LZ4F_HEADER_SIZE_MIN bytes, and <= LZ4F_HEADER_SIZE_MAX bytes.
|
378
384
|
*/
|
379
|
-
size_t LZ4F_headerSize(const void* src, size_t srcSize);
|
385
|
+
LZ4FLIB_API size_t LZ4F_headerSize(const void* src, size_t srcSize);
|
380
386
|
|
381
387
|
/*! LZ4F_getFrameInfo() :
|
382
388
|
* This function extracts frame parameters (max blockSize, dictID, etc.).
|
@@ -426,8 +432,10 @@ LZ4FLIB_API size_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
|
|
426
432
|
const void* srcBuffer, size_t* srcSizePtr);
|
427
433
|
|
428
434
|
/*! LZ4F_decompress() :
|
429
|
-
* Call this function repetitively to regenerate compressed
|
430
|
-
*
|
435
|
+
* Call this function repetitively to regenerate data compressed in `srcBuffer`.
|
436
|
+
*
|
437
|
+
* The function requires a valid dctx state.
|
438
|
+
* It will read up to *srcSizePtr bytes from srcBuffer,
|
431
439
|
* and decompress data into dstBuffer, of capacity *dstSizePtr.
|
432
440
|
*
|
433
441
|
* The nb of bytes consumed from srcBuffer will be written into *srcSizePtr (necessarily <= original value).
|
@@ -493,9 +501,9 @@ extern "C" {
|
|
493
501
|
* Use at your own risk.
|
494
502
|
*/
|
495
503
|
#ifdef LZ4F_PUBLISH_STATIC_FUNCTIONS
|
496
|
-
#define LZ4FLIB_STATIC_API LZ4FLIB_API
|
504
|
+
# define LZ4FLIB_STATIC_API LZ4FLIB_API
|
497
505
|
#else
|
498
|
-
#define LZ4FLIB_STATIC_API
|
506
|
+
# define LZ4FLIB_STATIC_API
|
499
507
|
#endif
|
500
508
|
|
501
509
|
|
data/contrib/lz4/lib/lz4hc.c
CHANGED
@@ -53,7 +53,7 @@
|
|
53
53
|
#include "lz4hc.h"
|
54
54
|
|
55
55
|
|
56
|
-
/*=== Common
|
56
|
+
/*=== Common definitions ===*/
|
57
57
|
#if defined(__GNUC__)
|
58
58
|
# pragma GCC diagnostic ignored "-Wunused-function"
|
59
59
|
#endif
|
@@ -61,15 +61,16 @@
|
|
61
61
|
# pragma clang diagnostic ignored "-Wunused-function"
|
62
62
|
#endif
|
63
63
|
|
64
|
-
/*=== Enums ===*/
|
65
|
-
typedef enum { noDictCtx, usingDictCtxHc } dictCtx_directive;
|
66
|
-
|
67
|
-
|
68
64
|
#define LZ4_COMMONDEFS_ONLY
|
69
65
|
#ifndef LZ4_SRC_INCLUDED
|
70
66
|
#include "lz4.c" /* LZ4_count, constants, mem */
|
71
67
|
#endif
|
72
68
|
|
69
|
+
|
70
|
+
/*=== Enums ===*/
|
71
|
+
typedef enum { noDictCtx, usingDictCtxHc } dictCtx_directive;
|
72
|
+
|
73
|
+
|
73
74
|
/*=== Constants ===*/
|
74
75
|
#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
|
75
76
|
#define LZ4_OPT_NUM (1<<12)
|
@@ -92,7 +93,7 @@ static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)
|
|
92
93
|
**************************************/
|
93
94
|
static void LZ4HC_clearTables (LZ4HC_CCtx_internal* hc4)
|
94
95
|
{
|
95
|
-
MEM_INIT(
|
96
|
+
MEM_INIT(hc4->hashTable, 0, sizeof(hc4->hashTable));
|
96
97
|
MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
|
97
98
|
}
|
98
99
|
|
@@ -161,8 +162,7 @@ int LZ4HC_countBack(const BYTE* const ip, const BYTE* const match,
|
|
161
162
|
static U32 LZ4HC_rotatePattern(size_t const rotate, U32 const pattern)
|
162
163
|
{
|
163
164
|
size_t const bitsToRotate = (rotate & (sizeof(pattern) - 1)) << 3;
|
164
|
-
if (bitsToRotate == 0)
|
165
|
-
return pattern;
|
165
|
+
if (bitsToRotate == 0) return pattern;
|
166
166
|
return LZ4HC_rotl32(pattern, (int)bitsToRotate);
|
167
167
|
}
|
168
168
|
|
@@ -172,7 +172,8 @@ static unsigned
|
|
172
172
|
LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, U32 const pattern32)
|
173
173
|
{
|
174
174
|
const BYTE* const iStart = ip;
|
175
|
-
reg_t const pattern = (sizeof(pattern)==8) ?
|
175
|
+
reg_t const pattern = (sizeof(pattern)==8) ?
|
176
|
+
(reg_t)pattern32 + (((reg_t)pattern32) << (sizeof(pattern)*4)) : pattern32;
|
176
177
|
|
177
178
|
while (likely(ip < iEnd-(sizeof(pattern)-1))) {
|
178
179
|
reg_t const diff = LZ4_read_ARCH(ip) ^ pattern;
|
@@ -270,7 +271,7 @@ LZ4HC_InsertAndGetWiderMatch (
|
|
270
271
|
DEBUGLOG(7, "First match at index %u / %u (lowestMatchIndex)",
|
271
272
|
matchIndex, lowestMatchIndex);
|
272
273
|
|
273
|
-
while ((matchIndex>=lowestMatchIndex) && (nbAttempts)) {
|
274
|
+
while ((matchIndex>=lowestMatchIndex) && (nbAttempts>0)) {
|
274
275
|
int matchLength=0;
|
275
276
|
nbAttempts--;
|
276
277
|
assert(matchIndex < ipIndex);
|
@@ -389,8 +390,8 @@ LZ4HC_InsertAndGetWiderMatch (
|
|
389
390
|
if (lookBackLength==0) { /* no back possible */
|
390
391
|
size_t const maxML = MIN(currentSegmentLength, srcPatternLength);
|
391
392
|
if ((size_t)longest < maxML) {
|
392
|
-
assert(base + matchIndex
|
393
|
-
if (ip -
|
393
|
+
assert(base + matchIndex != ip);
|
394
|
+
if ((size_t)(ip - base) - matchIndex > LZ4_DISTANCE_MAX) break;
|
394
395
|
assert(maxML < 2 GB);
|
395
396
|
longest = (int)maxML;
|
396
397
|
*matchpos = base + matchIndex; /* virtual pos, relative to ip, to retrieve offset */
|
@@ -410,7 +411,7 @@ LZ4HC_InsertAndGetWiderMatch (
|
|
410
411
|
} /* while ((matchIndex>=lowestMatchIndex) && (nbAttempts)) */
|
411
412
|
|
412
413
|
if ( dict == usingDictCtxHc
|
413
|
-
&& nbAttempts
|
414
|
+
&& nbAttempts > 0
|
414
415
|
&& ipIndex - lowestMatchIndex < LZ4_DISTANCE_MAX) {
|
415
416
|
size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->base);
|
416
417
|
U32 dictMatchIndex = dictCtx->hashTable[LZ4HC_hashPtr(ip)];
|
@@ -460,74 +461,90 @@ int LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index tabl
|
|
460
461
|
* @return : 0 if ok,
|
461
462
|
* 1 if buffer issue detected */
|
462
463
|
LZ4_FORCE_INLINE int LZ4HC_encodeSequence (
|
463
|
-
const BYTE**
|
464
|
-
BYTE**
|
465
|
-
const BYTE**
|
464
|
+
const BYTE** _ip,
|
465
|
+
BYTE** _op,
|
466
|
+
const BYTE** _anchor,
|
466
467
|
int matchLength,
|
467
468
|
const BYTE* const match,
|
468
469
|
limitedOutput_directive limit,
|
469
470
|
BYTE* oend)
|
470
471
|
{
|
472
|
+
#define ip (*_ip)
|
473
|
+
#define op (*_op)
|
474
|
+
#define anchor (*_anchor)
|
475
|
+
|
471
476
|
size_t length;
|
472
|
-
BYTE* const token =
|
477
|
+
BYTE* const token = op++;
|
473
478
|
|
474
479
|
#if defined(LZ4_DEBUG) && (LZ4_DEBUG >= 6)
|
475
480
|
static const BYTE* start = NULL;
|
476
481
|
static U32 totalCost = 0;
|
477
|
-
U32 const pos = (start==NULL) ? 0 : (U32)(
|
478
|
-
U32 const ll = (U32)(
|
482
|
+
U32 const pos = (start==NULL) ? 0 : (U32)(anchor - start);
|
483
|
+
U32 const ll = (U32)(ip - anchor);
|
479
484
|
U32 const llAdd = (ll>=15) ? ((ll-15) / 255) + 1 : 0;
|
480
485
|
U32 const mlAdd = (matchLength>=19) ? ((matchLength-19) / 255) + 1 : 0;
|
481
486
|
U32 const cost = 1 + llAdd + ll + 2 + mlAdd;
|
482
|
-
if (start==NULL) start =
|
487
|
+
if (start==NULL) start = anchor; /* only works for single segment */
|
483
488
|
/* g_debuglog_enable = (pos >= 2228) & (pos <= 2262); */
|
484
|
-
DEBUGLOG(6, "pos:%7u -- literals:%
|
489
|
+
DEBUGLOG(6, "pos:%7u -- literals:%4u, match:%4i, offset:%5u, cost:%4u + %5u",
|
485
490
|
pos,
|
486
|
-
(U32)(
|
491
|
+
(U32)(ip - anchor), matchLength, (U32)(ip-match),
|
487
492
|
cost, totalCost);
|
488
493
|
totalCost += cost;
|
489
494
|
#endif
|
490
495
|
|
491
496
|
/* Encode Literal length */
|
492
|
-
length = (size_t)(
|
493
|
-
|
497
|
+
length = (size_t)(ip - anchor);
|
498
|
+
LZ4_STATIC_ASSERT(notLimited == 0);
|
499
|
+
/* Check output limit */
|
500
|
+
if (limit && ((op + (length / 255) + length + (2 + 1 + LASTLITERALS)) > oend)) {
|
501
|
+
DEBUGLOG(6, "Not enough room to write %i literals (%i bytes remaining)",
|
502
|
+
(int)length, (int)(oend - op));
|
503
|
+
return 1;
|
504
|
+
}
|
494
505
|
if (length >= RUN_MASK) {
|
495
506
|
size_t len = length - RUN_MASK;
|
496
507
|
*token = (RUN_MASK << ML_BITS);
|
497
|
-
for(; len >= 255 ; len -= 255) *
|
498
|
-
*
|
508
|
+
for(; len >= 255 ; len -= 255) *op++ = 255;
|
509
|
+
*op++ = (BYTE)len;
|
499
510
|
} else {
|
500
511
|
*token = (BYTE)(length << ML_BITS);
|
501
512
|
}
|
502
513
|
|
503
514
|
/* Copy Literals */
|
504
|
-
LZ4_wildCopy8(
|
505
|
-
|
515
|
+
LZ4_wildCopy8(op, anchor, op + length);
|
516
|
+
op += length;
|
506
517
|
|
507
518
|
/* Encode Offset */
|
508
|
-
assert( (
|
509
|
-
LZ4_writeLE16(
|
519
|
+
assert( (ip - match) <= LZ4_DISTANCE_MAX ); /* note : consider providing offset as a value, rather than as a pointer difference */
|
520
|
+
LZ4_writeLE16(op, (U16)(ip - match)); op += 2;
|
510
521
|
|
511
522
|
/* Encode MatchLength */
|
512
523
|
assert(matchLength >= MINMATCH);
|
513
524
|
length = (size_t)matchLength - MINMATCH;
|
514
|
-
if (
|
525
|
+
if (limit && (op + (length / 255) + (1 + LASTLITERALS) > oend)) {
|
526
|
+
DEBUGLOG(6, "Not enough room to write match length");
|
527
|
+
return 1; /* Check output limit */
|
528
|
+
}
|
515
529
|
if (length >= ML_MASK) {
|
516
530
|
*token += ML_MASK;
|
517
531
|
length -= ML_MASK;
|
518
|
-
for(; length >= 510 ; length -= 510) { *
|
519
|
-
if (length >= 255) { length -= 255; *
|
520
|
-
*
|
532
|
+
for(; length >= 510 ; length -= 510) { *op++ = 255; *op++ = 255; }
|
533
|
+
if (length >= 255) { length -= 255; *op++ = 255; }
|
534
|
+
*op++ = (BYTE)length;
|
521
535
|
} else {
|
522
536
|
*token += (BYTE)(length);
|
523
537
|
}
|
524
538
|
|
525
539
|
/* Prepare next loop */
|
526
|
-
|
527
|
-
|
540
|
+
ip += matchLength;
|
541
|
+
anchor = ip;
|
528
542
|
|
529
543
|
return 0;
|
530
544
|
}
|
545
|
+
#undef ip
|
546
|
+
#undef op
|
547
|
+
#undef anchor
|
531
548
|
|
532
549
|
LZ4_FORCE_INLINE int LZ4HC_compress_hashChain (
|
533
550
|
LZ4HC_CCtx_internal* const ctx,
|
@@ -535,7 +552,7 @@ LZ4_FORCE_INLINE int LZ4HC_compress_hashChain (
|
|
535
552
|
char* const dest,
|
536
553
|
int* srcSizePtr,
|
537
554
|
int const maxOutputSize,
|
538
|
-
|
555
|
+
int maxNbAttempts,
|
539
556
|
const limitedOutput_directive limit,
|
540
557
|
const dictCtx_directive dict
|
541
558
|
)
|
@@ -565,7 +582,7 @@ LZ4_FORCE_INLINE int LZ4HC_compress_hashChain (
|
|
565
582
|
/* init */
|
566
583
|
*srcSizePtr = 0;
|
567
584
|
if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */
|
568
|
-
if (inputSize < LZ4_minLength) goto _last_literals;
|
585
|
+
if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
|
569
586
|
|
570
587
|
/* Main Loop */
|
571
588
|
while (ip <= mflimit) {
|
@@ -637,7 +654,11 @@ _Search3:
|
|
637
654
|
if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow;
|
638
655
|
ip = start2;
|
639
656
|
optr = op;
|
640
|
-
if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml2, ref2, limit, oend))
|
657
|
+
if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml2, ref2, limit, oend)) {
|
658
|
+
ml = ml2;
|
659
|
+
ref = ref2;
|
660
|
+
goto _dest_overflow;
|
661
|
+
}
|
641
662
|
continue;
|
642
663
|
}
|
643
664
|
|
@@ -709,17 +730,18 @@ _Search3:
|
|
709
730
|
_last_literals:
|
710
731
|
/* Encode Last Literals */
|
711
732
|
{ size_t lastRunSize = (size_t)(iend - anchor); /* literals */
|
712
|
-
size_t
|
713
|
-
size_t const totalSize = 1 +
|
733
|
+
size_t llAdd = (lastRunSize + 255 - RUN_MASK) / 255;
|
734
|
+
size_t const totalSize = 1 + llAdd + lastRunSize;
|
714
735
|
if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */
|
715
736
|
if (limit && (op + totalSize > oend)) {
|
716
|
-
if (limit == limitedOutput) return 0;
|
737
|
+
if (limit == limitedOutput) return 0;
|
717
738
|
/* adapt lastRunSize to fill 'dest' */
|
718
|
-
lastRunSize = (size_t)(oend - op) - 1
|
719
|
-
|
720
|
-
lastRunSize -=
|
739
|
+
lastRunSize = (size_t)(oend - op) - 1 /*token*/;
|
740
|
+
llAdd = (lastRunSize + 256 - RUN_MASK) / 256;
|
741
|
+
lastRunSize -= llAdd;
|
721
742
|
}
|
722
|
-
|
743
|
+
DEBUGLOG(6, "Final literal run : %i literals", (int)lastRunSize);
|
744
|
+
ip = anchor + lastRunSize; /* can be != iend if limit==fillOutput */
|
723
745
|
|
724
746
|
if (lastRunSize >= RUN_MASK) {
|
725
747
|
size_t accumulator = lastRunSize - RUN_MASK;
|
@@ -739,9 +761,25 @@ _last_literals:
|
|
739
761
|
|
740
762
|
_dest_overflow:
|
741
763
|
if (limit == fillOutput) {
|
764
|
+
/* Assumption : ip, anchor, ml and ref must be set correctly */
|
765
|
+
size_t const ll = (size_t)(ip - anchor);
|
766
|
+
size_t const ll_addbytes = (ll + 240) / 255;
|
767
|
+
size_t const ll_totalCost = 1 + ll_addbytes + ll;
|
768
|
+
BYTE* const maxLitPos = oend - 3; /* 2 for offset, 1 for token */
|
769
|
+
DEBUGLOG(6, "Last sequence overflowing");
|
742
770
|
op = optr; /* restore correct out pointer */
|
771
|
+
if (op + ll_totalCost <= maxLitPos) {
|
772
|
+
/* ll validated; now adjust match length */
|
773
|
+
size_t const bytesLeftForMl = (size_t)(maxLitPos - (op+ll_totalCost));
|
774
|
+
size_t const maxMlSize = MINMATCH + (ML_MASK-1) + (bytesLeftForMl * 255);
|
775
|
+
assert(maxMlSize < INT_MAX); assert(ml >= 0);
|
776
|
+
if ((size_t)ml > maxMlSize) ml = (int)maxMlSize;
|
777
|
+
if ((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1 + ml >= MFLIMIT) {
|
778
|
+
LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, notLimited, oend);
|
779
|
+
} }
|
743
780
|
goto _last_literals;
|
744
781
|
}
|
782
|
+
/* compression failed */
|
745
783
|
return 0;
|
746
784
|
}
|
747
785
|
|
@@ -752,7 +790,7 @@ static int LZ4HC_compress_optimal( LZ4HC_CCtx_internal* ctx,
|
|
752
790
|
int const nbSearches, size_t sufficient_len,
|
753
791
|
const limitedOutput_directive limit, int const fullUpdate,
|
754
792
|
const dictCtx_directive dict,
|
755
|
-
HCfavor_e favorDecSpeed);
|
793
|
+
const HCfavor_e favorDecSpeed);
|
756
794
|
|
757
795
|
|
758
796
|
LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal (
|
@@ -769,7 +807,7 @@ LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal (
|
|
769
807
|
typedef enum { lz4hc, lz4opt } lz4hc_strat_e;
|
770
808
|
typedef struct {
|
771
809
|
lz4hc_strat_e strat;
|
772
|
-
|
810
|
+
int nbSearches;
|
773
811
|
U32 targetLength;
|
774
812
|
} cParams_t;
|
775
813
|
static const cParams_t clTable[LZ4HC_CLEVEL_MAX+1] = {
|
@@ -788,7 +826,8 @@ LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal (
|
|
788
826
|
{ lz4opt,16384,LZ4_OPT_NUM }, /* 12==LZ4HC_CLEVEL_MAX */
|
789
827
|
};
|
790
828
|
|
791
|
-
DEBUGLOG(4, "LZ4HC_compress_generic(ctx=%p, src=%p, srcSize=%d)",
|
829
|
+
DEBUGLOG(4, "LZ4HC_compress_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)",
|
830
|
+
ctx, src, *srcSizePtr, limit);
|
792
831
|
|
793
832
|
if (limit == fillOutput && dstCapacity < 1) return 0; /* Impossible to store anything */
|
794
833
|
if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size (too large or negative) */
|
@@ -808,7 +847,7 @@ LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal (
|
|
808
847
|
assert(cParam.strat == lz4opt);
|
809
848
|
result = LZ4HC_compress_optimal(ctx,
|
810
849
|
src, dst, srcSizePtr, dstCapacity,
|
811
|
-
|
850
|
+
cParam.nbSearches, cParam.targetLength, limit,
|
812
851
|
cLevel == LZ4HC_CLEVEL_MAX, /* ultra mode */
|
813
852
|
dict, favor);
|
814
853
|
}
|
@@ -881,27 +920,22 @@ LZ4HC_compress_generic (
|
|
881
920
|
|
882
921
|
int LZ4_sizeofStateHC(void) { return (int)sizeof(LZ4_streamHC_t); }
|
883
922
|
|
884
|
-
#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 :
|
885
|
-
* it reports an aligment of 8-bytes,
|
886
|
-
* while actually aligning LZ4_streamHC_t on 4 bytes. */
|
887
923
|
static size_t LZ4_streamHC_t_alignment(void)
|
888
924
|
{
|
889
|
-
|
890
|
-
|
891
|
-
|
925
|
+
#if LZ4_ALIGN_TEST
|
926
|
+
typedef struct { char c; LZ4_streamHC_t t; } t_a;
|
927
|
+
return sizeof(t_a) - sizeof(LZ4_streamHC_t);
|
928
|
+
#else
|
929
|
+
return 1; /* effectively disabled */
|
892
930
|
#endif
|
931
|
+
}
|
893
932
|
|
894
933
|
/* state is presumed correctly initialized,
|
895
934
|
* in which case its size and alignment have already been validate */
|
896
935
|
int LZ4_compress_HC_extStateHC_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel)
|
897
936
|
{
|
898
937
|
LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)state)->internal_donotuse;
|
899
|
-
|
900
|
-
* it reports an aligment of 8-bytes,
|
901
|
-
* while actually aligning LZ4_streamHC_t on 4 bytes. */
|
902
|
-
assert(((size_t)state & (LZ4_streamHC_t_alignment() - 1)) == 0); /* check alignment */
|
903
|
-
#endif
|
904
|
-
if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */
|
938
|
+
if (!LZ4_isAligned(state, LZ4_streamHC_t_alignment())) return 0;
|
905
939
|
LZ4_resetStreamHC_fast((LZ4_streamHC_t*)state, compressionLevel);
|
906
940
|
LZ4HC_init_internal (ctx, (const BYTE*)src);
|
907
941
|
if (dstCapacity < LZ4_compressBound(srcSize))
|
@@ -950,10 +984,11 @@ int LZ4_compress_HC_destSize(void* state, const char* source, char* dest, int* s
|
|
950
984
|
/* allocation */
|
951
985
|
LZ4_streamHC_t* LZ4_createStreamHC(void)
|
952
986
|
{
|
953
|
-
LZ4_streamHC_t* const
|
954
|
-
|
955
|
-
|
956
|
-
|
987
|
+
LZ4_streamHC_t* const state =
|
988
|
+
(LZ4_streamHC_t*)ALLOC_AND_ZERO(sizeof(LZ4_streamHC_t));
|
989
|
+
if (state == NULL) return NULL;
|
990
|
+
LZ4_setCompressionLevel(state, LZ4HC_CLEVEL_DEFAULT);
|
991
|
+
return state;
|
957
992
|
}
|
958
993
|
|
959
994
|
int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr)
|
@@ -968,22 +1003,16 @@ int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr)
|
|
968
1003
|
LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size)
|
969
1004
|
{
|
970
1005
|
LZ4_streamHC_t* const LZ4_streamHCPtr = (LZ4_streamHC_t*)buffer;
|
971
|
-
if (buffer == NULL) return NULL;
|
972
|
-
if (size < sizeof(LZ4_streamHC_t)) return NULL;
|
973
|
-
#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 :
|
974
|
-
* it reports an aligment of 8-bytes,
|
975
|
-
* while actually aligning LZ4_streamHC_t on 4 bytes. */
|
976
|
-
if (((size_t)buffer) & (LZ4_streamHC_t_alignment() - 1)) return NULL; /* alignment check */
|
977
|
-
#endif
|
978
1006
|
/* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
|
979
1007
|
LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= LZ4_STREAMHCSIZE);
|
980
|
-
DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)",
|
981
|
-
/*
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
LZ4_streamHCPtr->internal_donotuse
|
1008
|
+
DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", buffer, (unsigned)size);
|
1009
|
+
/* check conditions */
|
1010
|
+
if (buffer == NULL) return NULL;
|
1011
|
+
if (size < sizeof(LZ4_streamHC_t)) return NULL;
|
1012
|
+
if (!LZ4_isAligned(buffer, LZ4_streamHC_t_alignment())) return NULL;
|
1013
|
+
/* init */
|
1014
|
+
{ LZ4HC_CCtx_internal* const hcstate = &(LZ4_streamHCPtr->internal_donotuse);
|
1015
|
+
MEM_INIT(hcstate, 0, sizeof(*hcstate)); }
|
987
1016
|
LZ4_setCompressionLevel(LZ4_streamHCPtr, LZ4HC_CLEVEL_DEFAULT);
|
988
1017
|
return LZ4_streamHCPtr;
|
989
1018
|
}
|
@@ -1028,7 +1057,7 @@ int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr,
|
|
1028
1057
|
const char* dictionary, int dictSize)
|
1029
1058
|
{
|
1030
1059
|
LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
|
1031
|
-
DEBUGLOG(4, "LZ4_loadDictHC(
|
1060
|
+
DEBUGLOG(4, "LZ4_loadDictHC(ctx:%p, dict:%p, dictSize:%d)", LZ4_streamHCPtr, dictionary, dictSize);
|
1032
1061
|
assert(LZ4_streamHCPtr != NULL);
|
1033
1062
|
if (dictSize > 64 KB) {
|
1034
1063
|
dictionary += (size_t)dictSize - 64 KB;
|
@@ -1069,14 +1098,15 @@ static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBl
|
|
1069
1098
|
ctxPtr->dictCtx = NULL;
|
1070
1099
|
}
|
1071
1100
|
|
1072
|
-
static int
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1101
|
+
static int
|
1102
|
+
LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
|
1103
|
+
const char* src, char* dst,
|
1104
|
+
int* srcSizePtr, int dstCapacity,
|
1105
|
+
limitedOutput_directive limit)
|
1076
1106
|
{
|
1077
1107
|
LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
|
1078
|
-
DEBUGLOG(
|
1079
|
-
LZ4_streamHCPtr, src, *srcSizePtr);
|
1108
|
+
DEBUGLOG(5, "LZ4_compressHC_continue_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)",
|
1109
|
+
LZ4_streamHCPtr, src, *srcSizePtr, limit);
|
1080
1110
|
assert(ctxPtr != NULL);
|
1081
1111
|
/* auto-init if forgotten */
|
1082
1112
|
if (ctxPtr->base == NULL) LZ4HC_init_internal (ctxPtr, (const BYTE*) src);
|
@@ -1100,8 +1130,7 @@ static int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
|
|
1100
1130
|
if (sourceEnd > dictEnd) sourceEnd = dictEnd;
|
1101
1131
|
ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
|
1102
1132
|
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
|
1103
|
-
|
1104
|
-
}
|
1133
|
+
} }
|
1105
1134
|
|
1106
1135
|
return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit);
|
1107
1136
|
}
|
@@ -1121,23 +1150,30 @@ int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, const ch
|
|
1121
1150
|
|
1122
1151
|
|
1123
1152
|
|
1124
|
-
/*
|
1125
|
-
|
1153
|
+
/* LZ4_saveDictHC :
|
1154
|
+
* save history content
|
1155
|
+
* into a user-provided buffer
|
1156
|
+
* which is then used to continue compression
|
1157
|
+
*/
|
1126
1158
|
int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
|
1127
1159
|
{
|
1128
1160
|
LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
|
1129
1161
|
int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
|
1130
|
-
DEBUGLOG(
|
1162
|
+
DEBUGLOG(5, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize);
|
1163
|
+
assert(prefixSize >= 0);
|
1131
1164
|
if (dictSize > 64 KB) dictSize = 64 KB;
|
1132
1165
|
if (dictSize < 4) dictSize = 0;
|
1133
1166
|
if (dictSize > prefixSize) dictSize = prefixSize;
|
1134
|
-
|
1167
|
+
if (safeBuffer == NULL) assert(dictSize == 0);
|
1168
|
+
if (dictSize > 0)
|
1169
|
+
memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
|
1135
1170
|
{ U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
|
1136
1171
|
streamPtr->end = (const BYTE*)safeBuffer + dictSize;
|
1137
1172
|
streamPtr->base = streamPtr->end - endIndex;
|
1138
1173
|
streamPtr->dictLimit = endIndex - (U32)dictSize;
|
1139
1174
|
streamPtr->lowLimit = endIndex - (U32)dictSize;
|
1140
|
-
if (streamPtr->nextToUpdate < streamPtr->dictLimit)
|
1175
|
+
if (streamPtr->nextToUpdate < streamPtr->dictLimit)
|
1176
|
+
streamPtr->nextToUpdate = streamPtr->dictLimit;
|
1141
1177
|
}
|
1142
1178
|
return dictSize;
|
1143
1179
|
}
|
@@ -1287,8 +1323,13 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
|
1287
1323
|
const dictCtx_directive dict,
|
1288
1324
|
const HCfavor_e favorDecSpeed)
|
1289
1325
|
{
|
1326
|
+
int retval = 0;
|
1290
1327
|
#define TRAILING_LITERALS 3
|
1328
|
+
#ifdef LZ4HC_HEAPMODE
|
1329
|
+
LZ4HC_optimal_t* const opt = (LZ4HC_optimal_t*)ALLOC(sizeof(LZ4HC_optimal_t) * (LZ4_OPT_NUM + TRAILING_LITERALS));
|
1330
|
+
#else
|
1291
1331
|
LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* ~64 KB, which is a bit large for stack... */
|
1332
|
+
#endif
|
1292
1333
|
|
1293
1334
|
const BYTE* ip = (const BYTE*) source;
|
1294
1335
|
const BYTE* anchor = ip;
|
@@ -1298,15 +1339,19 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
|
1298
1339
|
BYTE* op = (BYTE*) dst;
|
1299
1340
|
BYTE* opSaved = (BYTE*) dst;
|
1300
1341
|
BYTE* oend = op + dstCapacity;
|
1342
|
+
int ovml = MINMATCH; /* overflow - last sequence */
|
1343
|
+
const BYTE* ovref = NULL;
|
1301
1344
|
|
1302
1345
|
/* init */
|
1346
|
+
#ifdef LZ4HC_HEAPMODE
|
1347
|
+
if (opt == NULL) goto _return_label;
|
1348
|
+
#endif
|
1303
1349
|
DEBUGLOG(5, "LZ4HC_compress_optimal(dst=%p, dstCapa=%u)", dst, (unsigned)dstCapacity);
|
1304
1350
|
*srcSizePtr = 0;
|
1305
1351
|
if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */
|
1306
1352
|
if (sufficient_len >= LZ4_OPT_NUM) sufficient_len = LZ4_OPT_NUM-1;
|
1307
1353
|
|
1308
1354
|
/* Main Loop */
|
1309
|
-
assert(ip - anchor < LZ4_MAX_INPUT_SIZE);
|
1310
1355
|
while (ip <= mflimit) {
|
1311
1356
|
int const llen = (int)(ip - anchor);
|
1312
1357
|
int best_mlen, best_off;
|
@@ -1320,8 +1365,11 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
|
1320
1365
|
int const firstML = firstMatch.len;
|
1321
1366
|
const BYTE* const matchPos = ip - firstMatch.off;
|
1322
1367
|
opSaved = op;
|
1323
|
-
if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), firstML, matchPos, limit, oend) )
|
1368
|
+
if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), firstML, matchPos, limit, oend) ) { /* updates ip, op and anchor */
|
1369
|
+
ovml = firstML;
|
1370
|
+
ovref = matchPos;
|
1324
1371
|
goto _dest_overflow;
|
1372
|
+
}
|
1325
1373
|
continue;
|
1326
1374
|
}
|
1327
1375
|
|
@@ -1463,7 +1511,7 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
|
1463
1511
|
best_off = opt[last_match_pos].off;
|
1464
1512
|
cur = last_match_pos - best_mlen;
|
1465
1513
|
|
1466
|
-
|
1514
|
+
encode: /* cur, last_match_pos, best_mlen, best_off must be set */
|
1467
1515
|
assert(cur < LZ4_OPT_NUM);
|
1468
1516
|
assert(last_match_pos >= 1); /* == 1 when only one candidate */
|
1469
1517
|
DEBUGLOG(6, "reverse traversal, looking for shortest path (last_match_pos=%i)", last_match_pos);
|
@@ -1493,25 +1541,31 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
|
1493
1541
|
assert(ml >= MINMATCH);
|
1494
1542
|
assert((offset >= 1) && (offset <= LZ4_DISTANCE_MAX));
|
1495
1543
|
opSaved = op;
|
1496
|
-
if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ip - offset, limit, oend) )
|
1544
|
+
if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ip - offset, limit, oend) ) { /* updates ip, op and anchor */
|
1545
|
+
ovml = ml;
|
1546
|
+
ovref = ip - offset;
|
1497
1547
|
goto _dest_overflow;
|
1498
|
-
} }
|
1548
|
+
} } }
|
1499
1549
|
} /* while (ip <= mflimit) */
|
1500
1550
|
|
1501
|
-
|
1551
|
+
_last_literals:
|
1502
1552
|
/* Encode Last Literals */
|
1503
1553
|
{ size_t lastRunSize = (size_t)(iend - anchor); /* literals */
|
1504
|
-
size_t
|
1505
|
-
size_t const totalSize = 1 +
|
1554
|
+
size_t llAdd = (lastRunSize + 255 - RUN_MASK) / 255;
|
1555
|
+
size_t const totalSize = 1 + llAdd + lastRunSize;
|
1506
1556
|
if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */
|
1507
1557
|
if (limit && (op + totalSize > oend)) {
|
1508
|
-
if (limit == limitedOutput)
|
1558
|
+
if (limit == limitedOutput) { /* Check output limit */
|
1559
|
+
retval = 0;
|
1560
|
+
goto _return_label;
|
1561
|
+
}
|
1509
1562
|
/* adapt lastRunSize to fill 'dst' */
|
1510
|
-
lastRunSize = (size_t)(oend - op) - 1
|
1511
|
-
|
1512
|
-
lastRunSize -=
|
1563
|
+
lastRunSize = (size_t)(oend - op) - 1 /*token*/;
|
1564
|
+
llAdd = (lastRunSize + 256 - RUN_MASK) / 256;
|
1565
|
+
lastRunSize -= llAdd;
|
1513
1566
|
}
|
1514
|
-
|
1567
|
+
DEBUGLOG(6, "Final literal run : %i literals", (int)lastRunSize);
|
1568
|
+
ip = anchor + lastRunSize; /* can be != iend if limit==fillOutput */
|
1515
1569
|
|
1516
1570
|
if (lastRunSize >= RUN_MASK) {
|
1517
1571
|
size_t accumulator = lastRunSize - RUN_MASK;
|
@@ -1527,12 +1581,35 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
|
|
1527
1581
|
|
1528
1582
|
/* End */
|
1529
1583
|
*srcSizePtr = (int) (((const char*)ip) - source);
|
1530
|
-
|
1584
|
+
retval = (int) ((char*)op-dst);
|
1585
|
+
goto _return_label;
|
1531
1586
|
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1587
|
+
_dest_overflow:
|
1588
|
+
if (limit == fillOutput) {
|
1589
|
+
/* Assumption : ip, anchor, ovml and ovref must be set correctly */
|
1590
|
+
size_t const ll = (size_t)(ip - anchor);
|
1591
|
+
size_t const ll_addbytes = (ll + 240) / 255;
|
1592
|
+
size_t const ll_totalCost = 1 + ll_addbytes + ll;
|
1593
|
+
BYTE* const maxLitPos = oend - 3; /* 2 for offset, 1 for token */
|
1594
|
+
DEBUGLOG(6, "Last sequence overflowing (only %i bytes remaining)", (int)(oend-1-opSaved));
|
1595
|
+
op = opSaved; /* restore correct out pointer */
|
1596
|
+
if (op + ll_totalCost <= maxLitPos) {
|
1597
|
+
/* ll validated; now adjust match length */
|
1598
|
+
size_t const bytesLeftForMl = (size_t)(maxLitPos - (op+ll_totalCost));
|
1599
|
+
size_t const maxMlSize = MINMATCH + (ML_MASK-1) + (bytesLeftForMl * 255);
|
1600
|
+
assert(maxMlSize < INT_MAX); assert(ovml >= 0);
|
1601
|
+
if ((size_t)ovml > maxMlSize) ovml = (int)maxMlSize;
|
1602
|
+
if ((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1 + ovml >= MFLIMIT) {
|
1603
|
+
DEBUGLOG(6, "Space to end : %i + ml (%i)", (int)((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1), ovml);
|
1604
|
+
DEBUGLOG(6, "Before : ip = %p, anchor = %p", ip, anchor);
|
1605
|
+
LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ovml, ovref, notLimited, oend);
|
1606
|
+
DEBUGLOG(6, "After : ip = %p, anchor = %p", ip, anchor);
|
1607
|
+
} }
|
1608
|
+
goto _last_literals;
|
1609
|
+
}
|
1610
|
+
_return_label:
|
1611
|
+
#ifdef LZ4HC_HEAPMODE
|
1612
|
+
FREEMEM(opt);
|
1613
|
+
#endif
|
1614
|
+
return retval;
|
1615
|
+
}
|