summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile70
-rw-r--r--lib/lz4.c20
-rw-r--r--lib/lz4.h24
-rw-r--r--lib/lz4frame.c21
4 files changed, 88 insertions, 47 deletions
diff --git a/lib/Makefile b/lib/Makefile
index d63de18..abb6c07 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -62,7 +62,7 @@ ifeq ($(shell uname), Darwin)
SHARED_EXT = dylib
SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT)
SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT)
- SONAME_FLAGS = -install_name $(LIBDIR)/liblz4.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER)
+ SONAME_FLAGS = -install_name $(libdir)/liblz4.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER)
else
SONAME_FLAGS = -Wl,-soname=liblz4.$(SHARED_EXT).$(LIBVER_MAJOR)
SHARED_EXT = so
@@ -132,20 +132,22 @@ listL120: # extract lines >= 120 characters in *.{c,h}, by Takayuki Matsuoka (n
DESTDIR ?=
# directory variables : GNU conventions prefer lowercase
# see https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html
-# support both lower and uppercase (BSD), use uppercase in script
-prefix ?= /usr/local
-PREFIX ?= $(prefix)
-exec_prefix ?= $(PREFIX)
-libdir ?= $(exec_prefix)/lib
-LIBDIR ?= $(libdir)
-includedir ?= $(PREFIX)/include
-INCLUDEDIR ?= $(includedir)
+# support both lower and uppercase (BSD), use lower in script
+PREFIX ?= /usr/local
+prefix ?= $(PREFIX)
+EXEC_PREFIX ?= $(prefix)
+exec_prefix ?= $(EXEC_PREFIX)
+LIBDIR ?= $(exec_prefix)/lib
+libdir ?= $(LIBDIR)
+INCLUDEDIR ?= $(prefix)/include
+includedir ?= $(INCLUDEDIR)
ifneq (,$(filter $(shell uname),OpenBSD FreeBSD NetBSD DragonFly))
-PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig
+PKGCONFIGDIR ?= $(prefix)/libdata/pkgconfig
else
-PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig
+PKGCONFIGDIR ?= $(libdir)/pkgconfig
endif
+pkgconfigdir ?= $(PKGCONFIGDIR)
ifneq (,$(filter $(shell uname),SunOS))
INSTALL ?= ginstall
@@ -158,41 +160,41 @@ INSTALL_DATA ?= $(INSTALL) -m 644
liblz4.pc: liblz4.pc.in Makefile
@echo creating pkgconfig
- $(Q)sed -e 's|@PREFIX@|$(PREFIX)|' \
- -e 's|@LIBDIR@|$(LIBDIR)|' \
- -e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \
+ $(Q)sed -e 's|@PREFIX@|$(prefix)|' \
+ -e 's|@LIBDIR@|$(libdir)|' \
+ -e 's|@INCLUDEDIR@|$(includedir)|' \
-e 's|@VERSION@|$(LIBVER)|' \
$< >$@
install: lib liblz4.pc
- $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(PKGCONFIGDIR)/ $(DESTDIR)$(INCLUDEDIR)/ $(DESTDIR)$(LIBDIR)/
- $(Q)$(INSTALL_DATA) liblz4.pc $(DESTDIR)$(PKGCONFIGDIR)/
+ $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(pkgconfigdir)/ $(DESTDIR)$(includedir)/ $(DESTDIR)$(libdir)/
+ $(Q)$(INSTALL_DATA) liblz4.pc $(DESTDIR)$(pkgconfigdir)/
@echo Installing libraries
ifeq ($(BUILD_STATIC),yes)
- $(Q)$(INSTALL_DATA) liblz4.a $(DESTDIR)$(LIBDIR)/liblz4.a
- $(Q)$(INSTALL_DATA) lz4frame_static.h $(DESTDIR)$(INCLUDEDIR)/lz4frame_static.h
+ $(Q)$(INSTALL_DATA) liblz4.a $(DESTDIR)$(libdir)/liblz4.a
+ $(Q)$(INSTALL_DATA) lz4frame_static.h $(DESTDIR)$(includedir)/lz4frame_static.h
endif
ifeq ($(BUILD_SHARED),yes)
- $(Q)$(INSTALL_PROGRAM) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)
- $(Q)ln -sf liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT_MAJOR)
- $(Q)ln -sf liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT)
+ $(Q)$(INSTALL_PROGRAM) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)
+ $(Q)ln -sf liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT_MAJOR)
+ $(Q)ln -sf liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT)
endif
- @echo Installing headers in $(INCLUDEDIR)
- $(Q)$(INSTALL_DATA) lz4.h $(DESTDIR)$(INCLUDEDIR)/lz4.h
- $(Q)$(INSTALL_DATA) lz4hc.h $(DESTDIR)$(INCLUDEDIR)/lz4hc.h
- $(Q)$(INSTALL_DATA) lz4frame.h $(DESTDIR)$(INCLUDEDIR)/lz4frame.h
+ @echo Installing headers in $(includedir)
+ $(Q)$(INSTALL_DATA) lz4.h $(DESTDIR)$(includedir)/lz4.h
+ $(Q)$(INSTALL_DATA) lz4hc.h $(DESTDIR)$(includedir)/lz4hc.h
+ $(Q)$(INSTALL_DATA) lz4frame.h $(DESTDIR)$(includedir)/lz4frame.h
@echo lz4 libraries installed
uninstall:
- $(Q)$(RM) $(DESTDIR)$(LIBDIR)/pkgconfig/liblz4.pc
- $(Q)$(RM) $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT)
- $(Q)$(RM) $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT_MAJOR)
- $(Q)$(RM) $(DESTDIR)$(LIBDIR)/liblz4.$(SHARED_EXT_VER)
- $(Q)$(RM) $(DESTDIR)$(LIBDIR)/liblz4.a
- $(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/lz4.h
- $(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/lz4hc.h
- $(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/lz4frame.h
- $(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/lz4frame_static.h
+ $(Q)$(RM) $(DESTDIR)$(pkgconfigdir)/liblz4.pc
+ $(Q)$(RM) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT)
+ $(Q)$(RM) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT_MAJOR)
+ $(Q)$(RM) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT_VER)
+ $(Q)$(RM) $(DESTDIR)$(libdir)/liblz4.a
+ $(Q)$(RM) $(DESTDIR)$(includedir)/lz4.h
+ $(Q)$(RM) $(DESTDIR)$(includedir)/lz4hc.h
+ $(Q)$(RM) $(DESTDIR)$(includedir)/lz4frame.h
+ $(Q)$(RM) $(DESTDIR)$(includedir)/lz4frame_static.h
@echo lz4 libraries successfully uninstalled
endif
diff --git a/lib/lz4.c b/lib/lz4.c
index 3860c51..e51a3e0 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -683,13 +683,12 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
/* Init conditions */
if (outputLimited == fillOutput && maxOutputSize < 1) return 0; /* Impossible to store anything */
if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */
+ if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
if (tableType==byPtr) assert(dictDirective==noDict); /* only supported use case with byPtr */
assert(acceleration >= 1);
lowLimit = (const BYTE*)source - (dictDirective == withPrefix64k ? dictSize : 0);
- if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
-
/* Update context state */
if (dictDirective == usingDictCtx) {
/* Subsequent linked blocks can't use the dictionary. */
@@ -767,6 +766,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
} else if (dictDirective==usingExtDict) {
if (matchIndex < startIndex) {
DEBUGLOG(7, "extDict candidate: matchIndex=%5u < startIndex=%5u", matchIndex, startIndex);
+ assert(startIndex - matchIndex >= MINMATCH);
match = dictBase + matchIndex;
lowLimit = dictionary;
} else {
@@ -989,6 +989,7 @@ _last_literals:
if (outputLimited == fillOutput) {
*inputConsumed = (int) (((const char*)ip)-source);
}
+ DEBUGLOG(5, "LZ4_compress_generic: compressed %i bytes into %i bytes", inputSize, (int)(((char*)op) - dest));
return (int)(((char*)op) - dest);
}
@@ -1255,12 +1256,23 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch
{
const tableType_t tableType = byU32;
LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse;
- const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
+ const BYTE* dictEnd = streamPtr->dictionary + streamPtr->dictSize;
+
+ DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i)", inputSize);
if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */
LZ4_renormDictT(streamPtr, inputSize); /* avoid index overflow */
if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
+ /* invalidate tiny dictionaries */
+ if ( (streamPtr->dictSize-1 < 4) /* intentional underflow */
+ && (dictEnd != (const BYTE*)source) ) {
+ DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary);
+ streamPtr->dictSize = 0;
+ streamPtr->dictionary = (const BYTE*)source;
+ dictEnd = (const BYTE*)source;
+ }
+
/* Check overlapping input/dictionary space */
{ const BYTE* sourceEnd = (const BYTE*) source + inputSize;
if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) {
@@ -1402,6 +1414,8 @@ LZ4_FORCE_INLINE int LZ4_decompress_generic(
const BYTE* const shortiend = iend - (endOnInput ? 14 : 8) /*maxLL*/ - 2 /*offset*/;
const BYTE* const shortoend = oend - (endOnInput ? 14 : 8) /*maxLL*/ - 18 /*maxML*/;
+ DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i)", srcSize);
+
/* Special cases */
if ((partialDecoding) && (oexit > oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => just decode everything */
if ((endOnInput) && (unlikely(outputSize==0))) return ((srcSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */
diff --git a/lib/lz4.h b/lib/lz4.h
index 410f480..7d13122 100644
--- a/lib/lz4.h
+++ b/lib/lz4.h
@@ -380,6 +380,15 @@ LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int or
#ifdef LZ4_STATIC_LINKING_ONLY
/*! LZ4_resetStream_fast() :
+ * Use this, like LZ4_resetStream(), to prepare a context for a new chain of
+ * calls to a streaming API (e.g., LZ4_compress_fast_continue()).
+ *
+ * Note:
+ * Using this in advance of a non- streaming-compression function is redundant,
+ * and potentially bad for performance, since they all perform their own custom
+ * reset internally.
+ *
+ * Differences from LZ4_resetStream():
* When an LZ4_stream_t is known to be in a internally coherent state,
* it can often be prepared for a new compression with almost no work, only
* sometimes falling back to the full, expensive reset that is always required
@@ -389,13 +398,17 @@ LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int or
* LZ4_streams are guaranteed to be in a valid state when:
* - returned from LZ4_createStream()
* - reset by LZ4_resetStream()
- * - memset(stream, 0, sizeof(LZ4_stream_t))
+ * - memset(stream, 0, sizeof(LZ4_stream_t)), though this is discouraged
* - the stream was in a valid state and was reset by LZ4_resetStream_fast()
* - the stream was in a valid state and was then used in any compression call
* that returned success
* - the stream was in an indeterminate state and was used in a compression
- * call that fully reset the state (LZ4_compress_fast_extState()) and that
- * returned success
+ * call that fully reset the state (e.g., LZ4_compress_fast_extState()) and
+ * that returned success
+ *
+ * When a stream isn't known to be in a valid state, it is not safe to pass to
+ * any fastReset or streaming function. It must first be cleansed by the full
+ * LZ4_resetStream().
*/
LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
@@ -406,8 +419,9 @@ LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
* to call if the state buffer is known to be correctly initialized already
* (see above comment on LZ4_resetStream_fast() for a definition of "correctly
* initialized"). From a high level, the difference is that this function
- * initializes the provided state with a call to LZ4_resetStream_fast() while
- * LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
+ * initializes the provided state with a call to something like
+ * LZ4_resetStream_fast() while LZ4_compress_fast_extState() starts with a
+ * call to LZ4_resetStream().
*/
LZ4LIB_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
diff --git a/lib/lz4frame.c b/lib/lz4frame.c
index f57db24..e1d0b1d 100644
--- a/lib/lz4frame.c
+++ b/lib/lz4frame.c
@@ -472,6 +472,7 @@ LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize)
{
const char* dictStart = (const char*)dictBuffer;
LZ4F_CDict* cdict = (LZ4F_CDict*) ALLOC(sizeof(*cdict));
+ DEBUGLOG(4, "LZ4F_createCDict");
if (!cdict) return NULL;
if (dictSize > 64 KB) {
dictStart += dictSize - 64 KB;
@@ -551,9 +552,18 @@ LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_comp
*/
static void LZ4F_initStream(void* ctx,
const LZ4F_CDict* cdict,
- int level) {
+ int level,
+ LZ4F_blockMode_t blockMode) {
if (level < LZ4HC_CLEVEL_MIN) {
- LZ4_resetStream_fast((LZ4_stream_t *)ctx);
+ if (cdict != NULL || blockMode == LZ4F_blockLinked) {
+ /* In these cases, we will call LZ4_compress_fast_continue(),
+ * which needs an already reset context. Otherwise, we'll call a
+ * one-shot API. The non-continued APIs internally perform their own
+ * resets at the beginning of their calls, where they know what
+ * tableType they need the context to be in. So in that case this
+ * would be misguided / wasted work. */
+ LZ4_resetStream_fast((LZ4_stream_t*)ctx);
+ }
LZ4_attach_dictionary((LZ4_stream_t *)ctx, cdict ? cdict->fastCtx : NULL);
} else {
LZ4_resetStreamHC_fast((LZ4_streamHC_t*)ctx, level);
@@ -631,7 +641,7 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
cctxPtr->cdict = cdict;
if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) {
/* frame init only for blockLinked : blockIndependent will be init at each block */
- LZ4F_initStream(cctxPtr->lz4CtxPtr, cdict, cctxPtr->prefs.compressionLevel);
+ LZ4F_initStream(cctxPtr->lz4CtxPtr, cdict, cctxPtr->prefs.compressionLevel, LZ4F_blockLinked);
}
if (preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN) {
LZ4_favorDecompressionSpeed((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, (int)preferencesPtr->favorDecSpeed);
@@ -729,7 +739,7 @@ static size_t LZ4F_makeBlock(void* dst, const void* src, size_t srcSize,
static int LZ4F_compressBlock(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
{
int const acceleration = (level < -1) ? -level : 1;
- LZ4F_initStream(ctx, cdict, level);
+ LZ4F_initStream(ctx, cdict, level, LZ4F_blockIndependent);
if (cdict) {
return LZ4_compress_fast_continue((LZ4_stream_t*)ctx, src, dst, srcSize, dstCapacity, acceleration);
} else {
@@ -746,7 +756,7 @@ static int LZ4F_compressBlock_continue(void* ctx, const char* src, char* dst, in
static int LZ4F_compressBlockHC(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
{
- LZ4F_initStream(ctx, cdict, level);
+ LZ4F_initStream(ctx, cdict, level, LZ4F_blockIndependent);
if (cdict) {
return LZ4_compress_HC_continue((LZ4_streamHC_t*)ctx, src, dst, srcSize, dstCapacity);
}
@@ -799,6 +809,7 @@ size_t LZ4F_compressUpdate(LZ4F_cctx* cctxPtr,
LZ4F_lastBlockStatus lastBlockCompressed = notDone;
compressFunc_t const compress = LZ4F_selectCompression(cctxPtr->prefs.frameInfo.blockMode, cctxPtr->prefs.compressionLevel);
+ DEBUGLOG(4, "LZ4F_compressUpdate (srcSize=%zu)", srcSize);
if (cctxPtr->cStage != 1) return err0r(LZ4F_ERROR_GENERIC);
if (dstCapacity < LZ4F_compressBound_internal(srcSize, &(cctxPtr->prefs), cctxPtr->tmpInSize))