diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lz4.c | 50 | ||||
-rw-r--r-- | lib/lz4frame.c | 3 | ||||
-rw-r--r-- | lib/lz4frame.h | 2 | ||||
-rw-r--r-- | lib/lz4hc.c | 32 |
4 files changed, 55 insertions, 32 deletions
@@ -225,15 +225,15 @@ static const int LZ4_minLength = (MFLIMIT+1); #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) # include <stdio.h> -static int g_debuglog_enable = 1; -# define DEBUGLOG(l, ...) { \ - if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ - fprintf(stderr, __FILE__ ": "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " \n"); \ - } } + static int g_debuglog_enable = 1; +# define DEBUGLOG(l, ...) { \ + if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ + fprintf(stderr, __FILE__ ": "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " \n"); \ + } } #else -# define DEBUGLOG(l, ...) {} /* disabled */ +# define DEBUGLOG(l, ...) {} /* disabled */ #endif @@ -249,6 +249,10 @@ static int g_debuglog_enable = 1; typedef uint64_t U64; typedef uintptr_t uptrval; #else +# include <limits.h> +# if UINT_MAX != 4294967295UL +# error "LZ4 code (when not C++ or C99) assumes that sizeof(int) == 4" +# endif typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; @@ -370,12 +374,12 @@ static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3}; #ifndef LZ4_FAST_DEC_LOOP -# if defined(__i386__) || defined(__x86_64__) +# if defined __i386__ || defined _M_IX86 || defined __x86_64__ || defined _M_X64 # define LZ4_FAST_DEC_LOOP 1 # elif defined(__aarch64__) && !defined(__clang__) /* On aarch64, we disable this optimization for clang because on certain - * mobile chipsets and clang, it reduces performance. For more information - * refer to https://github.com/lz4/lz4/pull/707. */ + * mobile chipsets, performance is reduced with clang. For information + * refer to https://github.com/lz4/lz4/pull/707 */ # define LZ4_FAST_DEC_LOOP 1 # else # define LZ4_FAST_DEC_LOOP 0 @@ -628,7 +632,7 @@ int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, /*-****************************** * Compression functions ********************************/ -static U32 LZ4_hash4(U32 sequence, tableType_t const tableType) +LZ4_FORCE_INLINE U32 LZ4_hash4(U32 sequence, tableType_t const tableType) { if (tableType == byU16) return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); @@ -636,7 +640,7 @@ static U32 LZ4_hash4(U32 sequence, tableType_t const tableType) return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); } -static U32 LZ4_hash5(U64 sequence, tableType_t const tableType) +LZ4_FORCE_INLINE U32 LZ4_hash5(U64 sequence, tableType_t const tableType) { const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; if (LZ4_isLittleEndian()) { @@ -654,7 +658,7 @@ LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tab return LZ4_hash4(LZ4_read32(p), tableType); } -static void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) +LZ4_FORCE_INLINE void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) { switch (tableType) { @@ -666,7 +670,7 @@ static void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) } } -static void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType) +LZ4_FORCE_INLINE void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType) { switch (tableType) { @@ -678,7 +682,7 @@ static void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t cons } } -static void LZ4_putPositionOnHash(const BYTE* p, U32 h, +LZ4_FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) { @@ -703,7 +707,7 @@ LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_ * Assumption 1 : only valid if tableType == byU32 or byU16. * Assumption 2 : h is presumed valid (within limits of hash table) */ -static U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, tableType_t tableType) +LZ4_FORCE_INLINE U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, tableType_t tableType) { LZ4_STATIC_ASSERT(LZ4_MEMORY_USAGE > 2); if (tableType == byU32) { @@ -815,7 +819,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( int const maybe_extMem = (dictDirective == usingExtDict) || (dictDirective == usingDictCtx); U32 const prefixIdxLimit = startIndex - dictSize; /* used when dictDirective == dictSmall */ - const BYTE* const dictEnd = dictionary + dictSize; + const BYTE* const dictEnd = dictionary ? dictionary + dictSize : dictionary; const BYTE* anchor = (const BYTE*) source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimitPlusOne = iend - MFLIMIT + 1; @@ -823,7 +827,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic( /* the dictCtx currentOffset is indexed on the start of the dictionary, * while a dictionary in the current context precedes the currentOffset */ - const BYTE* dictBase = (dictDirective == usingDictCtx) ? + const BYTE* dictBase = !dictionary ? NULL : (dictDirective == usingDictCtx) ? dictionary + dictSize - dictCtx->currentOffset : dictionary + dictSize - startIndex; @@ -1345,8 +1349,8 @@ LZ4_stream_t* LZ4_createStream(void) while actually aligning LZ4_stream_t on 4 bytes. */ static size_t LZ4_stream_t_alignment(void) { - struct { char c; LZ4_stream_t t; } t_a; - return sizeof(t_a) - sizeof(t_a.t); + typedef struct { char c; LZ4_stream_t t; } t_a; + return sizeof(t_a) - sizeof(LZ4_stream_t); } #endif @@ -1625,8 +1629,8 @@ typedef enum { loop_error = -2, initial_error = -1, ok = 0 } variable_length_err LZ4_FORCE_INLINE unsigned read_variable_length(const BYTE**ip, const BYTE* lencheck, int loop_check, int initial_check, variable_length_error* error) { - unsigned length = 0; - unsigned s; + U32 length = 0; + U32 s; if (initial_check && unlikely((*ip) >= lencheck)) { /* overflow detection */ *error = initial_error; return length; diff --git a/lib/lz4frame.c b/lib/lz4frame.c index c9f630d..5d716ea 100644 --- a/lib/lz4frame.c +++ b/lib/lz4frame.c @@ -725,6 +725,9 @@ size_t LZ4F_compressBegin(LZ4F_cctx* cctxPtr, */ size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr) { + if (preferencesPtr && preferencesPtr->autoFlush) { + return LZ4F_compressBound_internal(srcSize, preferencesPtr, 0); + } return LZ4F_compressBound_internal(srcSize, preferencesPtr, (size_t)-1); } diff --git a/lib/lz4frame.h b/lib/lz4frame.h index 391e484..87b0b2a 100644 --- a/lib/lz4frame.h +++ b/lib/lz4frame.h @@ -284,7 +284,7 @@ LZ4FLIB_API size_t LZ4F_compressBegin(LZ4F_cctx* cctx, * @return is always the same for a srcSize and prefsPtr. * prefsPtr is optional : when NULL is provided, preferences will be set to cover worst case scenario. * tech details : - * @return includes the possibility that internal buffer might already be filled by up to (blockSize-1) bytes. + * @return if automatic flushing is not enabled, includes the possibility that internal buffer might already be filled by up to (blockSize-1) bytes. * It also includes frame footer (ending + checksum), since it might be generated by LZ4F_compressEnd(). * @return doesn't include frame header, as it was already generated by LZ4F_compressBegin(). */ diff --git a/lib/lz4hc.c b/lib/lz4hc.c index 5922ed7..687f87e 100644 --- a/lib/lz4hc.c +++ b/lib/lz4hc.c @@ -389,8 +389,8 @@ LZ4HC_InsertAndGetWiderMatch ( if (lookBackLength==0) { /* no back possible */ size_t const maxML = MIN(currentSegmentLength, srcPatternLength); if ((size_t)longest < maxML) { - assert(base + matchIndex < ip); - if (ip - (base+matchIndex) > LZ4_DISTANCE_MAX) break; + assert(base + matchIndex != ip); + if ((size_t)(ip - base) - matchIndex > LZ4_DISTANCE_MAX) break; assert(maxML < 2 GB); longest = (int)maxML; *matchpos = base + matchIndex; /* virtual pos, relative to ip, to retrieve offset */ @@ -886,8 +886,8 @@ int LZ4_sizeofStateHC(void) { return (int)sizeof(LZ4_streamHC_t); } * while actually aligning LZ4_streamHC_t on 4 bytes. */ static size_t LZ4_streamHC_t_alignment(void) { - struct { char c; LZ4_streamHC_t t; } t_a; - return sizeof(t_a) - sizeof(t_a.t); + typedef struct { char c; LZ4_streamHC_t t; } t_a; + return sizeof(t_a) - sizeof(LZ4_streamHC_t); } #endif @@ -1028,7 +1028,7 @@ int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize) { LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse; - DEBUGLOG(4, "LZ4_loadDictHC(%p, %p, %d)", LZ4_streamHCPtr, dictionary, dictSize); + DEBUGLOG(4, "LZ4_loadDictHC(ctx:%p, dict:%p, dictSize:%d)", LZ4_streamHCPtr, dictionary, dictSize); assert(LZ4_streamHCPtr != NULL); if (dictSize > 64 KB) { dictionary += (size_t)dictSize - 64 KB; @@ -1287,8 +1287,13 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx, const dictCtx_directive dict, const HCfavor_e favorDecSpeed) { + int retval = 0; #define TRAILING_LITERALS 3 +#ifdef LZ4HC_HEAPMODE + LZ4HC_optimal_t* const opt = (LZ4HC_optimal_t*)malloc(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... */ +#endif const BYTE* ip = (const BYTE*) source; const BYTE* anchor = ip; @@ -1300,6 +1305,9 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx, BYTE* oend = op + dstCapacity; /* init */ +#ifdef LZ4HC_HEAPMODE + if (opt == NULL) goto _return_label; +#endif DEBUGLOG(5, "LZ4HC_compress_optimal(dst=%p, dstCapa=%u)", dst, (unsigned)dstCapacity); *srcSizePtr = 0; if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */ @@ -1505,7 +1513,10 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx, size_t const totalSize = 1 + litLength + lastRunSize; if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */ if (limit && (op + totalSize > oend)) { - if (limit == limitedOutput) return 0; /* Check output limit */ + if (limit == limitedOutput) { /* Check output limit */ + retval = 0; + goto _return_label; + } /* adapt lastRunSize to fill 'dst' */ lastRunSize = (size_t)(oend - op) - 1; litLength = (lastRunSize + 255 - RUN_MASK) / 255; @@ -1527,12 +1538,17 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx, /* End */ *srcSizePtr = (int) (((const char*)ip) - source); - return (int) ((char*)op-dst); + retval = (int) ((char*)op-dst); + goto _return_label; _dest_overflow: if (limit == fillOutput) { op = opSaved; /* restore correct out pointer */ goto _last_literals; } - return 0; + _return_label: +#ifdef LZ4HC_HEAPMODE + free(opt); +#endif + return retval; } |