From d872b64f522fdb9b25efc3cb13003c791ffa2c6e Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 2 Nov 2016 12:52:20 +0100 Subject: [PATCH 001/185] added UTIL_setModificationTime, UTIL_getModificationTime --- programs/util.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/programs/util.h b/programs/util.h index aabebe961..1bbe2a736 100644 --- a/programs/util.h +++ b/programs/util.h @@ -46,8 +46,10 @@ extern "C" { ******************************************/ #include /* features.h with _POSIX_C_SOURCE, malloc */ #include /* fprintf */ -#include /* stat */ +#include /* stat, utime */ #include /* stat */ +#include /* utime */ +#include /* time */ #include "mem.h" /* U32, U64 */ @@ -142,6 +144,36 @@ UTIL_STATIC void UTIL_waitForNextTick(UTIL_time_t ticksPerSecond) /*-**************************************** * File functions ******************************************/ +UTIL_STATIC int UTIL_setModificationTime(const char *filename, time_t modtime) +{ + struct utimbuf timebuf; + + if (modtime == 0) return -1; + + timebuf.actime = time(NULL); + timebuf.modtime = modtime; + + /* On success, zero is returned. On error, -1 is returned, and errno is set appropriately. */ + return utime(filename, &timebuf); +} + + +UTIL_STATIC time_t UTIL_getModificationTime(const char* infilename) +{ + int r; +#if defined(_MSC_VER) + struct _stat64 statbuf; + r = _stat64(infilename, &statbuf); + if (r || !(statbuf.st_mode & S_IFREG)) return 0; /* No good... */ +#else + struct stat statbuf; + r = stat(infilename, &statbuf); + if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */ +#endif + return statbuf.st_mtime; +} + + UTIL_STATIC U64 UTIL_getFileSize(const char* infilename) { int r; From a42794df6170f45499f32896b12795dd4403521d Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 2 Nov 2016 13:08:39 +0100 Subject: [PATCH 002/185] preserve file modification time --- programs/fileio.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index c4c308e03..44b41221c 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -388,14 +388,17 @@ static int FIO_compressFilename_dstFile(cRess_t ress, const char* dstFileName, const char* srcFileName) { int result; + time_t modtime = 0; ress.dstFile = FIO_openDstFile(dstFileName); if (ress.dstFile==NULL) return 1; /* could not open dstFileName */ + if (strcmp (srcFileName, stdinmark)) modtime = UTIL_getModificationTime(srcFileName); result = FIO_compressFilename_srcFile(ress, dstFileName, srcFileName); if (fclose(ress.dstFile)) { DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; } /* error closing dstFile */ if (result!=0) { if (remove(dstFileName)) EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno)); } /* remove operation artefact */ + else if (strcmp (dstFileName, stdoutmark)) UTIL_setModificationTime(dstFileName, modtime); return result; } @@ -720,16 +723,21 @@ static int FIO_decompressDstFile(dRess_t ress, const char* dstFileName, const char* srcFileName) { int result; + time_t modtime = 0; + ress.dstFile = FIO_openDstFile(dstFileName); if (ress.dstFile==0) return 1; + if (strcmp (srcFileName, stdinmark)) modtime = UTIL_getModificationTime(srcFileName); result = FIO_decompressSrcFile(ress, srcFileName); - if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName); + if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName); + if ( (result != 0) && strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null (#316) */ && remove(dstFileName) ) result=1; /* don't do anything special if remove() fails */ + else if (strcmp (dstFileName, stdoutmark)) UTIL_setModificationTime(dstFileName, modtime); return result; } From fcf22e3473aa763d5abd19344041cb3960daa2aa Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 2 Nov 2016 14:08:07 +0100 Subject: [PATCH 003/185] set permissions, access and modification times --- programs/fileio.c | 14 ++++++++------ programs/util.h | 42 +++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 44b41221c..3d31a07c6 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -388,17 +388,18 @@ static int FIO_compressFilename_dstFile(cRess_t ress, const char* dstFileName, const char* srcFileName) { int result; - time_t modtime = 0; + stat_t statbuf; + int stat_result = 0; ress.dstFile = FIO_openDstFile(dstFileName); if (ress.dstFile==NULL) return 1; /* could not open dstFileName */ - if (strcmp (srcFileName, stdinmark)) modtime = UTIL_getModificationTime(srcFileName); + if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1; result = FIO_compressFilename_srcFile(ress, dstFileName, srcFileName); if (fclose(ress.dstFile)) { DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; } /* error closing dstFile */ if (result!=0) { if (remove(dstFileName)) EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno)); } /* remove operation artefact */ - else if (strcmp (dstFileName, stdoutmark)) UTIL_setModificationTime(dstFileName, modtime); + else if (strcmp (dstFileName, stdoutmark) && stat_result) UTIL_setFileStat(dstFileName, &statbuf); return result; } @@ -723,12 +724,13 @@ static int FIO_decompressDstFile(dRess_t ress, const char* dstFileName, const char* srcFileName) { int result; - time_t modtime = 0; + stat_t statbuf; + int stat_result = 0; ress.dstFile = FIO_openDstFile(dstFileName); if (ress.dstFile==0) return 1; - if (strcmp (srcFileName, stdinmark)) modtime = UTIL_getModificationTime(srcFileName); + if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1; result = FIO_decompressSrcFile(ress, srcFileName); if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName); @@ -737,7 +739,7 @@ static int FIO_decompressDstFile(dRess_t ress, && strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null (#316) */ && remove(dstFileName) ) result=1; /* don't do anything special if remove() fails */ - else if (strcmp (dstFileName, stdoutmark)) UTIL_setModificationTime(dstFileName, modtime); + else if (strcmp (dstFileName, stdoutmark) && stat_result) UTIL_setFileStat(dstFileName, &statbuf); return result; } diff --git a/programs/util.h b/programs/util.h index 1bbe2a736..7d503d9df 100644 --- a/programs/util.h +++ b/programs/util.h @@ -50,6 +50,7 @@ extern "C" { #include /* stat */ #include /* utime */ #include /* time */ +#include /* chown, stat */ #include "mem.h" /* U32, U64 */ @@ -144,33 +145,44 @@ UTIL_STATIC void UTIL_waitForNextTick(UTIL_time_t ticksPerSecond) /*-**************************************** * File functions ******************************************/ -UTIL_STATIC int UTIL_setModificationTime(const char *filename, time_t modtime) -{ - struct utimbuf timebuf; +#if defined(_MSC_VER) + typedef struct _stat64 stat_t; +#else + typedef struct stat stat_t; +#endif - if (modtime == 0) return -1; + +UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf) +{ + int res = 0; + struct utimbuf timebuf; + +#if !defined(_WIN32) + res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */ +#endif + + res += chmod(filename, statbuf->st_mode & 07777); /* Copy file permissions */ timebuf.actime = time(NULL); - timebuf.modtime = modtime; + timebuf.modtime = statbuf->st_mtime; + res += utime(filename, &timebuf); /* set access and modification times */ - /* On success, zero is returned. On error, -1 is returned, and errno is set appropriately. */ - return utime(filename, &timebuf); + errno = 0; + return -res; /* number of errors is returned */ } -UTIL_STATIC time_t UTIL_getModificationTime(const char* infilename) +UTIL_STATIC int UTIL_getFileStat(const char* infilename, stat_t *statbuf) { int r; #if defined(_MSC_VER) - struct _stat64 statbuf; - r = _stat64(infilename, &statbuf); - if (r || !(statbuf.st_mode & S_IFREG)) return 0; /* No good... */ + r = _stat64(infilename, statbuf); + if (r || !(statbuf->st_mode & S_IFREG)) return 0; /* No good... */ #else - struct stat statbuf; - r = stat(infilename, &statbuf); - if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */ + r = stat(infilename, statbuf); + if (r || !S_ISREG(statbuf->st_mode)) return 0; /* No good... */ #endif - return statbuf.st_mtime; + return 1; } From 0a5a5fb7fd7b23994dc916c7b290aa9b8422c06f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 2 Nov 2016 13:57:55 -0700 Subject: [PATCH 004/185] Fix #418 : printing selected segments in zdict debug mode can segfault with certain pathological patterns --- lib/dictBuilder/zdict.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index b3f20b12b..ea50b54ad 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -898,12 +898,14 @@ size_t ZDICT_trainFromBuffer_unsafe( U32 const nb = MIN(25, dictList[0].pos); U32 const dictContentSize = ZDICT_dictSize(dictList); U32 u; - DISPLAYLEVEL(3, "\n %u segments found, of total size %u \n", dictList[0].pos, dictContentSize); - DISPLAYLEVEL(3, "list %u best segments \n", nb); - for (u=1; u<=nb; u++) { - U32 pos = dictList[u].pos; - U32 length = dictList[u].length; - U32 printedLength = MIN(40, length); + DISPLAYLEVEL(3, "\n %u segments found, of total size %u \n", dictList[0].pos-1, dictContentSize); + DISPLAYLEVEL(3, "list %u best segments \n", nb-1); + for (u=1; u samplesBuffSize) || ((pos + length) > samplesBuffSize)) + return ERROR(GENERIC); /* should never happen */ DISPLAYLEVEL(3, "%3u:%3u bytes at pos %8u, savings %7u bytes |", u, length, pos, dictList[u].savings); ZDICT_printHex((const char*)samplesBuffer+pos, printedLength); From f3f13211ae6a016c696f68a2f915c318ec2cf7c3 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 2 Nov 2016 17:02:45 -0700 Subject: [PATCH 005/185] Fix #419 : no warning when setting custom LDFLAGS --- Makefile | 14 ++++++++++---- lib/Makefile | 25 +++++++++++++++++-------- programs/Makefile | 19 +++++++------------ 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 20ae31e44..96f5a9ad8 100644 --- a/Makefile +++ b/Makefile @@ -20,28 +20,32 @@ else VOID = /dev/null endif -.PHONY: default all zlibwrapper zstd clean install uninstall travis-install test clangtest gpptest armtest usan asan uasan - -default: libzstd zstd +.PHONY: default +default: lib zstd +.PHONY: all all: $(MAKE) -C $(ZSTDDIR) $@ $(MAKE) -C $(PRGDIR) $@ zstd32 $(MAKE) -C $(TESTDIR) $@ all32 -libzstd: +.PHONY: lib +lib: @$(MAKE) -C $(ZSTDDIR) zstd: @$(MAKE) -C $(PRGDIR) cp $(PRGDIR)/zstd . +.PHONY: zlibwrapper zlibwrapper: $(MAKE) -C $(ZWRAPDIR) test +.PHONY: test test: $(MAKE) -C $(TESTDIR) $@ +.PHONY: clean clean: @$(MAKE) -C $(ZSTDDIR) $@ > $(VOID) @$(MAKE) -C $(PRGDIR) $@ > $(VOID) @@ -56,6 +60,8 @@ clean: #------------------------------------------------------------------------------ ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD DragonFly NetBSD)) HOST_OS = POSIX +.PHONY: install uninstall travis-install clangtest gpptest armtest usan asan uasan + install: @$(MAKE) -C $(ZSTDDIR) $@ @$(MAKE) -C $(PRGDIR) $@ diff --git a/lib/Makefile b/lib/Makefile index 1117b491c..31219e380 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -27,7 +27,7 @@ CPPFLAGS= -I. -I./common CFLAGS ?= -O3 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) $(MOREFLAGS) ZSTD_FILES := common/*.c compress/*.c decompress/*.c dictBuilder/*.c @@ -39,7 +39,6 @@ ZSTD_FILES+= legacy/*.c CPPFLAGS += -I./legacy -DZSTD_LEGACY_SUPPORT=1 endif - # OS X linker doesn't support -soname, and use different extension # see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html ifeq ($(shell uname), Darwin) @@ -54,23 +53,33 @@ else SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) endif +LIBZSTD = libzstd.$(SHARED_EXT_VER) + .PHONY: default all clean install uninstall -default: clean libzstd +default: lib -all: clean libzstd +all: lib -libzstd: $(ZSTD_FILES) +libzstd.a: ARFLAGS = rcs +libzstd.a: $(ZSTD_FILES) @echo compiling static library @$(CC) $(FLAGS) -c $^ - @$(AR) rcs $@.a *.o + @$(AR) $(ARFLAGS) $@ *.o + +$(LIBZSTD): LDFLAGS += -shared -fPIC +$(LIBZSTD): $(ZSTD_FILES) @echo compiling dynamic library $(LIBVER) - @$(CC) $(FLAGS) -shared $^ -fPIC $(SONAME_FLAGS) -o $@.$(SHARED_EXT_VER) + @$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ @echo creating versioned links @ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT_MAJOR) @ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT) +libzstd : $(LIBZSTD) + +lib: libzstd.a libzstd + clean: @rm -f core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc @rm -f decompress/*.o @@ -89,7 +98,7 @@ libzstd.pc: libzstd.pc.in -e 's|@VERSION@|$(VERSION)|' \ $< >$@ -install: libzstd libzstd.pc +install: libzstd.a libzstd libzstd.pc @install -d -m 755 $(DESTDIR)$(LIBDIR)/pkgconfig/ $(DESTDIR)$(INCLUDEDIR)/ @install -m 755 libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_VER) @cp -a libzstd.$(SHARED_EXT_MAJOR) $(DESTDIR)$(LIBDIR) diff --git a/programs/Makefile b/programs/Makefile index f5e625f06..c4ead25f6 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -41,7 +41,6 @@ ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/huf_decompress.c ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c ZSTDDECOMP_O = $(ZSTDDIR)/decompress/zstd_decompress.o -ZSTDDECOMP32_O = $(ZSTDDIR)/decompress/zstd_decompress32.o ifeq ($(ZSTD_LEGACY_SUPPORT), 0) CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0 @@ -76,30 +75,27 @@ default: zstd all: zstd -$(ZSTDDECOMP_O): CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $(ZSTDDECOMP_O): CFLAGS += $(ALIGN_LOOP) -$(ZSTDDECOMP_O): $(ZSTDDIR)/decompress/zstd_decompress.c +zstd : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) zstd : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \ zstdcli.c fileio.c bench.c datagen.c dibio.c ifneq (,$(filter Windows%,$(OS))) windres\generate_res.bat endif - $(CC) $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ $(RES_FILE) -o $@$(EXT) + $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) -$(ZSTDDECOMP32_O): $(ZSTDDIR)/decompress/zstd_decompress.c - $(CC) -m32 $(ALIGN_LOOP) $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -c -o $@ - -zstd32 : $(ZSTDDECOMP32_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \ +zstd32 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) +zstd32 : $(ZSTDDIR)/decompress/zstd_decompress.c $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \ zstdcli.c fileio.c bench.c datagen.c dibio.c ifneq (,$(filter Windows%,$(OS))) windres\generate_res.bat endif - $(CC) -m32 $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ $(RES32_FILE) -o $@$(EXT) + $(CC) -m32 $(FLAGS) $^ $(RES32_FILE) -o $@$(EXT) -zstd_nolegacy : clean_decomp_o +zstd-nolegacy : clean_decomp_o $(MAKE) zstd ZSTD_LEGACY_SUPPORT=0 zstd-pgo : MOREFLAGS = -fprofile-generate @@ -111,7 +107,7 @@ zstd-pgo : clean zstd ./zstd -b7i2 $(PROFILE_WITH) ./zstd -b5 $(PROFILE_WITH) $(RM) zstd - $(RM) $(ZSTDDIR)/decompress/zstd_decompress.o + $(RM) $(ZSTDDECOMP_O) $(MAKE) zstd MOREFLAGS=-fprofile-use zstd-frugal: $(ZSTDDECOMP_O) $(ZSTD_FILES) zstdcli.c fileio.c @@ -142,7 +138,6 @@ clean: clean_decomp_o: @$(RM) $(ZSTDDECOMP_O) - @$(RM) $(ZSTDDECOMP32_O) #---------------------------------------------------------------------------------- From 179b19776fb8909dd5e719126a457e80234ed9a2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 2 Nov 2016 17:30:49 -0700 Subject: [PATCH 006/185] fileio.c does no longer need ZSTD_LEGACY_SUPPORT, and does no longer depend on zstd_legacy.h Added : ZSTD_isFrame() in experimental section --- lib/decompress/zstd_decompress.c | 19 ++++++++++++++- lib/zstd.h | 7 ++++++ programs/fileio.c | 42 +++++++++----------------------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 4c47930cd..b6a3865ca 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -193,7 +193,24 @@ static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) * Decompression section ***************************************************************/ -/* See compression format details in : doc/zstd_compression_format.md */ +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +unsigned ZSTD_isFrame(const void* buffer, size_t size) +{ + if (size < 4) return 0; + { U32 const magic = MEM_readLE32(buffer); + if (magic == ZSTD_MAGICNUMBER) return 1; + if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(buffer, size)) return 1; +#endif + return 0; +} + /** ZSTD_frameHeaderSize() : * srcSize must be >= ZSTD_frameHeaderSize_prefix. diff --git a/lib/zstd.h b/lib/zstd.h index ea5caf148..c18fd0d31 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -433,6 +433,13 @@ ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, /*--- Advanced decompression functions ---*/ +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size); + /*! ZSTD_estimateDCtxSize() : * Gives the potential amount of memory allocated to create a ZSTD_DCtx */ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); diff --git a/programs/fileio.c b/programs/fileio.c index c4c308e03..fe321015e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -8,16 +8,6 @@ */ -/* ************************************* - * Tuning options - ***************************************/ -#ifndef ZSTD_LEGACY_SUPPORT -/* LEGACY_SUPPORT : - * decompressor can decode older formats (starting from zstd 0.1+) */ -# define ZSTD_LEGACY_SUPPORT 1 -#endif - - /* ************************************* * Compiler Options ***************************************/ @@ -29,6 +19,7 @@ # define _POSIX_SOURCE 1 /* disable %llu warnings with MinGW on Windows */ #endif + /*-************************************* * Includes ***************************************/ @@ -44,10 +35,6 @@ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */ #include "zstd.h" -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) -# include "zstd_legacy.h" /* ZSTD_isLegacy */ -#endif - /*-************************************* * OS-specific Includes @@ -634,7 +621,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress, @return : 0 (no error) */ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_t bufferSize) { - size_t const blockSize = MIN (64 KB, bufferSize); + size_t const blockSize = MIN(64 KB, bufferSize); size_t readFromInput = 1; unsigned storedSkips = 0; @@ -682,21 +669,16 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - { U32 const magic = MEM_readLE32(ress.srcBuffer); - if (((magic & 0xFFFFFFF0U) != ZSTD_MAGIC_SKIPPABLE_START) & (magic != ZSTD_MAGICNUMBER) -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - & (!ZSTD_isLegacy(ress.srcBuffer, toRead)) -#endif - ) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } } + if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { + if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ + return result; + } else { + DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); + fclose(srcFile); + return 1; + } } filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead); } From d82efd8a708633affccfbf8571cb5fd712bc8636 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 2 Nov 2016 16:47:53 -0700 Subject: [PATCH 007/185] ZSTD_compress_usingDict() when dict gets loaded Specify that when `dict == NULL || dictSize < 8` no dictionary gets loaded. Also add some periods. --- doc/zstd_compression_format.md | 3 ++- doc/zstd_manual.html | 24 +++++++++++++----------- lib/compress/zstd_compress.c | 1 + lib/zstd.h | 24 +++++++++++++----------- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/doc/zstd_compression_format.md b/doc/zstd_compression_format.md index b58b43f5a..b48b39104 100644 --- a/doc/zstd_compression_format.md +++ b/doc/zstd_compression_format.md @@ -1135,7 +1135,8 @@ When `Repeated_Offset2` is used, it's swapped with `Repeated_Offset1`. Dictionary format ----------------- -`zstd` is compatible with "raw content" dictionaries, free of any format restriction. +`zstd` is compatible with "raw content" dictionaries, free of any format restriction, +except that they must be at least 8 bytes. But dictionaries created by `zstd --train` follow a format, described here. __Pre-requisites__ : a dictionary has a size, diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 2470a4555..33ea13c32 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -58,7 +58,7 @@

Compresses `src` content as a single zstd compressed frame into already allocated `dst`. Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. @return : compressed size written into `dst` (<= `dstCapacity), - or an error code if it fails (which can be tested using ZSTD_isError()) + or an error code if it fails (which can be tested using ZSTD_isError()).


size_t ZSTD_decompress( void* dst, size_t dstCapacity,
@@ -67,7 +67,7 @@
     `dstCapacity` is an upper bound of originalSize.
     If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
     @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
-              or an errorCode if it fails (which can be tested using ZSTD_isError()) 
+              or an errorCode if it fails (which can be tested using ZSTD_isError()). 
 


unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
@@ -96,7 +96,7 @@ const char* ZSTD_getErrorName(size_t code);     /*!< provides readable strin
 

Explicit memory management


 
 
size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
-

Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()) +

Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()).


Decompression context

typedef struct ZSTD_DCtx_s ZSTD_DCtx;
@@ -104,7 +104,7 @@ ZSTD_DCtx* ZSTD_createDCtx(void);
 size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
 

size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-

Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()) +

Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()).


Simple dictionary API


@@ -115,7 +115,8 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
                                      const void* dict,size_t dictSize,
                                            int compressionLevel);
 

Compression using a predefined Dictionary (see dictBuilder/zdict.h). - Note : This function load the dictionary, resulting in significant startup delay. + Note : This function loads the dictionary, resulting in significant startup delay. + Note : When `dict == NULL || dictSize < 8` no dictionary is used.


size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
@@ -124,7 +125,8 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
                                        const void* dict,size_t dictSize);
 

Decompression using a predefined Dictionary (see dictBuilder/zdict.h). Dictionary must be identical to the one used during compression. - Note : This function load the dictionary, resulting in significant startup delay + Note : This function loads the dictionary, resulting in significant startup delay. + Note : When `dict == NULL || dictSize < 8` no dictionary is used.


Fast dictionary API


@@ -133,11 +135,11 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
 

When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only. - `dict` can be released after ZSTD_CDict creation + `dict` can be released after ZSTD_CDict creation.


size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);
-

Function frees memory allocated by ZSTD_createCDict() +

Function frees memory allocated by ZSTD_createCDict().


size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
@@ -146,12 +148,12 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
                                       const ZSTD_CDict* cdict);
 

Compression using a digested Dictionary. Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. - Note that compression level is decided during dictionary creation + Note that compression level is decided during dictionary creation.


ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize);
 

Create a digested dictionary, ready to start decompression operation without startup delay. - `dict` can be released after creation + `dict` can be released after creation.


size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);
@@ -162,7 +164,7 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
                                               void* dst, size_t dstCapacity,
                                         const void* src, size_t srcSize,
                                         const ZSTD_DDict* ddict);
-

Decompression using a digested Dictionary +

Decompression using a digested Dictionary. Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times.


diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e7f7d9911..32059f84d 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2695,6 +2695,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel) { + if (!dict) dictSize = 0; ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize); params.fParams.contentSizeFlag = 1; return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params); diff --git a/lib/zstd.h b/lib/zstd.h index ea5caf148..d57c2092b 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -72,7 +72,7 @@ ZSTDLIB_API unsigned ZSTD_versionNumber (void); /**< returns version number of Compresses `src` content as a single zstd compressed frame into already allocated `dst`. Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. @return : compressed size written into `dst` (<= `dstCapacity), - or an error code if it fails (which can be tested using ZSTD_isError()) */ + or an error code if it fails (which can be tested using ZSTD_isError()). */ ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel); @@ -82,7 +82,7 @@ ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, `dstCapacity` is an upper bound of originalSize. If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), - or an errorCode if it fails (which can be tested using ZSTD_isError()) */ + or an errorCode if it fails (which can be tested using ZSTD_isError()). */ ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity, const void* src, size_t compressedSize); @@ -125,7 +125,7 @@ ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void); ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /*! ZSTD_compressCCtx() : - Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()) */ + Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */ ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel); /*= Decompression context */ @@ -134,7 +134,7 @@ ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void); ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /*! ZSTD_decompressDCtx() : -* Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()) */ +* Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). */ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); @@ -143,7 +143,8 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapa ***************************/ /*! ZSTD_compress_usingDict() : * Compression using a predefined Dictionary (see dictBuilder/zdict.h). -* Note : This function load the dictionary, resulting in significant startup delay. */ +* Note : This function loads the dictionary, resulting in significant startup delay. +* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, @@ -153,7 +154,8 @@ ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, /*! ZSTD_decompress_usingDict() : * Decompression using a predefined Dictionary (see dictBuilder/zdict.h). * Dictionary must be identical to the one used during compression. -* Note : This function load the dictionary, resulting in significant startup delay */ +* Note : This function loads the dictionary, resulting in significant startup delay. +* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, @@ -169,17 +171,17 @@ typedef struct ZSTD_CDict_s ZSTD_CDict; * When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. * ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. * ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only. -* `dict` can be released after ZSTD_CDict creation */ +* `dict` can be released after ZSTD_CDict creation. */ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel); /*! ZSTD_freeCDict() : -* Function frees memory allocated by ZSTD_createCDict() */ +* Function frees memory allocated by ZSTD_createCDict(). */ ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict); /*! ZSTD_compress_usingCDict() : * Compression using a digested Dictionary. * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. -* Note that compression level is decided during dictionary creation */ +* Note that compression level is decided during dictionary creation. */ ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, @@ -190,7 +192,7 @@ typedef struct ZSTD_DDict_s ZSTD_DDict; /*! ZSTD_createDDict() : * Create a digested dictionary, ready to start decompression operation without startup delay. -* `dict` can be released after creation */ +* `dict` can be released after creation. */ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize); /*! ZSTD_freeDDict() : @@ -198,7 +200,7 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize); ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict); /*! ZSTD_decompress_usingDDict() : -* Decompression using a digested Dictionary +* Decompression using a digested Dictionary. * Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */ ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, From 7347869fb684feedaecfa898a99bee2053c26c29 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 2 Nov 2016 22:28:37 -0700 Subject: [PATCH 008/185] fixed make install --- lib/Makefile | 7 ++++--- programs/Makefile | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 31219e380..04ebe26bd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,7 +26,8 @@ INCLUDEDIR=$(PREFIX)/include CPPFLAGS= -I. -I./common CFLAGS ?= -O3 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ - -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef + -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \ + -Wpointer-arith FLAGS = $(CPPFLAGS) $(CFLAGS) $(MOREFLAGS) @@ -73,8 +74,8 @@ $(LIBZSTD): $(ZSTD_FILES) @echo compiling dynamic library $(LIBVER) @$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ @echo creating versioned links - @ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT_MAJOR) - @ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT) + @ln -sf $@.$(SHARED_EXT_VER) libzstd.$(SHARED_EXT_MAJOR) + @ln -sf $@.$(SHARED_EXT_VER) libzstd.$(SHARED_EXT) libzstd : $(LIBZSTD) diff --git a/programs/Makefile b/programs/Makefile index c4ead25f6..64aeb668d 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -30,7 +30,8 @@ endif CPPFLAGS= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/dictBuilder CFLAGS ?= -O3 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ - -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef + -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \ + -Wpointer-arith CFLAGS += $(MOREFLAGS) FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) From 6c111fa3dae339cd5061f270b9f233886527f18b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 3 Nov 2016 00:44:02 -0700 Subject: [PATCH 009/185] fix zlibWrapper make test --- zlibWrapper/.gitignore | 8 +++++++- zlibWrapper/Makefile | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/zlibWrapper/.gitignore b/zlibWrapper/.gitignore index 1fd8f416c..c3376bad8 100644 --- a/zlibWrapper/.gitignore +++ b/zlibWrapper/.gitignore @@ -3,10 +3,16 @@ _* example.* example_zstd.* fitblk.* -fitblk_zstd.* +fitblk_zstd.* zwrapbench.* foo.gz +example +example_zstd +fitblk +fitblk_zstd +zwrapbench + # Misc files *.bat *.zip diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 0e4ca9e6f..b36a90d61 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -16,7 +16,7 @@ EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md CC ?= gcc -CFLAGS ?= -O3 +CFLAGS ?= -O3 CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -std=gnu99 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef LDFLAGS = $(LOC) @@ -50,7 +50,7 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench .c.o: $(CC) $(CFLAGS) -c -o $@ $< - + example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) @@ -75,10 +75,10 @@ $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwra $(CC) $(CFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZSTDLIBDIR)/libzstd.a: - $(MAKE) -C $(ZSTDLIBDIR) all + $(MAKE) -C $(ZSTDLIBDIR) libzstd.a $(ZSTDLIBDIR)/libzstd.so: - $(MAKE) -C $(ZSTDLIBDIR) all + $(MAKE) -C $(ZSTDLIBDIR) libzstd clean: -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench From 861cd06ded86323155f554812b2391b50410239c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 3 Nov 2016 01:11:56 -0700 Subject: [PATCH 010/185] fix test-zstd-nolegacy --- .travis.yml | 2 +- tests/Makefile | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3be4575d8..9396c98da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ matrix: packages: - gcc-4.8 - g++-4.8 - env: PLATFORM="Ubuntu 12.04 container" CMD="make zlibwrapper && make clean && make -C tests test-zstd_nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest && make -C contrib/pzstd all && make -C contrib/pzstd check && make -C contrib/pzstd clean" + env: PLATFORM="Ubuntu 12.04 container" CMD="make zlibwrapper && make clean && make -C tests test-zstd-nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest && make -C contrib/pzstd all && make -C contrib/pzstd check && make -C contrib/pzstd clean" - os: linux sudo: false env: PLATFORM="Ubuntu 12.04 container" CMD="make usan" diff --git a/tests/Makefile b/tests/Makefile index ecff18290..80e11d6b0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -76,7 +76,7 @@ zstd: zstd32: $(MAKE) -C $(PRGDIR) $@ -zstd_nolegacy: +zstd-nolegacy: $(MAKE) -C $(PRGDIR) $@ fullbench : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c @@ -181,8 +181,8 @@ test-zstd: zstd zstd-playTests test-zstd32: ZSTD = $(PRGDIR)/zstd32 test-zstd32: zstd32 zstd-playTests -test-zstd_nolegacy: ZSTD = $(PRGDIR)/zstd -test-zstd_nolegacy: zstd_nolegacy zstd-playTests +test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd +test-zstd-nolegacy: zstd-nolegacy zstd-playTests test-fullbench: fullbench datagen ./fullbench -i1 From b40884f43d316f7e2acef20cd7d53b752e31c8e8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 3 Nov 2016 09:54:53 +0100 Subject: [PATCH 011/185] preserve file modification time for Visual C++ --- programs/util.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/programs/util.h b/programs/util.h index 7d503d9df..fd07c348a 100644 --- a/programs/util.h +++ b/programs/util.h @@ -48,9 +48,15 @@ extern "C" { #include /* fprintf */ #include /* stat, utime */ #include /* stat */ -#include /* utime */ +#if defined(_MSC_VER) + #include /* utime */ + #include /* _chmod */ +#else + #include /* chown, stat */ + #include /* utime */ +#endif #include /* time */ -#include /* chown, stat */ +#include #include "mem.h" /* U32, U64 */ @@ -146,7 +152,8 @@ UTIL_STATIC void UTIL_waitForNextTick(UTIL_time_t ticksPerSecond) * File functions ******************************************/ #if defined(_MSC_VER) - typedef struct _stat64 stat_t; + #define chmod _chmod + typedef struct _stat64 stat_t; #else typedef struct stat stat_t; #endif @@ -157,16 +164,16 @@ UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf) int res = 0; struct utimbuf timebuf; + timebuf.actime = time(NULL); + timebuf.modtime = statbuf->st_mtime; + res += utime(filename, &timebuf); /* set access and modification times */ + #if !defined(_WIN32) res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */ #endif res += chmod(filename, statbuf->st_mode & 07777); /* Copy file permissions */ - timebuf.actime = time(NULL); - timebuf.modtime = statbuf->st_mtime; - res += utime(filename, &timebuf); /* set access and modification times */ - errno = 0; return -res; /* number of errors is returned */ } @@ -322,7 +329,6 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_ ((defined(__unix__) || defined(__unix) || defined(__midipix__)) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) /* snprintf, opendir */ # define UTIL_HAS_CREATEFILELIST # include /* opendir, readdir */ -# include UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char** bufEnd) { From 26306fcacff61770cb03df720251abb364529c6f Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 3 Nov 2016 11:38:01 +0100 Subject: [PATCH 012/185] BMK_SetNbIterations renamed to BMK_SetNbSeconds --- programs/bench.c | 18 +++++++++--------- programs/bench.h | 2 +- programs/fileio.c | 4 ++-- programs/zstdcli.c | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/programs/bench.c b/programs/bench.c index c477b2682..7b6e25206 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -33,7 +33,7 @@ # define ZSTD_GIT_COMMIT_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_GIT_COMMIT) #endif -#define NBLOOPS 3 +#define NBSECONDS 3 #define TIMELOOP_MICROSEC 1*1000000ULL /* 1 second */ #define ACTIVEPERIOD_MICROSEC 70*1000000ULL /* 70 seconds */ #define COOLPERIOD_SEC 10 @@ -82,7 +82,7 @@ static clock_t g_time = 0; /* ************************************* * Benchmark Parameters ***************************************/ -static U32 g_nbIterations = NBLOOPS; +static U32 g_nbSeconds = NBSECONDS; static size_t g_blockSize = 0; int g_additionalParam = 0; @@ -90,10 +90,10 @@ void BMK_setNotificationLevel(unsigned level) { g_displayLevel=level; } void BMK_setAdditionalParam(int additionalParam) { g_additionalParam=additionalParam; } -void BMK_SetNbIterations(unsigned nbLoops) +void BMK_SetNbSeconds(unsigned nbSeconds) { - g_nbIterations = nbLoops; - DISPLAYLEVEL(3, "- test >= %u seconds per compression / decompression -\n", g_nbIterations); + g_nbSeconds = nbSeconds; + DISPLAYLEVEL(3, "- test >= %u seconds per compression / decompression -\n", g_nbSeconds); } void BMK_SetBlockSize(size_t blockSize) @@ -175,7 +175,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, { U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL); U64 const crcOrig = XXH64(srcBuffer, srcSize, 0); UTIL_time_t coolTime; - U64 const maxTime = (g_nbIterations * TIMELOOP_MICROSEC) + 100; + U64 const maxTime = (g_nbSeconds * TIMELOOP_MICROSEC) + 100; U64 totalCTime=0, totalDTime=0; U32 cCompleted=0, dCompleted=0; # define NB_MARKS 4 @@ -188,7 +188,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, DISPLAYLEVEL(2, "\r%79s\r", ""); while (!cCompleted | !dCompleted) { UTIL_time_t clockStart; - U64 clockLoop = g_nbIterations ? TIMELOOP_MICROSEC : 1; + U64 clockLoop = g_nbSeconds ? TIMELOOP_MICROSEC : 1; /* overheat protection */ if (UTIL_clockSpanMicro(coolTime, ticksPerSecond) > ACTIVEPERIOD_MICROSEC) { @@ -306,7 +306,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, break; } } /* CRC Checking */ #endif - } /* for (testNb = 1; testNb <= (g_nbIterations + !g_nbIterations); testNb++) */ + } /* for (testNb = 1; testNb <= (g_nbSeconds + !g_nbSeconds); testNb++) */ if (g_displayLevel == 1) { double cSpeed = (double)srcSize / fastestC; @@ -361,7 +361,7 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, SET_HIGH_PRIORITY; if (g_displayLevel == 1 && !g_additionalParam) - DISPLAY("bench %s %s: input %u bytes, %u iterations, %u KB blocks\n", ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10)); + DISPLAY("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n", ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, (U32)benchedSize, g_nbSeconds, (U32)(g_blockSize>>10)); if (cLevelLast < cLevel) cLevelLast = cLevel; diff --git a/programs/bench.h b/programs/bench.h index 7350fd43d..1e3e3812b 100644 --- a/programs/bench.h +++ b/programs/bench.h @@ -17,7 +17,7 @@ int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, const char* dictFileName, int cLevel, int cLevelLast); /* Set Parameters */ -void BMK_SetNbIterations(unsigned nbLoops); +void BMK_SetNbSeconds(unsigned nbLoops); void BMK_SetBlockSize(size_t blockSize); void BMK_setAdditionalParam(int additionalParam); void BMK_setNotificationLevel(unsigned level); diff --git a/programs/fileio.c b/programs/fileio.c index 3d31a07c6..4759a786f 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -443,7 +443,7 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile SET_BINARY_MODE(stdout); for (u=0; u /* errno */ #include "fileio.h" #ifndef ZSTD_NOBENCH -# include "bench.h" /* BMK_benchFiles, BMK_SetNbIterations */ +# include "bench.h" /* BMK_benchFiles, BMK_SetNbSeconds */ #endif #ifndef ZSTD_NODICT # include "dibio.h" @@ -383,7 +383,7 @@ int main(int argCount, const char* argv[]) argument++; { U32 const iters = readU32FromChar(&argument); BMK_setNotificationLevel(displayLevel); - BMK_SetNbIterations(iters); + BMK_SetNbSeconds(iters); } break; From 3a415594b156d5d76e03f033aea1e67793513b1c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 3 Nov 2016 12:59:20 +0100 Subject: [PATCH 013/185] fixed MinGW compilation --- Makefile | 12 +++++++----- lib/Makefile | 2 ++ programs/Makefile | 2 -- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 96f5a9ad8..a57587341 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,12 @@ ZWRAPDIR = zlibWrapper TESTDIR = tests # Define nul output -ifneq (,$(filter Windows%,$(OS))) -VOID = nul -else VOID = /dev/null + +ifneq (,$(filter Windows%,$(OS))) +EXT =.exe +else +EXT = endif .PHONY: default @@ -35,7 +37,7 @@ lib: zstd: @$(MAKE) -C $(PRGDIR) - cp $(PRGDIR)/zstd . + cp $(PRGDIR)/zstd$(EXT) . .PHONY: zlibwrapper zlibwrapper: @@ -51,7 +53,7 @@ clean: @$(MAKE) -C $(PRGDIR) $@ > $(VOID) @$(MAKE) -C $(TESTDIR) $@ > $(VOID) @$(MAKE) -C $(ZWRAPDIR) $@ > $(VOID) - @$(RM) zstd + @$(RM) zstd$(EXT) @echo Cleaning completed diff --git a/lib/Makefile b/lib/Makefile index 04ebe26bd..cfc3028eb 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -73,9 +73,11 @@ $(LIBZSTD): LDFLAGS += -shared -fPIC $(LIBZSTD): $(ZSTD_FILES) @echo compiling dynamic library $(LIBVER) @$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ +ifeq (,$(filter Windows%,$(OS))) @echo creating versioned links @ln -sf $@.$(SHARED_EXT_VER) libzstd.$(SHARED_EXT_MAJOR) @ln -sf $@.$(SHARED_EXT_VER) libzstd.$(SHARED_EXT) +endif libzstd : $(LIBZSTD) diff --git a/programs/Makefile b/programs/Makefile index 64aeb668d..b72cebdb1 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -56,7 +56,6 @@ endif # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) EXT =.exe -VOID = nul RES64_FILE = windres\zstd64.res RES32_FILE = windres\zstd32.res ifneq (,$(filter x86_64%,$(shell $(CC) -dumpmachine))) @@ -66,7 +65,6 @@ else endif else EXT = -VOID = /dev/null endif From 9adf7bfd8ae433b19aeea50ff0986e329412d3a0 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 3 Nov 2016 15:38:13 +0100 Subject: [PATCH 014/185] fixed MinGW compilation (2) --- tests/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 80e11d6b0..26ae60078 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -50,12 +50,11 @@ ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) EXT =.exe -VOID = nul else EXT = -VOID = /dev/null endif +VOID = /dev/null ZBUFFTEST = -T2mn FUZZERTEST= -T5mn ZSTDRTTEST= --test-large-data From 4bafb5aa9712d5645a6faefc211dd47aa3818118 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 3 Nov 2016 11:32:45 -0700 Subject: [PATCH 015/185] The static library was moved to libzstd.a --- contrib/pzstd/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/pzstd/Makefile b/contrib/pzstd/Makefile index 2de50416c..ad0e55673 100644 --- a/contrib/pzstd/Makefile +++ b/contrib/pzstd/Makefile @@ -170,8 +170,7 @@ roundtrip: test/RoundTripTest$(EXT) # Use the static library that zstd builds for simplicity and # so we get the compiler options correct $(ZSTDDIR)/libzstd.a: $(ZSTD_FILES) - $(MAKE) -C $(ZSTDDIR) libzstd CFLAGS="$(ALL_CFLAGS)" LDFLAGS="$(ALL_LDFLAGS)" - + CFLAGS="$(ALL_CFLAGS)" LDFLAGS="$(ALL_LDFLAGS)" $(MAKE) -C $(ZSTDDIR) libzstd.a # Rules to build the tests test/RoundTripTest$(EXT): test/RoundTripTest.o $(PROGDIR)/datagen.o Options.o \ From c8a9ac312b11c4c48cc97ff9f21854a60770b5b5 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 3 Nov 2016 12:32:48 -0700 Subject: [PATCH 016/185] Fix dynamic libzstd symlinks --- lib/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 04ebe26bd..a7df44f2f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -74,8 +74,8 @@ $(LIBZSTD): $(ZSTD_FILES) @echo compiling dynamic library $(LIBVER) @$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ @echo creating versioned links - @ln -sf $@.$(SHARED_EXT_VER) libzstd.$(SHARED_EXT_MAJOR) - @ln -sf $@.$(SHARED_EXT_VER) libzstd.$(SHARED_EXT) + @ln -sf $(LIBZSTD) libzstd.$(SHARED_EXT_MAJOR) + @ln -sf $(LIBZSTD) libzstd.$(SHARED_EXT) libzstd : $(LIBZSTD) From 407a11f63e5bb68841ee7b7182bd558ea9472bf8 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 3 Nov 2016 15:52:01 -0700 Subject: [PATCH 017/185] fixed Visual compatibility --- .coverity.yml | 5 ----- lib/compress/zstd_compress.c | 3 +-- programs/zstdcli.c | 6 +++--- 3 files changed, 4 insertions(+), 10 deletions(-) delete mode 100644 .coverity.yml diff --git a/.coverity.yml b/.coverity.yml deleted file mode 100644 index 907f09601..000000000 --- a/.coverity.yml +++ /dev/null @@ -1,5 +0,0 @@ -configurationVersion: 1 - -filters: - # third-party embedded - - filePath: lib/dictBuilder/divsufsort.c diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 32059f84d..d152d10dc 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2695,8 +2695,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel) { - if (!dict) dictSize = 0; - ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize); + ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dict ? dictSize : 0); params.fParams.contentSizeFlag = 1; return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params); } diff --git a/programs/zstdcli.c b/programs/zstdcli.c index db4d6acc6..38eef2b56 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -238,9 +238,9 @@ int main(int argCount, const char* argv[]) /* init */ (void)recursive; (void)cLevelLast; /* not used when ZSTD_NOBENCH set */ - (void)dictCLevel; (void)dictSelect; (void)dictID; /* not used when ZSTD_NODICT set */ - (void)cLevel; /* not used when ZSTD_NOCOMPRESS set */ - (void)ultra; (void)memLimit; /* not used when ZSTD_NODECOMPRESS set */ + (void)dictCLevel; (void)dictSelect; (void)dictID; (void)maxDictSize; /* not used when ZSTD_NODICT set */ + (void)ultra; (void)cLevel; /* not used when ZSTD_NOCOMPRESS set */ + (void)memLimit; /* not used when ZSTD_NODECOMPRESS set */ if (filenameTable==NULL) { DISPLAY("zstd: %s \n", strerror(errno)); exit(1); } filenameTable[0] = stdinmark; displayOut = stderr; From d007eb5f9fec9fad15e3d22c71de19339e0c2b9b Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 4 Nov 2016 11:20:58 +0100 Subject: [PATCH 018/185] fixed clang warnings in zlibWrapper --- zlibWrapper/Makefile | 1 + zlibWrapper/examples/zwrapbench.c | 14 +++++++------- zlibWrapper/zstd_zlibwrapper.c | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index b36a90d61..25857c94a 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -19,6 +19,7 @@ CC ?= gcc CFLAGS ?= -O3 CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -std=gnu99 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef +CFLAGS += $(MOREFLAGS) LDFLAGS = $(LOC) RM = rm -f diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index d16fcfdd5..5ef7e5253 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -130,7 +130,7 @@ void BMK_SetBlockSize(size_t blockSize) **********************************************************/ typedef struct { - const char* srcPtr; + char* srcPtr; size_t srcSize; char* cPtr; size_t cRoom; @@ -145,7 +145,7 @@ typedef enum { BMK_ZSTD, BMK_ZSTD_STREAM, BMK_ZLIB, BMK_ZWRAP_ZLIB, BMK_ZWRAP_ZS #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) -static int BMK_benchMem(const void* srcBuffer, size_t srcSize, +static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* displayName, int cLevel, const size_t* fileSizes, U32 nbFiles, const void* dictBuffer, size_t dictBufferSize, BMK_compressor compressor) @@ -171,7 +171,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, UTIL_initTimer(&ticksPerSecond); /* Init blockTable data */ - { const char* srcPtr = (const char*)srcBuffer; + { char* srcPtr = (char*)srcBuffer; char* cPtr = (char*)compressedBuffer; char* resPtr = (char*)resultBuffer; U32 fileNb; @@ -307,7 +307,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (ret != Z_OK) EXM_THROW(1, "deflateSetDictionary failure"); if (ZWRAP_isUsingZSTDcompression()) useSetDict = 0; /* zstd doesn't require deflateSetDictionary after ZWRAP_deflateReset_keepDict */ } - def.next_in = (const void*) blockTable[blockNb].srcPtr; + def.next_in = (void*) blockTable[blockNb].srcPtr; def.avail_in = blockTable[blockNb].srcSize; def.total_in = 0; def.next_out = (void*) blockTable[blockNb].cPtr; @@ -338,7 +338,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, ret = deflateSetDictionary(&def, dictBuffer, dictBufferSize); if (ret != Z_OK) EXM_THROW(1, "deflateSetDictionary failure"); } - def.next_in = (const void*) blockTable[blockNb].srcPtr; + def.next_in = (void*) blockTable[blockNb].srcPtr; def.avail_in = blockTable[blockNb].srcSize; def.total_in = 0; def.next_out = (void*) blockTable[blockNb].cPtr; @@ -443,7 +443,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, else ret = inflateReset(&inf); if (ret != Z_OK) EXM_THROW(1, "inflateReset failure"); - inf.next_in = (const void*) blockTable[blockNb].cPtr; + inf.next_in = (void*) blockTable[blockNb].cPtr; inf.avail_in = blockTable[blockNb].cSize; inf.total_in = 0; inf.next_out = (void*) blockTable[blockNb].resPtr; @@ -475,7 +475,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, inf.opaque = Z_NULL; ret = inflateInit(&inf); if (ret != Z_OK) EXM_THROW(1, "inflateInit failure"); - inf.next_in = (const void*) blockTable[blockNb].cPtr; + inf.next_in = (void*) blockTable[blockNb].cPtr; inf.avail_in = blockTable[blockNb].cSize; inf.total_in = 0; inf.next_out = (void*) blockTable[blockNb].resPtr; diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 31e784a80..c653d7493 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -85,7 +85,7 @@ typedef struct { ZSTD_outBuffer outBuffer; ZWRAP_state_t comprState; unsigned long long pledgedSrcSize; -} ZWRAP_CCtx; +} ZWRAP_CCtx __attribute__ ((aligned (4))); size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc) @@ -404,7 +404,7 @@ typedef struct { int windowBits; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ -} ZWRAP_DCtx; +} ZWRAP_DCtx __attribute__ ((aligned (4))); int ZWRAP_isUsingZSTDdecompression(z_streamp strm) From d0815583d9b5c648fa005ac961a688035e768f5a Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 4 Nov 2016 11:37:27 +0100 Subject: [PATCH 019/185] Changed stdinmark and stdoutmark --- programs/fileio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.h b/programs/fileio.h index 60a7e0de8..a740f35ef 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -18,8 +18,8 @@ extern "C" { /* ************************************* * Special i/o constants **************************************/ -#define stdinmark "stdin" -#define stdoutmark "stdout" +#define stdinmark "/*stdin*\\" +#define stdoutmark "/*stdout*\\" #ifdef _WIN32 # define nulmark "nul" #else From 0694ae2c83fd02bcf488ebb0bbe5bc96dbbc099a Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 4 Nov 2016 16:05:28 +0100 Subject: [PATCH 020/185] typedef ZWRAP_CCtx internal_state --- zlibWrapper/zstd_zlibwrapper.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index c653d7493..4098abd80 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -10,7 +10,8 @@ #include /* vsprintf */ #include /* va_list, for z_gzprintf */ -#include +#define NO_DUMMY_DECL +#include /* without #define Z_PREFIX */ #include "zstd_zlibwrapper.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_MAGICNUMBER */ #include "zstd.h" @@ -85,7 +86,10 @@ typedef struct { ZSTD_outBuffer outBuffer; ZWRAP_state_t comprState; unsigned long long pledgedSrcSize; -} ZWRAP_CCtx __attribute__ ((aligned (4))); +} ZWRAP_CCtx; + +typedef ZWRAP_CCtx internal_state; + size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc) @@ -404,7 +408,7 @@ typedef struct { int windowBits; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ -} ZWRAP_DCtx __attribute__ ((aligned (4))); +} ZWRAP_DCtx; int ZWRAP_isUsingZSTDdecompression(z_streamp strm) From 7e06e6ab1999f78e1ebaaf41f2abca612af89749 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 4 Nov 2016 16:50:39 +0100 Subject: [PATCH 021/185] updated Makefile for zlibWrapper --- zlibWrapper/Makefile | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 25857c94a..48dc1a5b6 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -1,7 +1,7 @@ # Makefile for example of using zstd wrapper for zlib # # make - compiles examples -# make LOC=-DZWRAP_USE_ZSTD=1 - compiles examples with zstd compression turned on +# make MOREFLAGS=-DZWRAP_USE_ZSTD=1 - compiles examples with zstd compression turned on # make test - runs examples @@ -15,13 +15,10 @@ ZLIBWRAPPER_PATH = . EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md -CC ?= gcc -CFLAGS ?= -O3 -CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -std=gnu99 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -CFLAGS += $(MOREFLAGS) -LDFLAGS = $(LOC) -RM = rm -f + +CPPFLAGS = -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) +CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wstrict-aliasing=1 -Wundef all: clean fitblk example zwrapbench @@ -49,8 +46,8 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench $(VALGRIND) ./zwrapbench -qb3B1K $(TEST_FILE) $(VALGRIND) ./zwrapbench -rqb1e5 ../lib ../programs ../tests -.c.o: - $(CC) $(CFLAGS) -c -o $@ $< +#.c.o: +# $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) @@ -70,10 +67,10 @@ zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(EXAMPLE_PATH)/zwrapbench.o: $(EXAMPLE_PATH)/zwrapbench.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h - $(CC) $(CFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c + $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h - $(CC) $(CFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c + $(CC) $(CFLAGS) $(CPPFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZSTDLIBDIR)/libzstd.a: $(MAKE) -C $(ZSTDLIBDIR) libzstd.a From 6cecb35f982935f097d3684ea5b34dd671d9fb14 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 4 Nov 2016 17:49:17 +0100 Subject: [PATCH 022/185] zwrapbench uses z_const --- zlibWrapper/examples/zwrapbench.c | 14 +++++++------- zlibWrapper/zstd_zlibwrapper.c | 1 + zlibWrapper/zstd_zlibwrapper.h | 6 ++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index 5ef7e5253..ebf76e48f 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -130,7 +130,7 @@ void BMK_SetBlockSize(size_t blockSize) **********************************************************/ typedef struct { - char* srcPtr; + z_const char* srcPtr; size_t srcSize; char* cPtr; size_t cRoom; @@ -145,7 +145,7 @@ typedef enum { BMK_ZSTD, BMK_ZSTD_STREAM, BMK_ZLIB, BMK_ZWRAP_ZLIB, BMK_ZWRAP_ZS #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) -static int BMK_benchMem(void* srcBuffer, size_t srcSize, +static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize, const char* displayName, int cLevel, const size_t* fileSizes, U32 nbFiles, const void* dictBuffer, size_t dictBufferSize, BMK_compressor compressor) @@ -171,7 +171,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, UTIL_initTimer(&ticksPerSecond); /* Init blockTable data */ - { char* srcPtr = (char*)srcBuffer; + { z_const char* srcPtr = (z_const char*)srcBuffer; char* cPtr = (char*)compressedBuffer; char* resPtr = (char*)resultBuffer; U32 fileNb; @@ -307,7 +307,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, if (ret != Z_OK) EXM_THROW(1, "deflateSetDictionary failure"); if (ZWRAP_isUsingZSTDcompression()) useSetDict = 0; /* zstd doesn't require deflateSetDictionary after ZWRAP_deflateReset_keepDict */ } - def.next_in = (void*) blockTable[blockNb].srcPtr; + def.next_in = (z_const void*) blockTable[blockNb].srcPtr; def.avail_in = blockTable[blockNb].srcSize; def.total_in = 0; def.next_out = (void*) blockTable[blockNb].cPtr; @@ -338,7 +338,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, ret = deflateSetDictionary(&def, dictBuffer, dictBufferSize); if (ret != Z_OK) EXM_THROW(1, "deflateSetDictionary failure"); } - def.next_in = (void*) blockTable[blockNb].srcPtr; + def.next_in = (z_const void*) blockTable[blockNb].srcPtr; def.avail_in = blockTable[blockNb].srcSize; def.total_in = 0; def.next_out = (void*) blockTable[blockNb].cPtr; @@ -443,7 +443,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, else ret = inflateReset(&inf); if (ret != Z_OK) EXM_THROW(1, "inflateReset failure"); - inf.next_in = (void*) blockTable[blockNb].cPtr; + inf.next_in = (z_const void*) blockTable[blockNb].cPtr; inf.avail_in = blockTable[blockNb].cSize; inf.total_in = 0; inf.next_out = (void*) blockTable[blockNb].resPtr; @@ -475,7 +475,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, inf.opaque = Z_NULL; ret = inflateInit(&inf); if (ret != Z_OK) EXM_THROW(1, "inflateInit failure"); - inf.next_in = (void*) blockTable[blockNb].cPtr; + inf.next_in = (z_const void*) blockTable[blockNb].cPtr; inf.avail_in = blockTable[blockNb].cSize; inf.total_in = 0; inf.next_out = (void*) blockTable[blockNb].resPtr; diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 4098abd80..326fea260 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -11,6 +11,7 @@ #include /* vsprintf */ #include /* va_list, for z_gzprintf */ #define NO_DUMMY_DECL +#define ZLIB_CONST #include /* without #define Z_PREFIX */ #include "zstd_zlibwrapper.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_MAGICNUMBER */ diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 873413907..45d15bac0 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -15,16 +15,14 @@ extern "C" { #endif +#define ZLIB_CONST #define Z_PREFIX #include #if !defined(z_const) -#if ZLIB_VERNUM >= 0x1260 - #define z_const const -#else #define z_const #endif -#endif + /* returns a string with version of zstd library */ const char * zstdVersion(void); From dc904ad17bf608db483f6187bdbcd5ed43fea88d Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 4 Nov 2016 16:18:59 -0700 Subject: [PATCH 023/185] Fix bug in zstd v0.{5, 6} dictionary decompression Introduced by bb68062c590dbd46905907dd2a63a658040a79d4. --- lib/legacy/zstd_v05.c | 2 +- lib/legacy/zstd_v06.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index 201bf3c6b..f63a97fd7 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -2996,7 +2996,7 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx, lhSize=3; litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2); litCSize = ((istart[1] & 3) << 8) + istart[2]; - if (litCSize + litSize > srcSize) return ERROR(corruption_detected); + if (litCSize + lhSize > srcSize) return ERROR(corruption_detected); errorCode = HUFv05_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4); if (HUFv05_isError(errorCode)) return ERROR(corruption_detected); diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index b6fde3aa6..88be49438 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -3186,7 +3186,7 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx, lhSize=3; litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2); litCSize = ((istart[1] & 3) << 8) + istart[2]; - if (litCSize + litSize > srcSize) return ERROR(corruption_detected); + if (litCSize + lhSize > srcSize) return ERROR(corruption_detected); { size_t const errorCode = HUFv06_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4); if (HUFv06_isError(errorCode)) return ERROR(corruption_detected); From fd3be6bc97e33d0db6cbe93984ac71dd3de3327c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 7 Nov 2016 14:35:41 -0800 Subject: [PATCH 024/185] bump version number to 1.1.2 --- lib/zstd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zstd.h b/lib/zstd.h index 6d3cf56c6..eb2451cd3 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -55,7 +55,7 @@ ZSTDLIB_API unsigned ZSTD_versionNumber (void); /**< returns version number of #define ZSTD_VERSION_MAJOR 1 #define ZSTD_VERSION_MINOR 1 -#define ZSTD_VERSION_RELEASE 1 +#define ZSTD_VERSION_RELEASE 2 #define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE #define ZSTD_QUOTE(str) #str From 0018ca28dcd1091d6f2903395b2f5e19d8ef6572 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 7 Nov 2016 14:41:21 -0800 Subject: [PATCH 025/185] zstd cli : displays total decoded size, even when a stream consists of multiple frames --- NEWS | 3 +++ programs/fileio.c | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 7710a07aa..df23a2914 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +v1.1.2 +New : cli : status displays total amount decoded when stream/file consists of multiple appended frames (like pzstd) + v1.1.1 New : command -M#, --memory=, --memlimit=, --memlimit-decompress= to limit allowed memory consumption New : doc/zstd_manual.html, by Przemyslaw Skibinski diff --git a/programs/fileio.c b/programs/fileio.c index a17a78f30..16a74a0f6 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -580,7 +580,8 @@ static void FIO_fwriteSparseEnd(FILE* file, unsigned storedSkips) @return : size of decoded frame */ unsigned long long FIO_decompressFrame(dRess_t ress, - FILE* foutput, FILE* finput, size_t alreadyLoaded) + FILE* foutput, FILE* finput, size_t alreadyLoaded, + U64 alreadyDecoded) { U64 frameSize = 0; size_t readSize; @@ -604,7 +605,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress, /* Write block */ storedSkips = FIO_fwriteSparse(foutput, ress.dstBuffer, outBuff.pos, storedSkips); frameSize += outBuff.pos; - DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) ); + DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)((alreadyDecoded+frameSize)>>20) ); if (readSizeHint == 0) break; /* end of frame */ if (inBuff.size != inBuff.pos) EXM_THROW(37, "Decoding error : should consume entire input"); @@ -683,7 +684,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) fclose(srcFile); return 1; } } - filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead); + filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); } /* Final Status */ @@ -715,7 +716,7 @@ static int FIO_decompressDstFile(dRess_t ress, if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1; result = FIO_decompressSrcFile(ress, srcFileName); - if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName); + if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName); if ( (result != 0) && strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null (#316) */ From d41380ea5d12be87e3397577ebd13d0a4063d29d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 7 Nov 2016 14:55:12 -0800 Subject: [PATCH 026/185] make zstd a phony target at root --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a57587341..856b1a07b 100644 --- a/Makefile +++ b/Makefile @@ -35,8 +35,9 @@ all: lib: @$(MAKE) -C $(ZSTDDIR) +.PHONY: zstd zstd: - @$(MAKE) -C $(PRGDIR) + @$(MAKE) -C $(PRGDIR) $@ cp $(PRGDIR)/zstd$(EXT) . .PHONY: zlibwrapper From 8e4901eccd14d70a7e2bd31054a2c12c234430cf Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 8 Nov 2016 15:45:39 -0800 Subject: [PATCH 027/185] removed zbuff.h from include installation --- lib/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index a928c60c0..02eefc3f7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -75,8 +75,8 @@ $(LIBZSTD): $(ZSTD_FILES) @$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ ifeq (,$(filter Windows%,$(OS))) @echo creating versioned links - @ln -sf $(LIBZSTD) libzstd.$(SHARED_EXT_MAJOR) - @ln -sf $(LIBZSTD) libzstd.$(SHARED_EXT) + @ln -sf $@ libzstd.$(SHARED_EXT_MAJOR) + @ln -sf $@ libzstd.$(SHARED_EXT) endif libzstd : $(LIBZSTD) @@ -110,7 +110,6 @@ install: libzstd.a libzstd libzstd.pc @install -m 644 libzstd.a $(DESTDIR)$(LIBDIR)/libzstd.a @install -m 644 zstd.h $(DESTDIR)$(INCLUDEDIR)/zstd.h @install -m 644 common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h - @install -m 644 common/zbuff.h $(DESTDIR)$(INCLUDEDIR)/zbuff.h # Deprecated streaming functions @install -m 644 dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)/zdict.h @echo zstd static and shared library installed From cdff19c4b33186315902c4e2991c182a0a21f579 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 11 Nov 2016 17:26:54 -0800 Subject: [PATCH 028/185] minor comment change --- programs/fileio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 16a74a0f6..71593ac90 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -124,7 +124,7 @@ void FIO_setMemLimit(unsigned memLimit) { g_memLimit = memLimit; } DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \ DISPLAYLEVEL(1, "Error %i : ", error); \ DISPLAYLEVEL(1, __VA_ARGS__); \ - DISPLAYLEVEL(1, "\n"); \ + DISPLAYLEVEL(1, " \n"); \ exit(error); \ } @@ -132,6 +132,9 @@ void FIO_setMemLimit(unsigned memLimit) { g_memLimit = memLimit; } /*-************************************* * Functions ***************************************/ +/** FIO_openSrcFile() : + * condition : `dstFileName` must be non-NULL. + * @result : FILE* to `dstFileName`, or NULL if it fails */ static FILE* FIO_openSrcFile(const char* srcFileName) { FILE* f; From e579ab5faa4de2812f97174c2e17d3889a3c58ea Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 12:57:05 +0100 Subject: [PATCH 029/185] introduced QEMU_SYS --- Makefile | 10 +++++++--- tests/Makefile | 22 +++++++++++----------- tests/playTests.sh | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 856b1a07b..7d36ab2aa 100644 --- a/Makefile +++ b/Makefile @@ -93,15 +93,19 @@ clangtest: clean armtest: clean $(MAKE) -C $(TESTDIR) datagen # use native, faster - $(MAKE) -C $(TESTDIR) test CC=arm-linux-gnueabi-gcc ZSTDRTTEST= MOREFLAGS="-Werror -static" + $(MAKE) -C $(TESTDIR) test CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static" + +aarch64test: + $(MAKE) -C $(TESTDIR) datagen # use native, faster + $(MAKE) -C $(TESTDIR) test CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static" ppctest: clean $(MAKE) -C $(TESTDIR) datagen # use native, faster - $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static" + $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static" ppc64test: clean $(MAKE) -C $(TESTDIR) datagen # use native, faster - $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc ZSTDRTTEST= MOREFLAGS="-m64 -static" + $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static" usan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined" diff --git a/tests/Makefile b/tests/Makefile index 26ae60078..63177f5ef 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -166,7 +166,7 @@ endif #------------------------------------------------------------------------ ifneq (,$(filter $(HOST_OS),MSYS POSIX)) zstd-playTests: datagen - ZSTD=$(ZSTD) ./playTests.sh $(ZSTDRTTEST) + ZSTD="$(QEMU_SYS) $(ZSTD)" ./playTests.sh $(ZSTDRTTEST) test: test-zstd test-fullbench test-fuzzer test-zbuff test-zstream @@ -184,29 +184,29 @@ test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd test-zstd-nolegacy: zstd-nolegacy zstd-playTests test-fullbench: fullbench datagen - ./fullbench -i1 - ./fullbench -i1 -P0 + $(QEMU_SYS) ./fullbench -i1 + $(QEMU_SYS) ./fullbench -i1 -P0 test-fullbench32: fullbench32 datagen - ./fullbench32 -i1 - ./fullbench32 -i1 -P0 + $(QEMU_SYS) ./fullbench32 -i1 + $(QEMU_SYS) ./fullbench32 -i1 -P0 test-fuzzer: fuzzer - ./fuzzer $(FUZZERTEST) + $(QEMU_SYS) ./fuzzer $(FUZZERTEST) test-fuzzer32: fuzzer32 - ./fuzzer32 $(FUZZERTEST) + $(QEMU_SYS) ./fuzzer32 $(FUZZERTEST) test-zbuff: zbufftest - ./zbufftest $(ZBUFFTEST) + $(QEMU_SYS) ./zbufftest $(ZBUFFTEST) test-zbuff32: zbufftest32 - ./zbufftest32 $(ZBUFFTEST) + $(QEMU_SYS) ./zbufftest32 $(ZBUFFTEST) test-zstream: zstreamtest - ./zstreamtest $(ZBUFFTEST) + $(QEMU_SYS) ./zstreamtest $(ZBUFFTEST) test-zstream32: zstreamtest32 - ./zstreamtest32 $(ZBUFFTEST) + $(QEMU_SYS) ./zstreamtest32 $(ZBUFFTEST) endif diff --git a/tests/playTests.sh b/tests/playTests.sh index ad70538a3..1bc835f0c 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -36,7 +36,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then MD5SUM="md5 -r" fi -$ECHO "\nStarting playTests.sh isWindows=$isWindows" +$ECHO "\nStarting playTests.sh isWindows=$isWindows ZSTD='$ZSTD'" [ -n "$ZSTD" ] || die "ZSTD variable must be defined!" From 0b48a5964708c629f2b0e9cd0b70f047ba4f0c87 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 13:07:45 +0100 Subject: [PATCH 030/185] .travis.yml: added aarch64test and ppc64test --- .travis.yml | 102 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 40 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9396c98da..134b88e29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,19 @@ language: c -compiler: gcc matrix: fast_finish: true include: # OS X Mavericks - - os: osx - env: PLATFORM="OS X Mavericks" CMD="make gnu90test && make clean && make test && make clean && make travis-install" + - env: Ubu=OS_X_Mavericks Cmd="make gnu90test && make clean && make test && make clean && make travis-install" + os: osx + + # Container-based Ubuntu 12.04 LTS Server Edition 64 bit (doesn't support 32-bit includes) - - os: linux + - env: Ubu=12.04cont Cmd="make test && make clean && make travis-install" + os: linux sudo: false - env: PLATFORM="Ubuntu 12.04 container" CMD="make test && make clean && make travis-install" - - os: linux + + - env: Ubu=12.04cont Cmd="make zlibwrapper && make clean && make -C tests test-zstd-nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest && make -C contrib/pzstd all && make -C contrib/pzstd check && make -C contrib/pzstd clean" + os: linux sudo: false language: cpp install: @@ -22,32 +25,24 @@ matrix: packages: - gcc-4.8 - g++-4.8 - env: PLATFORM="Ubuntu 12.04 container" CMD="make zlibwrapper && make clean && make -C tests test-zstd-nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest && make -C contrib/pzstd all && make -C contrib/pzstd check && make -C contrib/pzstd clean" - - os: linux + + - env: Ubu=12.04cont Cmd="make usan" + os: linux sudo: false - env: PLATFORM="Ubuntu 12.04 container" CMD="make usan" - - os: linux + + - env: Ubu=12.04cont Cmd="make asan" + os: linux sudo: false - env: PLATFORM="Ubuntu 12.04 container" CMD="make asan" + + # Standard Ubuntu 12.04 LTS Server Edition 64 bit - - os: linux + - env: Ubu=12.04 Cmd="make -C programs zstd-small && make -C programs zstd-decompress && make -C programs zstd-compress && make -C programs clean && make -C tests versionsTest" + os: linux sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make armtest" - addons: - apt: - packages: - - gcc-arm-linux-gnueabi - - libc6-dev-armel-cross - - linux-libc-dev-armel-cross - - binfmt-support - - qemu - - qemu-user-static - - os: linux + + - env: Ubu=12.04 Cmd="make asan32" + os: linux sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make -C programs zstd-small && make -C programs zstd-decompress && make -C programs zstd-compress && make -C programs clean && make -C tests versionsTest" - - os: linux - sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make asan32" addons: apt: sources: @@ -55,13 +50,14 @@ matrix: packages: - libc6-dev-i386 - gcc-multilib - - os: linux + + - env: Ubu=12.04 Cmd='cd contrib/pzstd && make googletest && make tsan && make check && make clean && make asan && make check && make clean && cd ../..' + os: linux sudo: required install: - export CXX="g++-6" CC="gcc-6" - export LDFLAGS="-fuse-ld=gold" - export TESTFLAGS='--gtest_filter=-*ExtremelyLarge*' - env: PLATFORM="Ubuntu 12.04" CMD='cd contrib/pzstd && make googletest && make tsan && make check && make clean && make asan && make check && make clean && cd ../..' addons: apt: sources: @@ -69,21 +65,47 @@ matrix: packages: - gcc-6 - g++-6 + + # Ubuntu 14.04 LTS Server Edition 64 bit - - os: linux + - env: Ubu=14.04 Cmd="make armtest && make clean && make aarch64test" + dist: trusty + sudo: required + addons: + apt: + packages: + - qemu-system-arm + - qemu-user-static + - gcc-arm-linux-gnueabi + - libc6-dev-armel-cross + - gcc-aarch64-linux-gnu + - libc6-dev-arm64-cross + + - env: Ubu=14.04 Cmd='make ppctest && make clean && make ppc64test' + dist: trusty + sudo: required + addons: + apt: + packages: + - qemu-system-ppc + - qemu-user-static + - gcc-powerpc-linux-gnu + + - env: Ubu=14.04 Cmd='make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make -C tests valgrindTest' + os: linux dist: trusty sudo: required - env: PLATFORM="Ubuntu 14.04" CMD='make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make -C tests valgrindTest' addons: apt: packages: - valgrind - - os: linux + + - env: Ubu=14.04 Cmd="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest && make clean && make -C contrib/pzstd googletest32 && make -C contrib/pzstd all32 && make -C contrib/pzstd check && make -C contrib/pzstd clean" + os: linux dist: trusty sudo: required install: - export CXX="g++-4.8" CC="gcc-4.8" - env: PLATFORM="Ubuntu 14.04" CMD="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest && make clean && make -C contrib/pzstd googletest32 && make -C contrib/pzstd all32 && make -C contrib/pzstd check && make -C contrib/pzstd clean" addons: apt: packages: @@ -93,19 +115,21 @@ matrix: - gcc-4.8-multilib - g++-4.8 - g++-4.8-multilib - - os: linux + + - env: Ubu=14.04 Cmd="make -C tests test32" + os: linux dist: trusty sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make -C tests test32" addons: apt: packages: - libc6-dev-i386 - gcc-multilib - - os: linux + + - env: Ubu=14.04 Cmd="make gcc5test && make clean && make gcc6test" + os: linux dist: trusty sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make gcc5test && make clean && make gcc6test && sudo apt-get install -y -q qemu-system-ppc binfmt-support qemu-user-static gcc-powerpc-linux-gnu && make clean && make ppctest" addons: apt: sources: @@ -116,8 +140,6 @@ matrix: - gcc-5-multilib - gcc-6 - gcc-6-multilib - exclude: - - compiler: gcc script: - - sh -c "$CMD" + - sh -c "$Cmd" From c89c74ee91d0f31f62c1411b7e69c0c1add1f13a Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 13:41:18 +0100 Subject: [PATCH 031/185] updated .gitignore --- build/.gitignore | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/build/.gitignore b/build/.gitignore index 86ed710bd..bc8ac94d9 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -1,13 +1,18 @@ -*Copy - # Visual C++ -bin/ +.vs/ +*Copy +*.db +*.opensdf +*.sdf +*.suo +*.user + VS2005/ VS2008/ -VS2010/ -VS2012/ -VS2013/ -VS2015/ +VS2010/bin/ +VS2012/bin/ +VS2013/bin/ +VS2015/bin/ # CMake cmake/ From c7797789508431c58312d6342a08b551f047dd4f Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 15:56:26 +0100 Subject: [PATCH 032/185] updated IntDir and OutDir --- .travis.yml | 3 ++- build/VS2010/datagen/datagen.vcxproj | 5 ++--- build/VS2010/fullbench/fullbench.vcxproj | 5 ++--- build/VS2010/fuzzer/fuzzer.vcxproj | 5 ++--- build/VS2010/zstd/zstd.vcxproj | 5 ++--- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 134b88e29..993acc966 100644 --- a/.travis.yml +++ b/.travis.yml @@ -142,4 +142,5 @@ matrix: - gcc-6-multilib script: - - sh -c "$Cmd" + - JOB_NUMBER = $(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:' + - [ $JOB_NUMBER -eq 9 ] || [ $JOB_NUMBER -eq 10 ] && sh -c "$Cmd" diff --git a/build/VS2010/datagen/datagen.vcxproj b/build/VS2010/datagen/datagen.vcxproj index 6460de3a5..bd8a213da 100644 --- a/build/VS2010/datagen/datagen.vcxproj +++ b/build/VS2010/datagen/datagen.vcxproj @@ -22,7 +22,8 @@ {037E781E-81A6-494B-B1B3-438AB1200523} Win32Proj datagen - $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ @@ -67,7 +68,6 @@ true false $(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - $(Platform)\$(Configuration)\ true @@ -78,7 +78,6 @@ false false $(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - $(Platform)\$(Configuration)\ false diff --git a/build/VS2010/fullbench/fullbench.vcxproj b/build/VS2010/fullbench/fullbench.vcxproj index ea0f06e47..67fd62ba7 100644 --- a/build/VS2010/fullbench/fullbench.vcxproj +++ b/build/VS2010/fullbench/fullbench.vcxproj @@ -22,7 +22,8 @@ {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8} Win32Proj fullbench - $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ @@ -67,7 +68,6 @@ true $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); false - $(Platform)\$(Configuration)\ true @@ -78,7 +78,6 @@ false $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); false - $(Platform)\$(Configuration)\ false diff --git a/build/VS2010/fuzzer/fuzzer.vcxproj b/build/VS2010/fuzzer/fuzzer.vcxproj index 020e521aa..82fc02167 100644 --- a/build/VS2010/fuzzer/fuzzer.vcxproj +++ b/build/VS2010/fuzzer/fuzzer.vcxproj @@ -22,7 +22,8 @@ {6FD4352B-346C-4703-96EA-D4A8B9A6976E} Win32Proj fuzzer - $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ @@ -67,7 +68,6 @@ true false $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - $(Platform)\$(Configuration)\ true @@ -78,7 +78,6 @@ false false $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - $(Platform)\$(Configuration)\ false diff --git a/build/VS2010/zstd/zstd.vcxproj b/build/VS2010/zstd/zstd.vcxproj index 181bbe6df..c7a9ed73c 100644 --- a/build/VS2010/zstd/zstd.vcxproj +++ b/build/VS2010/zstd/zstd.vcxproj @@ -78,7 +78,8 @@ {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C} Win32Proj zstd - $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ @@ -124,7 +125,6 @@ $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false $(LibraryPath) - $(Platform)\$(Configuration)\ true @@ -137,7 +137,6 @@ $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false $(LibraryPath) - $(Platform)\$(Configuration)\ false From b5d423b6c21f11dbfe71d02c59b6e90577102c2e Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 15:56:50 +0100 Subject: [PATCH 033/185] zstdlib renamed to libzstd --- .../zstdlib.rc => libzstd/libzstd.rc} | 0 .../libzstd.vcxproj} | 19 ++++++++----------- build/VS2010/zstd.sln | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) rename build/VS2010/{zstdlib/zstdlib.rc => libzstd/libzstd.rc} (100%) rename build/VS2010/{zstdlib/zstdlib.vcxproj => libzstd/libzstd.vcxproj} (95%) diff --git a/build/VS2010/zstdlib/zstdlib.rc b/build/VS2010/libzstd/libzstd.rc similarity index 100% rename from build/VS2010/zstdlib/zstdlib.rc rename to build/VS2010/libzstd/libzstd.rc diff --git a/build/VS2010/zstdlib/zstdlib.vcxproj b/build/VS2010/libzstd/libzstd.vcxproj similarity index 95% rename from build/VS2010/zstdlib/zstdlib.vcxproj rename to build/VS2010/libzstd/libzstd.vcxproj index d32b4861f..15295c291 100644 --- a/build/VS2010/zstdlib/zstdlib.vcxproj +++ b/build/VS2010/libzstd/libzstd.vcxproj @@ -63,13 +63,14 @@ - + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850} Win32Proj - zstdlib - $(SolutionDir)bin\$(Platform)\$(Configuration)\ + libzstd + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ @@ -112,29 +113,25 @@ true - zstdlib_x86 - $(Platform)\$(Configuration)\ + libzstd_x86 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false true - zstdlib_x64 - $(Platform)\$(Configuration)\ + libzstd_x64 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - zstdlib_x86 - $(Platform)\$(Configuration)\ + libzstd_x86 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - zstdlib_x64 - $(Platform)\$(Configuration)\ + libzstd_x64 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false diff --git a/build/VS2010/zstd.sln b/build/VS2010/zstd.sln index 698b8fe50..4840a4d91 100644 --- a/build/VS2010/zstd.sln +++ b/build/VS2010/zstd.sln @@ -7,7 +7,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstdlib", "zstdlib\zstdlib.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd", "libzstd\libzstd.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}" EndProject From cba727ca8cbbb7d5740bf45c07683093c77c8124 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 15:59:57 +0100 Subject: [PATCH 034/185] updated appveyor.yml --- appveyor.yml | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index fbdc30c40..e131b2ca1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -85,43 +85,43 @@ build_script: ECHO *** Building Visual Studio 2010 %PLATFORM%\%CONFIGURATION% && ECHO *** && msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe && ECHO *** && ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% && ECHO *** && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe && ECHO *** && ECHO *** Building Visual Studio 2013 %PLATFORM%\%CONFIGURATION% && ECHO *** && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe && ECHO *** && ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% && ECHO *** && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && - COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe tests\ + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && + COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ ) test_script: From 9f26f72f97611f1fe9b34bccaddbaee96b984bc7 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 16:14:18 +0100 Subject: [PATCH 035/185] added libzstd-dll --- .travis.yml | 4 +- .../libzstd.rc => libzstd-dll/libzstd-dll.rc} | 4 +- build/VS2010/libzstd-dll/libzstd-dll.vcxproj | 225 ++++++++++++++++++ build/VS2010/libzstd-dll/lz4-dll.vcxproj | 175 ++++++++++++++ build/VS2010/libzstd/liblz4.vcxproj | 171 +++++++++++++ build/VS2010/libzstd/libzstd.vcxproj | 19 +- build/VS2010/zstd.sln | 28 ++- 7 files changed, 602 insertions(+), 24 deletions(-) rename build/VS2010/{libzstd/libzstd.rc => libzstd-dll/libzstd-dll.rc} (92%) create mode 100644 build/VS2010/libzstd-dll/libzstd-dll.vcxproj create mode 100644 build/VS2010/libzstd-dll/lz4-dll.vcxproj create mode 100644 build/VS2010/libzstd/liblz4.vcxproj diff --git a/.travis.yml b/.travis.yml index 993acc966..74a9964b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -142,5 +142,5 @@ matrix: - gcc-6-multilib script: - - JOB_NUMBER = $(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:' - - [ $JOB_NUMBER -eq 9 ] || [ $JOB_NUMBER -eq 10 ] && sh -c "$Cmd" + - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:' + - [ $JOB_NUMBER -eq 9 ] | [ $JOB_NUMBER -eq 10 ] && sh -c "$Cmd" diff --git a/build/VS2010/libzstd/libzstd.rc b/build/VS2010/libzstd-dll/libzstd-dll.rc similarity index 92% rename from build/VS2010/libzstd/libzstd.rc rename to build/VS2010/libzstd-dll/libzstd-dll.rc index de8ecbcf8..72ea168d2 100644 --- a/build/VS2010/libzstd/libzstd.rc +++ b/build/VS2010/libzstd-dll/libzstd-dll.rc @@ -35,9 +35,9 @@ BEGIN VALUE "CompanyName", "Yann Collet" VALUE "FileDescription", "Fast and efficient compression algorithm" VALUE "FileVersion", ZSTD_VERSION_STRING - VALUE "InternalName", "zstdlib.dll" + VALUE "InternalName", "libzstd.dll" VALUE "LegalCopyright", "Copyright (C) 2013-2016, Yann Collet" - VALUE "OriginalFilename", "zstdlib.dll" + VALUE "OriginalFilename", "libzstd.dll" VALUE "ProductName", "Zstandard" VALUE "ProductVersion", ZSTD_VERSION_STRING END diff --git a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj new file mode 100644 index 000000000..4bf816642 --- /dev/null +++ b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj @@ -0,0 +1,225 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {00000000-94D5-4BF9-8A50-7BD9929A0850} + Win32Proj + libzstd-dll + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ + + + + DynamicLibrary + true + MultiByte + + + DynamicLibrary + true + MultiByte + + + DynamicLibrary + false + true + MultiByte + + + DynamicLibrary + false + true + MultiByte + + + + + + + + + + + + + + + + + + + true + libzstd_x86 + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); + false + + + true + libzstd_x64 + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); + false + + + false + libzstd_x86 + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); + false + + + false + libzstd_x64 + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); + false + + + + + + Level4 + Disabled + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + EditAndContinue + true + false + + + Console + true + MachineX86 + + + + + + + Level4 + Disabled + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + ProgramDatabase + false + + + Console + true + + + + + Level4 + + + MaxSpeed + true + true + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + MultiThreaded + ProgramDatabase + All + + + Console + true + true + true + MachineX86 + + + + + Level4 + + + MaxSpeed + true + true + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + false + MultiThreaded + ProgramDatabase + true + true + All + + + Console + true + true + true + + + + + + diff --git a/build/VS2010/libzstd-dll/lz4-dll.vcxproj b/build/VS2010/libzstd-dll/lz4-dll.vcxproj new file mode 100644 index 000000000..ac1728706 --- /dev/null +++ b/build/VS2010/libzstd-dll/lz4-dll.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9800039D-4AAA-43A4-BB78-FEF6F4836927} + Win32Proj + liblz4-dll + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ + liblz4-dll + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + true + lz4_x86 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + + + true + lz4_x64 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + true + + + false + lz4_x86 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + + + false + lz4_x64 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + true + + + + + + Level4 + Disabled + WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + true + false + + + true + + + + + + + Level4 + Disabled + WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + true + true + /analyze:stacksize295252 %(AdditionalOptions) + + + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + false + false + + + true + true + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + false + true + /analyze:stacksize295252 %(AdditionalOptions) + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/VS2010/libzstd/liblz4.vcxproj b/build/VS2010/libzstd/liblz4.vcxproj new file mode 100644 index 000000000..bafc99807 --- /dev/null +++ b/build/VS2010/libzstd/liblz4.vcxproj @@ -0,0 +1,171 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9092C5CC-3E71-41B3-BF68-4A7BDD8A5476} + Win32Proj + liblz4 + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + true + liblz4_x86 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + + + true + liblz4_x64 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + true + + + false + liblz4_x86 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + + + false + liblz4_x64 + $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); + true + + + + + + Level4 + Disabled + WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + true + false + + + true + + + + + + + Level4 + Disabled + WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + true + true + /analyze:stacksize295252 %(AdditionalOptions) + + + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + false + false + + + true + true + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) + false + true + /analyze:stacksize295252 %(AdditionalOptions) + + + true + true + true + + + + + + + + + + + + + + + + + + + diff --git a/build/VS2010/libzstd/libzstd.vcxproj b/build/VS2010/libzstd/libzstd.vcxproj index 15295c291..11a608e0f 100644 --- a/build/VS2010/libzstd/libzstd.vcxproj +++ b/build/VS2010/libzstd/libzstd.vcxproj @@ -62,9 +62,6 @@ - - - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850} Win32Proj @@ -74,23 +71,23 @@ - DynamicLibrary + StaticLibrary true MultiByte - DynamicLibrary + StaticLibrary true MultiByte - DynamicLibrary + StaticLibrary false true MultiByte - DynamicLibrary + StaticLibrary false true MultiByte @@ -113,25 +110,25 @@ true - libzstd_x86 + libzstd_static_x86 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false true - libzstd_x64 + libzstd_static_x64 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - libzstd_x86 + libzstd_static_x86 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - libzstd_x64 + libzstd_static_x64 $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false diff --git a/build/VS2010/zstd.sln b/build/VS2010/zstd.sln index 4840a4d91..116f1c750 100644 --- a/build/VS2010/zstd.sln +++ b/build/VS2010/zstd.sln @@ -7,9 +7,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd", "libzstd\libzstd.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd-dll", "libzstd-dll\libzstd-dll.vcxproj", "{00000000-94D5-4BF9-8A50-7BD9929A0850}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -43,14 +45,6 @@ Global {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.Build.0 = Release|Win32 {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.ActiveCfg = Release|x64 {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.Build.0 = Release|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.ActiveCfg = Debug|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.Build.0 = Debug|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.ActiveCfg = Debug|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.Build.0 = Debug|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.ActiveCfg = Release|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.Build.0 = Release|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.ActiveCfg = Release|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.Build.0 = Release|x64 {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.ActiveCfg = Debug|Win32 {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.Build.0 = Debug|Win32 {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|x64.ActiveCfg = Debug|x64 @@ -59,6 +53,22 @@ Global {037E781E-81A6-494B-B1B3-438AB1200523}.Release|Win32.Build.0 = Release|Win32 {037E781E-81A6-494B-B1B3-438AB1200523}.Release|x64.ActiveCfg = Release|x64 {037E781E-81A6-494B-B1B3-438AB1200523}.Release|x64.Build.0 = Release|x64 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.ActiveCfg = Debug|Win32 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.Build.0 = Debug|Win32 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.ActiveCfg = Debug|x64 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.Build.0 = Debug|x64 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.ActiveCfg = Release|Win32 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.Build.0 = Release|Win32 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.ActiveCfg = Release|x64 + {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.Build.0 = Release|x64 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.ActiveCfg = Debug|Win32 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.Build.0 = Debug|Win32 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.ActiveCfg = Debug|x64 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.Build.0 = Debug|x64 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.ActiveCfg = Release|Win32 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.Build.0 = Release|Win32 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.ActiveCfg = Release|x64 + {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 15d9815a1831adcc54de6cdc9470bab185d277bd Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 16:39:17 +0100 Subject: [PATCH 036/185] fixed .travis.yml --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 74a9964b7..2ea02ce48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -143,4 +143,8 @@ matrix: script: - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:' - - [ $JOB_NUMBER -eq 9 ] | [ $JOB_NUMBER -eq 10 ] && sh -c "$Cmd" + - | + if [ $JOB_NUMBER -eq 9 || $JOB_NUMBER -eq 10 ]; then + sh -c "$Cmd" + fi + From e392b1fec0ff8d40ea7a20df934f976ebd4e52fd Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 16:52:51 +0100 Subject: [PATCH 037/185] fixed .travis.yml (2) --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ea02ce48..0d8aa2063 100644 --- a/.travis.yml +++ b/.travis.yml @@ -143,8 +143,4 @@ matrix: script: - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:' - - | - if [ $JOB_NUMBER -eq 9 || $JOB_NUMBER -eq 10 ]; then - sh -c "$Cmd" - fi - + - if [ $JOB_NUMBER -eq 9 ] || [ $JOB_NUMBER -eq 10 ]; then sh -c "$Cmd"; fi From 672dc775dc4be3c2ca2477d2d456175ed1f411d6 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 16:58:39 +0100 Subject: [PATCH 038/185] fixed .travis.yml (3) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0d8aa2063..2050d54cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -142,5 +142,5 @@ matrix: - gcc-6-multilib script: - - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:' + - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:') - if [ $JOB_NUMBER -eq 9 ] || [ $JOB_NUMBER -eq 10 ]; then sh -c "$Cmd"; fi From eb977a42ef9c253109d2784abf2c8bca78986d2b Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 17:26:58 +0100 Subject: [PATCH 039/185] "file" moved to tests/Makefile --- tests/Makefile | 1 + tests/playTests.sh | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 63177f5ef..c931adbe4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -166,6 +166,7 @@ endif #------------------------------------------------------------------------ ifneq (,$(filter $(HOST_OS),MSYS POSIX)) zstd-playTests: datagen + file $(ZSTD) ZSTD="$(QEMU_SYS) $(ZSTD)" ./playTests.sh $(ZSTDRTTEST) test: test-zstd test-fullbench test-fuzzer test-zbuff test-zstream diff --git a/tests/playTests.sh b/tests/playTests.sh index 1bc835f0c..a50604b7e 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -40,8 +40,6 @@ $ECHO "\nStarting playTests.sh isWindows=$isWindows ZSTD='$ZSTD'" [ -n "$ZSTD" ] || die "ZSTD variable must be defined!" -file $ZSTD - $ECHO "\n**** simple tests **** " ./datagen > tmp From f00e66a63d0aeadf2834648018ffdc6fd555ebed Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 14 Nov 2016 18:07:17 +0100 Subject: [PATCH 040/185] restore all Travis tests --- .travis.yml | 3 +- build/VS2010/libzstd-dll/lz4-dll.vcxproj | 175 ----------------------- build/VS2010/libzstd/liblz4.vcxproj | 171 ---------------------- 3 files changed, 2 insertions(+), 347 deletions(-) delete mode 100644 build/VS2010/libzstd-dll/lz4-dll.vcxproj delete mode 100644 build/VS2010/libzstd/liblz4.vcxproj diff --git a/.travis.yml b/.travis.yml index 2050d54cc..7866e5ab2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -143,4 +143,5 @@ matrix: script: - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:') - - if [ $JOB_NUMBER -eq 9 ] || [ $JOB_NUMBER -eq 10 ]; then sh -c "$Cmd"; fi + # - if [ $JOB_NUMBER -eq 9 ] || [ $JOB_NUMBER -eq 10 ]; then sh -c "$Cmd"; fi + - sh -c "$Cmd" diff --git a/build/VS2010/libzstd-dll/lz4-dll.vcxproj b/build/VS2010/libzstd-dll/lz4-dll.vcxproj deleted file mode 100644 index ac1728706..000000000 --- a/build/VS2010/libzstd-dll/lz4-dll.vcxproj +++ /dev/null @@ -1,175 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9800039D-4AAA-43A4-BB78-FEF6F4836927} - Win32Proj - liblz4-dll - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - liblz4-dll - - - - DynamicLibrary - true - Unicode - - - DynamicLibrary - true - Unicode - - - DynamicLibrary - false - true - Unicode - - - DynamicLibrary - false - true - Unicode - - - - - - - - - - - - - - - - - - - true - lz4_x86 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - - - true - lz4_x64 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - true - - - false - lz4_x86 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - - - false - lz4_x64 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - true - - - - - - Level4 - Disabled - WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - true - false - - - true - - - - - - - Level4 - Disabled - WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - true - true - /analyze:stacksize295252 %(AdditionalOptions) - - - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - false - false - - - true - true - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - false - true - /analyze:stacksize295252 %(AdditionalOptions) - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/VS2010/libzstd/liblz4.vcxproj b/build/VS2010/libzstd/liblz4.vcxproj deleted file mode 100644 index bafc99807..000000000 --- a/build/VS2010/libzstd/liblz4.vcxproj +++ /dev/null @@ -1,171 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9092C5CC-3E71-41B3-BF68-4A7BDD8A5476} - Win32Proj - liblz4 - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - StaticLibrary - true - Unicode - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - StaticLibrary - false - true - Unicode - - - - - - - - - - - - - - - - - - - true - liblz4_x86 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - - - true - liblz4_x64 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - true - - - false - liblz4_x86 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - - - false - liblz4_x64 - $(IncludePath);$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath); - true - - - - - - Level4 - Disabled - WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - true - false - - - true - - - - - - - Level4 - Disabled - WIN32;_DEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - true - true - /analyze:stacksize295252 %(AdditionalOptions) - - - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - false - false - - - true - true - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;LZ4_DLL_EXPORT=1;%(PreprocessorDefinitions) - false - true - /analyze:stacksize295252 %(AdditionalOptions) - - - true - true - true - - - - - - - - - - - - - - - - - - - From 1f0b09dc4c649c03e57b1904259da62e49a49ad6 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 14 Nov 2016 10:29:25 -0800 Subject: [PATCH 041/185] Fix travis-ci timeout. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9396c98da..8462b9712 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ matrix: language: cpp install: - export CXX="g++-4.8" CC="gcc-4.8" + - export TESTFLAGS='--gtest_filter=-*ExtremelyLarge*' addons: apt: sources: From 324c8ab000ee7b8fc48722c45f6a1bd58eb2f2ca Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 14 Nov 2016 11:02:03 -0800 Subject: [PATCH 042/185] [pzstd] Remove gtest dependency from make all --- .travis.yml | 2 +- appveyor.yml | 3 ++- contrib/pzstd/Makefile | 18 +++++++++++------- contrib/pzstd/README.md | 5 +++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8462b9712..73ff04863 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ matrix: packages: - gcc-4.8 - g++-4.8 - env: PLATFORM="Ubuntu 12.04 container" CMD="make zlibwrapper && make clean && make -C tests test-zstd-nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest && make -C contrib/pzstd all && make -C contrib/pzstd check && make -C contrib/pzstd clean" + env: PLATFORM="Ubuntu 12.04 container" CMD="make zlibwrapper && make clean && make -C tests test-zstd-nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest pzstd tests check && make -C contrib/pzstd clean" - os: linux sudo: false env: PLATFORM="Ubuntu 12.04 container" CMD="make usan" diff --git a/appveyor.yml b/appveyor.yml index fbdc30c40..bce87a3ab 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -51,7 +51,8 @@ build_script: ECHO *** Building pzstd for %PLATFORM% && ECHO *** && make -C contrib\pzstd googletest-mingw64 && - make -C contrib\pzstd all && + make -C contrib\pzstd pzstd.exe && + make -C contrib\pzstd tests && make -C contrib\pzstd check && make -C contrib\pzstd clean ) diff --git a/contrib/pzstd/Makefile b/contrib/pzstd/Makefile index ad0e55673..99d955e94 100644 --- a/contrib/pzstd/Makefile +++ b/contrib/pzstd/Makefile @@ -34,7 +34,7 @@ LDFLAGS ?= PZSTD_INC = -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I. GTEST_INC = -isystem googletest/googletest/include -PZSTD_CPPFLAGS = $(PZSTD_INC) $(GTEST_INC) +PZSTD_CPPFLAGS = $(PZSTD_INC) PZSTD_CCXXFLAGS = PZSTD_CFLAGS = $(PZSTD_CCXXFLAGS) PZSTD_CXXFLAGS = $(PZSTD_CCXXFLAGS) @@ -47,10 +47,10 @@ ALL_LDFLAGS = $(EXTRA_FLAGS) $(LDFLAGS) $(PZSTD_LDFLAGS) # gtest libraries need to go before "-lpthread" because they depend on it. GTEST_LIB = -L googletest/build/googlemock/gtest -LIBS = $(GTEST_LIB) -lpthread +LIBS = # Compilation commands -LD_COMMAND = $(CXX) $^ $(ALL_LDFLAGS) $(LIBS) -o $@ +LD_COMMAND = $(CXX) $^ $(ALL_LDFLAGS) $(LIBS) -lpthread -o $@ CC_COMMAND = $(CC) $(DEPFLAGS) $(ALL_CFLAGS) -c $< -o $@ CXX_COMMAND = $(CXX) $(DEPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@ @@ -109,7 +109,7 @@ uninstall: # Targets for many different builds .PHONY: all all: PZSTD_CPPFLAGS += -DNDEBUG -all: pzstd$(EXT) tests roundtrip +all: pzstd$(EXT) .PHONY: debug debug: EXTRA_FLAGS += -g @@ -130,7 +130,7 @@ ubsan: debug .PHONY: all32 all32: EXTRA_FLAGS += -m32 -all32: all +all32: all tests roundtrip .PHONY: debug32 debug32: EXTRA_FLAGS += -m32 @@ -177,12 +177,14 @@ test/RoundTripTest$(EXT): test/RoundTripTest.o $(PROGDIR)/datagen.o Options.o \ Pzstd.o SkippableFrame.o $(ZSTDDIR)/libzstd.a $(LD_COMMAND) -test/%Test$(EXT): GTEST_LIB += -lgtest -lgtest_main +test/%Test$(EXT): PZSTD_LDFLAGS += $(GTEST_LIB) +test/%Test$(EXT): LIBS += -lgtest -lgtest_main test/%Test$(EXT): test/%Test.o $(PROGDIR)/datagen.o Options.o Pzstd.o \ SkippableFrame.o $(ZSTDDIR)/libzstd.a $(LD_COMMAND) -utils/test/%Test$(EXT): GTEST_LIB += -lgtest -lgtest_main +utils/test/%Test$(EXT): PZSTD_LDFLAGS += $(GTEST_LIB) +utils/test/%Test$(EXT): LIBS += -lgtest -lgtest_main utils/test/%Test$(EXT): utils/test/%Test.o $(LD_COMMAND) @@ -233,10 +235,12 @@ $(PROGDIR)/%.o: $(PROGDIR)/%.c $(CXX_COMMAND) $(POSTCOMPILE) +test/%.o: PZSTD_CPPFLAGS += $(GTEST_INC) test/%.o: test/%.cpp $(CXX_COMMAND) $(POSTCOMPILE) +utils/test/%.o: PZSTD_CPPFLAGS += $(GTEST_INC) utils/test/%.o: utils/test/%.cpp $(CXX_COMMAND) $(POSTCOMPILE) diff --git a/contrib/pzstd/README.md b/contrib/pzstd/README.md index 3fe7b0b9d..84d945815 100644 --- a/contrib/pzstd/README.md +++ b/contrib/pzstd/README.md @@ -51,5 +51,6 @@ Pigz cannot do parallel decompression, it simply does each of reading, decompres ## Tests Tests require that you have [gtest](https://github.com/google/googletest) installed. -Modify `GTEST_INC` and `GTEST_LIB` in `test/Makefile` and `utils/test/Makefile` to work for your install of gtest. -Then run `make test` in the `contrib/pzstd` directory. +Set `GTEST_INC` and `GTEST_LIB` in `Makefile` to specify the location of the gtest headers and libraries. +Alternatively, run `make googletest`, which will clone googletest and build it. +Run `make tests && make check` to run tests. From 24701de877a486b2f59a869e0d38d5a697a5d7d8 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 14 Nov 2016 11:33:37 -0800 Subject: [PATCH 043/185] Fix uninitialized memory read --- lib/decompress/zstd_decompress.c | 21 +++++++++------------ lib/legacy/zstd_v02.c | 13 +++++-------- lib/legacy/zstd_v03.c | 13 +++++-------- lib/legacy/zstd_v04.c | 15 ++++++--------- lib/legacy/zstd_v05.c | 17 +++++++---------- lib/legacy/zstd_v06.c | 17 +++++++---------- lib/legacy/zstd_v07.c | 17 +++++++---------- 7 files changed, 46 insertions(+), 67 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index b6a3865ca..e8d6b1524 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -104,7 +104,6 @@ struct ZSTD_DCtx_s U32 dictID; const BYTE* litPtr; ZSTD_customMem customMem; - size_t litBufSize; size_t litSize; size_t rleSize; BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH]; @@ -429,10 +428,10 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, return ERROR(corruption_detected); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; dctx->litEntropy = 1; if (litEncType==set_compressed) dctx->HUFptr = dctx->hufTable; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } @@ -459,13 +458,12 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, if (litSize+lhSize > srcSize) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart+lhSize, litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+litSize; } /* direct reference into compressed stream */ dctx->litPtr = istart+lhSize; - dctx->litBufSize = srcSize-lhSize; dctx->litSize = litSize; return lhSize+litSize; } @@ -492,8 +490,8 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[lhSize], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: @@ -867,7 +865,7 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState) FORCE_NOINLINE size_t ZSTD_execSequenceLast7(BYTE* op, BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit_w, + const BYTE** litPtr, const BYTE* const litLimit, const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) { BYTE* const oLitEnd = op + sequence.litLength; @@ -879,7 +877,7 @@ size_t ZSTD_execSequenceLast7(BYTE* op, /* check */ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ - if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */ /* copy literals */ @@ -914,7 +912,7 @@ size_t ZSTD_execSequenceLast7(BYTE* op, FORCE_INLINE size_t ZSTD_execSequence(BYTE* op, BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit_w, + const BYTE** litPtr, const BYTE* const litLimit, const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) { BYTE* const oLitEnd = op + sequence.litLength; @@ -926,8 +924,8 @@ size_t ZSTD_execSequence(BYTE* op, /* check */ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ - if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */ - if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit_w, base, vBase, dictEnd); + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); /* copy Literals */ ZSTD_copy8(op, *litPtr); @@ -1002,7 +1000,6 @@ static size_t ZSTD_decompressSequences( BYTE* const oend = ostart + maxDstSize; BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litLimit_w = litPtr + dctx->litBufSize - WILDCOPY_OVERLENGTH; const BYTE* const litEnd = litPtr + dctx->litSize; const BYTE* const base = (const BYTE*) (dctx->base); const BYTE* const vBase = (const BYTE*) (dctx->vBase); @@ -1028,7 +1025,7 @@ static size_t ZSTD_decompressSequences( for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { nbSeq--; { seq_t const sequence = ZSTD_decodeSequence(&seqState); - size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_w, base, vBase, dictEnd); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); if (ZSTD_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } } diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index 24498fedf..acaa46323 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -2868,7 +2868,6 @@ struct ZSTD_DCtx_s blockType_t bType; U32 phase; const BYTE* litPtr; - size_t litBufSize; size_t litSize; BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */]; }; /* typedef'd to ZSTD_Dctx within "zstd_static.h" */ @@ -2940,8 +2939,8 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, size_t litSize = BLOCKSIZE; const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return readSize; /* works if it's an error too */ } case IS_RAW: @@ -2952,13 +2951,12 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, if (litSize > srcSize-3) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart, litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return litSize+3; } /* direct reference into compressed stream */ dctx->litPtr = istart+3; - dctx->litBufSize = srcSize-3; dctx->litSize = litSize; return litSize+3; } @@ -2968,8 +2966,8 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, if (litSize > BLOCKSIZE) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[3], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return 4; } } @@ -3175,7 +3173,7 @@ static size_t ZSTD_execSequence(BYTE* op, /* checks */ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ - if (litEnd > litLimit-8) return ERROR(corruption_detected); /* overRead beyond lit buffer */ + if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */ /* copy Literals */ ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ @@ -3241,7 +3239,6 @@ static size_t ZSTD_decompressSequences( BYTE* const oend = ostart + maxDstSize; size_t errorCode, dumpsLength; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litMax = litPtr + dctx->litBufSize; const BYTE* const litEnd = litPtr + dctx->litSize; int nbSeq; const BYTE* dumps; @@ -3277,7 +3274,7 @@ static size_t ZSTD_decompressSequences( size_t oneSeqSize; nbSeq--; ZSTD_decodeSequence(&sequence, &seqState); - oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litMax, base, oend); + oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litEnd, base, oend); if (ZSTD_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index a3bd1da23..48803ea0f 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -2509,7 +2509,6 @@ struct ZSTD_DCtx_s blockType_t bType; U32 phase; const BYTE* litPtr; - size_t litBufSize; size_t litSize; BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */]; }; /* typedef'd to ZSTD_Dctx within "zstd_static.h" */ @@ -2581,8 +2580,8 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, size_t litSize = BLOCKSIZE; const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return readSize; /* works if it's an error too */ } case IS_RAW: @@ -2593,13 +2592,12 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, if (litSize > srcSize-3) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart, litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return litSize+3; } /* direct reference into compressed stream */ dctx->litPtr = istart+3; - dctx->litBufSize = srcSize-3; dctx->litSize = litSize; return litSize+3; } @@ -2609,8 +2607,8 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, if (litSize > BLOCKSIZE) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[3], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return 4; } } @@ -2816,7 +2814,7 @@ static size_t ZSTD_execSequence(BYTE* op, /* checks */ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ - if (litEnd > litLimit-8) return ERROR(corruption_detected); /* overRead beyond lit buffer */ + if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */ /* copy Literals */ ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ @@ -2882,7 +2880,6 @@ static size_t ZSTD_decompressSequences( BYTE* const oend = ostart + maxDstSize; size_t errorCode, dumpsLength; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litMax = litPtr + dctx->litBufSize; const BYTE* const litEnd = litPtr + dctx->litSize; int nbSeq; const BYTE* dumps; @@ -2918,7 +2915,7 @@ static size_t ZSTD_decompressSequences( size_t oneSeqSize; nbSeq--; ZSTD_decodeSequence(&sequence, &seqState); - oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litMax, base, oend); + oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litEnd, base, oend); if (ZSTD_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 0a740baca..c0738b300 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -2706,7 +2706,6 @@ struct ZSTDv04_Dctx_s blockType_t bType; ZSTD_dStage stage; const BYTE* litPtr; - size_t litBufSize; size_t litSize; BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */]; BYTE headerBuffer[ZSTD_frameHeaderSize_max]; @@ -2847,8 +2846,8 @@ static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, size_t litSize = BLOCKSIZE; const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return readSize; /* works if it's an error too */ } case IS_RAW: @@ -2859,13 +2858,12 @@ static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, if (litSize > srcSize-3) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart, litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return litSize+3; } /* direct reference into compressed stream */ dctx->litPtr = istart+3; - dctx->litBufSize = srcSize-3; dctx->litSize = litSize; return litSize+3; } case IS_RLE: @@ -2874,8 +2872,8 @@ static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, if (litSize > BLOCKSIZE) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[3], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, 8); return 4; } default: @@ -3069,7 +3067,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) static size_t ZSTD_execSequence(BYTE* op, BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit_8, + const BYTE** litPtr, const BYTE* const litLimit, const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) { static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ @@ -3084,7 +3082,7 @@ static size_t ZSTD_execSequence(BYTE* op, /* check */ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ - if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */ + if (litEnd > litLimit) return ERROR(corruption_detected); /* risk read beyond lit buffer */ /* copy Literals */ ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ @@ -3167,7 +3165,6 @@ static size_t ZSTD_decompressSequences( BYTE* const oend = ostart + maxDstSize; size_t errorCode, dumpsLength; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8; const BYTE* const litEnd = litPtr + dctx->litSize; int nbSeq; const BYTE* dumps; @@ -3206,7 +3203,7 @@ static size_t ZSTD_decompressSequences( size_t oneSeqSize; nbSeq--; ZSTD_decodeSequence(&sequence, &seqState); - oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd); + oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); if (ZSTD_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index f63a97fd7..02ba89064 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -2731,7 +2731,6 @@ struct ZSTDv05_DCtx_s ZSTDv05_dStage stage; U32 flagStaticTables; const BYTE* litPtr; - size_t litBufSize; size_t litSize; BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH]; BYTE headerBuffer[ZSTDv05_frameHeaderSize_max]; @@ -2978,8 +2977,8 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx, return ERROR(corruption_detected); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } case IS_PCH: @@ -3002,8 +3001,8 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx, if (HUFv05_isError(errorCode)) return ERROR(corruption_detected); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } case IS_RAW: @@ -3028,13 +3027,12 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx, if (litSize+lhSize > srcSize) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart+lhSize, litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+litSize; } /* direct reference into compressed stream */ dctx->litPtr = istart+lhSize; - dctx->litBufSize = srcSize-lhSize; dctx->litSize = litSize; return lhSize+litSize; } @@ -3059,8 +3057,8 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx, if (litSize > BLOCKSIZE) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[lhSize], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: @@ -3289,7 +3287,7 @@ static void ZSTDv05_decodeSequence(seq_t* seq, seqState_t* seqState) static size_t ZSTDv05_execSequence(BYTE* op, BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit_8, + const BYTE** litPtr, const BYTE* const litLimit, const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) { static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ @@ -3304,7 +3302,7 @@ static size_t ZSTDv05_execSequence(BYTE* op, /* check */ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ - if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */ + if (litEnd > litLimit) return ERROR(corruption_detected); /* risk read beyond lit buffer */ /* copy Literals */ ZSTDv05_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ @@ -3378,7 +3376,6 @@ static size_t ZSTDv05_decompressSequences( BYTE* const oend = ostart + maxDstSize; size_t errorCode, dumpsLength; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8; const BYTE* const litEnd = litPtr + dctx->litSize; int nbSeq; const BYTE* dumps; @@ -3416,7 +3413,7 @@ static size_t ZSTDv05_decompressSequences( size_t oneSeqSize; nbSeq--; ZSTDv05_decodeSequence(&sequence, &seqState); - oneSeqSize = ZSTDv05_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd); + oneSeqSize = ZSTDv05_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); if (ZSTDv05_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 88be49438..01546f4e2 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -2893,7 +2893,6 @@ struct ZSTDv06_DCtx_s ZSTDv06_dStage stage; U32 flagRepeatTable; const BYTE* litPtr; - size_t litBufSize; size_t litSize; BYTE litBuffer[ZSTDv06_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH]; BYTE headerBuffer[ZSTDv06_FRAMEHEADERSIZE_MAX]; @@ -3170,8 +3169,8 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx, return ERROR(corruption_detected); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } case IS_PCH: @@ -3192,8 +3191,8 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx, if (HUFv06_isError(errorCode)) return ERROR(corruption_detected); } dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } case IS_RAW: @@ -3217,13 +3216,12 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx, if (litSize+lhSize > srcSize) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart+lhSize, litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+litSize; } /* direct reference into compressed stream */ dctx->litPtr = istart+lhSize; - dctx->litBufSize = srcSize-lhSize; dctx->litSize = litSize; return lhSize+litSize; } @@ -3247,8 +3245,8 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx, if (litSize > ZSTDv06_BLOCKSIZE_MAX) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[lhSize], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: @@ -3438,7 +3436,7 @@ static void ZSTDv06_decodeSequence(seq_t* seq, seqState_t* seqState) size_t ZSTDv06_execSequence(BYTE* op, BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit_8, + const BYTE** litPtr, const BYTE* const litLimit, const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) { BYTE* const oLitEnd = op + sequence.litLength; @@ -3451,7 +3449,7 @@ size_t ZSTDv06_execSequence(BYTE* op, /* check */ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ - if (iLitEnd > litLimit_8) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ /* copy Literals */ ZSTDv06_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ @@ -3523,7 +3521,6 @@ static size_t ZSTDv06_decompressSequences( BYTE* const oend = ostart + maxDstSize; BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8; const BYTE* const litEnd = litPtr + dctx->litSize; FSEv06_DTable* DTableLL = dctx->LLTable; FSEv06_DTable* DTableML = dctx->MLTable; @@ -3567,7 +3564,7 @@ static size_t ZSTDv06_decompressSequences( pos, (U32)sequence.litLength, (U32)sequence.matchLength, (U32)sequence.offset); #endif - { size_t const oneSeqSize = ZSTDv06_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd); + { size_t const oneSeqSize = ZSTDv06_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); if (ZSTDv06_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } } diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index c7693f240..1050080b2 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -3021,7 +3021,6 @@ struct ZSTDv07_DCtx_s U32 dictID; const BYTE* litPtr; ZSTDv07_customMem customMem; - size_t litBufSize; size_t litSize; BYTE litBuffer[ZSTDv07_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH]; BYTE headerBuffer[ZSTDv07_FRAMEHEADERSIZE_MAX]; @@ -3395,9 +3394,9 @@ size_t ZSTDv07_decodeLiteralsBlock(ZSTDv07_DCtx* dctx, return ERROR(corruption_detected); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv07_BLOCKSIZE_ABSOLUTEMAX+8; dctx->litSize = litSize; dctx->litEntropy = 1; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } case lbt_repeat: @@ -3418,8 +3417,8 @@ size_t ZSTDv07_decodeLiteralsBlock(ZSTDv07_DCtx* dctx, if (HUFv07_isError(errorCode)) return ERROR(corruption_detected); } dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv07_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } case lbt_raw: @@ -3443,13 +3442,12 @@ size_t ZSTDv07_decodeLiteralsBlock(ZSTDv07_DCtx* dctx, if (litSize+lhSize > srcSize) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart+lhSize, litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv07_BLOCKSIZE_ABSOLUTEMAX+8; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+litSize; } /* direct reference into compressed stream */ dctx->litPtr = istart+lhSize; - dctx->litBufSize = srcSize-lhSize; dctx->litSize = litSize; return lhSize+litSize; } @@ -3473,8 +3471,8 @@ size_t ZSTDv07_decodeLiteralsBlock(ZSTDv07_DCtx* dctx, if (litSize > ZSTDv07_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[lhSize], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = ZSTDv07_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH; dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: @@ -3662,7 +3660,7 @@ static seq_t ZSTDv07_decodeSequence(seqState_t* seqState) static size_t ZSTDv07_execSequence(BYTE* op, BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit_w, + const BYTE** litPtr, const BYTE* const litLimit, const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) { BYTE* const oLitEnd = op + sequence.litLength; @@ -3674,7 +3672,7 @@ size_t ZSTDv07_execSequence(BYTE* op, /* check */ if ((oLitEnd>oend_w) | (oMatchEnd>oend)) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ - if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ /* copy Literals */ ZSTDv07_wildcopy(op, *litPtr, sequence.litLength); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ @@ -3746,7 +3744,6 @@ static size_t ZSTDv07_decompressSequences( BYTE* const oend = ostart + maxDstSize; BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litLimit_w = litPtr + dctx->litBufSize - WILDCOPY_OVERLENGTH; const BYTE* const litEnd = litPtr + dctx->litSize; FSEv07_DTable* DTableLL = dctx->LLTable; FSEv07_DTable* DTableML = dctx->MLTable; @@ -3776,7 +3773,7 @@ static size_t ZSTDv07_decompressSequences( for ( ; (BITv07_reloadDStream(&(seqState.DStream)) <= BITv07_DStream_completed) && nbSeq ; ) { nbSeq--; { seq_t const sequence = ZSTDv07_decodeSequence(&seqState); - size_t const oneSeqSize = ZSTDv07_execSequence(op, oend, sequence, &litPtr, litLimit_w, base, vBase, dictEnd); + size_t const oneSeqSize = ZSTDv07_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); if (ZSTDv07_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } } From 4359d21ad7281f77bfba8003d3da40d9157ef05f Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 14 Nov 2016 17:52:51 -0800 Subject: [PATCH 044/185] Merge two memset() calls into one --- lib/decompress/zstd_decompress.c | 3 +-- lib/legacy/zstd_v02.c | 3 +-- lib/legacy/zstd_v03.c | 3 +-- lib/legacy/zstd_v04.c | 3 +-- lib/legacy/zstd_v05.c | 3 +-- lib/legacy/zstd_v06.c | 3 +-- lib/legacy/zstd_v07.c | 3 +-- 7 files changed, 7 insertions(+), 14 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index e8d6b1524..cc92ca276 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -488,10 +488,9 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, break; } if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[lhSize], litSize); + memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index acaa46323..ed082aad7 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -2964,10 +2964,9 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, { const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */ if (litSize > BLOCKSIZE) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[3], litSize); + memset(dctx->litBuffer, istart[3], litSize + 8); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, 8); return 4; } } diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index 48803ea0f..321450670 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -2605,10 +2605,9 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx, { const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */ if (litSize > BLOCKSIZE) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[3], litSize); + memset(dctx->litBuffer, istart[3], litSize + 8); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, 8); return 4; } } diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index c0738b300..11b5481a1 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -2870,10 +2870,9 @@ static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, { const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */ if (litSize > BLOCKSIZE) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[3], litSize); + memset(dctx->litBuffer, istart[3], litSize + 8); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, 8); return 4; } default: diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index 02ba89064..bf1235a35 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -3055,10 +3055,9 @@ size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx, break; } if (litSize > BLOCKSIZE) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[lhSize], litSize); + memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 01546f4e2..6584d4858 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -3243,10 +3243,9 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx, break; } if (litSize > ZSTDv06_BLOCKSIZE_MAX) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[lhSize], litSize); + memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 1050080b2..2ae6c5ad2 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -3469,10 +3469,9 @@ size_t ZSTDv07_decodeLiteralsBlock(ZSTDv07_DCtx* dctx, break; } if (litSize > ZSTDv07_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[lhSize], litSize); + memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+1; } default: From 9d4e8f694ebf7813c2eb6ba24acf9aa27af4b5b3 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 15 Nov 2016 17:28:49 +0100 Subject: [PATCH 045/185] removed _x86 and _x64 --- build/VS2010/libzstd-dll/libzstd-dll.vcxproj | 8 ++++---- build/VS2010/libzstd/libzstd.vcxproj | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj index 4bf816642..5b894b05b 100644 --- a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj +++ b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj @@ -113,25 +113,25 @@ true - libzstd_x86 + libzstd $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false true - libzstd_x64 + libzstd $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - libzstd_x86 + libzstd $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - libzstd_x64 + libzstd $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false diff --git a/build/VS2010/libzstd/libzstd.vcxproj b/build/VS2010/libzstd/libzstd.vcxproj index 11a608e0f..18f9f643b 100644 --- a/build/VS2010/libzstd/libzstd.vcxproj +++ b/build/VS2010/libzstd/libzstd.vcxproj @@ -110,25 +110,25 @@ true - libzstd_static_x86 + libzstd_static $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false true - libzstd_static_x64 + libzstd_static $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - libzstd_static_x86 + libzstd_static $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false false - libzstd_static_x64 + libzstd_static $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); false From fbcd862f2681cb2b0f4dad42bad8740a4be6b943 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 15 Nov 2016 17:29:15 +0100 Subject: [PATCH 046/185] added fullbench-dll --- .../fullbench-dll/fullbench-dll.vcxproj | 178 ++++++++++++++++++ build/VS2010/zstd.sln | 10 + 2 files changed, 188 insertions(+) create mode 100644 build/VS2010/fullbench-dll/fullbench-dll.vcxproj diff --git a/build/VS2010/fullbench-dll/fullbench-dll.vcxproj b/build/VS2010/fullbench-dll/fullbench-dll.vcxproj new file mode 100644 index 000000000..a06a178bb --- /dev/null +++ b/build/VS2010/fullbench-dll/fullbench-dll.vcxproj @@ -0,0 +1,178 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8} + Win32Proj + fullbench-dll + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + true + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + true + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + false + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + false + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + true + false + + + Console + true + $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) + liblz4.lib;%(AdditionalDependencies) + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + true + false + + + Console + true + $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) + liblz4.lib;%(AdditionalDependencies) + + + + + Level4 + + + MaxSpeed + true + true + WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + false + false + MultiThreaded + + + Console + true + true + true + $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) + liblz4.lib;%(AdditionalDependencies) + + + + + Level4 + + + MaxSpeed + true + true + WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + false + false + MultiThreaded + + + Console + true + true + true + $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) + liblz4.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + diff --git a/build/VS2010/zstd.sln b/build/VS2010/zstd.sln index 116f1c750..bb409abaf 100644 --- a/build/VS2010/zstd.sln +++ b/build/VS2010/zstd.sln @@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench-dll", "fullbench-dll\fullbench-dll.vcxproj", "{00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd", "libzstd\libzstd.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}" @@ -45,6 +47,14 @@ Global {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.Build.0 = Release|Win32 {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.ActiveCfg = Release|x64 {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.Build.0 = Release|x64 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|Win32.Build.0 = Debug|Win32 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|x64.ActiveCfg = Debug|x64 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|x64.Build.0 = Debug|x64 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.ActiveCfg = Release|Win32 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.Build.0 = Release|Win32 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.ActiveCfg = Release|x64 + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.Build.0 = Release|x64 {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.ActiveCfg = Debug|Win32 {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.Build.0 = Debug|Win32 {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|x64.ActiveCfg = Debug|x64 From 179555c1d1e7541e6345c134f671759c4a57f23f Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 15 Nov 2016 18:05:46 +0100 Subject: [PATCH 047/185] working fullbench-dll --- .../fullbench-dll/fullbench-dll.vcxproj | 27 +++++++++++-------- build/VS2010/zstd.sln | 3 +++ lib/common/zstd_internal.h | 2 ++ lib/zstd.h | 4 ++- tests/fullbench.c | 11 +++++--- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/build/VS2010/fullbench-dll/fullbench-dll.vcxproj b/build/VS2010/fullbench-dll/fullbench-dll.vcxproj index a06a178bb..3609f3ac0 100644 --- a/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +++ b/build/VS2010/fullbench-dll/fullbench-dll.vcxproj @@ -1,4 +1,4 @@ - + @@ -19,7 +19,7 @@ - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8} + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8} Win32Proj fullbench-dll $(SolutionDir)bin\$(Platform)_$(Configuration)\ @@ -90,7 +90,7 @@ Level4 Disabled - WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) true false @@ -98,7 +98,7 @@ Console true $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - liblz4.lib;%(AdditionalDependencies) + libzstd.lib;%(AdditionalDependencies) @@ -107,7 +107,7 @@ Level4 Disabled - WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) true false @@ -115,7 +115,7 @@ Console true $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - liblz4.lib;%(AdditionalDependencies) + libzstd.lib;%(AdditionalDependencies) @@ -126,7 +126,7 @@ MaxSpeed true true - WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) false false MultiThreaded @@ -137,7 +137,7 @@ true true $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - liblz4.lib;%(AdditionalDependencies) + libzstd.lib;%(AdditionalDependencies) @@ -148,7 +148,7 @@ MaxSpeed true true - WIN32;_DEBUG;_CONSOLE;LZ4_DLL_IMPORT=1;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) false false MultiThreaded @@ -159,7 +159,7 @@ true true $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - liblz4.lib;%(AdditionalDependencies) + libzstd.lib;%(AdditionalDependencies) @@ -172,7 +172,12 @@ + + + {00000000-94d5-4bf9-8a50-7bd9929a0850} + + - + \ No newline at end of file diff --git a/build/VS2010/zstd.sln b/build/VS2010/zstd.sln index bb409abaf..12032db44 100644 --- a/build/VS2010/zstd.sln +++ b/build/VS2010/zstd.sln @@ -8,6 +8,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench-dll", "fullbench-dll\fullbench-dll.vcxproj", "{00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}" + ProjectSection(ProjectDependencies) = postProject + {00000000-94D5-4BF9-8A50-7BD9929A0850} = {00000000-94D5-4BF9-8A50-7BD9929A0850} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}" EndProject diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index d889c840f..266209e4c 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -234,7 +234,9 @@ int ZSTD_isSkipFrame(ZSTD_DCtx* dctx); /* custom memory allocation functions */ void* ZSTD_defaultAllocFunction(void* opaque, size_t size); void ZSTD_defaultFreeFunction(void* opaque, void* address); +#ifndef ZSTD_DLL_IMPORT static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL }; +#endif void* ZSTD_malloc(size_t size, ZSTD_customMem customMem); void ZSTD_free(void* ptr, ZSTD_customMem customMem); diff --git a/lib/zstd.h b/lib/zstd.h index eb2451cd3..7db135b5b 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -23,8 +23,10 @@ extern "C" { * ZSTD_DLL_EXPORT : * Enable exporting of functions when building a Windows DLL */ -#if defined(_WIN32) && defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) # define ZSTDLIB_API __declspec(dllexport) +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDLIB_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ #else # define ZSTDLIB_API #endif diff --git a/tests/fullbench.c b/tests/fullbench.c index ffc32f9bb..1f82e478f 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -112,6 +112,7 @@ size_t local_ZSTD_decompress(void* dst, size_t dstSize, void* buff2, const void* } static ZSTD_DCtx* g_zdc = NULL; +#ifndef ZSTD_DLL_IMPORT extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize); size_t local_ZSTD_decodeLiteralsBlock(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize) { @@ -127,7 +128,7 @@ size_t local_ZSTD_decodeSeqHeaders(void* dst, size_t dstSize, void* buff2, const (void)src; (void)srcSize; (void)dst; (void)dstSize; return ZSTD_decodeSeqHeaders(g_zdc, &nbSeq, buff2, g_cSize); } - +#endif static ZSTD_CStream* g_cstream= NULL; size_t local_ZSTD_compressStream(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) @@ -222,13 +223,15 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) case 12: benchFunction = local_ZSTD_decompressContinue; benchName = "ZSTD_decompressContinue"; break; - case 31: +#ifndef ZSTD_DLL_IMPORT + case 31: benchFunction = local_ZSTD_decodeLiteralsBlock; benchName = "ZSTD_decodeLiteralsBlock"; break; case 32: benchFunction = local_ZSTD_decodeSeqHeaders; benchName = "ZSTD_decodeSeqHeaders"; break; - case 41: +#endif + case 41: benchFunction = local_ZSTD_compressStream; benchName = "ZSTD_compressStream"; break; case 42: @@ -260,6 +263,7 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, 1); break; +#ifndef ZSTD_DLL_IMPORT case 31: /* ZSTD_decodeLiteralsBlock */ if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); { blockProperties_t bp; @@ -304,6 +308,7 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) srcSize = srcSize > 128 KB ? 128 KB : srcSize; /* speed relative to block */ break; } +#endif case 41 : if (g_cstream==NULL) g_cstream = ZSTD_createCStream(); break; From 811b34d962a400847926230677691bd11bf34b36 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 15 Nov 2016 19:02:39 +0100 Subject: [PATCH 048/185] fix Visual Studio warnings --- tests/fullbench.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/fullbench.c b/tests/fullbench.c index 1f82e478f..46af8172a 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -308,6 +308,9 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) srcSize = srcSize > 128 KB ? 128 KB : srcSize; /* speed relative to block */ break; } +#else + case 31: + goto _cleanOut; #endif case 41 : if (g_cstream==NULL) g_cstream = ZSTD_createCStream(); From f147fccd0c5da08ab05995b85922444f575c9183 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 15 Nov 2016 16:39:09 -0800 Subject: [PATCH 049/185] [pzstd] Fix frame size for small files + add logging --- contrib/pzstd/Pzstd.cpp | 15 ++++++--------- contrib/pzstd/Pzstd.h | 12 ++++++++++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index c5b4ce4cb..1778fef25 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -341,15 +341,7 @@ static size_t calculateStep( std::uintmax_t size, size_t numThreads, const ZSTD_parameters ¶ms) { - size_t step = size_t{1} << (params.cParams.windowLog + 2); - // If file size is known, see if a smaller step will spread work more evenly - if (size != 0) { - const std::uintmax_t newStep = size / numThreads; - if (newStep != 0 && newStep <= std::numeric_limits::max()) { - step = std::min(step, static_cast(newStep)); - } - } - return step; + return size_t{1} << (params.cParams.windowLog + 2); } namespace { @@ -401,6 +393,7 @@ std::uint64_t asyncCompressChunks( // Break the input up into chunks of size `step` and compress each chunk // independently. size_t step = calculateStep(size, numThreads, params); + state.log(DEBUG, "Chosen frame size: %zu\n", step); auto status = FileStatus::Continue; while (status == FileStatus::Continue && !state.errorHolder.hasError()) { // Make a new input queue that we will put the chunk's input data into. @@ -415,6 +408,7 @@ std::uint64_t asyncCompressChunks( }); // Pass the output queue to the writer thread. chunks.push(std::move(out)); + state.log(VERBOSE, "Starting a new frame\n"); // Fill the input queue for the compression job we just started status = readData(*in, ZSTD_CStreamInSize(), step, fd, &bytesRead); } @@ -551,11 +545,14 @@ std::uint64_t asyncDecompressFrames( if (frameSize == 0) { // We hit a non SkippableFrame ==> not compressed by pzstd or corrupted // Pass the rest of the source to this decompression task + state.log(VERBOSE, + "Input not in pzstd format, falling back to serial decompression\n"); while (status == FileStatus::Continue && !state.errorHolder.hasError()) { status = readData(*in, chunkSize, chunkSize, fd, &totalBytesRead); } break; } + state.log(VERBOSE, "Decompressing a frame of size %zu", frameSize); // Fill the input queue for the decompression job we just started status = readData(*in, chunkSize, frameSize, fd, &totalBytesRead); } diff --git a/contrib/pzstd/Pzstd.h b/contrib/pzstd/Pzstd.h index 9fb2c4884..dc60dd9b8 100644 --- a/contrib/pzstd/Pzstd.h +++ b/contrib/pzstd/Pzstd.h @@ -40,7 +40,8 @@ class SharedState { if (!options.decompress) { auto parameters = options.determineParameters(); cStreamPool.reset(new ResourcePool{ - [parameters]() -> ZSTD_CStream* { + [this, parameters]() -> ZSTD_CStream* { + this->log(VERBOSE, "Creating new ZSTD_CStream\n"); auto zcs = ZSTD_createCStream(); if (zcs) { auto err = ZSTD_initCStream_advanced( @@ -57,7 +58,8 @@ class SharedState { }}); } else { dStreamPool.reset(new ResourcePool{ - []() -> ZSTD_DStream* { + [this]() -> ZSTD_DStream* { + this->log(VERBOSE, "Creating new ZSTD_DStream\n"); auto zds = ZSTD_createDStream(); if (zds) { auto err = ZSTD_initDStream(zds); @@ -74,6 +76,12 @@ class SharedState { } } + ~SharedState() { + // The resource pools have references to this, so destroy them first. + cStreamPool.reset(); + dStreamPool.reset(); + } + Logger log; ErrorHolder errorHolder; std::unique_ptr> cStreamPool; From bcd61586a86dd3efb9b800636f6c7c83b10942cb Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 15 Nov 2016 17:46:28 -0800 Subject: [PATCH 050/185] [pzstd] Cast unused parameters to void --- contrib/pzstd/Pzstd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index 1778fef25..f4cb19d9c 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -341,6 +341,8 @@ static size_t calculateStep( std::uintmax_t size, size_t numThreads, const ZSTD_parameters ¶ms) { + (void)size; + (void)numThreads; return size_t{1} << (params.cParams.windowLog + 2); } From 52afb3993ee93dbbac1fd7f732e0cdfd401f91aa Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 16 Nov 2016 08:50:54 -0800 Subject: [PATCH 051/185] zbuff API now generates deprecation warnings --- NEWS | 4 ++- lib/Makefile | 3 +- lib/README.md | 6 ++-- lib/common/zbuff.h | 73 +++++++++++++++++++++++++++++----------------- programs/zstdcli.c | 2 +- tests/Makefile | 15 ++++------ 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/NEWS b/NEWS index df23a2914..e6fb2be6c 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ v1.1.2 -New : cli : status displays total amount decoded when stream/file consists of multiple appended frames (like pzstd) +cli : new : preserve file attributes, by Przemyslaw Skibinski +cli : fixed : status displays total amount decoded when stream/file consists of multiple appended frames (like pzstd) +API : changed : zbuff prototypes now generate deprecation warnings v1.1.1 New : command -M#, --memory=, --memlimit=, --memlimit-decompress= to limit allowed memory consumption diff --git a/lib/Makefile b/lib/Makefile index 02eefc3f7..3aacb831c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -23,7 +23,7 @@ PREFIX ?= /usr/local LIBDIR ?= $(PREFIX)/lib INCLUDEDIR=$(PREFIX)/include -CPPFLAGS= -I. -I./common +CPPFLAGS= -I. -I./common -DXXH_NAMESPACE=XXH_ CFLAGS ?= -O3 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \ @@ -110,6 +110,7 @@ install: libzstd.a libzstd libzstd.pc @install -m 644 libzstd.a $(DESTDIR)$(LIBDIR)/libzstd.a @install -m 644 zstd.h $(DESTDIR)$(INCLUDEDIR)/zstd.h @install -m 644 common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h + @install -m 644 common/zbuff.h $(DESTDIR)$(INCLUDEDIR)/zbuff.h @install -m 644 dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)/zdict.h @echo zstd static and shared library installed diff --git a/lib/README.md b/lib/README.md index efcbdc616..d321f06b3 100644 --- a/lib/README.md +++ b/lib/README.md @@ -46,9 +46,9 @@ Other optional functionalities provided are : #### Obsolete streaming API Streaming is now provided within `zstd.h`. -Older streaming API is still provided within `common/zbuff.h`. -It is considered obsolete, and will be removed in a future version. -Consider migrating towards newer streaming API. +Older streaming API is still available within `common/zbuff.h`. +It is now deprecated, and will be removed in a future version. +Consider migrating towards newer streaming API in `zstd.h`. #### Miscellaneous diff --git a/lib/common/zbuff.h b/lib/common/zbuff.h index f99e06197..e8af504de 100644 --- a/lib/common/zbuff.h +++ b/lib/common/zbuff.h @@ -9,11 +9,11 @@ /* *************************************************************** * NOTES/WARNINGS -*****************************************************************/ -/* The streaming API defined here will soon be deprecated by the -* new one in 'zstd.h'; consider migrating towards newer streaming -* API. See 'lib/README.md'. -*****************************************************************/ +******************************************************************/ +/* The streaming API defined here is deprecated. + * Consider migrating towards ZSTD_compressStream() API in `zstd.h` + * See 'lib/README.md'. + *****************************************************************/ #ifndef ZSTD_BUFFERED_H_23987 #define ZSTD_BUFFERED_H_23987 @@ -39,6 +39,27 @@ extern "C" { # define ZSTDLIB_API #endif +/* Deprecation warnings */ +/* Should these warnings be a problem, + it is generally possible to disable them, + typically with -Wno-deprecated-declarations for gcc + or _CRT_SECURE_NO_WARNINGS in Visual. + Otherwise, it's also possible to define ZBUFF_DISABLE_DEPRECATE_WARNINGS */ +#ifdef ZBUFF_DISABLE_DEPRECATE_WARNINGS +# define ZBUFF_DEPRECATED(message) /* disable deprecation warnings */ +#else +# if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) +# define ZBUFF_DEPRECATED(message) __attribute__((deprecated(message))) +# elif defined(__GNUC__) && (__GNUC__ >= 3) +# define ZBUFF_DEPRECATED(message) __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define ZBUFF_DEPRECATED(message) __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement ZBUFF_DEPRECATED for this compiler") +# define ZBUFF_DEPRECATED(message) +# endif +#endif /* ZBUFF_DISABLE_DEPRECATE_WARNINGS */ + /* ************************************* * Streaming functions @@ -50,15 +71,15 @@ extern "C" { * frames created by one can be decoded by the other one */ typedef struct ZBUFF_CCtx_s ZBUFF_CCtx; -ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx(void); -ZSTDLIB_API size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx); +ZBUFF_DEPRECATED("use ZSTD_createCStream") ZBUFF_CCtx* ZBUFF_createCCtx(void); +ZBUFF_DEPRECATED("use ZSTD_freeCStream") size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx); -ZSTDLIB_API size_t ZBUFF_compressInit(ZBUFF_CCtx* cctx, int compressionLevel); -ZSTDLIB_API size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); +ZBUFF_DEPRECATED("use ZSTD_initCStream") size_t ZBUFF_compressInit(ZBUFF_CCtx* cctx, int compressionLevel); +ZBUFF_DEPRECATED("use ZSTD_initCStream_usingDict") size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); -ZSTDLIB_API size_t ZBUFF_compressContinue(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr, const void* src, size_t* srcSizePtr); -ZSTDLIB_API size_t ZBUFF_compressFlush(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr); -ZSTDLIB_API size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr); +ZBUFF_DEPRECATED("use ZSTD_compressStream") size_t ZBUFF_compressContinue(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr, const void* src, size_t* srcSizePtr); +ZBUFF_DEPRECATED("use ZSTD_flushStream") size_t ZBUFF_compressFlush(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr); +ZBUFF_DEPRECATED("use ZSTD_endStream") size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr); /*-************************************************* * Streaming compression - howto @@ -102,13 +123,13 @@ ZSTDLIB_API size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* dstCap typedef struct ZBUFF_DCtx_s ZBUFF_DCtx; -ZSTDLIB_API ZBUFF_DCtx* ZBUFF_createDCtx(void); -ZSTDLIB_API size_t ZBUFF_freeDCtx(ZBUFF_DCtx* dctx); +ZBUFF_DEPRECATED("use ZSTD_createDStream") ZBUFF_DCtx* ZBUFF_createDCtx(void); +ZBUFF_DEPRECATED("use ZSTD_freeDStream") size_t ZBUFF_freeDCtx(ZBUFF_DCtx* dctx); -ZSTDLIB_API size_t ZBUFF_decompressInit(ZBUFF_DCtx* dctx); -ZSTDLIB_API size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* dctx, const void* dict, size_t dictSize); +ZBUFF_DEPRECATED("use ZSTD_initDStream") size_t ZBUFF_decompressInit(ZBUFF_DCtx* dctx); +ZBUFF_DEPRECATED("use ZSTD_initDStream_usingDict") size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, +ZBUFF_DEPRECATED("use ZSTD_decompressStream") size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, void* dst, size_t* dstCapacityPtr, const void* src, size_t* srcSizePtr); @@ -141,15 +162,15 @@ ZSTDLIB_API size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, /* ************************************* * Tool functions ***************************************/ -ZSTDLIB_API unsigned ZBUFF_isError(size_t errorCode); -ZSTDLIB_API const char* ZBUFF_getErrorName(size_t errorCode); +ZBUFF_DEPRECATED("use ZSTD_isError") unsigned ZBUFF_isError(size_t errorCode); +ZBUFF_DEPRECATED("use ZSTD_getErrorName") const char* ZBUFF_getErrorName(size_t errorCode); /** Functions below provide recommended buffer sizes for Compression or Decompression operations. * These sizes are just hints, they tend to offer better latency */ -ZSTDLIB_API size_t ZBUFF_recommendedCInSize(void); -ZSTDLIB_API size_t ZBUFF_recommendedCOutSize(void); -ZSTDLIB_API size_t ZBUFF_recommendedDInSize(void); -ZSTDLIB_API size_t ZBUFF_recommendedDOutSize(void); +ZBUFF_DEPRECATED("use ZSTD_CStreamInSize") size_t ZBUFF_recommendedCInSize(void); +ZBUFF_DEPRECATED("use ZSTD_CStreamOutSize") size_t ZBUFF_recommendedCOutSize(void); +ZBUFF_DEPRECATED("use ZSTD_DStreamInSize") size_t ZBUFF_recommendedDInSize(void); +ZBUFF_DEPRECATED("use ZSTD_DStreamOutSize") size_t ZBUFF_recommendedDOutSize(void); #ifdef ZBUFF_STATIC_LINKING_ONLY @@ -169,15 +190,15 @@ ZSTDLIB_API size_t ZBUFF_recommendedDOutSize(void); /*--- Custom memory allocator ---*/ /*! ZBUFF_createCCtx_advanced() : * Create a ZBUFF compression context using external alloc and free functions */ -ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem); +ZBUFF_DEPRECATED("use ZSTD_createCStream_advanced") ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem); /*! ZBUFF_createDCtx_advanced() : * Create a ZBUFF decompression context using external alloc and free functions */ -ZSTDLIB_API ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem); +ZBUFF_DEPRECATED("use ZSTD_createDStream_advanced") ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem); /*--- Advanced Streaming Initialization ---*/ -ZSTDLIB_API size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, +ZBUFF_DEPRECATED("use ZSTD_initDStream_usingDict") size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index a4b8486bf..63ee99dac 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -21,7 +21,7 @@ /*-************************************ -* Includes +* Dependencies **************************************/ #include "util.h" /* Compiler options, UTIL_HAS_CREATEFILELIST */ #include /* strcmp, strlen */ diff --git a/tests/Makefile b/tests/Makefile index c931adbe4..d3a280e58 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -14,10 +14,8 @@ # paramgrill : parameter tester for zstd # test-zstd-speed.py : script for testing zstd speed difference between commits # versionsTest : compatibility test between zstd versions stored on Github (v0.1+) -# zbufftest : Test tool, to check ZBUFF integrity on target platform -# zbufftest32: Same as zbufftest, but forced to compile in 32-bits mode # zstreamtest : Fuzzer test tool for zstd streaming API -# zbufftest32: Same as zstreamtest, but forced to compile in 32-bits mode +# zstreamtest32: Same as zstreamtest, but forced to compile in 32-bits mode # ########################################################################## DESTDIR?= @@ -63,9 +61,9 @@ ZSTDRTTEST= --test-large-data default: fullbench -all: fullbench fuzzer zbufftest zstreamtest paramgrill datagen +all: fullbench fuzzer zstreamtest paramgrill datagen -all32: fullbench32 fuzzer32 zbufftest32 zstreamtest32 +all32: fullbench32 fuzzer32 zstreamtest32 @@ -139,7 +137,7 @@ ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD Dr HOST_OS = POSIX valgrindTest: VALGRIND = valgrind --leak-check=full --error-exitcode=1 -valgrindTest: zstd datagen fuzzer fullbench zbufftest +valgrindTest: zstd datagen fuzzer fullbench @echo "\n ---- valgrind tests : memory analyzer ----" $(VALGRIND) ./datagen -g50M > $(VOID) $(VALGRIND) $(PRGDIR)/zstd ; if [ $$? -eq 0 ] ; then echo "zstd without argument should have failed"; false; fi @@ -151,7 +149,6 @@ valgrindTest: zstd datagen fuzzer fullbench zbufftest @rm tmp $(VALGRIND) ./fuzzer -T1mn -t1 $(VALGRIND) ./fullbench -i1 - $(VALGRIND) ./zbufftest -T1mn endif @@ -169,9 +166,9 @@ zstd-playTests: datagen file $(ZSTD) ZSTD="$(QEMU_SYS) $(ZSTD)" ./playTests.sh $(ZSTDRTTEST) -test: test-zstd test-fullbench test-fuzzer test-zbuff test-zstream +test: test-zstd test-fullbench test-fuzzer test-zstream -test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zbuff32 test-zstream32 +test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zstream32 test-all: test test32 valgrindTest From 883a7cacc4b58ca2de4ce91229f20811895c8db5 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 16 Nov 2016 08:58:32 -0800 Subject: [PATCH 052/185] removed zbufftest from list of clang tests on Appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 6c1e0bc2c..f49d7cf42 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,7 +25,7 @@ install: - MKDIR bin - if [%COMPILER%]==[gcc] SET PATH_ORIGINAL=%PATH% - if [%COMPILER%]==[gcc] ( - SET "CLANG_PARAMS=-C tests zstd fullbench fuzzer zbufftest paramgrill datagen CC=clang MOREFLAGS="--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion"" && + SET "CLANG_PARAMS=-C tests zstd fullbench fuzzer paramgrill datagen CC=clang MOREFLAGS="--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion"" && SET "PATH_MINGW32=c:\MinGW\bin;c:\MinGW\usr\bin" && SET "PATH_MINGW64=c:\msys64\mingw64\bin;c:\msys64\usr\bin" && COPY C:\MinGW\bin\mingw32-make.exe C:\MinGW\bin\make.exe && From 3d18088b386e349fd51ddd11b765efe7d85577e8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 17 Nov 2016 18:04:41 +0100 Subject: [PATCH 053/185] updated windres --- lib/compress/zstd_compress.c | 4 ++-- programs/windres/zstd32.res | Bin 1044 -> 1044 bytes programs/windres/zstd64.res | Bin 1044 -> 1044 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index d152d10dc..f7286ae8f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -739,8 +739,8 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v { #if 0 /* for debug */ static const BYTE* g_start = NULL; - const U32 pos = (U32)(literals - g_start); - if (g_start==NULL) g_start = literals; + const U32 pos = (U32)((const BYTE*)literals - g_start); + if (g_start==NULL) g_start = (const BYTE*)literals; //if ((pos > 1) && (pos < 50000)) printf("Cpos %6u :%5u literals & match %3u bytes at distance %6u \n", pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode); diff --git a/programs/windres/zstd32.res b/programs/windres/zstd32.res index aec8fcf24e4f15e1915af725ba5b957fa3e7b50a..6135dc431fed231ce2143b394625bc0b52b0615a 100644 GIT binary patch delta 33 pcmbQjF@ Date: Fri, 18 Nov 2016 11:46:30 +0100 Subject: [PATCH 054/185] bench.c without dict uses ZSTD_compressCCtx --- .gitignore | 2 ++ programs/bench.c | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 220a1e0eb..6f792e615 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ _zstdbench/ .DS_Store googletest/ *.d + +build/VS2010/zwrapbench/zwrapbench.vcxproj \ No newline at end of file diff --git a/programs/bench.c b/programs/bench.c index 7b6e25206..df68d0ada 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -213,11 +213,18 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure"); do { U32 blockNb; + size_t rSize; for (blockNb=0; blockNb Date: Mon, 21 Nov 2016 12:33:10 +0100 Subject: [PATCH 055/185] VC projects: removed ZBUFF references --- build/.gitignore | 1 + build/VS2010/fullbench/fullbench.vcxproj | 3 --- build/VS2010/fuzzer/fuzzer.vcxproj | 1 - build/VS2010/libzstd-dll/libzstd-dll.vcxproj | 3 --- build/VS2010/libzstd/libzstd.vcxproj | 3 --- build/VS2010/zstd/zstd.vcxproj | 3 --- 6 files changed, 1 insertion(+), 13 deletions(-) diff --git a/build/.gitignore b/build/.gitignore index bc8ac94d9..51fed59bb 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -6,6 +6,7 @@ *.sdf *.suo *.user +*.opendb VS2005/ VS2008/ diff --git a/build/VS2010/fullbench/fullbench.vcxproj b/build/VS2010/fullbench/fullbench.vcxproj index 67fd62ba7..e16f5e1db 100644 --- a/build/VS2010/fullbench/fullbench.vcxproj +++ b/build/VS2010/fullbench/fullbench.vcxproj @@ -162,10 +162,8 @@ - - @@ -174,7 +172,6 @@ - diff --git a/build/VS2010/fuzzer/fuzzer.vcxproj b/build/VS2010/fuzzer/fuzzer.vcxproj index 82fc02167..7227c7ec0 100644 --- a/build/VS2010/fuzzer/fuzzer.vcxproj +++ b/build/VS2010/fuzzer/fuzzer.vcxproj @@ -174,7 +174,6 @@ - diff --git a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj index 5b894b05b..81da84c7d 100644 --- a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj +++ b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj @@ -26,10 +26,8 @@ - - @@ -49,7 +47,6 @@ - diff --git a/build/VS2010/libzstd/libzstd.vcxproj b/build/VS2010/libzstd/libzstd.vcxproj index 18f9f643b..661c20dfc 100644 --- a/build/VS2010/libzstd/libzstd.vcxproj +++ b/build/VS2010/libzstd/libzstd.vcxproj @@ -26,10 +26,8 @@ - - @@ -49,7 +47,6 @@ - diff --git a/build/VS2010/zstd/zstd.vcxproj b/build/VS2010/zstd/zstd.vcxproj index c7a9ed73c..5b5852689 100644 --- a/build/VS2010/zstd/zstd.vcxproj +++ b/build/VS2010/zstd/zstd.vcxproj @@ -26,10 +26,8 @@ - - @@ -52,7 +50,6 @@ - From 93a09eedf1bb6c281f003aaae37cd2f0a1d3cf80 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 12:33:27 +0100 Subject: [PATCH 056/185] added libzstd.def --- lib/dll/libzstd.def | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 lib/dll/libzstd.def diff --git a/lib/dll/libzstd.def b/lib/dll/libzstd.def new file mode 100644 index 000000000..0a3259e9e --- /dev/null +++ b/lib/dll/libzstd.def @@ -0,0 +1,86 @@ +LIBRARY libzstd.dll +EXPORTS + ZDICT_getDictID + ZDICT_getErrorName + ZDICT_isError + ZDICT_trainFromBuffer + ZSTD_CStreamInSize + ZSTD_CStreamOutSize + ZSTD_DStreamInSize + ZSTD_DStreamOutSize + ZSTD_adjustCParams + ZSTD_checkCParams + ZSTD_compress + ZSTD_compressBegin + ZSTD_compressBegin_advanced + ZSTD_compressBegin_usingDict + ZSTD_compressBlock + ZSTD_compressBound + ZSTD_compressCCtx + ZSTD_compressContinue + ZSTD_compressEnd + ZSTD_compressStream + ZSTD_compress_advanced + ZSTD_compress_usingCDict + ZSTD_compress_usingDict + ZSTD_copyCCtx + ZSTD_copyDCtx + ZSTD_createCCtx + ZSTD_createCCtx_advanced + ZSTD_createCDict + ZSTD_createCDict_advanced + ZSTD_createCStream + ZSTD_createCStream_advanced + ZSTD_createDCtx + ZSTD_createDCtx_advanced + ZSTD_createDDict + ZSTD_createDStream + ZSTD_createDStream_advanced + ZSTD_decompress + ZSTD_decompressBegin + ZSTD_decompressBegin_usingDict + ZSTD_decompressBlock + ZSTD_decompressContinue + ZSTD_decompressDCtx + ZSTD_decompressStream + ZSTD_decompress_usingDDict + ZSTD_decompress_usingDict + ZSTD_endStream + ZSTD_estimateCCtxSize + ZSTD_estimateDCtxSize + ZSTD_flushStream + ZSTD_freeCCtx + ZSTD_freeCDict + ZSTD_freeCStream + ZSTD_freeDCtx + ZSTD_freeDDict + ZSTD_freeDStream + ZSTD_getBlockSizeMax + ZSTD_getCParams + ZSTD_getDecompressedSize + ZSTD_getErrorName + ZSTD_getFrameParams + ZSTD_getParams + ZSTD_initCStream + ZSTD_initCStream_advanced + ZSTD_initCStream_usingCDict + ZSTD_initCStream_usingDict + ZSTD_initDStream + ZSTD_initDStream_usingDDict + ZSTD_initDStream_usingDict + ZSTD_insertBlock + ZSTD_isError + ZSTD_isFrame + ZSTD_maxCLevel + ZSTD_nextInputType + ZSTD_nextSrcSizeToDecompress + ZSTD_resetCStream + ZSTD_resetDStream + ZSTD_setDStreamParameter + ZSTD_sizeof_CCtx + ZSTD_sizeof_CDict + ZSTD_sizeof_CStream + ZSTD_sizeof_DCtx + ZSTD_sizeof_DDict + ZSTD_sizeof_DStream + ZSTD_versionNumber From 8bb86e330b80bfb29fffc25fa38affdb2dfa44e9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 12:51:01 +0100 Subject: [PATCH 057/185] create DLL with Windows --- lib/Makefile | 9 ++++++--- tests/Makefile | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 3aacb831c..681c048c6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -72,8 +72,11 @@ libzstd.a: $(ZSTD_FILES) $(LIBZSTD): LDFLAGS += -shared -fPIC $(LIBZSTD): $(ZSTD_FILES) @echo compiling dynamic library $(LIBVER) +ifneq (,$(filter Windows%,$(OS))) + @$(CC) $(FLAGS) -DZSTD_DLL_EXPORT=1 -shared $^ -o dll\libzstd.dll + dlltool -D dll\libzstd.dll -d dll\libzstd.def -l dll\libzstd.lib +else @$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ -ifeq (,$(filter Windows%,$(OS))) @echo creating versioned links @ln -sf $@ libzstd.$(SHARED_EXT_MAJOR) @ln -sf $@ libzstd.$(SHARED_EXT) @@ -84,8 +87,8 @@ libzstd : $(LIBZSTD) lib: libzstd.a libzstd clean: - @rm -f core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc - @rm -f decompress/*.o + @$(RM) -f core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc dll/libzstd.dll dll/libzstd.lib + @$(RM) -f decompress/*.o @echo Cleaning library completed #------------------------------------------------------------------------ diff --git a/tests/Makefile b/tests/Makefile index d3a280e58..e2e8e0881 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -82,6 +82,14 @@ fullbench : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c fullbench32 : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c $(CC) -m32 $(FLAGS) $^ -o $@$(EXT) +fullbench-lib: $(PRGDIR)/datagen.c fullbench.c + $(MAKE) -C $(ZSTDDIR) libzstd.a + $(CC) $(FLAGS) $^ -o $@$(EXT) $(ZSTDDIR)/libzstd.a + +fullbench-dll: $(PRGDIR)/datagen.c fullbench.c + $(MAKE) -C $(ZSTDDIR) libzstd + $(CC) $(FLAGS) $^ -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll + fuzzer : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder fuzzer : $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c $(CC) $(FLAGS) $^ -o $@$(EXT) From cc3887085f938464ad0cad34b6b0e4c0b7f1bf05 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 13:58:58 +0100 Subject: [PATCH 058/185] updated build\README.md --- .gitignore | 3 ++- build/.gitignore | 1 + build/README.md | 33 +++++++++++++++++++++++++++++++++ tests/Makefile | 1 + tests/fullbench.c | 21 ++++++++++++++------- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 6f792e615..796a696d3 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,5 @@ _zstdbench/ googletest/ *.d -build/VS2010/zwrapbench/zwrapbench.vcxproj \ No newline at end of file +# Directories +bin/ diff --git a/build/.gitignore b/build/.gitignore index 51fed59bb..f03aac8b3 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -11,6 +11,7 @@ VS2005/ VS2008/ VS2010/bin/ +VS2010/zwrapbench/ VS2012/bin/ VS2013/bin/ VS2015/bin/ diff --git a/build/README.md b/build/README.md index 8dc67326b..c4abe9efd 100644 --- a/build/README.md +++ b/build/README.md @@ -21,3 +21,36 @@ The following projects are included with the zstd distribution: 6. Change `Debug` to `Release` and if you have 64-bit Windows change also `Win32` to `x64`. 7. Press F7 on keyboard or select `BUILD` from the menu bar and choose `Build Solution`. 8. If compilation will be fine a compiled executable will be in `projects\VS2010\bin\x64\Release\zstd.exe` + + +#### Projects available within zstd.sln + +The Visual Studio solution file `visual\VS2010\zstd.sln` contains many projects that will be compiled to the +`visual\VS2010\bin\$(Platform)_$(Configuration)` directory. For example `zstd` set to `x64` and +`Release` will be compiled to `visual\VS2010\bin\x64_Release\zstd.exe`. The solution file contains the +following projects: + +- `zstd` : Command Line Utility, supporting gzip-like arguments +- `datagen` : Synthetic and parametrable data generator, for tests +- `fullbench` : Precisely measure speed for each zstd inner functions +- `fuzzer` : Test tool, to check zstd integrity on target platform +- `libzstd` : A static ZSTD library compiled to `libzstd_static.lib` +- `libzstd-dll` : A dynamic ZSTD library (DLL) compiled to `libzstd.dll` with the import library `libzstd.lib` +- `fullbench-dll` : The fullbench program compiled with the import library; the executable requires ZSTD DLL + + +#### Using ZSTD DLL with Microsoft Visual C++ project + +The header file `lib\zstd.h` and the import library +`visual\VS2010\bin\$(Platform)_$(Configuration)\libzstd.lib` are required to compile +a project using Visual C++. + +1. The path to header files should be added to `Additional Include Directories` that can + be found in Project Properties of Visual Studio IDE in the `C/C++` Property Pages on the `General` page. +2. The import library has to be added to `Additional Dependencies` that can + be found in Project Properties in the `Linker` Property Pages on the `Input` page. + If one will provide only the name `libzstd.lib` without a full path to the library + then the directory has to be added to `Linker\General\Additional Library Directories`. + +The compiled executable will require ZSTD DLL which is available at +`visual\VS2010\bin\$(Platform)_$(Configuration)\libzstd.dll`. diff --git a/tests/Makefile b/tests/Makefile index e2e8e0881..7e5c66ad8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -132,6 +132,7 @@ clean: @$(RM) -f core *.o tmp* result* *.gcda dictionary *.zst \ $(PRGDIR)/zstd$(EXT) $(PRGDIR)/zstd32$(EXT) \ fullbench$(EXT) fullbench32$(EXT) \ + fullbench-lib$(EXT) fullbench-dll$(EXT) \ fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \ zstreamtest$(EXT) zstreamtest32$(EXT) \ datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) diff --git a/tests/fullbench.c b/tests/fullbench.c index 46af8172a..233b4e931 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -17,11 +17,16 @@ #include /* clock_t, clock, CLOCKS_PER_SEC */ #include "mem.h" -#include "zstd_internal.h" /* ZSTD_blockHeaderSize, blockType_e, KB, MB */ -#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressBegin, ZSTD_compressContinue, etc. */ +#ifndef ZSTD_DLL_IMPORT + #include "zstd_internal.h" /* ZSTD_blockHeaderSize, blockType_e, KB, MB */ + #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressBegin, ZSTD_compressContinue, etc. */ +#else + #define KB *(1 <<10) + #define MB *(1 <<20) + #define GB *(1U<<30) + typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; +#endif #include "zstd.h" /* ZSTD_VERSION_STRING */ -#define FSE_STATIC_LINKING_ONLY /* FSE_DTABLE_SIZE_U32 */ -#include "fse.h" #include "datagen.h" @@ -111,8 +116,8 @@ size_t local_ZSTD_decompress(void* dst, size_t dstSize, void* buff2, const void* return ZSTD_decompress(dst, dstSize, buff2, g_cSize); } -static ZSTD_DCtx* g_zdc = NULL; #ifndef ZSTD_DLL_IMPORT +static ZSTD_DCtx* g_zdc = NULL; extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize); size_t local_ZSTD_decodeLiteralsBlock(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize) { @@ -165,6 +170,7 @@ static size_t local_ZSTD_decompressStream(void* dst, size_t dstCapacity, void* b return buffOut.pos; } +#ifndef ZSTD_DLL_IMPORT static ZSTD_CCtx* g_zcc = NULL; size_t local_ZSTD_compressContinue(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) { @@ -194,6 +200,7 @@ size_t local_ZSTD_decompressContinue(void* dst, size_t dstCapacity, void* buff2, return regeneratedSize; } +#endif /*_******************************************************* @@ -217,13 +224,13 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) case 2: benchFunction = local_ZSTD_decompress; benchName = "ZSTD_decompress"; break; +#ifndef ZSTD_DLL_IMPORT case 11: benchFunction = local_ZSTD_compressContinue; benchName = "ZSTD_compressContinue"; break; case 12: benchFunction = local_ZSTD_decompressContinue; benchName = "ZSTD_decompressContinue"; break; -#ifndef ZSTD_DLL_IMPORT case 31: benchFunction = local_ZSTD_decodeLiteralsBlock; benchName = "ZSTD_decodeLiteralsBlock"; break; @@ -256,6 +263,7 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) case 2: g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, 1); break; +#ifndef ZSTD_DLL_IMPORT case 11 : if (g_zcc==NULL) g_zcc = ZSTD_createCCtx(); break; @@ -263,7 +271,6 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, 1); break; -#ifndef ZSTD_DLL_IMPORT case 31: /* ZSTD_decodeLiteralsBlock */ if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); { blockProperties_t bp; From b85f7677433f7f16e8ef72956086312ef3604746 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 14:10:55 +0100 Subject: [PATCH 059/185] files to generate ZSTD Windows binary package --- lib/dll/example/Makefile | 47 +++++++ lib/dll/example/README.md | 69 ++++++++++ lib/dll/example/build_package.bat | 17 +++ lib/dll/example/fullbench-dll.sln | 25 ++++ lib/dll/example/fullbench-dll.vcxproj | 179 ++++++++++++++++++++++++++ 5 files changed, 337 insertions(+) create mode 100644 lib/dll/example/Makefile create mode 100644 lib/dll/example/README.md create mode 100644 lib/dll/example/build_package.bat create mode 100644 lib/dll/example/fullbench-dll.sln create mode 100644 lib/dll/example/fullbench-dll.vcxproj diff --git a/lib/dll/example/Makefile b/lib/dll/example/Makefile new file mode 100644 index 000000000..36041a0e3 --- /dev/null +++ b/lib/dll/example/Makefile @@ -0,0 +1,47 @@ +# ########################################################################## +# Copyright (c) 2016-present, Yann Collet, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. +# ########################################################################## + +VOID := /dev/null +ZSTDDIR := ../include +LIBDIR := ../static +DLLDIR := ../dll + +CFLAGS ?= -O3 # can select custom flags. For example : CFLAGS="-O2 -g" make +CFLAGS += -Wall -Wextra -Wundef -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum \ + -Wdeclaration-after-statement -Wstrict-prototypes \ + -Wpointer-arith -Wstrict-aliasing=1 +CFLAGS += $(MOREFLAGS) +CPPFLAGS:= -I$(ZSTDDIR) -DXXH_NAMESPACE=ZSTD_ +FLAGS := $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) + + +# Define *.exe as extension for Windows systems +ifneq (,$(filter Windows%,$(OS))) +EXT =.exe +else +EXT = +endif + +.PHONY: default fullbench-dll fullbench-lib + + +default: all + +all: fullbench-dll fullbench-lib + + +fullbench-lib: fullbench.c datagen.c + $(CC) $(FLAGS) $^ -o $@$(EXT) $(LIBDIR)/libzstd_static.lib + +fullbench-dll: fullbench.c datagen.c + $(CC) $(FLAGS) $^ -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(DLLDIR)/libzstd.dll + +clean: + @$(RM) fullbench-dll$(EXT) fullbench-lib$(EXT) \ + @echo Cleaning completed diff --git a/lib/dll/example/README.md b/lib/dll/example/README.md new file mode 100644 index 000000000..34d19855c --- /dev/null +++ b/lib/dll/example/README.md @@ -0,0 +1,69 @@ +ZSTD Windows binary package +==================================== + +#### The package contents + +- `zstd.exe` : Command Line Utility, supporting gzip-like arguments +- `dll\libzstd.dll` : The DLL of ZSTD library +- `dll\libzstd.lib` : The import library of ZSTD library for Visual C++ +- `example\` : The example of usage of ZSTD library +- `include\` : Header files required with ZSTD library +- `static\libzstd_static.lib` : The static ZSTD library + + +#### Usage of Command Line Interface + +Command Line Interface (CLI) supports gzip-like arguments. +By default CLI takes an input file and compresses it to an output file: +``` + Usage: zstd [arg] [input] [output] +``` +The full list of commands for CLI can be obtained with `-h` or `-H`. The ratio can +be improved with commands from `-3` to `-16` but higher levels also have slower +compression. CLI includes in-memory compression benchmark module with compression +levels starting from `-b` and ending with `-e` with iteration time of `-i` seconds. +CLI supports aggregation of parameters i.e. `-b1`, `-e18`, and `-i1` can be joined +into `-b1e18i1`. + + +#### The example of usage of static and dynamic ZSTD libraries with gcc/MinGW + +Use `cd example` and `make` to build `fullbench-dll` and `fullbench-lib`. +`fullbench-dll` uses a dynamic ZSTD library from the `dll` directory. +`fullbench-lib` uses a static ZSTD library from the `lib` directory. + + +#### Using ZSTD DLL with gcc/MinGW + +The header files from `include\` and the dynamic library `dll\libzstd.dll` +are required to compile a project using gcc/MinGW. +The dynamic library has to be added to linking options. +It means that if a project that uses ZSTD consists of a single `test-dll.c` +file it should be compiled with "libzstd.dll". For example: +``` + gcc $(CFLAGS) -Iinclude\ test-dll.c -o test-dll dll\libzstd.dll +``` +The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. + + +#### The example of usage of static and dynamic ZSTD libraries with Visual C++ + +Open `example\fullbench-dll.sln` to compile `fullbench-dll` that uses a +dynamic ZSTD library from the `dll` directory. The solution works with Visual C++ +2010 or newer. When one will open the solution with Visual C++ newer than 2010 +then the solution will upgraded to the current version. + + +#### Using ZSTD DLL with Visual C++ + +The header files from `include\` and the import library `dll\libzstd.lib` +are required to compile a project using Visual C++. + +1. The path to header files should be added to `Additional Include Directories` that can + be found in project properties `C/C++` then `General`. +2. The import library has to be added to `Additional Dependencies` that can + be found in project properties `Linker` then `Input`. + If one will provide only the name `libzstd.lib` without a full path to the library + the directory has to be added to `Linker\General\Additional Library Directories`. + +The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. diff --git a/lib/dll/example/build_package.bat b/lib/dll/example/build_package.bat new file mode 100644 index 000000000..ce738a56c --- /dev/null +++ b/lib/dll/example/build_package.bat @@ -0,0 +1,17 @@ +@ECHO OFF +MKDIR bin\dll bin\static bin\example bin\include +COPY tests\fullbench.c bin\example\ +COPY programs\datagen.c bin\example\ +COPY programs\datagen.h bin\example\ +COPY programs\util.h bin\example\ +COPY lib\common\mem.h bin\example\ +COPY lib\common\zstd_errors.h bin\example\ +COPY lib\common\zstd_internal.h bin\example\ +COPY lib\common\error_private.h bin\example\ +COPY lib\zstd.h bin\include\ +COPY lib\libzstd.a bin\static\libzstd_static.lib +COPY lib\dll\libzstd.* bin\dll\ +COPY lib\dll\example\Makefile bin\example\ +COPY lib\dll\example\fullbench-dll.* bin\example\ +COPY lib\dll\example\README.md bin\ +COPY programs\zstd.exe bin\zstd.exe diff --git a/lib/dll/example/fullbench-dll.sln b/lib/dll/example/fullbench-dll.sln new file mode 100644 index 000000000..72e302e7f --- /dev/null +++ b/lib/dll/example/fullbench-dll.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2012 for Windows Desktop +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench-dll", "fullbench-dll.vcxproj", "{13992FD2-077E-4954-B065-A428198201A9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {13992FD2-077E-4954-B065-A428198201A9}.Debug|Win32.ActiveCfg = Debug|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Debug|Win32.Build.0 = Debug|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Debug|x64.ActiveCfg = Debug|x64 + {13992FD2-077E-4954-B065-A428198201A9}.Debug|x64.Build.0 = Debug|x64 + {13992FD2-077E-4954-B065-A428198201A9}.Release|Win32.ActiveCfg = Release|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Release|Win32.Build.0 = Release|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Release|x64.ActiveCfg = Release|x64 + {13992FD2-077E-4954-B065-A428198201A9}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/lib/dll/example/fullbench-dll.vcxproj b/lib/dll/example/fullbench-dll.vcxproj new file mode 100644 index 000000000..3faacbae1 --- /dev/null +++ b/lib/dll/example/fullbench-dll.vcxproj @@ -0,0 +1,179 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8} + Win32Proj + fullbench-dll + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + true + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + true + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + false + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + false + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + true + false + ..\include + + + Console + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + true + false + ..\include + + + Console + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + + + + + Level4 + + + MaxSpeed + true + true + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + false + ..\include + false + MultiThreaded + + + Console + true + true + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + + + + + Level4 + + + MaxSpeed + true + true + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + false + false + ..\include + MultiThreaded + + + Console + true + true + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + + + + + + + + + + + + + \ No newline at end of file From 62d19a6f39655578534999bc23dc673271ebff36 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 14:22:08 +0100 Subject: [PATCH 060/185] lib\README.md: added Using MinGW+MSYS to create DLL --- lib/README.md | 16 ++++++++++++++++ lib/dll/example/README.md | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/README.md b/lib/README.md index d321f06b3..d33ad52c2 100644 --- a/lib/README.md +++ b/lib/README.md @@ -43,6 +43,22 @@ Other optional functionalities provided are : For example, advanced API for version `v0.4` is in `legacy/zstd_v04.h` . +#### Using MinGW+MSYS to create DLL + +DLL can be created using MinGW+MSYS with the `make libzstd` command. +This command creates `dll\libzstd.dll` and the import library `dll\libzstd.lib`. +The import library is only required with Visual C++. +The header file `zstd.h` and the dynamic library `dll\libzstd.dll` are required to +compile a project using gcc/MinGW. +The dynamic library has to be added to linking options. +It means that if a project that uses ZSTD consists of a single `test-dll.c` +file it should be linked with `dll\libzstd.dll`. For example: +``` + gcc $(CFLAGS) -Iinclude/ test-dll.c -o test-dll dll\libzstd.dll +``` +The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. + + #### Obsolete streaming API Streaming is now provided within `zstd.h`. diff --git a/lib/dll/example/README.md b/lib/dll/example/README.md index 34d19855c..957a29f35 100644 --- a/lib/dll/example/README.md +++ b/lib/dll/example/README.md @@ -39,7 +39,7 @@ The header files from `include\` and the dynamic library `dll\libzstd.dll` are required to compile a project using gcc/MinGW. The dynamic library has to be added to linking options. It means that if a project that uses ZSTD consists of a single `test-dll.c` -file it should be compiled with "libzstd.dll". For example: +file it should be linked with `dll\libzstd.dll`. For example: ``` gcc $(CFLAGS) -Iinclude\ test-dll.c -o test-dll dll\libzstd.dll ``` From eec700a3b764e137bdec9546dda21c576fa5f724 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 14:34:03 +0100 Subject: [PATCH 061/185] exclude zbuff_compress.c and zbuff_decompress.c --- build/VS2008/fullbench/fullbench.vcproj | 12 ------------ build/VS2008/fuzzer/fuzzer.vcproj | 4 ---- build/VS2008/zstd/zstd.vcproj | 16 ---------------- build/VS2008/zstdlib/zstdlib.vcproj | 16 ---------------- lib/Makefile | 5 ++++- 5 files changed, 4 insertions(+), 49 deletions(-) diff --git a/build/VS2008/fullbench/fullbench.vcproj b/build/VS2008/fullbench/fullbench.vcproj index 8fe4f109c..0734219b4 100644 --- a/build/VS2008/fullbench/fullbench.vcproj +++ b/build/VS2008/fullbench/fullbench.vcproj @@ -364,14 +364,6 @@ RelativePath="..\..\..\lib\decompress\huf_decompress.c" > - - - - @@ -426,10 +418,6 @@ RelativePath="..\..\..\lib\common\mem.h" > - - diff --git a/build/VS2008/fuzzer/fuzzer.vcproj b/build/VS2008/fuzzer/fuzzer.vcproj index 3644b8c75..311b79909 100644 --- a/build/VS2008/fuzzer/fuzzer.vcproj +++ b/build/VS2008/fuzzer/fuzzer.vcproj @@ -430,10 +430,6 @@ RelativePath="..\..\..\lib\common\xxhash.h" > - - diff --git a/build/VS2008/zstd/zstd.vcproj b/build/VS2008/zstd/zstd.vcproj index 1d51f51cf..ad64f8696 100644 --- a/build/VS2008/zstd/zstd.vcproj +++ b/build/VS2008/zstd/zstd.vcproj @@ -380,14 +380,6 @@ RelativePath="..\..\..\lib\common\xxhash.c" > - - - - @@ -482,14 +474,6 @@ RelativePath="..\..\..\lib\common\xxhash.h" > - - - - diff --git a/build/VS2008/zstdlib/zstdlib.vcproj b/build/VS2008/zstdlib/zstdlib.vcproj index 9c61e9494..b1c103e32 100644 --- a/build/VS2008/zstdlib/zstdlib.vcproj +++ b/build/VS2008/zstdlib/zstdlib.vcproj @@ -360,14 +360,6 @@ RelativePath="..\..\..\lib\common\xxhash.c" > - - - - @@ -458,14 +450,6 @@ RelativePath="..\..\..\lib\common\xxhash.h" > - - - - diff --git a/lib/Makefile b/lib/Makefile index 681c048c6..8f316aa68 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -31,7 +31,10 @@ CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ FLAGS = $(CPPFLAGS) $(CFLAGS) $(MOREFLAGS) -ZSTD_FILES := common/*.c compress/*.c decompress/*.c dictBuilder/*.c +ZSTD_FILES := $(wildcard common/*.c compress/*.c decompress/*.c dictBuilder/*.c) +ZSTD_EXCLUDE := compress/zbuff_compress.c decompress/zbuff_decompress.c +ZSTD_FILES := $(filter-out $(ZSTD_EXCLUDE), $(ZSTD_FILES)) + ifeq ($(ZSTD_LEGACY_SUPPORT), 0) CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0 From de4b4fc36f7e6e16956f2740e88b579f8f5d9dc2 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 15:03:05 +0100 Subject: [PATCH 062/185] zlibWrapper: added XXH_NAMESPACE --- zlibWrapper/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 48dc1a5b6..2503f0d7f 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -16,7 +16,7 @@ EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md -CPPFLAGS = -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) +CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wstrict-aliasing=1 -Wundef From 5ddcd9d9ae438bc497c39a0c4cf095fcbcfde8ad Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 16:37:56 +0100 Subject: [PATCH 063/185] bench.c: fixed MAX_CLEVEL --- programs/bench.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/programs/bench.c b/programs/bench.c index df68d0ada..32d3a5dcd 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -483,12 +483,18 @@ static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility free(srcBuffer); } +#define ZSTD_MAX_CLEVEL 22 int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, const char* dictFileName, int cLevel, int cLevelLast) { double const compressibility = (double)g_compressibilityDefault / 100; + if (cLevel > ZSTD_MAX_CLEVEL) cLevel = ZSTD_MAX_CLEVEL; + if (cLevelLast > ZSTD_MAX_CLEVEL) cLevelLast = ZSTD_MAX_CLEVEL; + if (cLevelLast < cLevel) cLevelLast = cLevel; + if (cLevelLast > cLevel) DISPLAYLEVEL(2, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast); + if (nbFiles == 0) BMK_syntheticTest(cLevel, cLevelLast, compressibility); else From ad3e94512c3f53850cbe200f222720a4edf7ba8f Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 21 Nov 2016 20:22:12 +0100 Subject: [PATCH 064/185] fixed warnings from static analyzer in zstd_opt.h --- lib/compress/zstd_opt.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h index 90d511c7e..53cd2326c 100644 --- a/lib/compress/zstd_opt.h +++ b/lib/compress/zstd_opt.h @@ -416,7 +416,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* check repCode */ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor); for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart)) && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) { mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch; @@ -501,7 +501,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = minMatch; { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1); for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart)) && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) { mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch; @@ -601,7 +601,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ offset--; } else { if (offset != 0) { - best_off = ((offset==ZSTD_REP_MOVE_OPT) && (litLength==0)) ? (rep[0] - 1) : (rep[offset]); + best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]); if (offset != 1) rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = best_off; @@ -671,7 +671,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, /* check repCode */ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor); for (i = (ip==anchor); i Date: Wed, 23 Nov 2016 17:22:54 +0100 Subject: [PATCH 065/185] zstd_opt.h: improved price function --- lib/common/zstd_internal.h | 1 + lib/compress/zstd_opt.h | 47 ++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 266209e4c..a5002fb11 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -222,6 +222,7 @@ typedef struct { U32 log2litSum; U32 log2offCodeSum; U32 factor; + U32 staticPrices; U32 cachedPrice; U32 cachedLitLength; const BYTE* cachedLiterals; diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h index 53cd2326c..ef17f7964 100644 --- a/lib/compress/zstd_opt.h +++ b/lib/compress/zstd_opt.h @@ -15,8 +15,9 @@ #define ZSTD_OPT_H_91842398743 -#define ZSTD_FREQ_DIV 5 -#define ZSTD_MAX_PRICE (1<<30) +#define ZSTD_LITFREQ_ADD 2 +#define ZSTD_FREQ_DIV 4 +#define ZSTD_MAX_PRICE (1<<30) /*-************************************* * Price functions for optimal parser @@ -31,22 +32,32 @@ FORCE_INLINE void ZSTD_setLog2Prices(seqStore_t* ssPtr) } -MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr) +MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr, const BYTE* src, size_t srcSize) { unsigned u; ssPtr->cachedLiterals = NULL; ssPtr->cachedPrice = ssPtr->cachedLitLength = 0; + ssPtr->staticPrices = 0; if (ssPtr->litLengthSum == 0) { - ssPtr->litSum = (2<staticPrices = 1; + + for (u=0; u<=MaxLit; u++) + ssPtr->litFreq[u] = 0; + for (u=0; ulitFreq[src[u]]++; + + ssPtr->litSum = 0; ssPtr->litLengthSum = MaxLL+1; ssPtr->matchLengthSum = MaxML+1; ssPtr->offCodeSum = (MaxOff+1); - ssPtr->matchSum = (2<matchSum = (ZSTD_LITFREQ_ADD<litFreq[u] = 2; + for (u=0; u<=MaxLit; u++) { + ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u]>>ZSTD_FREQ_DIV); + ssPtr->litSum += ssPtr->litFreq[u]; + } for (u=0; u<=MaxLL; u++) ssPtr->litLengthFreq[u] = 1; for (u=0; u<=MaxML; u++) @@ -61,11 +72,11 @@ MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr) ssPtr->litSum = 0; for (u=0; u<=MaxLit; u++) { - ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u]>>ZSTD_FREQ_DIV); + ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u]>>(ZSTD_FREQ_DIV+1)); ssPtr->litSum += ssPtr->litFreq[u]; } for (u=0; u<=MaxLL; u++) { - ssPtr->litLengthFreq[u] = 1 + (ssPtr->litLengthFreq[u]>>ZSTD_FREQ_DIV); + ssPtr->litLengthFreq[u] = 1 + (ssPtr->litLengthFreq[u]>>(ZSTD_FREQ_DIV+1)); ssPtr->litLengthSum += ssPtr->litLengthFreq[u]; } for (u=0; u<=MaxML; u++) { @@ -73,6 +84,7 @@ MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr) ssPtr->matchLengthSum += ssPtr->matchLengthFreq[u]; ssPtr->matchSum += ssPtr->matchLengthFreq[u] * (u + 3); } + ssPtr->matchSum *= ZSTD_LITFREQ_ADD; for (u=0; u<=MaxOff; u++) { ssPtr->offCodeFreq[u] = 1 + (ssPtr->offCodeFreq[u]>>ZSTD_FREQ_DIV); ssPtr->offCodeSum += ssPtr->offCodeFreq[u]; @@ -87,6 +99,9 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY { U32 price, u; + if (ssPtr->staticPrices) + return ZSTD_highbit32((U32)litLength+1) + (litLength*6); + if (litLength == 0) return ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[0]+1); @@ -124,9 +139,13 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength, const int ultra) { /* offset */ + U32 price; BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1); - U32 price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1); + if (seqStorePtr->staticPrices) + return ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + ZSTD_highbit32((U32)matchLength+1) + 16 + offCode; + + price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1); if (!ultra && offCode >= 20) price += (offCode-19)*2; /* match Length */ @@ -144,9 +163,9 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B U32 u; /* literals */ - seqStorePtr->litSum += litLength; + seqStorePtr->litSum += litLength*ZSTD_LITFREQ_ADD; for (u=0; u < litLength; u++) - seqStorePtr->litFreq[literals[u]]++; + seqStorePtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD; /* literal Length */ { const BYTE LL_deltaCode = 19; @@ -401,7 +420,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* init */ ctx->nextToUpdate3 = ctx->nextToUpdate; - ZSTD_rescaleFreqs(seqStorePtr); + ZSTD_rescaleFreqs(seqStorePtr, src, srcSize); ip += (ip==prefixStart); { U32 i; for (i=0; irep[i]; } @@ -656,7 +675,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, { U32 i; for (i=0; irep[i]; } ctx->nextToUpdate3 = ctx->nextToUpdate; - ZSTD_rescaleFreqs(seqStorePtr); + ZSTD_rescaleFreqs(seqStorePtr, src, srcSize); ip += (ip==prefixStart); /* Match Loop */ From fc4193bda5e8c0c46de9da304215ec219e49419c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 23 Nov 2016 18:17:18 +0100 Subject: [PATCH 066/185] fixed g++ warnings --- lib/compress/zstd_opt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h index ef17f7964..f071c4f30 100644 --- a/lib/compress/zstd_opt.h +++ b/lib/compress/zstd_opt.h @@ -420,7 +420,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* init */ ctx->nextToUpdate3 = ctx->nextToUpdate; - ZSTD_rescaleFreqs(seqStorePtr, src, srcSize); + ZSTD_rescaleFreqs(seqStorePtr, (const BYTE*)src, srcSize); ip += (ip==prefixStart); { U32 i; for (i=0; irep[i]; } @@ -675,7 +675,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, { U32 i; for (i=0; irep[i]; } ctx->nextToUpdate3 = ctx->nextToUpdate; - ZSTD_rescaleFreqs(seqStorePtr, src, srcSize); + ZSTD_rescaleFreqs(seqStorePtr, (const BYTE*)src, srcSize); ip += (ip==prefixStart); /* Match Loop */ From fd0ac93024b074d50f7b8e9d46e1a22720654719 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 23 Nov 2016 21:45:29 +0100 Subject: [PATCH 067/185] bench.c: use ZSTD_maxCLevel() --- programs/bench.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/programs/bench.c b/programs/bench.c index 32d3a5dcd..5f31bb4bf 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -483,15 +483,14 @@ static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility free(srcBuffer); } -#define ZSTD_MAX_CLEVEL 22 int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, const char* dictFileName, int cLevel, int cLevelLast) { double const compressibility = (double)g_compressibilityDefault / 100; - if (cLevel > ZSTD_MAX_CLEVEL) cLevel = ZSTD_MAX_CLEVEL; - if (cLevelLast > ZSTD_MAX_CLEVEL) cLevelLast = ZSTD_MAX_CLEVEL; + if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel(); + if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel(); if (cLevelLast < cLevel) cLevelLast = cLevel; if (cLevelLast > cLevel) DISPLAYLEVEL(2, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast); From 50524bf0da482e4b340b709eaa3ef0e4a83d17ba Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 23 Nov 2016 15:11:07 -0800 Subject: [PATCH 068/185] delayed decompression --- lib/decompress/zstd_decompress.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index cc92ca276..1890a8530 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1013,7 +1013,9 @@ static size_t ZSTD_decompressSequences( /* Regen sequences */ if (nbSeq) { + seq_t sequences[4]; seqState_t seqState; + int seqNb; dctx->fseEntropy = 1; { U32 i; for (i=0; irep[i]; } CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); @@ -1021,16 +1023,31 @@ static size_t ZSTD_decompressSequences( FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); - for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { - nbSeq--; - { seq_t const sequence = ZSTD_decodeSequence(&seqState); - size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); + /* prepare in advance */ + int const seqAdvance = MIN(nbSeq, 3); + for (seqNb=0; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNbrep[i] = (U32)(seqState.prevOffset[i]); } } From 73f88a66f17539f86f03fa0ecf7c0e56c23d02da Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 23 Nov 2016 15:43:30 -0800 Subject: [PATCH 069/185] added prefetch --- lib/decompress/zstd_decompress.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 1890a8530..d85c803b1 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -775,6 +775,7 @@ typedef struct { size_t litLength; size_t matchLength; size_t offset; + const BYTE* match; } seq_t; typedef struct { @@ -783,6 +784,7 @@ typedef struct { FSE_DState_t stateOffb; FSE_DState_t stateML; size_t prevOffset[ZSTD_REP_NUM]; + const BYTE* ptr; } seqState_t; @@ -851,11 +853,14 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState) if (MEM_32bits() || (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); + seq.match = seqState->ptr + seq.litLength - seq.offset; /* only for single memory segment ! */ + /* ANS state update */ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ + seqState->ptr += seq.matchLength + seq.litLength; return seq; } @@ -919,7 +924,7 @@ size_t ZSTD_execSequence(BYTE* op, BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; const BYTE* const iLitEnd = *litPtr + sequence.litLength; - const BYTE* match = oLitEnd - sequence.offset; + const BYTE* match = sequence.match; /* check */ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ @@ -987,6 +992,8 @@ size_t ZSTD_execSequence(BYTE* op, return sequenceLength; } +#include +#define PREFETCH(ptr) _mm_prefetch(ptr, _MM_HINT_T0); static size_t ZSTD_decompressSequences( ZSTD_DCtx* dctx, @@ -1018,6 +1025,7 @@ static size_t ZSTD_decompressSequences( int seqNb; dctx->fseEntropy = 1; { U32 i; for (i=0; irep[i]; } + seqState.ptr = op; CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); @@ -1025,28 +1033,28 @@ static size_t ZSTD_decompressSequences( /* prepare in advance */ int const seqAdvance = MIN(nbSeq, 3); - for (seqNb=0; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNbrep[i] = (U32)(seqState.prevOffset[i]); } From 3bf9a72d9567cb0b78fc786f40a4351ea19f558c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 24 Nov 2016 18:26:30 +0100 Subject: [PATCH 070/185] experimental support for gz* functions --- zlibWrapper/gzclose.c | 25 ++ zlibWrapper/gzguts.h | 209 +++++++++++ zlibWrapper/gzlib.c | 634 +++++++++++++++++++++++++++++++++ zlibWrapper/gzread.c | 596 +++++++++++++++++++++++++++++++ zlibWrapper/gzwrite.c | 577 ++++++++++++++++++++++++++++++ zlibWrapper/zstd_zlibwrapper.c | 230 +----------- 6 files changed, 2053 insertions(+), 218 deletions(-) create mode 100644 zlibWrapper/gzclose.c create mode 100644 zlibWrapper/gzguts.h create mode 100644 zlibWrapper/gzlib.c create mode 100644 zlibWrapper/gzread.c create mode 100644 zlibWrapper/gzwrite.c diff --git a/zlibWrapper/gzclose.c b/zlibWrapper/gzclose.c new file mode 100644 index 000000000..caeb99a31 --- /dev/null +++ b/zlibWrapper/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h new file mode 100644 index 000000000..da66159a3 --- /dev/null +++ b/zlibWrapper/gzguts.h @@ -0,0 +1,209 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zstd_zlibwrapper.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99, yet still not supported by + Microsoft more than a decade later!), _snprintf does not guarantee null + termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/zlibWrapper/gzlib.c b/zlibWrapper/gzlib.c new file mode 100644 index 000000000..fae202ef8 --- /dev/null +++ b/zlibWrapper/gzlib.c @@ -0,0 +1,634 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef _WIN32 + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef _WIN32 + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef _WIN32 + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef _WIN32 +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c new file mode 100644 index 000000000..2d28122d8 --- /dev/null +++ b/zlibWrapper/gzread.c @@ -0,0 +1,596 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + //printf("strm->next_in[0]=%d strm->next_in[1]=%d\n", strm->next_in[0], strm->next_in[1]); + if (strm->avail_in > 1 && + ((strm->next_in[0] == 31 && strm->next_in[1] == 139) + || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { // zstd + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/zlibWrapper/gzwrite.c b/zlibWrapper/gzwrite.c new file mode 100644 index 000000000..aa767fbf6 --- /dev/null +++ b/zlibWrapper/gzwrite.c @@ -0,0 +1,577 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = (unsigned char *)malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + copy = state->size - have; + if (copy > len) + copy = len; + memcpy(state->in + have, buf, copy); + strm->avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (z_const Bytef *)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf((char *)(state->in), format, va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf((char *)(state->in), format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf((char *)(state->in), size, format, va); + len = strlen((char *)(state->in)); +# else + len = vsnprintf((char *)(state->in), size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen((char *)(state->in)); +# else + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 326fea260..477c53b41 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -24,8 +24,8 @@ #define ZSTD_HEADERSIZE ZSTD_frameHeaderSize_min #define ZWRAP_DEFAULT_CLEVEL 3 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ -#define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */ -#define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */ +#define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */ +#define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */ #define FINISH_WITH_GZ_ERR(msg) { (void)msg; return Z_STREAM_ERROR; } #define FINISH_WITH_NULL_ERR(msg) { (void)msg; return NULL; } @@ -81,6 +81,7 @@ typedef enum { ZWRAP_useInit, ZWRAP_useReset, ZWRAP_streamEnd } ZWRAP_state_t; typedef struct { ZSTD_CStream* zbc; int compressionLevel; + int streamEnd; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ ZSTD_inBuffer inBuffer; @@ -187,6 +188,7 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, if (level == Z_DEFAULT_COMPRESSION) level = ZWRAP_DEFAULT_CLEVEL; + zwc->streamEnd = 0; zwc->compressionLevel = level; strm->state = (struct internal_state*) zwc; /* use state which in not used by user */ strm->total_in = 0; @@ -214,6 +216,10 @@ int ZWRAP_deflateReset_keepDict(z_streamp strm) if (!g_ZWRAP_useZSTDcompression) return deflateReset(strm); + { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + if (zwc) zwc->streamEnd = 0; + } + strm->total_in = 0; strm->total_out = 0; strm->adler = 0; @@ -230,7 +236,7 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) ZWRAP_deflateReset_keepDict(strm); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - if (zwc) zwc->comprState = 0; + if (zwc) zwc->comprState = ZWRAP_useInit; } return Z_OK; } @@ -319,6 +325,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (flush == Z_FINISH) { size_t bytesLeft; + if (zwc->streamEnd) return Z_STREAM_END; zwc->outBuffer.dst = strm->next_out; zwc->outBuffer.size = strm->avail_out; zwc->outBuffer.pos = 0; @@ -328,7 +335,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; - if (bytesLeft == 0) { LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; } + if (bytesLeft == 0) { zwc->streamEnd = 1; LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; } } else if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) { @@ -519,6 +526,7 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, { int ret = z_inflateInit_ (strm, version, stream_size); + LOG_WRAPPERD("- inflateInit2 windowBits=%d\n", windowBits); if (ret == Z_OK) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state; if (zwd == NULL) return Z_STREAM_ERROR; @@ -1015,220 +1023,6 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen, return Z_OK; } - - - /* gzip file access functions */ -ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzopen(path, mode); - FINISH_WITH_NULL_ERR("gzopen is not supported!"); -} - - -ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzdopen(fd, mode); - FINISH_WITH_NULL_ERR("gzdopen is not supported!"); -} - - -#if ZLIB_VERNUM >= 0x1240 -ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzbuffer(file, size); - FINISH_WITH_GZ_ERR("gzbuffer is not supported!"); -} - - -ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzoffset(file); - FINISH_WITH_GZ_ERR("gzoffset is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzclose_r(file); - FINISH_WITH_GZ_ERR("gzclose_r is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzclose_w(file); - FINISH_WITH_GZ_ERR("gzclose_w is not supported!"); -} -#endif - - -ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzsetparams(file, level, strategy); - FINISH_WITH_GZ_ERR("gzsetparams is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzread(file, buf, len); - FINISH_WITH_GZ_ERR("gzread is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file, - voidpc buf, unsigned len)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzwrite(file, buf, len); - FINISH_WITH_GZ_ERR("gzwrite is not supported!"); -} - - -#if ZLIB_VERNUM >= 0x1260 -ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...)) -#else -ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...)) -#endif -{ - if (!g_ZWRAP_useZSTDcompression) { - int ret; - char buf[1024]; - va_list args; - va_start (args, format); - ret = vsprintf (buf, format, args); - va_end (args); - - ret = gzprintf(file, buf); - return ret; - } - FINISH_WITH_GZ_ERR("gzprintf is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzputs(file, s); - FINISH_WITH_GZ_ERR("gzputs is not supported!"); -} - - -ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzgets(file, buf, len); - FINISH_WITH_NULL_ERR("gzgets is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzputc(file, c); - FINISH_WITH_GZ_ERR("gzputc is not supported!"); -} - - -#if ZLIB_VERNUM == 0x1260 -ZEXTERN int ZEXPORT z_gzgetc_ OF((gzFile file)) -#else -ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file)) -#endif -{ - if (!g_ZWRAP_useZSTDcompression) - return gzgetc(file); - FINISH_WITH_GZ_ERR("gzgetc is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzungetc(c, file); - FINISH_WITH_GZ_ERR("gzungetc is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzflush(file, flush); - FINISH_WITH_GZ_ERR("gzflush is not supported!"); -} - - -ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzseek(file, offset, whence); - FINISH_WITH_GZ_ERR("gzseek is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzrewind(file); - FINISH_WITH_GZ_ERR("gzrewind is not supported!"); -} - - -ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gztell(file); - FINISH_WITH_GZ_ERR("gztell is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzeof OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzeof(file); - FINISH_WITH_GZ_ERR("gzeof is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzdirect(file); - FINISH_WITH_GZ_ERR("gzdirect is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzclose OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzclose(file); - FINISH_WITH_GZ_ERR("gzclose is not supported!"); -} - - -ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzerror(file, errnum); - FINISH_WITH_NULL_ERR("gzerror is not supported!"); -} - - -ZEXTERN void ZEXPORT z_gzclearerr OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - gzclearerr(file); -} - - #endif /* !Z_SOLO */ From 6b3c2018dbde85eed1c53e6484eddf2ced4dd2a8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 24 Nov 2016 18:26:47 +0100 Subject: [PATCH 071/185] added minigzip --- zlibWrapper/Makefile | 6 +- zlibWrapper/minigzip.c | 651 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 656 insertions(+), 1 deletion(-) create mode 100644 zlibWrapper/minigzip.c diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 2503f0d7f..b58552761 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -18,7 +18,8 @@ TEST_FILE = ../doc/zstd_compression_format.md CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wstrict-aliasing=1 -Wundef +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef +#-Wstrict-aliasing=1 all: clean fitblk example zwrapbench @@ -49,6 +50,9 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench #.c.o: # $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< +minigzip: gzclose.c gzlib.c gzread.c gzwrite.c minigzip.c $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) + example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) diff --git a/zlibWrapper/minigzip.c b/zlibWrapper/minigzip.c new file mode 100644 index 000000000..e56d5e1d7 --- /dev/null +++ b/zlibWrapper/minigzip.c @@ -0,0 +1,651 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* @(#) $Id$ */ + +#include "zstd_zlibwrapper.h" +#include + +#ifdef STDC +# include +# include +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# ifdef UNDER_CE +# include +# endif +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif +#endif + +#if defined(UNDER_CE) +# include +# define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +static char *strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +static void pwinerror (s) + const char *s; +{ + if (s && *s) + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); + else + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +#ifdef Z_SOLO +/* for Z_SOLO, create simplified gz* functions using deflate and inflate */ + +#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) +# include /* for unlink() */ +#endif + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + q = Z_NULL; + return calloc(n, m); +} + +void myfree(q, p) + void *q, *p; +{ + q = Z_NULL; + free(p); +} + +typedef struct gzFile_s { + FILE *file; + int write; + int err; + char *msg; + z_stream strm; +} *gzFile; + +gzFile gzopen OF((const char *, const char *)); +gzFile gzdopen OF((int, const char *)); +gzFile gz_open OF((const char *, int, const char *)); + +gzFile gzopen(path, mode) +const char *path; +const char *mode; +{ + return gz_open(path, -1, mode); +} + +gzFile gzdopen(fd, mode) +int fd; +const char *mode; +{ + return gz_open(NULL, fd, mode); +} + +gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gzFile gz; + int ret; + + gz = malloc(sizeof(struct gzFile_s)); + if (gz == NULL) + return NULL; + gz->write = strchr(mode, 'w') != NULL; + gz->strm.zalloc = myalloc; + gz->strm.zfree = myfree; + gz->strm.opaque = Z_NULL; + if (gz->write) + ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0); + else { + gz->strm.next_in = 0; + gz->strm.avail_in = Z_NULL; + ret = inflateInit2(&(gz->strm), 15 + 16); + } + if (ret != Z_OK) { + free(gz); + return NULL; + } + gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : + fopen(path, gz->write ? "wb" : "rb"); + if (gz->file == NULL) { + gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); + free(gz); + return NULL; + } + gz->err = 0; + gz->msg = ""; + return gz; +} + +int gzwrite OF((gzFile, const void *, unsigned)); + +int gzwrite(gz, buf, len) + gzFile gz; + const void *buf; + unsigned len; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL || !gz->write) + return 0; + strm = &(gz->strm); + strm->next_in = (void *)buf; + strm->avail_in = len; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_NO_FLUSH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + return len; +} + +int gzread OF((gzFile, void *, unsigned)); + +int gzread(gz, buf, len) + gzFile gz; + void *buf; + unsigned len; +{ + int ret; + unsigned got; + unsigned char in[1]; + z_stream *strm; + + if (gz == NULL || gz->write) + return 0; + if (gz->err) + return 0; + strm = &(gz->strm); + strm->next_out = (void *)buf; + strm->avail_out = len; + do { + got = fread(in, 1, 1, gz->file); + if (got == 0) + break; + strm->next_in = in; + strm->avail_in = 1; + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_DATA_ERROR) { + gz->err = Z_DATA_ERROR; + gz->msg = strm->msg; + return 0; + } + if (ret == Z_STREAM_END) + inflateReset(strm); + } while (strm->avail_out); + return len - strm->avail_out; +} + +int gzclose OF((gzFile)); + +int gzclose(gz) + gzFile gz; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL) + return Z_STREAM_ERROR; + strm = &(gz->strm); + if (gz->write) { + strm->next_in = Z_NULL; + strm->avail_in = 0; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_FINISH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + deflateEnd(strm); + } + else + inflateEnd(strm); + fclose(gz->file); + free(gz); + return Z_OK; +} + +const char *gzerror OF((gzFile, int *)); + +const char *gzerror(gz, err) + gzFile gz; + int *err; +{ + *err = gz->err; + return gz->msg; +} + +#endif + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); +#else + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); +#endif + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf, sizeof(buf), "%s", file); +#else + strcpy(buf, file); +#endif + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); +#else + strcat(infile, GZ_SUFFIX); +#endif + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * -c : write to standard output + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -r : compress with Z_RLE + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int copyout = 0; + int uncompr = 0; + gzFile file; + char *bname, outmode[20]; + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outmode, sizeof(outmode), "%s", "wb6 "); +#else + strcpy(outmode, "wb6 "); +#endif + + prog = argv[0]; + bname = strrchr(argv[0], '/'); + if (bname) + bname++; + else + bname = argv[0]; + argc--, argv++; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + while (argc > 0) { + if (strcmp(*argv, "-c") == 0) + copyout = 1; + else if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if (strcmp(*argv, "-r") == 0) + outmode[3] = 'R'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (outmode[3] == ' ') + outmode[3] = 0; + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = gzopen(*argv, "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(*argv); + } + } else { + if (copyout) { + FILE * in = fopen(*argv, "rb"); + + if (in == NULL) { + perror(*argv); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(*argv, outmode); + } + } + } while (argv++, --argc); + } + return 0; +} From 37a00f2ac7ddc12aa152acc93e4b27bd814b1f07 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 25 Nov 2016 14:09:29 +0100 Subject: [PATCH 072/185] turn on test_gzio --- zlibWrapper/examples/example.c | 5 ++--- zlibWrapper/{ => examples}/minigzip.c | 0 2 files changed, 2 insertions(+), 3 deletions(-) rename zlibWrapper/{ => examples}/minigzip.c (100%) diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c index 20ed81d57..9483129d2 100644 --- a/zlibWrapper/examples/example.c +++ b/zlibWrapper/examples/example.c @@ -600,9 +600,8 @@ int main(argc, argv) #else test_compress(compr, comprLen, uncompr, uncomprLen); - if (!ZWRAP_isUsingZSTDcompression()) - test_gzio((argc > 1 ? argv[1] : TESTFILE), - uncompr, uncomprLen); + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); #endif test_deflate(compr, comprLen); diff --git a/zlibWrapper/minigzip.c b/zlibWrapper/examples/minigzip.c similarity index 100% rename from zlibWrapper/minigzip.c rename to zlibWrapper/examples/minigzip.c From 96fca2bd2d7f713525d579149638c7fcbe1d3653 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 25 Nov 2016 14:36:27 +0100 Subject: [PATCH 073/185] improved zwrapbench.c --- zlibWrapper/examples/zwrapbench.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index ebf76e48f..e0aca0015 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -239,11 +239,18 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize, do { U32 blockNb; + size_t rSize; for (blockNb=0; blockNb Date: Fri, 25 Nov 2016 14:45:55 +0100 Subject: [PATCH 074/185] added minigzip test --- zlibWrapper/Makefile | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index b58552761..ada7ab651 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -12,6 +12,7 @@ ZLIB_LIBRARY ?= -lz ZSTDLIBDIR = ../lib ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.a ZLIBWRAPPER_PATH = . +GZFILES = gzclose.o gzlib.o gzread.o gzwrite.o EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md @@ -22,15 +23,27 @@ CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdecla #-Wstrict-aliasing=1 -all: clean fitblk example zwrapbench +# Define *.exe as extension for Windows systems +ifneq (,$(filter Windows%,$(OS))) +EXT =.exe +else +EXT = +endif -test: example fitblk example_zstd fitblk_zstd zwrapbench + +all: clean fitblk example zwrapbench minigzip + +test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd ./example ./example_zstd ./fitblk 10240 <$(TEST_FILE) ./fitblk 40960 <$(TEST_FILE) ./fitblk_zstd 10240 <$(TEST_FILE) ./fitblk_zstd 40960 <$(TEST_FILE) + @echo ---- minigzip start ---- + ./minigzip_zstd zwrapbench$(EXT) + ./minigzip_zstd -d zwrapbench$(EXT).gz + @echo ---- minigzip end ---- ./zwrapbench -qb3B1K $(TEST_FILE) ./zwrapbench -rqb1e5 ../lib ../programs ../tests @@ -50,25 +63,27 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench #.c.o: # $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -minigzip: gzclose.c gzlib.c gzread.c gzwrite.c minigzip.c $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +minigzip: $(EXAMPLE_PATH)/minigzip.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -o $@ -example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +minigzip_zstd: $(EXAMPLE_PATH)/minigzip.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -o $@ -example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ + +example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ -fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ -$(EXAMPLE_PATH)/zwrapbench.o: $(EXAMPLE_PATH)/zwrapbench.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c @@ -82,6 +97,7 @@ $(ZSTDLIBDIR)/libzstd.a: $(ZSTDLIBDIR)/libzstd.so: $(MAKE) -C $(ZSTDLIBDIR) libzstd + clean: - -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench + -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench minigzip minigzip_zstd @echo Cleaning completed From a6417761972c80aea1fb5162b9405c3d94379dc0 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 25 Nov 2016 17:13:25 +0100 Subject: [PATCH 075/185] zlibWrapper: improve "make clean" --- zlibWrapper/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index ada7ab651..0c8db9c7a 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -19,7 +19,7 @@ TEST_FILE = ../doc/zstd_compression_format.md CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef #-Wstrict-aliasing=1 @@ -99,5 +99,5 @@ $(ZSTDLIBDIR)/libzstd.so: clean: - -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench minigzip minigzip_zstd + -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o foo.gz example$(EXT) example_zstd$(EXT) fitblk$(EXT) fitblk_zstd$(EXT) zwrapbench$(EXT) minigzip$(EXT) minigzip_zstd$(EXT) @echo Cleaning completed From edd3e2a83435b5e72a51d302aec95cf79d49e590 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 12:46:16 +0100 Subject: [PATCH 076/185] Z_TREES only with ZLIB_VERNUM >= 0x1240 --- zlibWrapper/README.md | 2 +- zlibWrapper/zstd_zlibwrapper.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 5fefac1d3..cbf1b1b30 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -137,12 +137,12 @@ Supported methods: - compress2 - compressBound - uncompress +- gzip file access functions Ignored methods (they do nothing): - deflateParams Unsupported methods: -- gzip file access functions - deflateCopy - deflateTune - deflatePending diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 477c53b41..3b23358f3 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -321,7 +321,12 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->avail_in -= zwc->inBuffer.pos; } - if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); + if (flush == Z_FULL_FLUSH +#if ZLIB_VERNUM >= 0x1240 + || flush == Z_TREES +#endif + || flush == Z_BLOCK) + return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); if (flush == Z_FINISH) { size_t bytesLeft; From 91437d844d8408977e160f5a1e90348deb91e2d8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 13:25:42 +0100 Subject: [PATCH 077/185] added gzcompatibility.h --- zlibWrapper/gzcompatibility.h | 47 +++++++++++++++++++++++++++++++++++ zlibWrapper/gzguts.h | 1 + 2 files changed, 48 insertions(+) create mode 100644 zlibWrapper/gzcompatibility.h diff --git a/zlibWrapper/gzcompatibility.h b/zlibWrapper/gzcompatibility.h new file mode 100644 index 000000000..d6e83a737 --- /dev/null +++ b/zlibWrapper/gzcompatibility.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2016-present, Przemyslaw Skibinski, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#if ZLIB_VERNUM == 0x1260 && !defined(_LARGEFILE64_SOURCE) + // #define _LARGEFILE64_SOURCE 0 +#endif + +#if ZLIB_VERNUM <= 0x1240 +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif +#endif + + +#if ZLIB_VERNUM <= 0x1250 +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +#endif + + +#if ZLIB_VERNUM <= 0x1270 +#if defined(_WIN32) && !defined(Z_SOLO) +# include /* for wchar_t */ +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#endif diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index da66159a3..c7ccc84a2 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -20,6 +20,7 @@ #include #include "zstd_zlibwrapper.h" +#include "gzcompatibility.h" #ifdef STDC # include # include From c77befef811040c126adf37b8e421e99f9a1a822 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 14:09:26 +0100 Subject: [PATCH 078/185] make gz* functions compatible with zlib 1.2.3+ --- zlibWrapper/gzcompatibility.h | 4 +--- zlibWrapper/gzread.c | 13 +++++++++++++ zlibWrapper/zstd_zlibwrapper.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/gzcompatibility.h b/zlibWrapper/gzcompatibility.h index d6e83a737..a4f275e11 100644 --- a/zlibWrapper/gzcompatibility.h +++ b/zlibWrapper/gzcompatibility.h @@ -7,9 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#if ZLIB_VERNUM == 0x1260 && !defined(_LARGEFILE64_SOURCE) - // #define _LARGEFILE64_SOURCE 0 -#endif + #if ZLIB_VERNUM <= 0x1240 ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index 2d28122d8..c982b1429 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -381,11 +381,24 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ +#if ZLIB_VERNUM >= 0x1261 #ifdef Z_PREFIX_SET # undef z_gzgetc #else # undef gzgetc #endif +#endif + +#if ZLIB_VERNUM == 0x1260 +# undef gzgetc +#endif + +#if ZLIB_VERNUM <= 0x1250 +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); +#endif + + int ZEXPORT gzgetc(file) gzFile file; { diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 45d15bac0..382716921 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -17,6 +17,7 @@ extern "C" { #define ZLIB_CONST #define Z_PREFIX +#define ZLIB_INTERNAL /* disables gz*64 functions but fixes zlib 1.2.4 with Z_PREFIX */ #include #if !defined(z_const) From 8b3e2f1a0b41e783c4985903fa2b38e9da7a79dd Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 15:41:36 +0100 Subject: [PATCH 079/185] updated zlibWrapper/Makefile --- zlibWrapper/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 0c8db9c7a..c6f061756 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -6,7 +6,7 @@ # Paths to static and dynamic zlib and zstd libraries -# Use "make ZLIB_LIBRARY=path/to/zlib" to select a path to library +# Use "make ZLIB_PATH=path/to/zlib ZLIB_LIBRARY=path/to/libz.a" to select a path to library ZLIB_LIBRARY ?= -lz ZSTDLIBDIR = ../lib @@ -17,7 +17,7 @@ EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md -CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) +CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef #-Wstrict-aliasing=1 @@ -41,8 +41,8 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd ./fitblk_zstd 10240 <$(TEST_FILE) ./fitblk_zstd 40960 <$(TEST_FILE) @echo ---- minigzip start ---- - ./minigzip_zstd zwrapbench$(EXT) - ./minigzip_zstd -d zwrapbench$(EXT).gz + ./minigzip_zstd example$(EXT) + ./minigzip_zstd -d example$(EXT).gz @echo ---- minigzip end ---- ./zwrapbench -qb3B1K $(TEST_FILE) ./zwrapbench -rqb1e5 ../lib ../programs ../tests From 0fa3447dee0319322cf5ebaa64e4321dd8887f92 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 16:55:14 +0100 Subject: [PATCH 080/185] plainly marked altered files from zlib --- zlibWrapper/Makefile | 1 + zlibWrapper/examples/example.c | 11 +++++++---- zlibWrapper/examples/fitblk.c | 5 ++++- zlibWrapper/examples/minigzip.c | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index c6f061756..41b334d32 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -8,6 +8,7 @@ # Paths to static and dynamic zlib and zstd libraries # Use "make ZLIB_PATH=path/to/zlib ZLIB_LIBRARY=path/to/libz.a" to select a path to library ZLIB_LIBRARY ?= -lz +ZLIB_PATH ?= . ZSTDLIBDIR = ../lib ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.a diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c index 9483129d2..9000f7a32 100644 --- a/zlibWrapper/examples/example.c +++ b/zlibWrapper/examples/example.c @@ -1,8 +1,11 @@ -/* example.c -- usage example of the zlib compression library - * the file contains minimal changes required to be compiled with zstd wrapper for zlib - */ +/* example.c contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" + * - test_flush() and test_sync() use functions not supported by zlibWrapper + therefore they are disabled while zstd compression is turned on */ - /* +/* example.c -- usage example of the zlib compression library + */ +/* Copyright (c) 1995-2006, 2011 Jean-loup Gailly This software is provided 'as-is', without any express or implied diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index e3fda3c80..760e338a2 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -1,3 +1,7 @@ +/* fitblk.c contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" + * - writing block to stdout was disabled */ + /* fitblk.c: example of fitting compressed output to a specified size Not copyrighted -- provided to the public domain Version 1.1 25 November 2004 Mark Adler */ @@ -54,7 +58,6 @@ #include #include #include -//#include "zlib.h" #include "zstd_zlibwrapper.h" #define LOG_FITBLK(...) /*printf(__VA_ARGS__)*/ diff --git a/zlibWrapper/examples/minigzip.c b/zlibWrapper/examples/minigzip.c index e56d5e1d7..0ddc93f25 100644 --- a/zlibWrapper/examples/minigzip.c +++ b/zlibWrapper/examples/minigzip.c @@ -1,3 +1,6 @@ +/* minigzip.c contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" */ + /* minigzip.c -- simulate gzip using the zlib compression library * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h From 764e70a4f35c3f84a5bc61e42a1c856809d46eb5 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 28 Nov 2016 15:50:16 -0800 Subject: [PATCH 081/185] added decodeSequencesLong --- lib/decompress/zstd_decompress.c | 80 ++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index d85c803b1..ea5722e2a 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -927,9 +927,11 @@ size_t ZSTD_execSequence(BYTE* op, const BYTE* match = sequence.match; /* check */ +#if 1 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); +#endif /* copy Literals */ ZSTD_copy8(op, *litPtr); @@ -939,6 +941,7 @@ size_t ZSTD_execSequence(BYTE* op, *litPtr = iLitEnd; /* update for next sequence */ /* copy Match */ +#if 1 if (sequence.offset > (size_t)(oLitEnd - base)) { /* offset beyond prefix */ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); @@ -960,6 +963,7 @@ size_t ZSTD_execSequence(BYTE* op, } } } /* Requirement: op <= oend_w */ +#endif /* match within prefix */ if (sequence.offset < 8) { @@ -992,8 +996,6 @@ size_t ZSTD_execSequence(BYTE* op, return sequenceLength; } -#include -#define PREFETCH(ptr) _mm_prefetch(ptr, _MM_HINT_T0); static size_t ZSTD_decompressSequences( ZSTD_DCtx* dctx, @@ -1020,7 +1022,68 @@ static size_t ZSTD_decompressSequences( /* Regen sequences */ if (nbSeq) { - seq_t sequences[4]; + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i=0; irep[i]; } + CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); + FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { + nbSeq--; + { seq_t const sequence = ZSTD_decodeSequence(&seqState); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } } + + /* check if reached exact end */ + if (nbSeq) return ERROR(corruption_detected); + /* save reps for next block */ + { U32 i; for (i=0; irep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + { size_t const lastLLSize = litEnd - litPtr; + if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); + memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + + return op-ostart; +} + +#define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0); +static size_t ZSTD_decompressSequencesLong( + ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE* const)dst; + BYTE* const oend = ostart + maxDstSize; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const base = (const BYTE*) (dctx->base); + const BYTE* const vBase = (const BYTE*) (dctx->vBase); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + int nbSeq; + + /* Build Decoding Tables */ + { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); + if (ZSTD_isError(seqHSize)) return seqHSize; + ip += seqHSize; + } + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 8 +#define STOSEQ_MASK (STORED_SEQS-1) +#define ADVANCED_SEQS 5 + seq_t sequences[STORED_SEQS]; seqState_t seqState; int seqNb; dctx->fseEntropy = 1; @@ -1032,7 +1095,7 @@ static size_t ZSTD_decompressSequences( FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); /* prepare in advance */ - int const seqAdvance = MIN(nbSeq, 3); + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb Date: Mon, 28 Nov 2016 16:11:30 -0800 Subject: [PATCH 082/185] restored normal mode --- lib/decompress/zstd_decompress.c | 321 +++++++++++++++++++++++-------- 1 file changed, 238 insertions(+), 83 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index ea5722e2a..d96dd7841 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -788,7 +788,7 @@ typedef struct { } seqState_t; -static seq_t ZSTD_decodeSequence(seqState_t* seqState) +static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) { seq_t seq; @@ -914,7 +914,7 @@ size_t ZSTD_execSequenceLast7(BYTE* op, FORCE_INLINE -size_t ZSTD_execSequence(BYTE* op, +size_t ZSTD_execSequenceLong(BYTE* op, BYTE* const oend, seq_t sequence, const BYTE** litPtr, const BYTE* const litLimit, const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) @@ -997,6 +997,242 @@ size_t ZSTD_execSequence(BYTE* op, } +#define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0); +static size_t ZSTD_decompressSequencesLong( + ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE* const)dst; + BYTE* const oend = ostart + maxDstSize; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const base = (const BYTE*) (dctx->base); + const BYTE* const vBase = (const BYTE*) (dctx->vBase); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + int nbSeq; + + /* Build Decoding Tables */ + { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); + if (ZSTD_isError(seqHSize)) return seqHSize; + ip += seqHSize; + } + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 8 +#define STOSEQ_MASK (STORED_SEQS-1) +#define ADVANCED_SEQS 5 + seq_t sequences[STORED_SEQS]; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; + dctx->fseEntropy = 1; + { U32 i; for (i=0; irep[i]; } + seqState.ptr = op; + CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); + FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + /* prepare in advance */ + for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNbrep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + { size_t const lastLLSize = litEnd - litPtr; + if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); + memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + + return op-ostart; +} + + +static seq_t ZSTD_decodeSequence(seqState_t* seqState) +{ + seq_t seq; + + U32 const llCode = FSE_peekSymbol(&seqState->stateLL); + U32 const mlCode = FSE_peekSymbol(&seqState->stateML); + U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ + + U32 const llBits = LL_bits[llCode]; + U32 const mlBits = ML_bits[mlCode]; + U32 const ofBits = ofCode; + U32 const totalBits = llBits+mlBits+ofBits; + + static const U32 LL_base[MaxLL+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 }; + + static const U32 ML_base[MaxML+1] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; + + static const U32 OF_base[MaxOff+1] = { + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; + + /* sequence */ + { size_t offset; + if (!ofCode) + offset = 0; + else { + offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); + } + + if (ofCode <= 1) { + offset += (llCode==0); + if (offset) { + size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } else { + offset = seqState->prevOffset[0]; + } + } else { + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } + seq.offset = offset; + } + + seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ + if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); + + seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&seqState->DStream, llBits) : 0); /* <= 16 bits */ + if (MEM_32bits() || + (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); + + /* ANS state update */ + FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ + FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ + + return seq; +} + + +FORCE_INLINE +size_t ZSTD_execSequence(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + /* check */ + if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); + + /* copy Literals */ + ZSTD_copy8(op, *litPtr); + if (sequence.litLength > 8) + ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - base)) { + /* offset beyond prefix */ + if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); + match = dictEnd - (base-match); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = base; + if (op > oend_w) { + U32 i; + for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; + return sequenceLength; + } + } } + /* Requirement: op <= oend_w */ + + /* match within prefix */ + if (sequence.offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ + int const sub2 = dec64table[sequence.offset]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[sequence.offset]; + ZSTD_copy4(op+4, match); + match -= sub2; + } else { + ZSTD_copy8(op, match); + } + op += 8; match += 8; + + if (oMatchEnd > oend-(16-MINMATCH)) { + if (op < oend_w) { + ZSTD_wildcopy(op, match, oend_w - op); + match += oend_w - op; + op = oend_w; + } + while (op < oMatchEnd) *op++ = *match++; + } else { + ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ + } + return sequenceLength; +} + + static size_t ZSTD_decompressSequences( ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, @@ -1054,86 +1290,6 @@ static size_t ZSTD_decompressSequences( return op-ostart; } -#define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0); -static size_t ZSTD_decompressSequencesLong( - ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize) -{ - const BYTE* ip = (const BYTE*)seqStart; - const BYTE* const iend = ip + seqSize; - BYTE* const ostart = (BYTE* const)dst; - BYTE* const oend = ostart + maxDstSize; - BYTE* op = ostart; - const BYTE* litPtr = dctx->litPtr; - const BYTE* const litEnd = litPtr + dctx->litSize; - const BYTE* const base = (const BYTE*) (dctx->base); - const BYTE* const vBase = (const BYTE*) (dctx->vBase); - const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - int nbSeq; - - /* Build Decoding Tables */ - { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); - if (ZSTD_isError(seqHSize)) return seqHSize; - ip += seqHSize; - } - - /* Regen sequences */ - if (nbSeq) { -#define STORED_SEQS 8 -#define STOSEQ_MASK (STORED_SEQS-1) -#define ADVANCED_SEQS 5 - seq_t sequences[STORED_SEQS]; - seqState_t seqState; - int seqNb; - dctx->fseEntropy = 1; - { U32 i; for (i=0; irep[i]; } - seqState.ptr = op; - CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); - FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); - FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); - FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); - - /* prepare in advance */ - int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); - for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNbrep[i] = (U32)(seqState.prevOffset[i]); } - } - - /* last literal segment */ - { size_t const lastLLSize = litEnd - litPtr; - if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); - memcpy(op, litPtr, lastLLSize); - op += lastLLSize; - } - - return op-ostart; -} - static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) { @@ -1145,7 +1301,6 @@ static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) } } - static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) From ce3527ca0c11bce66b5d64d36a3f1f0355d4c10c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 28 Nov 2016 18:38:52 -0800 Subject: [PATCH 083/185] combined normal and long decoder --- lib/decompress/zstd_decompress.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index d96dd7841..2d4087335 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -56,6 +56,15 @@ #endif +#if defined(_MSC_VER) +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define ZSTD_PREFETCH(ptr) _mm_prefetch(ptr, _MM_HINT_T0) +#elif defined(__GNUC__) +# define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0) +#else +# define ZSTD_PREFETCH(ptr) /* disabled */ +#endif + /*-************************************* * Macros ***************************************/ @@ -997,7 +1006,6 @@ size_t ZSTD_execSequenceLong(BYTE* op, } -#define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0); static size_t ZSTD_decompressSequencesLong( ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, @@ -1023,9 +1031,9 @@ static size_t ZSTD_decompressSequencesLong( /* Regen sequences */ if (nbSeq) { -#define STORED_SEQS 8 +#define STORED_SEQS 4 #define STOSEQ_MASK (STORED_SEQS-1) -#define ADVANCED_SEQS 5 +#define ADVANCED_SEQS 4 seq_t sequences[STORED_SEQS]; int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); seqState_t seqState; @@ -1315,6 +1323,8 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, ip += litCSize; srcSize -= litCSize; } + if (dctx->fParams.windowSize > 23) + return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize); return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize); } From 52e136ed3d174d134500fbf679bec9ddcbdff490 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 28 Nov 2016 19:59:11 -0800 Subject: [PATCH 084/185] long decoder compatible with round and separate buffers --- lib/common/mem.h | 4 +++- lib/decompress/zstd_decompress.c | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/common/mem.h b/lib/common/mem.h index 681dd35d2..32c63dd17 100644 --- a/lib/common/mem.h +++ b/lib/common/mem.h @@ -55,14 +55,16 @@ MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (size typedef int32_t S32; typedef uint64_t U64; typedef int64_t S64; + typedef intptr_t iPtrDiff; #else - typedef unsigned char BYTE; + typedef unsigned char BYTE; typedef unsigned short U16; typedef signed short S16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; typedef signed long long S64; + typedef ptrdiff_t iPtrDiff; #endif diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 2d4087335..da3cf56e2 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -794,6 +794,8 @@ typedef struct { FSE_DState_t stateML; size_t prevOffset[ZSTD_REP_NUM]; const BYTE* ptr; + const BYTE* base; + iPtrDiff gotoDict; } seqState_t; @@ -862,7 +864,8 @@ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) if (MEM_32bits() || (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); - seq.match = seqState->ptr + seq.litLength - seq.offset; /* only for single memory segment ! */ + seq.match = seqState->ptr + seq.litLength - seq.offset; /* single memory segment ! */ + if (seq.match < seqState->base) seq.match += seqState->gotoDict; /* what if seq.match underflows ? prefetch is a non issue, but match has now a wrong address */ /* ANS state update */ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ @@ -954,7 +957,6 @@ size_t ZSTD_execSequenceLong(BYTE* op, if (sequence.offset > (size_t)(oLitEnd - base)) { /* offset beyond prefix */ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); - match = dictEnd - (base-match); if (match + sequence.matchLength <= dictEnd) { memmove(oLitEnd, match, sequence.matchLength); return sequenceLength; @@ -1041,6 +1043,8 @@ static size_t ZSTD_decompressSequencesLong( dctx->fseEntropy = 1; { U32 i; for (i=0; irep[i]; } seqState.ptr = op; + seqState.base = base; + seqState.gotoDict = (iPtrDiff)(dictEnd - base); CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); From c53eea7c1a84e0afd8eebc849e499a7e9948781c Mon Sep 17 00:00:00 2001 From: OBATA Akio Date: Tue, 29 Nov 2016 16:47:53 +0900 Subject: [PATCH 085/185] libzstd.pc.in: Change to use variables for libdir and includedir --- lib/libzstd.pc.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libzstd.pc.in b/lib/libzstd.pc.in index 9399363dd..703da060b 100644 --- a/lib/libzstd.pc.in +++ b/lib/libzstd.pc.in @@ -10,5 +10,5 @@ Name: zstd Description: lossless compression algorithm library URL: https://github.com/facebook/zstd Version: @VERSION@ -Libs: -L@LIBDIR@ -lzstd -Cflags: -I@INCLUDEDIR@ +Libs: -L${libdir} -lzstd +Cflags: -I${includedir} From a1f60632cb29b407af70b88670c78109cf412355 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 15:50:28 +0100 Subject: [PATCH 086/185] gz_statep is union --- zlibWrapper/gzclose.c | 2 +- zlibWrapper/gzguts.h | 7 +- zlibWrapper/gzlib.c | 228 +++++++++++++++++++++--------------------- 3 files changed, 121 insertions(+), 116 deletions(-) diff --git a/zlibWrapper/gzclose.c b/zlibWrapper/gzclose.c index caeb99a31..b75124762 100644 --- a/zlibWrapper/gzclose.c +++ b/zlibWrapper/gzclose.c @@ -18,7 +18,7 @@ int ZEXPORT gzclose(file) return Z_STREAM_ERROR; state = (gz_statep)file; - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); + return state.state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); #else return gzclose_r(file); #endif diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index c7ccc84a2..c4c74f1a1 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -191,7 +191,12 @@ typedef struct { /* zlib inflate or deflate stream */ z_stream strm; /* stream structure in-place (not a pointer) */ } gz_state; -typedef gz_state FAR *gz_statep; + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ +typedef union { + gz_state* state; + gzFile file; +} gz_statep; /* shared functions */ void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); diff --git a/zlibWrapper/gzlib.c b/zlibWrapper/gzlib.c index fae202ef8..e811313b5 100644 --- a/zlibWrapper/gzlib.c +++ b/zlibWrapper/gzlib.c @@ -75,16 +75,16 @@ char ZLIB_INTERNAL *gz_strwinerror (error) local void gz_reset(state) gz_statep state; { - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ + state.state->x.have = 0; /* no output data available */ + if (state.state->mode == GZ_READ) { /* for reading ... */ + state.state->eof = 0; /* not at end of file */ + state.state->past = 0; /* have not read past end yet */ + state.state->how = LOOK; /* look for gzip header */ } - state->seek = 0; /* no seek request pending */ + state.state->seek = 0; /* no seek request pending */ gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ + state.state->x.pos = 0; /* no uncompressed data yet */ + state.state->strm.avail_in = 0; /* no input data yet */ } /* Open a gzip file either by name or file descriptor. */ @@ -108,36 +108,36 @@ local gzFile gz_open(path, fd, mode) return NULL; /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) + state = (gz_statep)(gz_state*)malloc(sizeof(gz_state)); + if (state.state == NULL) return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ + state.state->size = 0; /* no buffers allocated yet */ + state.state->want = GZBUFSIZE; /* requested buffer size */ + state.state->msg = NULL; /* no error message yet */ /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; + state.state->mode = GZ_NONE; + state.state->level = Z_DEFAULT_COMPRESSION; + state.state->strategy = Z_DEFAULT_STRATEGY; + state.state->direct = 0; while (*mode) { if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; + state.state->level = *mode - '0'; else switch (*mode) { case 'r': - state->mode = GZ_READ; + state.state->mode = GZ_READ; break; #ifndef NO_GZCOMPRESS case 'w': - state->mode = GZ_WRITE; + state.state->mode = GZ_WRITE; break; case 'a': - state->mode = GZ_APPEND; + state.state->mode = GZ_APPEND; break; #endif case '+': /* can't read and write at the same time */ - free(state); + free(state.state); return NULL; case 'b': /* ignore -- will request binary anyway */ break; @@ -152,19 +152,19 @@ local gzFile gz_open(path, fd, mode) break; #endif case 'f': - state->strategy = Z_FILTERED; + state.state->strategy = Z_FILTERED; break; case 'h': - state->strategy = Z_HUFFMAN_ONLY; + state.state->strategy = Z_HUFFMAN_ONLY; break; case 'R': - state->strategy = Z_RLE; + state.state->strategy = Z_RLE; break; case 'F': - state->strategy = Z_FIXED; + state.state->strategy = Z_FIXED; break; case 'T': - state->direct = 1; + state.state->direct = 1; break; default: /* could consider as an error, but just ignore */ ; @@ -173,18 +173,18 @@ local gzFile gz_open(path, fd, mode) } /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); + if (state.state->mode == GZ_NONE) { + free(state.state); return NULL; } /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); + if (state.state->mode == GZ_READ) { + if (state.state->direct) { + free(state.state); return NULL; } - state->direct = 1; /* for empty file */ + state.state->direct = 1; /* for empty file */ } /* save the path name for error messages */ @@ -197,23 +197,23 @@ local gzFile gz_open(path, fd, mode) else #endif len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); + state.state->path = (char *)malloc(len + 1); + if (state.state->path == NULL) { + free(state.state); return NULL; } #ifdef _WIN32 if (fd == -2) if (len) - wcstombs(state->path, path, len + 1); + wcstombs(state.state->path, path, len + 1); else - *(state->path) = 0; + *(state.state->path) = 0; else #endif #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->path, len + 1, "%s", (const char *)path); + snprintf(state.state->path, len + 1, "%s", (const char *)path); #else - strcpy(state->path, path); + strcpy(state.state->path, path); #endif /* compute the flags for open() */ @@ -227,41 +227,41 @@ local gzFile gz_open(path, fd, mode) #ifdef O_CLOEXEC (cloexec ? O_CLOEXEC : 0) | #endif - (state->mode == GZ_READ ? + (state.state->mode == GZ_READ ? O_RDONLY : (O_WRONLY | O_CREAT | #ifdef O_EXCL (exclusive ? O_EXCL : 0) | #endif - (state->mode == GZ_WRITE ? + (state.state->mode == GZ_WRITE ? O_TRUNC : O_APPEND))); /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( + state.state->fd = fd > -1 ? fd : ( #ifdef _WIN32 fd == -2 ? _wopen(path, oflag, 0666) : #endif open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); + if (state.state->fd == -1) { + free(state.state->path); + free(state.state); return NULL; } - if (state->mode == GZ_APPEND) - state->mode = GZ_WRITE; /* simplify later checks */ + if (state.state->mode == GZ_APPEND) + state.state->mode = GZ_WRITE; /* simplify later checks */ /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; + if (state.state->mode == GZ_READ) { + state.state->start = LSEEK(state.state->fd, 0, SEEK_CUR); + if (state.state->start == -1) state.state->start = 0; } /* initialize stream */ gz_reset(state); /* return stream */ - return (gzFile)state; + return (gzFile)state.file; } /* -- see zlib.h -- */ @@ -321,17 +321,17 @@ int ZEXPORT gzbuffer(file, size) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* make sure we haven't already allocated memory */ - if (state->size != 0) + if (state.state->size != 0) return -1; /* check and set requested size */ if (size < 2) size = 2; /* need two bytes to check magic header */ - state->want = size; + state.state->want = size; return 0; } @@ -347,12 +347,12 @@ int ZEXPORT gzrewind(file) state = (gz_statep)file; /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return -1; /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + if (LSEEK(state.state->fd, state.state->start, SEEK_SET) == -1) return -1; gz_reset(state); return 0; @@ -372,11 +372,11 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) + if (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR) return -1; /* can only seek from start or relative to current position */ @@ -385,32 +385,32 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) /* normalize offset to a SEEK_CUR specification */ if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; + offset -= state.state->x.pos; + else if (state.state->seek) + offset += state.state->skip; + state.state->seek = 0; /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (state.state->mode == GZ_READ && state.state->how == COPY && + state.state->x.pos + offset >= 0) { + ret = LSEEK(state.state->fd, offset - state.state->x.have, SEEK_CUR); if (ret == -1) return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; + state.state->x.have = 0; + state.state->eof = 0; + state.state->past = 0; + state.state->seek = 0; gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; + state.state->strm.avail_in = 0; + state.state->x.pos += offset; + return state.state->x.pos; } /* calculate skip amount, rewinding if needed for back seek when reading */ if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ + if (state.state->mode != GZ_READ) /* writing -- can't go backwards */ return -1; - offset += state->x.pos; + offset += state.state->x.pos; if (offset < 0) /* before start of file! */ return -1; if (gzrewind(file) == -1) /* rewind, then skip to offset */ @@ -418,21 +418,21 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) } /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; + if (state.state->mode == GZ_READ) { + n = GT_OFF(state.state->x.have) || (z_off64_t)state.state->x.have > offset ? + (unsigned)offset : state.state->x.have; + state.state->x.have -= n; + state.state->x.next += n; + state.state->x.pos += n; offset -= n; } /* request skip (if not zero) */ if (offset) { - state->seek = 1; - state->skip = offset; + state.state->seek = 1; + state.state->skip = offset; } - return state->x.pos + offset; + return state.state->x.pos + offset; } /* -- see zlib.h -- */ @@ -457,11 +457,11 @@ z_off64_t ZEXPORT gztell64(file) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); + return state.state->x.pos + (state.state->seek ? state.state->skip : 0); } /* -- see zlib.h -- */ @@ -485,15 +485,15 @@ z_off64_t ZEXPORT gzoffset64(file) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); + offset = LSEEK(state.state->fd, 0, SEEK_CUR); if (offset == -1) return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ + if (state.state->mode == GZ_READ) /* reading */ + offset -= state.state->strm.avail_in; /* don't count buffered input */ return offset; } @@ -517,11 +517,11 @@ int ZEXPORT gzeof(file) if (file == NULL) return 0; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return 0; /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; + return state.state->mode == GZ_READ ? state.state->past : 0; } /* -- see zlib.h -- */ @@ -535,14 +535,14 @@ const char * ZEXPORT gzerror(file, errnum) if (file == NULL) return NULL; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return NULL; /* return error information */ if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); + *errnum = state.state->err; + return state.state->err == Z_MEM_ERROR ? "out of memory" : + (state.state->msg == NULL ? "" : state.state->msg); } /* -- see zlib.h -- */ @@ -555,13 +555,13 @@ void ZEXPORT gzclearerr(file) if (file == NULL) return; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return; /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; + if (state.state->mode == GZ_READ) { + state.state->eof = 0; + state.state->past = 0; } gz_error(state, Z_OK, NULL); } @@ -578,18 +578,18 @@ void ZLIB_INTERNAL gz_error(state, err, msg) const char *msg; { /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; + if (state.state->msg != NULL) { + if (state.state->err != Z_MEM_ERROR) + free(state.state->msg); + state.state->msg = NULL; } /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; + state.state->x.have = 0; /* set error code, and if no message, then done */ - state->err = err; + state.state->err = err; if (msg == NULL) return; @@ -598,18 +598,18 @@ void ZLIB_INTERNAL gz_error(state, err, msg) return; /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + if ((state.state->msg = (char *)malloc(strlen(state.state->path) + strlen(msg) + 3)) == NULL) { - state->err = Z_MEM_ERROR; + state.state->err = Z_MEM_ERROR; return; } #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); + snprintf(state.state->msg, strlen(state.state->path) + strlen(msg) + 3, + "%s%s%s", state.state->path, ": ", msg); #else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); + strcpy(state.state->msg, state.state->path); + strcat(state.state->msg, ": "); + strcat(state.state->msg, msg); #endif return; } From 0feb24a2fab3d63b97f69f84ffaa2c30da90714c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 16:05:52 +0100 Subject: [PATCH 087/185] gzread.c, gzwrite.c: gz_statep is union --- zlibWrapper/gzread.c | 258 +++++++++++++++++++++--------------------- zlibWrapper/gzwrite.c | 236 +++++++++++++++++++------------------- 2 files changed, 247 insertions(+), 247 deletions(-) diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index c982b1429..5bc0f6ff9 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -27,7 +27,7 @@ local int gz_load(state, buf, len, have) *have = 0; do { - ret = read(state->fd, buf + *have, len - *have); + ret = read(state.state->fd, buf + *have, len - *have); if (ret <= 0) break; *have += ret; @@ -37,7 +37,7 @@ local int gz_load(state, buf, len, have) return -1; } if (ret == 0) - state->eof = 1; + state.state->eof = 1; return 0; } @@ -52,24 +52,24 @@ local int gz_avail(state) gz_statep state; { unsigned got; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); - if (state->err != Z_OK && state->err != Z_BUF_ERROR) + if (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR) return -1; - if (state->eof == 0) { + if (state.state->eof == 0) { if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; + unsigned char *p = state.state->in; unsigned const char *q = strm->next_in; unsigned n = strm->avail_in; do { *p++ = *q++; } while (--n); } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) + if (gz_load(state, state.state->in + strm->avail_in, + state.state->size - strm->avail_in, &got) == -1) return -1; strm->avail_in += got; - strm->next_in = state->in; + strm->next_in = state.state->in; } return 0; } @@ -86,33 +86,33 @@ local int gz_avail(state) local int gz_look(state) gz_statep state; { - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* allocate read buffers and inflate memory */ - if (state->size == 0) { + if (state.state->size == 0) { /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); + state.state->in = (unsigned char *)malloc(state.state->want); + state.state->out = (unsigned char *)malloc(state.state->want << 1); + if (state.state->in == NULL || state.state->out == NULL) { + if (state.state->out != NULL) + free(state.state->out); + if (state.state->in != NULL) + free(state.state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } - state->size = state->want; + state.state->size = state.state->want; /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; + state.state->strm.zalloc = Z_NULL; + state.state->strm.zfree = Z_NULL; + state.state->strm.opaque = Z_NULL; + state.state->strm.avail_in = 0; + state.state->strm.next_in = Z_NULL; + if (inflateInit2(&(state.state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state.state->out); + free(state.state->in); + state.state->size = 0; gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } @@ -138,31 +138,31 @@ local int gz_look(state) ((strm->next_in[0] == 31 && strm->next_in[1] == 139) || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { // zstd inflateReset(strm); - state->how = GZIP; - state->direct = 0; + state.state->how = GZIP; + state.state->direct = 0; return 0; } /* no gzip header -- if we were decoding gzip before, then this is trailing garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { + if (state.state->direct == 0) { strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; + state.state->eof = 1; + state.state->x.have = 0; return 0; } /* doing raw i/o, copy any leftover input to output -- this assumes that the output buffer is larger than the input buffer, which also assures space for gzungetc() */ - state->x.next = state->out; + state.state->x.next = state.state->out; if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; + memcpy(state.state->x.next, strm->next_in, strm->avail_in); + state.state->x.have = strm->avail_in; strm->avail_in = 0; } - state->how = COPY; - state->direct = 1; + state.state->how = COPY; + state.state->direct = 1; return 0; } @@ -176,7 +176,7 @@ local int gz_decomp(state) { int ret = Z_OK; unsigned had; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* fill output buffer up to end of deflate stream */ had = strm->avail_out; @@ -208,12 +208,12 @@ local int gz_decomp(state) } while (strm->avail_out && ret != Z_STREAM_END); /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; + state.state->x.have = had - strm->avail_out; + state.state->x.next = strm->next_out - state.state->x.have; /* if the gzip stream completed successfully, look for another */ if (ret == Z_STREAM_END) - state->how = LOOK; + state.state->how = LOOK; /* good decompression */ return 0; @@ -228,29 +228,29 @@ local int gz_decomp(state) local int gz_fetch(state) gz_statep state; { - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); do { - switch(state->how) { + switch(state.state->how) { case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ if (gz_look(state) == -1) return -1; - if (state->how == LOOK) + if (state.state->how == LOOK) return 0; break; case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + if (gz_load(state, state.state->out, state.state->size << 1, &(state.state->x.have)) == -1) return -1; - state->x.next = state->out; + state.state->x.next = state.state->out; return 0; case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; + strm->avail_out = state.state->size << 1; + strm->next_out = state.state->out; if (gz_decomp(state) == -1) return -1; } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + } while (state.state->x.have == 0 && (!state.state->eof || strm->avail_in)); return 0; } @@ -264,17 +264,17 @@ local int gz_skip(state, len) /* skip over len bytes or reach end-of-file, whichever comes first */ while (len) /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; + if (state.state->x.have) { + n = GT_OFF(state.state->x.have) || (z_off64_t)state.state->x.have > len ? + (unsigned)len : state.state->x.have; + state.state->x.have -= n; + state.state->x.next += n; + state.state->x.pos += n; len -= n; } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) + else if (state.state->eof && state.state->strm.avail_in == 0) break; /* need more data to skip -- load up output buffer */ @@ -300,11 +300,11 @@ int ZEXPORT gzread(file, buf, len) if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return -1; /* since an int is returned, make sure len fits in one, otherwise return @@ -319,9 +319,9 @@ int ZEXPORT gzread(file, buf, len) return 0; /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_skip(state, state.state->skip) == -1) return -1; } @@ -329,22 +329,22 @@ int ZEXPORT gzread(file, buf, len) got = 0; do { /* first just try copying data from the output buffer */ - if (state->x.have) { - n = state->x.have > len ? len : state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; + if (state.state->x.have) { + n = state.state->x.have > len ? len : state.state->x.have; + memcpy(buf, state.state->x.next, n); + state.state->x.next += n; + state.state->x.have -= n; } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) { - state->past = 1; /* tried to read past end */ + else if (state.state->eof && strm->avail_in == 0) { + state.state->past = 1; /* tried to read past end */ break; } /* need output data -- for small len or new stream load up our output buffer */ - else if (state->how == LOOK || len < (state->size << 1)) { + else if (state.state->how == LOOK || len < (state.state->size << 1)) { /* get more output, looking for header if required */ if (gz_fetch(state) == -1) return -1; @@ -354,7 +354,7 @@ int ZEXPORT gzread(file, buf, len) } /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ + else if (state.state->how == COPY) { /* read directly */ if (gz_load(state, (unsigned char *)buf, len, &n) == -1) return -1; } @@ -365,15 +365,15 @@ int ZEXPORT gzread(file, buf, len) strm->next_out = (unsigned char *)buf; if (gz_decomp(state) == -1) return -1; - n = state->x.have; - state->x.have = 0; + n = state.state->x.have; + state.state->x.have = 0; } /* update progress */ len -= n; buf = (char *)buf + n; got += n; - state->x.pos += n; + state.state->x.pos += n; } while (len); /* return number of bytes read into user buffer (will fit in int) */ @@ -412,15 +412,15 @@ int ZEXPORT gzgetc(file) state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return -1; /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; + if (state.state->x.have) { + state.state->x.have--; + state.state->x.pos++; + return *(state.state->x.next)++; } /* nothing there -- try gzread() */ @@ -447,14 +447,14 @@ int ZEXPORT gzungetc(c, file) state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return -1; /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_skip(state, state.state->skip) == -1) return -1; } @@ -463,34 +463,34 @@ int ZEXPORT gzungetc(c, file) return -1; /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; + if (state.state->x.have == 0) { + state.state->x.have = 1; + state.state->x.next = state.state->out + (state.state->size << 1) - 1; + state.state->x.next[0] = c; + state.state->x.pos--; + state.state->past = 0; return c; } /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { + if (state.state->x.have == (state.state->size << 1)) { gz_error(state, Z_DATA_ERROR, "out of room to push characters"); return -1; } /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) + if (state.state->x.next == state.state->out) { + unsigned char *src = state.state->out + state.state->x.have; + unsigned char *dest = state.state->out + (state.state->size << 1); + while (src > state.state->out) *--dest = *--src; - state->x.next = dest; + state.state->x.next = dest; } - state->x.have++; - state->x.next--; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; + state.state->x.have++; + state.state->x.next--; + state.state->x.next[0] = c; + state.state->x.pos--; + state.state->past = 0; return c; } @@ -511,14 +511,14 @@ char * ZEXPORT gzgets(file, buf, len) state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return NULL; /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_skip(state, state.state->skip) == -1) return NULL; } @@ -529,24 +529,24 @@ char * ZEXPORT gzgets(file, buf, len) left = (unsigned)len - 1; if (left) do { /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) + if (state.state->x.have == 0 && gz_fetch(state) == -1) return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ + if (state.state->x.have == 0) { /* end of file */ + state.state->past = 1; /* read past end */ break; /* return what we have */ } /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); + n = state.state->x.have > left ? left : state.state->x.have; + eol = (unsigned char *)memchr(state.state->x.next, '\n', n); if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; + n = (unsigned)(eol - state.state->x.next) + 1; /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; + memcpy(buf, state.state->x.next, n); + state.state->x.have -= n; + state.state->x.next += n; + state.state->x.pos += n; left -= n; buf += n; } while (left && eol == NULL); @@ -571,11 +571,11 @@ int ZEXPORT gzdirect(file) /* if the state is not known, but we can find out, then do so (this is mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + if (state.state->mode == GZ_READ && state.state->how == LOOK && state.state->x.have == 0) (void)gz_look(state); /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; + return state.state->direct; } /* -- see zlib.h -- */ @@ -591,19 +591,19 @@ int ZEXPORT gzclose_r(file) state = (gz_statep)file; /* check that we're reading */ - if (state->mode != GZ_READ) + if (state.state->mode != GZ_READ) return Z_STREAM_ERROR; /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); + if (state.state->size) { + inflateEnd(&(state.state->strm)); + free(state.state->out); + free(state.state->in); } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + err = state.state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); + free(state.state->path); + ret = close(state.state->fd); + free(state.state); return ret ? Z_ERRNO : err; } diff --git a/zlibWrapper/gzwrite.c b/zlibWrapper/gzwrite.c index aa767fbf6..7d4a614f2 100644 --- a/zlibWrapper/gzwrite.c +++ b/zlibWrapper/gzwrite.c @@ -16,21 +16,21 @@ local int gz_init(state) gz_statep state; { int ret; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* allocate input buffer */ - state->in = (unsigned char *)malloc(state->want); - if (state->in == NULL) { + state.state->in = (unsigned char *)malloc(state.state->want); + if (state.state->in == NULL) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } /* only need output buffer and deflate state if compressing */ - if (!state->direct) { + if (!state.state->direct) { /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); + state.state->out = (unsigned char *)malloc(state.state->want); + if (state.state->out == NULL) { + free(state.state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } @@ -39,24 +39,24 @@ local int gz_init(state) strm->zalloc = Z_NULL; strm->zfree = Z_NULL; strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + ret = deflateInit2(strm, state.state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state.state->strategy); if (ret != Z_OK) { - free(state->out); - free(state->in); + free(state.state->out); + free(state.state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } } /* mark state as initialized */ - state->size = state->want; + state.state->size = state.state->want; /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; + if (!state.state->direct) { + strm->avail_out = state.state->size; + strm->next_out = state.state->out; + state.state->x.next = strm->next_out; } return 0; } @@ -73,15 +73,15 @@ local int gz_comp(state, flush) { int ret, got; unsigned have; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return -1; /* write directly if requested */ - if (state->direct) { - got = write(state->fd, strm->next_in, strm->avail_in); + if (state.state->direct) { + got = write(state.state->fd, strm->next_in, strm->avail_in); if (got < 0 || (unsigned)got != strm->avail_in) { gz_error(state, Z_ERRNO, zstrerror()); return -1; @@ -97,17 +97,17 @@ local int gz_comp(state, flush) doing Z_FINISH then don't write until we get to Z_STREAM_END */ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->x.next); - if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + have = (unsigned)(strm->next_out - state.state->x.next); + if (have && ((got = write(state.state->fd, state.state->x.next, have)) < 0 || (unsigned)got != have)) { gz_error(state, Z_ERRNO, zstrerror()); return -1; } if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; + strm->avail_out = state.state->size; + strm->next_out = state.state->out; } - state->x.next = strm->next_out; + state.state->x.next = strm->next_out; } /* compress */ @@ -136,7 +136,7 @@ local int gz_zero(state, len) { int first; unsigned n; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) @@ -145,15 +145,15 @@ local int gz_zero(state, len) /* compress len zeros (len guaranteed > 0) */ first = 1; while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; + n = GT_OFF(state.state->size) || (z_off64_t)state.state->size > len ? + (unsigned)len : state.state->size; if (first) { - memset(state->in, 0, n); + memset(state.state->in, 0, n); first = 0; } strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; + strm->next_in = state.state->in; + state.state->x.pos += n; if (gz_comp(state, Z_NO_FLUSH) == -1) return -1; len -= n; @@ -175,10 +175,10 @@ int ZEXPORT gzwrite(file, buf, len) if (file == NULL) return 0; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return 0; /* since an int is returned, make sure len fits in one, otherwise return @@ -193,31 +193,31 @@ int ZEXPORT gzwrite(file, buf, len) return 0; /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return 0; } /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { + if (len < state.state->size) { /* copy to input buffer, compress when full */ do { unsigned have, copy; if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - copy = state->size - have; + strm->next_in = state.state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state.state->in); + copy = state.state->size - have; if (copy > len) copy = len; - memcpy(state->in + have, buf, copy); + memcpy(state.state->in + have, buf, copy); strm->avail_in += copy; - state->x.pos += copy; + state.state->x.pos += copy; buf = (const char *)buf + copy; len -= copy; if (len && gz_comp(state, Z_NO_FLUSH) == -1) @@ -232,7 +232,7 @@ int ZEXPORT gzwrite(file, buf, len) /* directly compress user buffer to file */ strm->avail_in = len; strm->next_in = (z_const Bytef *)buf; - state->x.pos += len; + state.state->x.pos += len; if (gz_comp(state, Z_NO_FLUSH) == -1) return 0; } @@ -255,29 +255,29 @@ int ZEXPORT gzputc(file, c) if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return -1; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return -1; } /* try writing to input buffer for speed (state->size == 0 if buffer not initialized) */ - if (state->size) { + if (state.state->size) { if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = c; + strm->next_in = state.state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state.state->in); + if (have < state.state->size) { + state.state->in[have] = c; strm->avail_in++; - state->x.pos++; + state.state->x.pos++; return c & 0xff; } } @@ -317,20 +317,20 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return 0; /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return 0; } @@ -339,33 +339,33 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) return 0; /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + size = (int)(state.state->size); + state.state->in[size - 1] = 0; #ifdef NO_vsnprintf # ifdef HAS_vsprintf_void - (void)vsprintf((char *)(state->in), format, va); + (void)vsprintf((char *)(state.state->in), format, va); for (len = 0; len < size; len++) - if (state->in[len] == 0) break; + if (state.state->in[len] == 0) break; # else - len = vsprintf((char *)(state->in), format, va); + len = vsprintf((char *)(state.state->in), format, va); # endif #else # ifdef HAS_vsnprintf_void - (void)vsnprintf((char *)(state->in), size, format, va); - len = strlen((char *)(state->in)); + (void)vsnprintf((char *)(state.state->in), size, format, va); + len = strlen((char *)(state.state->in)); # else - len = vsnprintf((char *)(state->in), size, format, va); + len = vsnprintf((char *)(state.state->in), size, format, va); # endif #endif /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + if (len <= 0 || len >= (int)size || state.state->in[size - 1] != 0) return 0; /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; + strm->next_in = state.state->in; + state.state->x.pos += len; return len; } @@ -398,24 +398,24 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that can really pass pointer in ints */ if (sizeof(int) != sizeof(void *)) return 0; /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return 0; /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return 0; } @@ -424,38 +424,38 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, return 0; /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + size = (int)(state.state->size); + state.state->in[size - 1] = 0; #ifdef NO_snprintf # ifdef HAS_sprintf_void - sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + sprintf((char *)(state.state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); for (len = 0; len < size; len++) - if (state->in[len] == 0) break; + if (state.state->in[len] == 0) break; # else - len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + len = sprintf((char *)(state.state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #else # ifdef HAS_snprintf_void - snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + snprintf((char *)(state.state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen((char *)(state->in)); + len = strlen((char *)(state.state->in)); # else - len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + len = snprintf((char *)(state.state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #endif /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + if (len <= 0 || len >= (int)size || state.state->in[size - 1] != 0) return 0; /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; + strm->next_in = state.state->in; + state.state->x.pos += len; return len; } @@ -474,7 +474,7 @@ int ZEXPORT gzflush(file, flush) state = (gz_statep)file; /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return Z_STREAM_ERROR; /* check flush parameter */ @@ -482,15 +482,15 @@ int ZEXPORT gzflush(file, flush) return Z_STREAM_ERROR; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return -1; } /* compress remaining data with requested flush */ gz_comp(state, flush); - return state->err; + return state.state->err; } /* -- see zlib.h -- */ @@ -506,32 +506,32 @@ int ZEXPORT gzsetparams(file, level, strategy) if (file == NULL) return Z_STREAM_ERROR; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return Z_STREAM_ERROR; /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) + if (level == state.state->level && strategy == state.state->strategy) return Z_OK; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return -1; } /* change compression parameters for subsequent input */ - if (state->size) { + if (state.state->size) { /* flush previous input with previous parameters before changing */ if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) - return state->err; + return state.state->err; deflateParams(strm, level, strategy); } - state->level = level; - state->strategy = strategy; + state.state->level = level; + state.state->strategy = strategy; return Z_OK; } @@ -548,30 +548,30 @@ int ZEXPORT gzclose_w(file) state = (gz_statep)file; /* check that we're writing */ - if (state->mode != GZ_WRITE) + if (state.state->mode != GZ_WRITE) return Z_STREAM_ERROR; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) + ret = state.state->err; } /* flush, free memory, and close file */ if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); + ret = state.state->err; + if (state.state->size) { + if (!state.state->direct) { + (void)deflateEnd(&(state.state->strm)); + free(state.state->out); } - free(state->in); + free(state.state->in); } gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) + free(state.state->path); + if (close(state.state->fd) == -1) ret = Z_ERRNO; - free(state); + free(state.state); return ret; } From 087bd2c1988f6f33a23d70ee43202018aa41b32b Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 17:57:00 +0100 Subject: [PATCH 088/185] compile with -Wstrict-aliasing=1 --- zlibWrapper/Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 41b334d32..49d44e35a 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -20,8 +20,7 @@ TEST_FILE = ../doc/zstd_compression_format.md CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -#-Wstrict-aliasing=1 +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -Wstrict-aliasing=1 # Define *.exe as extension for Windows systems @@ -34,7 +33,7 @@ endif all: clean fitblk example zwrapbench minigzip -test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd +test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip minigzip_zstd ./example ./example_zstd ./fitblk 10240 <$(TEST_FILE) @@ -43,6 +42,10 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd ./fitblk_zstd 40960 <$(TEST_FILE) @echo ---- minigzip start ---- ./minigzip_zstd example$(EXT) + cp example$(EXT).gz example$(EXT)_zstd.gz + ./minigzip_zstd -d example$(EXT).gz + ./minigzip example$(EXT) + cp example$(EXT).gz example$(EXT)_gz.gz ./minigzip_zstd -d example$(EXT).gz @echo ---- minigzip end ---- ./zwrapbench -qb3B1K $(TEST_FILE) From f0d7da79dea23443fd86cf3d51b392b342b4c2e5 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 18:02:34 +0100 Subject: [PATCH 089/185] updated headers in gz* files --- zlibWrapper/gzclose.c | 3 +++ zlibWrapper/gzguts.h | 4 ++++ zlibWrapper/gzlib.c | 3 +++ zlibWrapper/gzread.c | 3 +++ zlibWrapper/gzwrite.c | 3 +++ 5 files changed, 16 insertions(+) diff --git a/zlibWrapper/gzclose.c b/zlibWrapper/gzclose.c index b75124762..b5b7480c3 100644 --- a/zlibWrapper/gzclose.c +++ b/zlibWrapper/gzclose.c @@ -1,3 +1,6 @@ +/* gzclose.c contains minimal changes required to be compiled with zlibWrapper: + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzclose.c -- zlib gzclose() function * Copyright (C) 2004, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index c4c74f1a1..3d8d7e76a 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -1,3 +1,7 @@ +/* gzguts.h contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzguts.h -- zlib internal header definitions for gz* operations * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/zlibWrapper/gzlib.c b/zlibWrapper/gzlib.c index e811313b5..172041df5 100644 --- a/zlibWrapper/gzlib.c +++ b/zlibWrapper/gzlib.c @@ -1,3 +1,6 @@ +/* gzlib.c contains minimal changes required to be compiled with zlibWrapper: + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzlib.c -- zlib functions common to reading and writing gzip files * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index 5bc0f6ff9..ad33ebc62 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -1,3 +1,6 @@ +/* gzread.c contains minimal changes required to be compiled with zlibWrapper: + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzread.c -- zlib functions for reading gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/zlibWrapper/gzwrite.c b/zlibWrapper/gzwrite.c index 7d4a614f2..d1478d3c1 100644 --- a/zlibWrapper/gzwrite.c +++ b/zlibWrapper/gzwrite.c @@ -1,3 +1,6 @@ +/* gzwrite.c contains minimal changes required to be compiled with zlibWrapper: + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzwrite.c -- zlib functions for writing gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h From adf215e6e3386be49de16471a1dfd8624359311c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 20:32:42 +0100 Subject: [PATCH 090/185] fixed Travis warnings --- zlibWrapper/gzguts.h | 1 - 1 file changed, 1 deletion(-) diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index 3d8d7e76a..5ec33a5b8 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -196,7 +196,6 @@ typedef struct { z_stream strm; /* stream structure in-place (not a pointer) */ } gz_state; -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ typedef union { gz_state* state; gzFile file; From 05c00f2ff771bf80488b8c106de5dd2d275b2512 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 29 Nov 2016 11:46:37 -0800 Subject: [PATCH 091/185] Fix ZSTD_STATIC_LINKING_ONLY with double include --- lib/zstd.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/zstd.h b/lib/zstd.h index 7db135b5b..607612026 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -7,13 +7,13 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#ifndef ZSTD_H_235446 -#define ZSTD_H_235446 - #if defined (__cplusplus) extern "C" { #endif +#ifndef ZSTD_H_235446 +#define ZSTD_H_235446 + /* ====== Dependency ======*/ #include /* size_t */ @@ -313,9 +313,11 @@ ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* outp ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */ +#endif /* ZSTD_H_235446 */ -#ifdef ZSTD_STATIC_LINKING_ONLY +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY /**************************************************************************************** * START OF ADVANCED AND EXPERIMENTAL FUNCTIONS @@ -642,10 +644,8 @@ ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCa ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */ -#endif /* ZSTD_STATIC_LINKING_ONLY */ +#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ #if defined (__cplusplus) } #endif - -#endif /* ZSTD_H_235446 */ From 4f5350f610a93817554bf402946ae9203a6ca7b7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 29 Nov 2016 13:12:24 -0800 Subject: [PATCH 092/185] long matches support overflow --- lib/decompress/zstd_decompress.c | 14 ++++++++------ programs/bench.c | 6 +++--- tests/playTests.sh | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index da3cf56e2..6539eb41e 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -793,8 +793,8 @@ typedef struct { FSE_DState_t stateOffb; FSE_DState_t stateML; size_t prevOffset[ZSTD_REP_NUM]; - const BYTE* ptr; const BYTE* base; + size_t pos; iPtrDiff gotoDict; } seqState_t; @@ -864,15 +864,17 @@ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) if (MEM_32bits() || (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); - seq.match = seqState->ptr + seq.litLength - seq.offset; /* single memory segment ! */ - if (seq.match < seqState->base) seq.match += seqState->gotoDict; /* what if seq.match underflows ? prefetch is a non issue, but match has now a wrong address */ + { size_t const pos = seqState->pos + seq.litLength; + seq.match = seqState->base + pos - seq.offset; /* single memory segment */ + if (seq.offset > pos) seq.match += seqState->gotoDict; /* separate memory segment */ + seqState->pos = pos + seq.matchLength; + } /* ANS state update */ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ - seqState->ptr += seq.matchLength + seq.litLength; return seq; } @@ -1042,8 +1044,8 @@ static size_t ZSTD_decompressSequencesLong( int seqNb; dctx->fseEntropy = 1; { U32 i; for (i=0; irep[i]; } - seqState.ptr = op; seqState.base = base; + seqState.pos = (size_t)(op-base); seqState.gotoDict = (iPtrDiff)(dictEnd - base); CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); @@ -1194,7 +1196,7 @@ size_t ZSTD_execSequence(BYTE* op, if (sequence.offset > (size_t)(oLitEnd - base)) { /* offset beyond prefix */ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); - match = dictEnd - (base-match); + match += (dictEnd-base); if (match + sequence.matchLength <= dictEnd) { memmove(oLitEnd, match, sequence.matchLength); return sequenceLength; diff --git a/programs/bench.c b/programs/bench.c index df68d0ada..4efba160a 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -175,7 +175,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, { U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL); U64 const crcOrig = XXH64(srcBuffer, srcSize, 0); UTIL_time_t coolTime; - U64 const maxTime = (g_nbSeconds * TIMELOOP_MICROSEC) + 100; + U64 const maxTime = (g_nbSeconds * TIMELOOP_MICROSEC) + 1; U64 totalCTime=0, totalDTime=0; U32 cCompleted=0, dCompleted=0; # define NB_MARKS 4 @@ -234,7 +234,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, { U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond); if (clockSpan < fastestC*nbLoops) fastestC = clockSpan / nbLoops; totalCTime += clockSpan; - cCompleted = totalCTime>maxTime; + cCompleted = (totalCTime >= maxTime); } } cSize = 0; @@ -279,7 +279,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, { U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond); if (clockSpan < fastestD*nbLoops) fastestD = clockSpan / nbLoops; totalDTime += clockSpan; - dCompleted = totalDTime>maxTime; + dCompleted = (totalDTime >= maxTime); } } markNb = (markNb+1) % NB_MARKS; diff --git a/tests/playTests.sh b/tests/playTests.sh index a50604b7e..c539d567f 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -16,7 +16,7 @@ roundTripTest() { rm -f tmp1 tmp2 $ECHO "roundTripTest: ./datagen $1 $p | $ZSTD -v$c | $ZSTD -d" ./datagen $1 $p | $MD5SUM > tmp1 - ./datagen $1 $p | $ZSTD -v$c | $ZSTD -d | $MD5SUM > tmp2 + ./datagen $1 $p | $ZSTD --ultra -v$c | $ZSTD -d | $MD5SUM > tmp2 diff -q tmp1 tmp2 } From 37870d7a668f9cf5f5d7b4d4b4c85ee700fe1830 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 29 Nov 2016 14:31:57 -0800 Subject: [PATCH 093/185] fixed minor visual warning --- lib/decompress/zstd_decompress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 6539eb41e..d6d97c1d4 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -58,7 +58,7 @@ #if defined(_MSC_VER) # include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ -# define ZSTD_PREFETCH(ptr) _mm_prefetch(ptr, _MM_HINT_T0) +# define ZSTD_PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0) #elif defined(__GNUC__) # define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0) #else From a56ac2815c971c98051e80a9d0d7828038b9d837 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 29 Nov 2016 15:30:23 -0800 Subject: [PATCH 094/185] restored normal decoder speed --- lib/decompress/zstd_decompress.c | 503 +++++++++++++++---------------- 1 file changed, 251 insertions(+), 252 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index d6d97c1d4..3e9be3f6a 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -799,87 +799,6 @@ typedef struct { } seqState_t; -static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) -{ - seq_t seq; - - U32 const llCode = FSE_peekSymbol(&seqState->stateLL); - U32 const mlCode = FSE_peekSymbol(&seqState->stateML); - U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ - - U32 const llBits = LL_bits[llCode]; - U32 const mlBits = ML_bits[mlCode]; - U32 const ofBits = ofCode; - U32 const totalBits = llBits+mlBits+ofBits; - - static const U32 LL_base[MaxLL+1] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, - 0x2000, 0x4000, 0x8000, 0x10000 }; - - static const U32 ML_base[MaxML+1] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, - 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; - - static const U32 OF_base[MaxOff+1] = { - 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, - 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, - 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, - 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; - - /* sequence */ - { size_t offset; - if (!ofCode) - offset = 0; - else { - offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); - } - - if (ofCode <= 1) { - offset += (llCode==0); - if (offset) { - size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; - temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ - if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset = temp; - } else { - offset = seqState->prevOffset[0]; - } - } else { - seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - } - seq.offset = offset; - } - - seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ - if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); - - seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&seqState->DStream, llBits) : 0); /* <= 16 bits */ - if (MEM_32bits() || - (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); - - { size_t const pos = seqState->pos + seq.litLength; - seq.match = seqState->base + pos - seq.offset; /* single memory segment */ - if (seq.offset > pos) seq.match += seqState->gotoDict; /* separate memory segment */ - seqState->pos = pos + seq.matchLength; - } - - /* ANS state update */ - FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ - FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ - FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ - - return seq; -} - - FORCE_NOINLINE size_t ZSTD_execSequenceLast7(BYTE* op, BYTE* const oend, seq_t sequence, @@ -927,169 +846,6 @@ size_t ZSTD_execSequenceLast7(BYTE* op, } -FORCE_INLINE -size_t ZSTD_execSequenceLong(BYTE* op, - BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit, - const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) -{ - BYTE* const oLitEnd = op + sequence.litLength; - size_t const sequenceLength = sequence.litLength + sequence.matchLength; - BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ - BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; - const BYTE* const iLitEnd = *litPtr + sequence.litLength; - const BYTE* match = sequence.match; - - /* check */ -#if 1 - if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ - if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ - if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); -#endif - - /* copy Literals */ - ZSTD_copy8(op, *litPtr); - if (sequence.litLength > 8) - ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ - op = oLitEnd; - *litPtr = iLitEnd; /* update for next sequence */ - - /* copy Match */ -#if 1 - if (sequence.offset > (size_t)(oLitEnd - base)) { - /* offset beyond prefix */ - if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); - if (match + sequence.matchLength <= dictEnd) { - memmove(oLitEnd, match, sequence.matchLength); - return sequenceLength; - } - /* span extDict & currentPrefixSegment */ - { size_t const length1 = dictEnd - match; - memmove(oLitEnd, match, length1); - op = oLitEnd + length1; - sequence.matchLength -= length1; - match = base; - if (op > oend_w) { - U32 i; - for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; - return sequenceLength; - } - } } - /* Requirement: op <= oend_w */ -#endif - - /* match within prefix */ - if (sequence.offset < 8) { - /* close range match, overlap */ - static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ - static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ - int const sub2 = dec64table[sequence.offset]; - op[0] = match[0]; - op[1] = match[1]; - op[2] = match[2]; - op[3] = match[3]; - match += dec32table[sequence.offset]; - ZSTD_copy4(op+4, match); - match -= sub2; - } else { - ZSTD_copy8(op, match); - } - op += 8; match += 8; - - if (oMatchEnd > oend-(16-MINMATCH)) { - if (op < oend_w) { - ZSTD_wildcopy(op, match, oend_w - op); - match += oend_w - op; - op = oend_w; - } - while (op < oMatchEnd) *op++ = *match++; - } else { - ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ - } - return sequenceLength; -} - - -static size_t ZSTD_decompressSequencesLong( - ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize) -{ - const BYTE* ip = (const BYTE*)seqStart; - const BYTE* const iend = ip + seqSize; - BYTE* const ostart = (BYTE* const)dst; - BYTE* const oend = ostart + maxDstSize; - BYTE* op = ostart; - const BYTE* litPtr = dctx->litPtr; - const BYTE* const litEnd = litPtr + dctx->litSize; - const BYTE* const base = (const BYTE*) (dctx->base); - const BYTE* const vBase = (const BYTE*) (dctx->vBase); - const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - int nbSeq; - - /* Build Decoding Tables */ - { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); - if (ZSTD_isError(seqHSize)) return seqHSize; - ip += seqHSize; - } - - /* Regen sequences */ - if (nbSeq) { -#define STORED_SEQS 4 -#define STOSEQ_MASK (STORED_SEQS-1) -#define ADVANCED_SEQS 4 - seq_t sequences[STORED_SEQS]; - int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); - seqState_t seqState; - int seqNb; - dctx->fseEntropy = 1; - { U32 i; for (i=0; irep[i]; } - seqState.base = base; - seqState.pos = (size_t)(op-base); - seqState.gotoDict = (iPtrDiff)(dictEnd - base); - CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); - FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); - FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); - FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); - - /* prepare in advance */ - for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNbrep[i] = (U32)(seqState.prevOffset[i]); } - } - - /* last literal segment */ - { size_t const lastLLSize = litEnd - litPtr; - if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); - memcpy(op, litPtr, lastLLSize); - op += lastLLSize; - } - - return op-ostart; -} static seq_t ZSTD_decodeSequence(seqState_t* seqState) @@ -1305,16 +1061,250 @@ static size_t ZSTD_decompressSequences( } -static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) +static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) { - if (dst != dctx->previousDstEnd) { /* not contiguous */ - dctx->dictEnd = dctx->previousDstEnd; - dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base)); - dctx->base = dst; - dctx->previousDstEnd = dst; + seq_t seq; + + U32 const llCode = FSE_peekSymbol(&seqState->stateLL); + U32 const mlCode = FSE_peekSymbol(&seqState->stateML); + U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ + + U32 const llBits = LL_bits[llCode]; + U32 const mlBits = ML_bits[mlCode]; + U32 const ofBits = ofCode; + U32 const totalBits = llBits+mlBits+ofBits; + + static const U32 LL_base[MaxLL+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 }; + + static const U32 ML_base[MaxML+1] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; + + static const U32 OF_base[MaxOff+1] = { + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; + + /* sequence */ + { size_t offset; + if (!ofCode) + offset = 0; + else { + offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); + } + + if (ofCode <= 1) { + offset += (llCode==0); + if (offset) { + size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } else { + offset = seqState->prevOffset[0]; + } + } else { + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } + seq.offset = offset; } + + seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ + if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); + + seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&seqState->DStream, llBits) : 0); /* <= 16 bits */ + if (MEM_32bits() || + (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); + + { size_t const pos = seqState->pos + seq.litLength; + seq.match = seqState->base + pos - seq.offset; /* single memory segment */ + if (seq.offset > pos) seq.match += seqState->gotoDict; /* separate memory segment */ + seqState->pos = pos + seq.matchLength; + } + + /* ANS state update */ + FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ + FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ + + return seq; } +FORCE_INLINE +size_t ZSTD_execSequenceLong(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = sequence.match; + + /* check */ +#if 1 + if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); +#endif + + /* copy Literals */ + ZSTD_copy8(op, *litPtr); + if (sequence.litLength > 8) + ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* copy Match */ +#if 1 + if (sequence.offset > (size_t)(oLitEnd - base)) { + /* offset beyond prefix */ + if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = base; + if (op > oend_w) { + U32 i; + for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; + return sequenceLength; + } + } } + /* Requirement: op <= oend_w */ +#endif + + /* match within prefix */ + if (sequence.offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ + int const sub2 = dec64table[sequence.offset]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[sequence.offset]; + ZSTD_copy4(op+4, match); + match -= sub2; + } else { + ZSTD_copy8(op, match); + } + op += 8; match += 8; + + if (oMatchEnd > oend-(16-MINMATCH)) { + if (op < oend_w) { + ZSTD_wildcopy(op, match, oend_w - op); + match += oend_w - op; + op = oend_w; + } + while (op < oMatchEnd) *op++ = *match++; + } else { + ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ + } + return sequenceLength; +} + +static size_t ZSTD_decompressSequencesLong( + ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE* const)dst; + BYTE* const oend = ostart + maxDstSize; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const base = (const BYTE*) (dctx->base); + const BYTE* const vBase = (const BYTE*) (dctx->vBase); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + int nbSeq; + + /* Build Decoding Tables */ + { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); + if (ZSTD_isError(seqHSize)) return seqHSize; + ip += seqHSize; + } + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 4 +#define STOSEQ_MASK (STORED_SEQS-1) +#define ADVANCED_SEQS 4 + seq_t sequences[STORED_SEQS]; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; + dctx->fseEntropy = 1; + { U32 i; for (i=0; irep[i]; } + seqState.base = base; + seqState.pos = (size_t)(op-base); + seqState.gotoDict = (iPtrDiff)(dictEnd - base); + CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); + FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + /* prepare in advance */ + for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNbrep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + { size_t const lastLLSize = litEnd - litPtr; + if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); + memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + + return op-ostart; +} + + static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) @@ -1329,12 +1319,21 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, ip += litCSize; srcSize -= litCSize; } - if (dctx->fParams.windowSize > 23) - return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize); + if (dctx->fParams.windowSize > (1<<23)) return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize); return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize); } +static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) +{ + if (dst != dctx->previousDstEnd) { /* not contiguous */ + dctx->dictEnd = dctx->previousDstEnd; + dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base)); + dctx->base = dst; + dctx->previousDstEnd = dst; + } +} + size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) From 25f46dcc0fa4b3336d65dbf636824dc76f5278bf Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 29 Nov 2016 16:59:27 -0800 Subject: [PATCH 095/185] minor const --- lib/compress/zstd_compress.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f7286ae8f..b2aabb94e 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1482,8 +1482,9 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co hashTable[h] = current; /* Update Hash Table */ while (nbCompares-- && (matchIndex > windowLow)) { - U32* nextPtr = bt + 2*(matchIndex & btMask); + U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + #ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */ const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */ if (matchIndex == predictedSmall) { @@ -1579,7 +1580,7 @@ static size_t ZSTD_insertBtAndFindBestMatch ( hashTable[h] = current; /* Update Hash Table */ while (nbCompares-- && (matchIndex > windowLow)) { - U32* nextPtr = bt + 2*(matchIndex & btMask); + U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ const BYTE* match; From b766c8029c503e48d208922042a58f083ad07bc1 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 29 Nov 2016 17:11:01 -0800 Subject: [PATCH 096/185] update NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index e6fb2be6c..28ea1c85d 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ v1.1.2 +Improved : better decompression speed at high compression settings cli : new : preserve file attributes, by Przemyslaw Skibinski cli : fixed : status displays total amount decoded when stream/file consists of multiple appended frames (like pzstd) API : changed : zbuff prototypes now generate deprecation warnings From ff504de39127f1d738bafb3de9d033193470de3a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 29 Nov 2016 17:42:46 -0800 Subject: [PATCH 097/185] minor decompression speed improvement --- lib/decompress/zstd_decompress.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 3e9be3f6a..3106fa014 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -873,17 +873,17 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState) 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; static const U32 OF_base[MaxOff+1] = { - 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, - 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, - 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, - 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; /* sequence */ { size_t offset; if (!ofCode) offset = 0; else { - offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); } @@ -906,10 +906,10 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState) seq.offset = offset; } - seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ + seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); - seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&seqState->DStream, llBits) : 0); /* <= 16 bits */ + seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ if (MEM_32bits() || (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); @@ -1086,17 +1086,17 @@ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; static const U32 OF_base[MaxOff+1] = { - 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, - 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, - 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, - 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; /* sequence */ { size_t offset; if (!ofCode) offset = 0; else { - offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); } @@ -1119,10 +1119,10 @@ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) seq.offset = offset; } - seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ + seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); - seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&seqState->DStream, llBits) : 0); /* <= 16 bits */ + seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ if (MEM_32bits() || (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); From 1cc37ad8eed7b88bba28f7e25e9fbb843e8eb0a5 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 29 Nov 2016 18:06:59 -0800 Subject: [PATCH 098/185] modified NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 28ea1c85d..79ceec771 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ v1.1.2 -Improved : better decompression speed at high compression settings +Improved : faster decompression speed at ultra compression settings and in 32-bits mode cli : new : preserve file attributes, by Przemyslaw Skibinski cli : fixed : status displays total amount decoded when stream/file consists of multiple appended frames (like pzstd) API : changed : zbuff prototypes now generate deprecation warnings From 45f7e00197697c1d23aa355a87f6011125b6ee7c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 30 Nov 2016 08:02:58 +0100 Subject: [PATCH 099/185] gz_state FAR *state --- zlibWrapper/gzguts.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index 5ec33a5b8..e2538df15 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -197,7 +197,7 @@ typedef struct { } gz_state; typedef union { - gz_state* state; + gz_state FAR *state; gzFile file; } gz_statep; From 0e14675df2550f9850d62ab8f5e0b66554afe7d9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 30 Nov 2016 13:34:21 +0100 Subject: [PATCH 100/185] fileio.c: detect .gz files --- programs/fileio.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 71593ac90..a11f92868 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -74,6 +74,7 @@ #define MAX_DICT_SIZE (8 MB) /* protection against large input (attack scenario) */ #define FNSPACE 30 +#define GZ_EXTENSION ".gz" /*-************************************* @@ -658,11 +659,20 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) FILE* const dstFile = ress.dstFile; FILE* srcFile; unsigned readSomething = 0; + size_t const suffixSize = strlen(GZ_EXTENSION); + size_t const sfnSize = strlen(srcFileName); + const char* const suffixPtr = srcFileName + sfnSize - suffixSize; + + if (sfnSize > suffixSize && strcmp(suffixPtr, GZ_EXTENSION) == 0) { + DISPLAYLEVEL(1, "zstd: %s: gz file cannot be uncompressed -- ignored \n", srcFileName); + return 1; + } if (UTIL_isDirectory(srcFileName)) { DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName); return 1; } + srcFile = FIO_openSrcFile(srcFileName); if (srcFile==0) return 1; @@ -763,6 +773,7 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles if (fclose(ress.dstFile)) EXM_THROW(72, "Write error : cannot properly close stdout"); } else { size_t const suffixSize = strlen(suffix); + size_t const gzSuffixSize = strlen(GZ_EXTENSION); size_t dfnSize = FNSPACE; unsigned u; char* dstFileName = (char*)malloc(FNSPACE); @@ -771,6 +782,7 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles const char* const srcFileName = srcNamesTable[u]; size_t const sfnSize = strlen(srcFileName); const char* const suffixPtr = srcFileName + sfnSize - suffixSize; + const char* const gzSuffixPtr = srcFileName + sfnSize - gzSuffixSize; if (dfnSize+suffixSize <= sfnSize+1) { free(dstFileName); dfnSize = sfnSize + 20; @@ -778,12 +790,18 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles if (dstFileName==NULL) EXM_THROW(74, "not enough memory for dstFileName"); } if (sfnSize <= suffixSize || strcmp(suffixPtr, suffix) != 0) { - DISPLAYLEVEL(1, "zstd: %s: unknown suffix (%4s expected) -- ignored \n", srcFileName, suffix); - skippedFiles++; - continue; + if (sfnSize <= gzSuffixSize || strcmp(gzSuffixPtr, GZ_EXTENSION) != 0) { + DISPLAYLEVEL(1, "zstd: %s: unknown suffix (%4s expected) -- ignored \n", srcFileName, suffix); + skippedFiles++; + continue; + } else { + memcpy(dstFileName, srcFileName, sfnSize - gzSuffixSize); + dstFileName[sfnSize-gzSuffixSize] = '\0'; + } + } else { + memcpy(dstFileName, srcFileName, sfnSize - suffixSize); + dstFileName[sfnSize-suffixSize] = '\0'; } - memcpy(dstFileName, srcFileName, sfnSize - suffixSize); - dstFileName[sfnSize-suffixSize] = '\0'; missingFiles += FIO_decompressDstFile(ress, dstFileName, srcFileName); } From abfb51f5f2241ca69a55dd676029b8b9618dd29c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 30 Nov 2016 15:05:54 +0100 Subject: [PATCH 101/185] gzstd: decompresses .gz files --- programs/Makefile | 5 ++- programs/fileio.c | 85 +++++++++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index b72cebdb1..4f5a00d5b 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -82,7 +82,7 @@ zstd : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \ ifneq (,$(filter Windows%,$(OS))) windres\generate_res.bat endif - $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) + $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(LDFLAGS) zstd32 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) @@ -124,6 +124,9 @@ zstd-decompress: clean_decomp_o zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) +gzstd: clean_decomp_o + CFLAGS+=-DZSTD_GZDECOMPRESS LDFLAGS+=-lz $(MAKE) zstd + generate_res: windres\generate_res.bat diff --git a/programs/fileio.c b/programs/fileio.c index a11f92868..733abe01d 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -34,6 +34,9 @@ #include "fileio.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */ #include "zstd.h" +#ifdef ZSTD_GZDECOMPRESS +#include "zlib.h" +#endif /*-************************************* @@ -657,56 +660,74 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) { unsigned long long filesize = 0; FILE* const dstFile = ress.dstFile; - FILE* srcFile; unsigned readSomething = 0; size_t const suffixSize = strlen(GZ_EXTENSION); size_t const sfnSize = strlen(srcFileName); const char* const suffixPtr = srcFileName + sfnSize - suffixSize; - if (sfnSize > suffixSize && strcmp(suffixPtr, GZ_EXTENSION) == 0) { - DISPLAYLEVEL(1, "zstd: %s: gz file cannot be uncompressed -- ignored \n", srcFileName); - return 1; - } - if (UTIL_isDirectory(srcFileName)) { DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName); return 1; } - srcFile = FIO_openSrcFile(srcFileName); - if (srcFile==0) return 1; + if (sfnSize <= suffixSize || strcmp(suffixPtr, GZ_EXTENSION) != 0) { + FILE* srcFile = FIO_openSrcFile(srcFileName); + if (srcFile==0) return 1; - /* for each frame */ - for ( ; ; ) { - /* check magic number -> version */ - size_t const toRead = 4; - size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); - if (sizeCheck==0) { - if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - break; /* no more input */ + /* for each frame */ + for ( ; ; ) { + /* check magic number -> version */ + size_t const toRead = 4; + size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); + if (sizeCheck==0) { + if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + break; /* no more input */ + } + readSomething = 1; /* there is at least >= 4 bytes in srcFile */ + if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { + if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ + return result; + } else { + DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); + fclose(srcFile); + return 1; + } } + filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); } - readSomething = 1; /* there is at least >= 4 bytes in srcFile */ - if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } - filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); + /* Close file */ + if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ + } else { +#ifndef ZSTD_GZDECOMPRESS + DISPLAYLEVEL(1, "zstd: %s: gz file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); + return 1; +#else + int readBytes; + gzFile gzSrcFile = gzopen(srcFileName, "rb"); + if (gzSrcFile == NULL) { DISPLAY("zstd: %s: gzopen error \n", srcFileName); return 1; } + + do { + readBytes = gzread(gzSrcFile, ress.dstBuffer, ress.dstBufferSize); + if (readBytes < 0) { DISPLAY("zstd: %s: gzread error \n", srcFileName); return 1; } + if (readBytes > 0) { + size_t const sizeCheck = fwrite(ress.dstBuffer, 1, readBytes, dstFile); + if (sizeCheck != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file"); + } + filesize += readBytes; + } while ((size_t)readBytes == ress.dstBufferSize); + + if (gzclose(gzSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzclose error \n", srcFileName); return 1; } +#endif } /* Final Status */ DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize); - /* Close */ - if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ - if (g_removeSrcFile) { if (remove(srcFileName)) EXM_THROW(34, "zstd: %s: %s", srcFileName, strerror(errno)); }; + /* Remove source file */ + if (g_removeSrcFile) { if (remove(srcFileName)) EXM_THROW(35, "zstd: %s: %s", srcFileName, strerror(errno)); }; return 0; } From 0efaf7e7b1fee82e4fda3f5b78dbfa27856c0869 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 30 Nov 2016 15:20:24 +0100 Subject: [PATCH 102/185] added test-gzstd --- .travis.yml | 4 ++-- tests/Makefile | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c001152f5..148a98f1b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: os: linux sudo: false - - env: Ubu=12.04cont Cmd="make zlibwrapper && make clean && make -C tests test-zstd-nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest pzstd tests check && make -C contrib/pzstd clean" + - env: Ubu=12.04cont Cmd="make zlibwrapper && make clean && make -C tests test-zstd-nolegacy && make clean && make cmaketest && make clean && make -C contrib/pzstd googletest pzstd tests check && make -C contrib/pzstd clean" os: linux sudo: false language: cpp @@ -37,7 +37,7 @@ matrix: # Standard Ubuntu 12.04 LTS Server Edition 64 bit - - env: Ubu=12.04 Cmd="make -C programs zstd-small && make -C programs zstd-decompress && make -C programs zstd-compress && make -C programs clean && make -C tests versionsTest" + - env: Ubu=12.04 Cmd="make -C programs zstd-small zstd-decompress zstd-compress && make -C tests test-gzstd && make -C programs clean && make -C tests versionsTest" os: linux sudo: required diff --git a/tests/Makefile b/tests/Makefile index 7e5c66ad8..ca899d2f8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -76,6 +76,9 @@ zstd32: zstd-nolegacy: $(MAKE) -C $(PRGDIR) $@ +gzstd: + $(MAKE) -C $(PRGDIR) $@ + fullbench : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c $(CC) $(FLAGS) $^ -o $@$(EXT) @@ -190,6 +193,11 @@ test-zstd32: zstd32 zstd-playTests test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd test-zstd-nolegacy: zstd-nolegacy zstd-playTests +test-gzstd: gzstd + gzip README.md test-zstd-speed.py + $(PRGDIR)/zstd -d README.md.gz -o README2.md + $(PRGDIR)/zstd -d README.md.gz test-zstd-speed.py.gz + test-fullbench: fullbench datagen $(QEMU_SYS) ./fullbench -i1 $(QEMU_SYS) ./fullbench -i1 -P0 From 166830ed0a87471203c5ecba576be24f6e1fd72e Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 30 Nov 2016 16:43:07 +0100 Subject: [PATCH 103/185] autodetect -lz --- programs/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/programs/Makefile b/programs/Makefile index 4f5a00d5b..e44f11264 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -125,7 +125,11 @@ zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) gzstd: clean_decomp_o - CFLAGS+=-DZSTD_GZDECOMPRESS LDFLAGS+=-lz $(MAKE) zstd +ifeq ($(shell ld -lz 2>/dev/null && echo -n true),true) + $(MAKE) zstd MOREFLAGS=-DZSTD_GZDECOMPRESS LDFLAGS="-lz" +else + $(MAKE) zstd +endif generate_res: windres\generate_res.bat From 95eb43be09e84f229a953697a5e5b7644e27eb01 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 30 Nov 2016 11:06:58 -0800 Subject: [PATCH 104/185] updated pkg config file --- lib/libzstd.pc.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/libzstd.pc.in b/lib/libzstd.pc.in index 703da060b..1d07b91f2 100644 --- a/lib/libzstd.pc.in +++ b/lib/libzstd.pc.in @@ -1,5 +1,5 @@ # ZSTD - standard compression algorithm -# Copyright (C) 2014-2015, Yann Collet. +# Copyright (C) 2014-2016, Yann Collet, Facebook # BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) prefix=@PREFIX@ @@ -7,8 +7,8 @@ libdir=@LIBDIR@ includedir=@INCLUDEDIR@ Name: zstd -Description: lossless compression algorithm library -URL: https://github.com/facebook/zstd +Description: fast lossless compression algorithm library +URL: http://www.zstd.net/ Version: @VERSION@ Libs: -L${libdir} -lzstd Cflags: -I${includedir} From 766431909f61f450d6e93c7e4405fdbabfb0c175 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 30 Nov 2016 12:36:45 -0800 Subject: [PATCH 105/185] introduced FSE_decompress_wksp(), to use less stack space --- lib/common/entropy_common.c | 3 ++- lib/common/fse.h | 5 ++++- lib/common/fse_decompress.c | 36 ++++++++++++++++++------------------ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/common/entropy_common.c b/lib/common/entropy_common.c index 18bba0e87..8a31c4696 100644 --- a/lib/common/entropy_common.c +++ b/lib/common/entropy_common.c @@ -187,8 +187,9 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, huffWeight[n+1] = ip[n/2] & 15; } } } else { /* header compressed with FSE (normal case) */ + FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(5)]; /* 5 is max possible tableLog for HUF header */ if (iSize+1 > srcSize) return ERROR(srcSize_wrong); - oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */ + oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 5); /* max (hwSize-1) values decoded, as last one is implied */ if (FSE_isError(oSize)) return oSize; } diff --git a/lib/common/fse.h b/lib/common/fse.h index cecb1aef7..2f4506330 100644 --- a/lib/common/fse.h +++ b/lib/common/fse.h @@ -286,7 +286,7 @@ If there is an error, the function will return an error code, which can be teste #define FSE_BLOCKBOUND(size) (size + (size>>7)) #define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ -/* It is possible to statically allocate FSE CTable/DTable as a table of unsigned using below macros */ +/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ #define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2)) #define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */ - ip += NCountLength; - cSrcSize -= NCountLength; - } + size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(NCountLength)) return NCountLength; + //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ + if (tableLog > maxLog) return ERROR(tableLog_tooLarge); + ip += NCountLength; + cSrcSize -= NCountLength; - CHECK_F( FSE_buildDTable (dt, counting, maxSymbolValue, tableLog) ); + CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) ); - return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); /* always return, even if it is an error code */ + return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ +} + + +typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; + +size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) +{ + DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ + return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG); } From d79a9a00d91f6feb60d43906ee849438b1703c0c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 30 Nov 2016 15:52:20 -0800 Subject: [PATCH 106/185] Introduced FSE_compress_wksp() and FSE_buildCTable_wksp() to reduce stack memory usage --- lib/common/fse.h | 13 +++++ lib/compress/fse_compress.c | 104 +++++++++++++++++++++-------------- lib/compress/huf_compress.c | 15 ++--- lib/compress/zstd_compress.c | 13 +++-- 4 files changed, 90 insertions(+), 55 deletions(-) diff --git a/lib/common/fse.h b/lib/common/fse.h index 2f4506330..9de22b5e1 100644 --- a/lib/common/fse.h +++ b/lib/common/fse.h @@ -300,12 +300,25 @@ size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* s unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); /**< same as FSE_optimalTableLog(), which used `minus==2` */ +/* FSE_compress_wksp() : + * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). + * `workSpace` size must be `(1< wkspSize) return ERROR(tableLog_tooLarge); tableU16[-2] = (U16) tableLog; tableU16[-1] = (U16) maxSymbolValue; @@ -181,6 +188,13 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned } +size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */ + return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol)); +} + + #ifndef FSE_COMMONDEFS_ONLY @@ -189,7 +203,7 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned ****************************************************************/ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) { - size_t maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3; + size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3; return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ } @@ -486,7 +500,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, U32 ToDistribute; /* Init */ - U32 lowThreshold = (U32)(total >> tableLog); + U32 const lowThreshold = (U32)(total >> tableLog); U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); for (s=0; s<=maxSymbolValue; s++) { @@ -534,17 +548,16 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, return 0; } - { - U64 const vStepLog = 62 - tableLog; + { U64 const vStepLog = 62 - tableLog; U64 const mid = (1ULL << (vStepLog-1)) - 1; U64 const rStep = ((((U64)1<> vStepLog); - U32 sEnd = (U32)(end >> vStepLog); - U32 weight = sEnd - sStart; + U64 const end = tmpTotal + (count[s] * rStep); + U32 const sStart = (U32)(tmpTotal >> vStepLog); + U32 const sEnd = (U32)(end >> vStepLog); + U32 const weight = sEnd - sStart; if (weight < 1) return ERROR(GENERIC); norm[s] = (short)weight; @@ -566,7 +579,6 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ { U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; - U64 const scale = 62 - tableLog; U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */ U64 const vStep = 1ULL<<(scale-20); @@ -594,7 +606,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, } } if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { /* corner case, need another normalization method */ - size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); + size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); if (FSE_isError(errorCode)) return errorCode; } else normalizedCounter[largest] += (short)stillToDistribute; @@ -643,17 +655,15 @@ size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits) /* Build Symbol Transformation Table */ { const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits); - for (s=0; s<=maxSymbolValue; s++) { symbolTT[s].deltaNbBits = deltaNbBits; symbolTT[s].deltaFindState = s-1; } } - return 0; } -/* fake FSE_CTable, for rle (100% always same symbol) input */ +/* fake FSE_CTable, for rle input (always same symbol) */ size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue) { void* ptr = ct; @@ -685,14 +695,13 @@ static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize, const BYTE* const iend = istart + srcSize; const BYTE* ip=iend; - BIT_CStream_t bitC; FSE_CState_t CState1, CState2; /* init */ if (srcSize <= 2) return 0; - { size_t const errorCode = BIT_initCStream(&bitC, dst, dstSize); - if (FSE_isError(errorCode)) return 0; } + { size_t const initError = BIT_initCStream(&bitC, dst, dstSize); + if (FSE_isError(initError)) return 0; /* not enough space available to write a bitstream */ } #define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s)) @@ -715,7 +724,7 @@ static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize, } /* 2 or 4 encoding per loop */ - for ( ; ip>istart ; ) { + while ( ip>istart ) { FSE_encodeSymbol(&bitC, &CState2, *--ip); @@ -741,7 +750,7 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize, const void* src, size_t srcSize, const FSE_CTable* ct) { - const unsigned fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); + unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); if (fast) return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); @@ -752,7 +761,14 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize, size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } -size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) +#define CHECK_E_F(e, f) size_t const e = f; if (FSE_isError(e)) return f +#define CHECK_F(f) { CHECK_E_F(_var_err__, f); } + +/* FSE_compress_wksp() : + * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). + * `workSpace` size must be `(1<> 7)) return 0; /* Heuristic : not compressible enough */ + { CHECK_E_F(maxCount, FSE_count(count, &maxSymbolValue, ip, srcSize) ); + if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */ + if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ + if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ + } tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); - errorCode = FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue); - if (FSE_isError(errorCode)) return errorCode; + CHECK_F( FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue) ); /* Write table description header */ - errorCode = FSE_writeNCount (op, oend-op, norm, maxSymbolValue, tableLog); - if (FSE_isError(errorCode)) return errorCode; - op += errorCode; + { CHECK_E_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); + op += nc_err; + } /* Compress */ - errorCode = FSE_buildCTable (ct, norm, maxSymbolValue, tableLog); - if (FSE_isError(errorCode)) return errorCode; - errorCode = FSE_compress_usingCTable(op, oend - op, ip, srcSize, ct); - if (errorCode == 0) return 0; /* not enough space for compressed data */ - op += errorCode; + CHECK_F( FSE_buildCTable_wksp(ct, norm, maxSymbolValue, tableLog, workSpace, 1<= srcSize-1 ) - return 0; + if ( (size_t)(op-ostart) >= srcSize-1 ) return 0; return op-ostart; } -size_t FSE_compress (void* dst, size_t dstSize, const void* src, size_t srcSize) +size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) { - return FSE_compress2(dst, dstSize, src, (U32)srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG); + BYTE scratchBuffer[1 << FSE_MAX_TABLELOG]; + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, scratchBuffer); +} + +size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG); } diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 78784aa36..d4ae35ecd 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -88,13 +88,15 @@ typedef struct nodeElt_s { size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog) { - BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; + BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; BYTE* op = (BYTE*)dst; +#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 + BYTE scratchBuffer[1< HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC); + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); /* convert to weight */ bitsToWeight[0] = 0; @@ -103,23 +105,22 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, for (n=0; n1) & (size < maxSymbolValue/2)) { /* FSE compressed */ op[0] = (BYTE)size; return size+1; - } - } + } } /* raw values */ - if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen */ + if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */ if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */ op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1)); huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */ for (n=0; nsequences - seqStorePtr->sequencesStart; BYTE* seqHead; + BYTE scratchBuffer[1<litStart; @@ -601,7 +602,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { LLtype = set_repeat; } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) { - FSE_buildCTable(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog); + FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); LLtype = set_basic; } else { size_t nbSeq_1 = nbSeq; @@ -611,7 +612,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ if (FSE_isError(NCountSize)) return ERROR(GENERIC); op += NCountSize; } - FSE_buildCTable(CTable_LitLength, norm, max, tableLog); + FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); LLtype = set_compressed; } } @@ -625,7 +626,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { Offtype = set_repeat; } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) { - FSE_buildCTable(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog); + FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); Offtype = set_basic; } else { size_t nbSeq_1 = nbSeq; @@ -635,7 +636,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ if (FSE_isError(NCountSize)) return ERROR(GENERIC); op += NCountSize; } - FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog); + FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); Offtype = set_compressed; } } @@ -649,7 +650,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { MLtype = set_repeat; } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) { - FSE_buildCTable(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog); + FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); MLtype = set_basic; } else { size_t nbSeq_1 = nbSeq; @@ -659,7 +660,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ if (FSE_isError(NCountSize)) return ERROR(GENERIC); op += NCountSize; } - FSE_buildCTable(CTable_MatchLength, norm, max, tableLog); + FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); MLtype = set_compressed; } } From 5e00b848a837c82117b6cd6186837e8a7d0bf175 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 30 Nov 2016 16:46:13 -0800 Subject: [PATCH 107/185] FSE_compress_wksp() uses less stack space --- lib/common/fse.h | 12 ++++++------ lib/compress/fse_compress.c | 38 ++++++++++++++++++------------------- lib/compress/huf_compress.c | 4 ++-- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/common/fse.h b/lib/common/fse.h index 9de22b5e1..0588651e2 100644 --- a/lib/common/fse.h +++ b/lib/common/fse.h @@ -302,25 +302,25 @@ unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsi /* FSE_compress_wksp() : * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). - * `workSpace` size must be `(1<2)?(maxTableLog-2):0)) ) +size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits); -/**< build a fake FSE_CTable, designed to not compress an input, where each symbol uses nbBits */ +/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); /**< build a fake FSE_CTable, designed to compress always the same symbolValue */ /* FSE_buildCTable_wksp() : * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). - * wkspSize should be sized to handle worst case situation, which is `(1<= `(1<= sizeof(CTable_max_t)); /* A compilation error here means FSE_CTABLE_SIZE_U32 is not large enough */ - if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC); - size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); - return size; + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32); } FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog) @@ -766,9 +756,9 @@ size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } /* FSE_compress_wksp() : * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). - * `workSpace` size must be `(1<= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); - return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, scratchBuffer); + return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer)); } size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index d4ae35ecd..3a1c05110 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -92,7 +92,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; BYTE* op = (BYTE*)dst; #define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 - BYTE scratchBuffer[1<1) & (size < maxSymbolValue/2)) { /* FSE compressed */ op[0] = (BYTE)size; From 979cab412b4cf2962fb267833f54a14d83074a01 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 30 Nov 2016 18:10:38 -0800 Subject: [PATCH 108/185] fixed some minor visual silent cast warnings. introduced FSE_count_parallel_wksp(). --- lib/compress/fse_compress.c | 41 ++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index 6e949d654..e4b3dcaca 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -115,7 +115,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsi U32 highThreshold = tableSize-1; /* CTable header */ - if ((1< wkspSize) return ERROR(tableLog_tooLarge); + if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge); tableU16[-2] = (U16) tableLog; tableU16[-1] = (U16) maxSymbolValue; @@ -322,7 +322,6 @@ static size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, unsigned maxSymbolValue = *maxSymbolValuePtr; unsigned max=0; - memset(count, 0, (maxSymbolValue+1)*sizeof(*count)); if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; } @@ -337,20 +336,24 @@ static size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, } -static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr, +/* FSE_count_parallel_wksp() : + * Same as FSE_count_parallel(), but using an externally provided scratch buffer. + * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */ +static size_t FSE_count_parallel_wksp( + unsigned* count, unsigned* maxSymbolValuePtr, const void* source, size_t sourceSize, - unsigned checkMax) + unsigned checkMax, unsigned* const workSpace) { const BYTE* ip = (const BYTE*)source; const BYTE* const iend = ip+sourceSize; unsigned maxSymbolValue = *maxSymbolValuePtr; unsigned max=0; + U32* const Counting1 = workSpace; + U32* const Counting2 = Counting1 + 256; + U32* const Counting3 = Counting2 + 256; + U32* const Counting4 = Counting3 + 256; - - U32 Counting1[256] = { 0 }; - U32 Counting2[256] = { 0 }; - U32 Counting3[256] = { 0 }; - U32 Counting4[256] = { 0 }; + memset(Counting1, 0, 4*256*sizeof(unsigned)); /* safety checks */ if (!sourceSize) { @@ -396,16 +399,26 @@ static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr, if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall); } } - { U32 s; for (s=0; s<=maxSymbolValue; s++) { - count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s]; - if (count[s] > max) max = count[s]; - }} + { U32 s; for (s=0; s<=maxSymbolValue; s++) { + count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s]; + if (count[s] > max) max = count[s]; + } } while (!count[maxSymbolValue]) maxSymbolValue--; *maxSymbolValuePtr = maxSymbolValue; return (size_t)max; } + +static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + unsigned checkMax) +{ + U32 tmpCounters[1024]; + return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMax, tmpCounters); +} + + /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* source, size_t sourceSize) @@ -417,7 +430,7 @@ size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* source, size_t sourceSize) { - if (*maxSymbolValuePtr <255) + if (*maxSymbolValuePtr < 255) return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 1); *maxSymbolValuePtr = 255; return FSE_countFast(count, maxSymbolValuePtr, source, sourceSize); From dc2fe75732eea8cb4bb2b2dd5641094dafcaa84f Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 1 Dec 2016 11:56:20 +0100 Subject: [PATCH 109/185] gzread.c: improved comments --- zlibWrapper/gzread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index ad33ebc62..51ffef3e6 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -138,8 +138,8 @@ local int gz_look(state) single byte is sufficient indication that it is not a gzip file) */ //printf("strm->next_in[0]=%d strm->next_in[1]=%d\n", strm->next_in[0], strm->next_in[1]); if (strm->avail_in > 1 && - ((strm->next_in[0] == 31 && strm->next_in[1] == 139) - || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { // zstd + ((strm->next_in[0] == 31 && strm->next_in[1] == 139) /* gz header */ + || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { /* zstd header */ inflateReset(strm); state.state->how = GZIP; state.state->direct = 0; From 19aad42ee1e696433a8a84944099a1505d348cb9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 1 Dec 2016 11:56:31 +0100 Subject: [PATCH 110/185] added FIO_decompressGzFile --- programs/fileio.c | 71 ++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 733abe01d..e3c8a3de8 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -651,6 +651,30 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ } +#ifdef ZSTD_GZDECOMPRESS +static unsigned long long FIO_decompressGzFile(dRess_t ress, const char* srcFileName, gzFile gzSrcFile) +{ + unsigned long long filesize = 0; + int readBytes; + if (gzSrcFile == NULL) { DISPLAY("zstd: %s: gzopen error \n", srcFileName); return 0; } + + do { + readBytes = gzread(gzSrcFile, ress.dstBuffer, ress.dstBufferSize); + if (readBytes < 0) { DISPLAY("zstd: %s: gzread error \n", srcFileName); return 0; } + if (readBytes > 0) { + size_t const sizeCheck = fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile); + if (sizeCheck != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file"); + } + filesize += readBytes; + } while ((size_t)readBytes == ress.dstBufferSize); + + if (gzclose(gzSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzclose error \n", srcFileName); return 0; } + + return filesize; +} +#endif + + /** FIO_decompressSrcFile() : Decompression `srcFileName` into `ress.dstFile` @return : 0 : OK @@ -679,23 +703,30 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) /* check magic number -> version */ size_t const toRead = 4; size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); + const BYTE* buf = (const BYTE*)ress.srcBuffer; if (sizeCheck==0) { if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ break; /* no more input */ } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } - filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); + if (buf[0] == 31 && buf[1] == 139) { /* gz header */ + unsigned long long result = FIO_decompressGzFile(ress, srcFileName, gzdopen(fileno(srcFile), "rb")); + if (result == 0) return 1; + filesize += result; + } else { + if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { + if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ + return result; + } else { + DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); + fclose(srcFile); + return 1; + } } + filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); + } } /* Close file */ if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ @@ -704,21 +735,9 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) DISPLAYLEVEL(1, "zstd: %s: gz file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); return 1; #else - int readBytes; - gzFile gzSrcFile = gzopen(srcFileName, "rb"); - if (gzSrcFile == NULL) { DISPLAY("zstd: %s: gzopen error \n", srcFileName); return 1; } - - do { - readBytes = gzread(gzSrcFile, ress.dstBuffer, ress.dstBufferSize); - if (readBytes < 0) { DISPLAY("zstd: %s: gzread error \n", srcFileName); return 1; } - if (readBytes > 0) { - size_t const sizeCheck = fwrite(ress.dstBuffer, 1, readBytes, dstFile); - if (sizeCheck != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file"); - } - filesize += readBytes; - } while ((size_t)readBytes == ress.dstBufferSize); - - if (gzclose(gzSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzclose error \n", srcFileName); return 1; } + unsigned long long result = FIO_decompressGzFile(ress, srcFileName, gzopen(srcFileName, "rb")); + if (result == 0) return 1; + filesize += result; #endif } From daaf7545390c080b434aae6fc05828b35a651e69 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 1 Dec 2016 13:29:19 +0100 Subject: [PATCH 111/185] detect stream with ungetc --- programs/fileio.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index e3c8a3de8..535308e58 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -664,8 +664,8 @@ static unsigned long long FIO_decompressGzFile(dRess_t ress, const char* srcFile if (readBytes > 0) { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile); if (sizeCheck != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file"); + filesize += readBytes; } - filesize += readBytes; } while ((size_t)readBytes == ress.dstBufferSize); if (gzclose(gzSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzclose error \n", srcFileName); return 0; } @@ -700,21 +700,27 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) /* for each frame */ for ( ; ; ) { - /* check magic number -> version */ - size_t const toRead = 4; - size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); - const BYTE* buf = (const BYTE*)ress.srcBuffer; - if (sizeCheck==0) { - if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - break; /* no more input */ + if (srcFile == stdin) { + int c = getc(srcFile); + if (c < 0) break; /* no more input */ + c = ungetc(c, srcFile); /* only one pushback is guaranteed */ + if (c == 31) { /* 31,139 = gz header */ + unsigned long long result = FIO_decompressGzFile(ress, srcFileName, gzdopen(fileno(srcFile), "rb")); + printf("result=%d\n", (int)result); + if (result == 0) return 1; + filesize += result; + continue; + } } - readSomething = 1; /* there is at least >= 4 bytes in srcFile */ - if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - if (buf[0] == 31 && buf[1] == 139) { /* gz header */ - unsigned long long result = FIO_decompressGzFile(ress, srcFileName, gzdopen(fileno(srcFile), "rb")); - if (result == 0) return 1; - filesize += result; - } else { + /* check magic number -> version */ + { size_t const toRead = 4; + size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); + if (sizeCheck==0) { + if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + break; /* no more input */ + } + readSomething = 1; /* there is at least >= 4 bytes in srcFile */ + if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); From e928f7e16db5113e09902b822a2ce82e05624f11 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 1 Dec 2016 16:13:35 -0800 Subject: [PATCH 112/185] introduced ext_wksp variants of count to reduce stack memory usage --- lib/common/fse.h | 36 ++++++--- lib/common/huf.h | 8 +- lib/compress/fse_compress.c | 59 +++++++------- lib/compress/huf_compress.c | 145 ++++++++++++++++++++++++----------- lib/compress/zstd_compress.c | 11 +-- 5 files changed, 175 insertions(+), 84 deletions(-) diff --git a/lib/common/fse.h b/lib/common/fse.h index 0588651e2..8b07d184d 100644 --- a/lib/common/fse.h +++ b/lib/common/fse.h @@ -294,8 +294,31 @@ If there is an error, the function will return an error code, which can be teste /* ***************************************** * FSE advanced API *******************************************/ +/* FSE_count_wksp() : + * Same as FSE_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= `1024` unsigned + */ +size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, unsigned* workSpace); + +/** FSE_countFast() : + * same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr + */ size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); -/**< same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr */ + +/* FSE_countFast_wksp() : + * Same as FSE_countFast(), but using an externally provided scratch buffer. + * `workSpace` must be a table of minimum `1024` unsigned + */ +size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* workSpace); + +/*! FSE_count_simple + * Same as FSE_countFast(), but does not use any additional memory (not even on stack). + * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` (presuming it's also the size of `count`). +*/ +size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); + + unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); /**< same as FSE_optimalTableLog(), which used `minus==2` */ @@ -334,13 +357,9 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size *******************************************/ /*! This API consists of small unitary functions, which highly benefit from being inlined. - You will want to enable link-time-optimization to ensure these functions are properly inlined in your binary. - Visual seems to do it automatically. - For gcc or clang, you'll need to add -flto flag at compilation and linking stages. - If none of these solutions is applicable, include "fse.c" directly. + Hence their body are included in next section. */ -typedef struct -{ +typedef struct { ptrdiff_t value; const void* stateTable; const void* symbolTT; @@ -400,8 +419,7 @@ If there is an error, it returns an errorCode (which can be tested using FSE_isE /* ***************************************** * FSE symbol decompression API *******************************************/ -typedef struct -{ +typedef struct { size_t state; const void* table; /* precise table may vary, depending on U16 */ } FSE_DState_t; diff --git a/lib/common/huf.h b/lib/common/huf.h index 29bab4b76..06568f08a 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -90,6 +90,11 @@ const char* HUF_getErrorName(size_t code); /**< provides error code string (us * Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog` */ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); +/** HUF_compress4X_wksp() : +* Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of <= 1024 unsigned */ +size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, unsigned* workSpace); + + #ifdef HUF_STATIC_LINKING_ONLY @@ -208,12 +213,13 @@ size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* c /* single stream variants */ size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); +size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, unsigned* workSpace); /**< `workSpace` must be a table of at least 1024 unsigned */ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ -size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index e4b3dcaca..840a3fec5 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -308,14 +308,14 @@ size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalized * Counting histogram ****************************************************************/ /*! FSE_count_simple - This function just counts byte values within `src`, - and store the histogram into table `count`. - This function is unsafe : it doesn't check that all values within `src` can fit into `count`. + This function counts byte values within `src`, and store the histogram into table `count`. + It doesn't use any additional memory. + But this function is unsafe : it doesn't check that all values within `src` can fit into `count`. For this reason, prefer using a table `count` with 256 elements. @return : count of most numerous element */ -static size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, - const void* src, size_t srcSize) +size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; const BYTE* const end = ip + srcSize; @@ -409,31 +409,41 @@ static size_t FSE_count_parallel_wksp( return (size_t)max; } - -static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr, - const void* source, size_t sourceSize, - unsigned checkMax) +/* FSE_countFast_wksp() : + * Same as FSE_countFast(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= `1024` unsigned */ +size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, unsigned* workSpace) { - U32 tmpCounters[1024]; - return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMax, tmpCounters); + if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize); + return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace); } - /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* source, size_t sourceSize) { - if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize); - return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 0); + unsigned tmpCounters[1024]; + return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters); +} + +/* FSE_count_wksp() : + * Same as FSE_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= `1024` unsigned */ +size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, unsigned* workSpace) +{ + if (*maxSymbolValuePtr < 255) + return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace); + *maxSymbolValuePtr = 255; + return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace); } size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, - const void* source, size_t sourceSize) + const void* src, size_t srcSize) { - if (*maxSymbolValuePtr < 255) - return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 1); - *maxSymbolValuePtr = 255; - return FSE_countFast(count, maxSymbolValuePtr, source, sourceSize); + unsigned tmpCounters[1024]; + return FSE_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters); } @@ -764,7 +774,7 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize, size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } -#define CHECK_E_F(e, f) size_t const e = f; if (FSE_isError(e)) return f +#define CHECK_E_F(e, f) size_t const e = f; if (ERR_isError(e)) return f #define CHECK_F(f) { CHECK_E_F(_var_err__, f); } /* FSE_compress_wksp() : @@ -773,9 +783,6 @@ size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } */ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) { - const BYTE* const istart = (const BYTE*) src; - const BYTE* ip = istart; - BYTE* const ostart = (BYTE*) dst; BYTE* op = ostart; BYTE* const oend = ostart + dstSize; @@ -794,14 +801,14 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG; /* Scan input and build symbol stats */ - { CHECK_E_F(maxCount, FSE_count(count, &maxSymbolValue, ip, srcSize) ); + { CHECK_E_F(maxCount, FSE_count(count, &maxSymbolValue, src, srcSize) ); if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ } tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); - CHECK_F( FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue) ); + CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) ); /* Write table description header */ { CHECK_E_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); @@ -810,7 +817,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src /* Compress */ CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) ); - { CHECK_E_F(cSize, FSE_compress_usingCTable(op, oend - op, ip, srcSize, CTable) ); + { CHECK_E_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) ); if (cSize == 0) return 0; /* not enough space for compressed data */ op += cSize; } diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 3a1c05110..ff2e82ae8 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -56,6 +56,8 @@ * Error Management ****************************************************************/ #define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ +#define CHECK_E_F(e, f) size_t const e = f; if (ERR_isError(e)) return f +#define CHECK_F(f) { CHECK_E_F(_var_err__, f); } /* ************************************************************** @@ -70,18 +72,60 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS /* ******************************************************* * HUF : Huffman block compression *********************************************************/ +/* HUF_compressWeights() : + * Same as FSE_compress(), but dedicated to huff0's weights compression. + * The use case needs much less stack memory. + * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX. + */ +#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 +size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize) +{ + BYTE* const ostart = (BYTE*) dst; + BYTE* op = ostart; + BYTE* const oend = ostart + dstSize; + + U32 maxSymbolValue = HUF_TABLELOG_MAX; + U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; + + FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; + BYTE scratchBuffer[1< not compressible */ + } + + tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue); + CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) ); + + /* Write table description header */ + { CHECK_E_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); + op += hSize; + } + + /* Compress */ + CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) ); + { CHECK_E_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) ); + if (cSize == 0) return 0; /* not enough space for compressed data */ + op += cSize; + } + + return op-ostart; +} + + struct HUF_CElt_s { U16 val; BYTE nbBits; }; /* typedef'd to HUF_CElt within "huf.h" */ -typedef struct nodeElt_s { - U32 count; - U16 parent; - BYTE byte; - BYTE nbBits; -} nodeElt; - /*! HUF_writeCTable() : `CTable` : huffman tree to save, using huf representation. @return : size of saved CTable */ @@ -91,8 +135,6 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; BYTE* op = (BYTE*)dst; -#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 - FSE_CTable scratchBuffer[FSE_WKSP_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; U32 n; /* check conditions */ @@ -106,18 +148,17 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, huffWeight[n] = bitsToWeight[CTable[n].nbBits]; /* attempt weights compression by FSE */ - { size_t const size = FSE_compress_wksp(op+1, maxDstSize-1, huffWeight, maxSymbolValue, HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER, scratchBuffer, sizeof(scratchBuffer)); - if (FSE_isError(size)) return size; - if ((size>1) & (size < maxSymbolValue/2)) { /* FSE compressed */ - op[0] = (BYTE)size; - return size+1; + { CHECK_E_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) ); + if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */ + op[0] = (BYTE)hSize; + return hSize+1; } } - /* raw values */ + /* write raw values as 4-bits (max : 15) */ if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */ if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */ op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1)); - huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */ + huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */ for (n=0; n HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); @@ -175,6 +213,13 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si } +typedef struct nodeElt_s { + U32 count; + U16 parent; + BYTE byte; + BYTE nbBits; +} nodeElt; + static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits) { const U32 largestBits = huffNode[lastNonNull].nbBits; @@ -280,6 +325,9 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue) } +/** HUF_buildCTable() : + * Note : count is used before tree is written, so they can safely overlap + */ #define STARTNODE (HUF_SYMBOLVALUE_MAX+1) size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits) { @@ -420,32 +468,28 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si if (srcSize < 12) return 0; /* no saving possible : too small input */ op += 6; /* jumpTable */ - { size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable); - if (HUF_isError(cSize)) return cSize; + { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); if (cSize==0) return 0; MEM_writeLE16(ostart, (U16)cSize); op += cSize; } ip += segmentSize; - { size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable); - if (HUF_isError(cSize)) return cSize; + { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); if (cSize==0) return 0; MEM_writeLE16(ostart+2, (U16)cSize); op += cSize; } ip += segmentSize; - { size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable); - if (HUF_isError(cSize)) return cSize; + { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); if (cSize==0) return 0; MEM_writeLE16(ostart+4, (U16)cSize); op += cSize; } ip += segmentSize; - { size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable); - if (HUF_isError(cSize)) return cSize; + { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) ); if (cSize==0) return 0; op += cSize; } @@ -454,18 +498,21 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si } +/* `workSpace` must a table of at least 1024 unsigned */ static size_t HUF_compress_internal ( void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, - unsigned singleStream) + unsigned singleStream, unsigned* workSpace) { BYTE* const ostart = (BYTE*)dst; BYTE* const oend = ostart + dstSize; BYTE* op = ostart; - U32 count[HUF_SYMBOLVALUE_MAX+1]; - HUF_CElt CTable[HUF_SYMBOLVALUE_MAX+1]; + union { + U32 count[HUF_SYMBOLVALUE_MAX+1]; + HUF_CElt CTable[HUF_SYMBOLVALUE_MAX+1]; + } table; /* `count` can overlap with `CTable`; saves 1 KB */ /* checks & inits */ if (!srcSize) return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */ @@ -476,30 +523,27 @@ static size_t HUF_compress_internal ( if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT; /* Scan input and build symbol stats */ - { size_t const largest = FSE_count (count, &maxSymbolValue, (const BYTE*)src, srcSize); - if (HUF_isError(largest)) return largest; + { CHECK_E_F(largest, FSE_count_wksp (table.count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace) ); if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */ } /* Build Huffman Tree */ huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue); - { size_t const maxBits = HUF_buildCTable (CTable, count, maxSymbolValue, huffLog); - if (HUF_isError(maxBits)) return maxBits; + { CHECK_E_F(maxBits, HUF_buildCTable (table.CTable, table.count, maxSymbolValue, huffLog) ); huffLog = (U32)maxBits; } /* Write table description header */ - { size_t const hSize = HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog); - if (HUF_isError(hSize)) return hSize; + { CHECK_E_F(hSize, HUF_writeCTable (op, dstSize, table.CTable, maxSymbolValue, huffLog) ); if (hSize + 12 >= srcSize) return 0; /* not useful to try compression */ op += hSize; } /* Compress */ { size_t const cSize = (singleStream) ? - HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) : /* single segment */ - HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable); + HUF_compress1X_usingCTable(op, oend - op, src, srcSize, table.CTable) : /* single segment */ + HUF_compress4X_usingCTable(op, oend - op, src, srcSize, table.CTable); if (HUF_isError(cSize)) return cSize; if (cSize==0) return 0; /* uncompressible */ op += cSize; @@ -513,21 +557,36 @@ static size_t HUF_compress_internal ( } +size_t HUF_compress1X_wksp (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, unsigned* workSpace) +{ + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace); +} + size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog) { - return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1); + unsigned workSpace[1024]; + return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace); +} + +size_t HUF_compress4X_wksp (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, unsigned* workSpace) +{ + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace); } size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog) { - return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0); + unsigned workSpace[1024]; + return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace); } - size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize) { return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_TABLELOG_DEFAULT); diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e93f6671f..853b0c3bf 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -82,6 +82,7 @@ struct ZSTD_CCtx_s FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; + unsigned tmpCounters[1024]; }; ZSTD_CCtx* ZSTD_createCCtx(void) @@ -470,8 +471,8 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc, singleStream = 1; cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable); } else { - cLitSize = singleStream ? HUF_compress1X(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11) - : HUF_compress2 (ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11); + cLitSize = singleStream ? HUF_compress1X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters) + : HUF_compress4X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters); } if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) @@ -594,7 +595,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, /* CTable for Literal Lengths */ { U32 max = MaxLL; - size_t const mostFrequent = FSE_countFast(count, &max, llCodeTable, nbSeq); + size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters); if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = llCodeTable[0]; FSE_buildCTable_rle(CTable_LitLength, (BYTE)max); @@ -618,7 +619,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, /* CTable for Offsets */ { U32 max = MaxOff; - size_t const mostFrequent = FSE_countFast(count, &max, ofCodeTable, nbSeq); + size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters); if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = ofCodeTable[0]; FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max); @@ -642,7 +643,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, /* CTable for MatchLengths */ { U32 max = MaxML; - size_t const mostFrequent = FSE_countFast(count, &max, mlCodeTable, nbSeq); + size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters); if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = *mlCodeTable; FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max); From 643d9a234b5022ec7d5717dcf6f582bd4e481e22 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 1 Dec 2016 16:24:04 -0800 Subject: [PATCH 113/185] replaced usage of FSE_buildCTable by FSE_buildCTable_wksp, using less stack space in the process --- frame.txt | 128 +++++++++++++++++++++++++++++++++++ lib/compress/fse_compress.c | 10 +-- lib/compress/huf_compress.c | 32 ++++----- lib/compress/zstd_compress.c | 7 +- 4 files changed, 153 insertions(+), 24 deletions(-) create mode 100644 frame.txt diff --git a/frame.txt b/frame.txt new file mode 100644 index 000000000..58902c328 --- /dev/null +++ b/frame.txt @@ -0,0 +1,128 @@ +common/fse_decompress.c:321:8: warning: stack frame size of 16984 bytes in function 'FSE_decompress' [-Wframe-larger-than=] +size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) + ^ +1 warning generated. +compress/fse_compress.c:185:8: warning: stack frame size of 4120 bytes in function 'FSE_buildCTable' [-Wframe-larger-than=] +size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) + ^ +compress/fse_compress.c:423:8: warning: stack frame size of 4152 bytes in function 'FSE_countFast' [-Wframe-larger-than=] +size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + ^ +compress/fse_compress.c:442:8: warning: stack frame size of 4120 bytes in function 'FSE_count' [-Wframe-larger-than=] +size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, + ^ +compress/fse_compress.c:784:8: warning: stack frame size of 5752 bytes in function 'FSE_compress_wksp' [-Wframe-larger-than=] +size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) + ^ +compress/fse_compress.c:836:8: warning: stack frame size of 14392 bytes in function 'FSE_compress2' [-Wframe-larger-than=] +size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) + ^ +compress/fse_compress.c:844:8: warning: stack frame size of 14392 bytes in function 'FSE_compress' [-Wframe-larger-than=] +size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) + ^ +6 warnings generated. +compress/huf_compress.c:332:8: warning: stack frame size of 4472 bytes in function 'HUF_buildCTable' [-Wframe-larger-than=] +size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits) + ^ +compress/huf_compress.c:567:8: warning: stack frame size of 4136 bytes in function 'HUF_compress1X' [-Wframe-larger-than=] +size_t HUF_compress1X (void* dst, size_t dstSize, + ^ +compress/huf_compress.c:582:8: warning: stack frame size of 4136 bytes in function 'HUF_compress2' [-Wframe-larger-than=] +size_t HUF_compress2 (void* dst, size_t dstSize, + ^ +compress/huf_compress.c:590:8: warning: stack frame size of 4136 bytes in function 'HUF_compress' [-Wframe-larger-than=] +size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize) + ^ +4 warnings generated. +compress/zstd_compress.c:2711:8: warning: stack frame size of 8168 bytes in function 'ZSTD_compress' [-Wframe-larger-than=] +size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel) + ^ +1 warning generated. +decompress/huf_decompress.c:224:8: warning: stack frame size of 8264 bytes in function 'HUF_decompress1X2' [-Wframe-larger-than=] +size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +decompress/huf_decompress.c:347:8: warning: stack frame size of 8280 bytes in function 'HUF_decompress4X2' [-Wframe-larger-than=] +size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +decompress/huf_decompress.c:445:8: warning: stack frame size of 2408 bytes in function 'HUF_readDTableX4' [-Wframe-larger-than=] +size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) + ^ +decompress/huf_decompress.c:636:8: warning: stack frame size of 16456 bytes in function 'HUF_decompress1X4' [-Wframe-larger-than=] +size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +decompress/huf_decompress.c:758:8: warning: stack frame size of 16472 bytes in function 'HUF_decompress4X4' [-Wframe-larger-than=] +size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +5 warnings generated. +dictBuilder/divsufsort.c:1441:1: warning: stack frame size of 2472 bytes in function 'sort_typeBstar' [-Wframe-larger-than=] +sort_typeBstar(const unsigned char *T, int *SA, +^ +1 warning generated. +dictBuilder/zdict.c:828:8: warning: stack frame size of 7176 bytes in function 'ZDICT_addEntropyTablesFromBuffer_advanced' [-Wframe-larger-than=] +size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, + ^ +1 warning generated. +common/fse_decompress.c:321:8: warning: stack frame size of 16984 bytes in function 'FSE_decompress' [-Wframe-larger-than=] +size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) + ^ +1 warning generated. +compress/fse_compress.c:185:8: warning: stack frame size of 4120 bytes in function 'FSE_buildCTable' [-Wframe-larger-than=] +size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) + ^ +compress/fse_compress.c:423:8: warning: stack frame size of 4152 bytes in function 'FSE_countFast' [-Wframe-larger-than=] +size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + ^ +compress/fse_compress.c:442:8: warning: stack frame size of 4120 bytes in function 'FSE_count' [-Wframe-larger-than=] +size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, + ^ +compress/fse_compress.c:784:8: warning: stack frame size of 5752 bytes in function 'FSE_compress_wksp' [-Wframe-larger-than=] +size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) + ^ +compress/fse_compress.c:836:8: warning: stack frame size of 14392 bytes in function 'FSE_compress2' [-Wframe-larger-than=] +size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) + ^ +compress/fse_compress.c:844:8: warning: stack frame size of 14392 bytes in function 'FSE_compress' [-Wframe-larger-than=] +size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) + ^ +6 warnings generated. +compress/huf_compress.c:332:8: warning: stack frame size of 4472 bytes in function 'HUF_buildCTable' [-Wframe-larger-than=] +size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits) + ^ +compress/huf_compress.c:567:8: warning: stack frame size of 4136 bytes in function 'HUF_compress1X' [-Wframe-larger-than=] +size_t HUF_compress1X (void* dst, size_t dstSize, + ^ +compress/huf_compress.c:582:8: warning: stack frame size of 4136 bytes in function 'HUF_compress2' [-Wframe-larger-than=] +size_t HUF_compress2 (void* dst, size_t dstSize, + ^ +compress/huf_compress.c:590:8: warning: stack frame size of 4136 bytes in function 'HUF_compress' [-Wframe-larger-than=] +size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize) + ^ +4 warnings generated. +compress/zstd_compress.c:2711:8: warning: stack frame size of 8168 bytes in function 'ZSTD_compress' [-Wframe-larger-than=] +size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel) + ^ +1 warning generated. +decompress/huf_decompress.c:224:8: warning: stack frame size of 8264 bytes in function 'HUF_decompress1X2' [-Wframe-larger-than=] +size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +decompress/huf_decompress.c:347:8: warning: stack frame size of 8280 bytes in function 'HUF_decompress4X2' [-Wframe-larger-than=] +size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +decompress/huf_decompress.c:445:8: warning: stack frame size of 2408 bytes in function 'HUF_readDTableX4' [-Wframe-larger-than=] +size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) + ^ +decompress/huf_decompress.c:636:8: warning: stack frame size of 16456 bytes in function 'HUF_decompress1X4' [-Wframe-larger-than=] +size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +decompress/huf_decompress.c:758:8: warning: stack frame size of 16472 bytes in function 'HUF_decompress4X4' [-Wframe-larger-than=] +size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + ^ +5 warnings generated. +dictBuilder/divsufsort.c:1441:1: warning: stack frame size of 2472 bytes in function 'sort_typeBstar' [-Wframe-larger-than=] +sort_typeBstar(const unsigned char *T, int *SA, +^ +1 warning generated. +dictBuilder/zdict.c:828:8: warning: stack frame size of 7176 bytes in function 'ZDICT_addEntropyTablesFromBuffer_advanced' [-Wframe-larger-than=] +size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, + ^ +1 warning generated. diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index 840a3fec5..6627facfe 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -774,8 +774,8 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize, size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } -#define CHECK_E_F(e, f) size_t const e = f; if (ERR_isError(e)) return f -#define CHECK_F(f) { CHECK_E_F(_var_err__, f); } +#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f +#define CHECK_F(f) { CHECK_V_F(_var_err__, f); } /* FSE_compress_wksp() : * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). @@ -801,7 +801,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG; /* Scan input and build symbol stats */ - { CHECK_E_F(maxCount, FSE_count(count, &maxSymbolValue, src, srcSize) ); + { CHECK_V_F(maxCount, FSE_count(count, &maxSymbolValue, src, srcSize) ); if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ @@ -811,13 +811,13 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) ); /* Write table description header */ - { CHECK_E_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); + { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); op += nc_err; } /* Compress */ CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) ); - { CHECK_E_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) ); + { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) ); if (cSize == 0) return 0; /* not enough space for compressed data */ op += cSize; } diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index ff2e82ae8..4ed093eee 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -56,8 +56,8 @@ * Error Management ****************************************************************/ #define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ -#define CHECK_E_F(e, f) size_t const e = f; if (ERR_isError(e)) return f -#define CHECK_F(f) { CHECK_E_F(_var_err__, f); } +#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f +#define CHECK_F(f) { CHECK_V_F(_var_err__, f); } /* ************************************************************** @@ -97,7 +97,7 @@ size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, if (wtSize <= 1) return 0; /* Not compressible */ /* Scan input and build symbol stats */ - { CHECK_E_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize) ); + { CHECK_V_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize) ); if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ } @@ -106,13 +106,13 @@ size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) ); /* Write table description header */ - { CHECK_E_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); + { CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) ); op += hSize; } /* Compress */ CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) ); - { CHECK_E_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) ); + { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) ); if (cSize == 0) return 0; /* not enough space for compressed data */ op += cSize; } @@ -148,7 +148,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, huffWeight[n] = bitsToWeight[CTable[n].nbBits]; /* attempt weights compression by FSE */ - { CHECK_E_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) ); + { CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) ); if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */ op[0] = (BYTE)hSize; return hSize+1; @@ -173,7 +173,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si U32 nbSymbols = 0; /* get symbol weights */ - CHECK_E_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize)); + CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize)); /* check result */ if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); @@ -424,8 +424,8 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si /* init */ if (dstSize < 8) return 0; /* not enough space to compress */ - { size_t const errorCode = BIT_initCStream(&bitC, op, oend-op); - if (HUF_isError(errorCode)) return 0; } + { size_t const initErr = BIT_initCStream(&bitC, op, oend-op); + if (HUF_isError(initErr)) return 0; } n = srcSize & ~3; /* join to mod 4 */ switch (srcSize & 3) @@ -468,28 +468,28 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si if (srcSize < 12) return 0; /* no saving possible : too small input */ op += 6; /* jumpTable */ - { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); if (cSize==0) return 0; MEM_writeLE16(ostart, (U16)cSize); op += cSize; } ip += segmentSize; - { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); if (cSize==0) return 0; MEM_writeLE16(ostart+2, (U16)cSize); op += cSize; } ip += segmentSize; - { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) ); if (cSize==0) return 0; MEM_writeLE16(ostart+4, (U16)cSize); op += cSize; } ip += segmentSize; - { CHECK_E_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) ); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) ); if (cSize==0) return 0; op += cSize; } @@ -523,19 +523,19 @@ static size_t HUF_compress_internal ( if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT; /* Scan input and build symbol stats */ - { CHECK_E_F(largest, FSE_count_wksp (table.count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace) ); + { CHECK_V_F(largest, FSE_count_wksp (table.count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace) ); if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */ } /* Build Huffman Tree */ huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue); - { CHECK_E_F(maxBits, HUF_buildCTable (table.CTable, table.count, maxSymbolValue, huffLog) ); + { CHECK_V_F(maxBits, HUF_buildCTable (table.CTable, table.count, maxSymbolValue, huffLog) ); huffLog = (U32)maxBits; } /* Write table description header */ - { CHECK_E_F(hSize, HUF_writeCTable (op, dstSize, table.CTable, maxSymbolValue, huffLog) ); + { CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, table.CTable, maxSymbolValue, huffLog) ); if (hSize + 12 >= srcSize) return 0; /* not useful to try compression */ op += hSize; } diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 853b0c3bf..30296989b 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2509,6 +2509,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_ const BYTE* const dictEnd = dictPtr + dictSize; short offcodeNCount[MaxOff+1]; unsigned offcodeMaxValue = MaxOff; + BYTE scratchBuffer[1<hufTable, 255, dict, dictSize); if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted); @@ -2520,7 +2521,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_ if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ - CHECK_E (FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted); + CHECK_E (FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted); dictPtr += offcodeHeaderSize; } @@ -2531,7 +2532,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_ if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); /* Every match length code must have non-zero probability */ CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML)); - CHECK_E (FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted); + CHECK_E (FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted); dictPtr += matchlengthHeaderSize; } @@ -2542,7 +2543,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_ if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); /* Every literal length code must have non-zero probability */ CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL)); - CHECK_E(FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted); + CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted); dictPtr += litlengthHeaderSize; } From 850c76d04597b537767fd543ec2c6ec587d570f2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 1 Dec 2016 16:26:25 -0800 Subject: [PATCH 114/185] removed test artefact --- frame.txt | 128 ------------------------------------------------------ 1 file changed, 128 deletions(-) delete mode 100644 frame.txt diff --git a/frame.txt b/frame.txt deleted file mode 100644 index 58902c328..000000000 --- a/frame.txt +++ /dev/null @@ -1,128 +0,0 @@ -common/fse_decompress.c:321:8: warning: stack frame size of 16984 bytes in function 'FSE_decompress' [-Wframe-larger-than=] -size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) - ^ -1 warning generated. -compress/fse_compress.c:185:8: warning: stack frame size of 4120 bytes in function 'FSE_buildCTable' [-Wframe-larger-than=] -size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) - ^ -compress/fse_compress.c:423:8: warning: stack frame size of 4152 bytes in function 'FSE_countFast' [-Wframe-larger-than=] -size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, - ^ -compress/fse_compress.c:442:8: warning: stack frame size of 4120 bytes in function 'FSE_count' [-Wframe-larger-than=] -size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, - ^ -compress/fse_compress.c:784:8: warning: stack frame size of 5752 bytes in function 'FSE_compress_wksp' [-Wframe-larger-than=] -size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) - ^ -compress/fse_compress.c:836:8: warning: stack frame size of 14392 bytes in function 'FSE_compress2' [-Wframe-larger-than=] -size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) - ^ -compress/fse_compress.c:844:8: warning: stack frame size of 14392 bytes in function 'FSE_compress' [-Wframe-larger-than=] -size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) - ^ -6 warnings generated. -compress/huf_compress.c:332:8: warning: stack frame size of 4472 bytes in function 'HUF_buildCTable' [-Wframe-larger-than=] -size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits) - ^ -compress/huf_compress.c:567:8: warning: stack frame size of 4136 bytes in function 'HUF_compress1X' [-Wframe-larger-than=] -size_t HUF_compress1X (void* dst, size_t dstSize, - ^ -compress/huf_compress.c:582:8: warning: stack frame size of 4136 bytes in function 'HUF_compress2' [-Wframe-larger-than=] -size_t HUF_compress2 (void* dst, size_t dstSize, - ^ -compress/huf_compress.c:590:8: warning: stack frame size of 4136 bytes in function 'HUF_compress' [-Wframe-larger-than=] -size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize) - ^ -4 warnings generated. -compress/zstd_compress.c:2711:8: warning: stack frame size of 8168 bytes in function 'ZSTD_compress' [-Wframe-larger-than=] -size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel) - ^ -1 warning generated. -decompress/huf_decompress.c:224:8: warning: stack frame size of 8264 bytes in function 'HUF_decompress1X2' [-Wframe-larger-than=] -size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -decompress/huf_decompress.c:347:8: warning: stack frame size of 8280 bytes in function 'HUF_decompress4X2' [-Wframe-larger-than=] -size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -decompress/huf_decompress.c:445:8: warning: stack frame size of 2408 bytes in function 'HUF_readDTableX4' [-Wframe-larger-than=] -size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) - ^ -decompress/huf_decompress.c:636:8: warning: stack frame size of 16456 bytes in function 'HUF_decompress1X4' [-Wframe-larger-than=] -size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -decompress/huf_decompress.c:758:8: warning: stack frame size of 16472 bytes in function 'HUF_decompress4X4' [-Wframe-larger-than=] -size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -5 warnings generated. -dictBuilder/divsufsort.c:1441:1: warning: stack frame size of 2472 bytes in function 'sort_typeBstar' [-Wframe-larger-than=] -sort_typeBstar(const unsigned char *T, int *SA, -^ -1 warning generated. -dictBuilder/zdict.c:828:8: warning: stack frame size of 7176 bytes in function 'ZDICT_addEntropyTablesFromBuffer_advanced' [-Wframe-larger-than=] -size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, - ^ -1 warning generated. -common/fse_decompress.c:321:8: warning: stack frame size of 16984 bytes in function 'FSE_decompress' [-Wframe-larger-than=] -size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) - ^ -1 warning generated. -compress/fse_compress.c:185:8: warning: stack frame size of 4120 bytes in function 'FSE_buildCTable' [-Wframe-larger-than=] -size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) - ^ -compress/fse_compress.c:423:8: warning: stack frame size of 4152 bytes in function 'FSE_countFast' [-Wframe-larger-than=] -size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, - ^ -compress/fse_compress.c:442:8: warning: stack frame size of 4120 bytes in function 'FSE_count' [-Wframe-larger-than=] -size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, - ^ -compress/fse_compress.c:784:8: warning: stack frame size of 5752 bytes in function 'FSE_compress_wksp' [-Wframe-larger-than=] -size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) - ^ -compress/fse_compress.c:836:8: warning: stack frame size of 14392 bytes in function 'FSE_compress2' [-Wframe-larger-than=] -size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog) - ^ -compress/fse_compress.c:844:8: warning: stack frame size of 14392 bytes in function 'FSE_compress' [-Wframe-larger-than=] -size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize) - ^ -6 warnings generated. -compress/huf_compress.c:332:8: warning: stack frame size of 4472 bytes in function 'HUF_buildCTable' [-Wframe-larger-than=] -size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits) - ^ -compress/huf_compress.c:567:8: warning: stack frame size of 4136 bytes in function 'HUF_compress1X' [-Wframe-larger-than=] -size_t HUF_compress1X (void* dst, size_t dstSize, - ^ -compress/huf_compress.c:582:8: warning: stack frame size of 4136 bytes in function 'HUF_compress2' [-Wframe-larger-than=] -size_t HUF_compress2 (void* dst, size_t dstSize, - ^ -compress/huf_compress.c:590:8: warning: stack frame size of 4136 bytes in function 'HUF_compress' [-Wframe-larger-than=] -size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize) - ^ -4 warnings generated. -compress/zstd_compress.c:2711:8: warning: stack frame size of 8168 bytes in function 'ZSTD_compress' [-Wframe-larger-than=] -size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel) - ^ -1 warning generated. -decompress/huf_decompress.c:224:8: warning: stack frame size of 8264 bytes in function 'HUF_decompress1X2' [-Wframe-larger-than=] -size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -decompress/huf_decompress.c:347:8: warning: stack frame size of 8280 bytes in function 'HUF_decompress4X2' [-Wframe-larger-than=] -size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -decompress/huf_decompress.c:445:8: warning: stack frame size of 2408 bytes in function 'HUF_readDTableX4' [-Wframe-larger-than=] -size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) - ^ -decompress/huf_decompress.c:636:8: warning: stack frame size of 16456 bytes in function 'HUF_decompress1X4' [-Wframe-larger-than=] -size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -decompress/huf_decompress.c:758:8: warning: stack frame size of 16472 bytes in function 'HUF_decompress4X4' [-Wframe-larger-than=] -size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) - ^ -5 warnings generated. -dictBuilder/divsufsort.c:1441:1: warning: stack frame size of 2472 bytes in function 'sort_typeBstar' [-Wframe-larger-than=] -sort_typeBstar(const unsigned char *T, int *SA, -^ -1 warning generated. -dictBuilder/zdict.c:828:8: warning: stack frame size of 7176 bytes in function 'ZDICT_addEntropyTablesFromBuffer_advanced' [-Wframe-larger-than=] -size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, - ^ -1 warning generated. From a0d742b1e475691271af354c227f12f838134620 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 1 Dec 2016 17:47:30 -0800 Subject: [PATCH 115/185] introduced HUF_buildCTable_wksp(), to reduce stack memory usage --- lib/common/huf.h | 27 +++++++++++--------- lib/compress/huf_compress.c | 48 ++++++++++++++++++++++++------------ lib/compress/zstd_compress.c | 4 +-- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 06568f08a..5087d36a2 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -73,9 +73,7 @@ size_t HUF_decompress(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); -/* **************************************** -* Tool functions -******************************************/ +/* *** Tool functions *** */ #define HUF_BLOCKSIZE_MAX (128 * 1024) size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ @@ -84,15 +82,15 @@ unsigned HUF_isError(size_t code); /**< tells if a return value is an const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ -/* *** Advanced function *** */ +/* *** Advanced function *** */ /** HUF_compress2() : * Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog` */ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); /** HUF_compress4X_wksp() : -* Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of <= 1024 unsigned */ -size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, unsigned* workSpace); +* Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */ +size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least 1024 unsigned */ @@ -146,10 +144,6 @@ size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, con size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ -size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); -size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ - /* **************************************** * HUF detailed API @@ -174,6 +168,12 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, un size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned. + */ +size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize); + /*! HUF_readStats() : Read compact Huffman tree, saved by HUF_writeCTable(). `huffWeight` is destination buffer. @@ -213,17 +213,20 @@ size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* c /* single stream variants */ size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); -size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, unsigned* workSpace); /**< `workSpace` must be a table of at least 1024 unsigned */ +size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least 1024 unsigned */ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ +size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); +size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ + size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); - #endif /* HUF_STATIC_LINKING_ONLY */ diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 4ed093eee..bf464daaf 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -325,23 +325,26 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue) } -/** HUF_buildCTable() : - * Note : count is used before tree is written, so they can safely overlap +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned. */ #define STARTNODE (HUF_SYMBOLVALUE_MAX+1) -size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits) +typedef nodeElt huffNodeTable[2*HUF_SYMBOLVALUE_MAX+1 +1]; +size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize) { - nodeElt huffNode0[2*HUF_SYMBOLVALUE_MAX+1 +1]; - nodeElt* huffNode = huffNode0 + 1; + nodeElt* const huffNode0 = (nodeElt*)workSpace; + nodeElt* const huffNode = huffNode0+1; U32 n, nonNullRank; int lowS, lowN; U16 nodeNb = STARTNODE; U32 nodeRoot; /* safety checks */ + if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC); /* workSpace is not large enough */ if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT; if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC); - memset(huffNode0, 0, sizeof(huffNode0)); + memset(huffNode0, 0, sizeof(huffNodeTable)); /* sort, decreasing order */ HUF_sort(huffNode, count, maxSymbolValue); @@ -354,7 +357,7 @@ size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U3 huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb; nodeNb++; lowS-=2; for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30); - huffNode0[0].count = (U32)(1U<<31); + huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */ /* create parents */ while (nodeNb <= nodeRoot) { @@ -397,6 +400,15 @@ size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U3 return maxNbBits; } +/** HUF_buildCTable() : + * Note : count is used before tree is written, so they can safely overlap + */ +size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits) +{ + huffNodeTable nodeTable; + return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, nodeTable, sizeof(nodeTable)); +} + static void HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable) { BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits); @@ -503,7 +515,8 @@ static size_t HUF_compress_internal ( void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, - unsigned singleStream, unsigned* workSpace) + unsigned singleStream, + void* workSpace, size_t wkspSize) { BYTE* const ostart = (BYTE*)dst; BYTE* const oend = ostart + dstSize; @@ -515,6 +528,7 @@ static size_t HUF_compress_internal ( } table; /* `count` can overlap with `CTable`; saves 1 KB */ /* checks & inits */ + if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC); if (!srcSize) return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */ if (!dstSize) return 0; /* cannot fit within dst budget */ if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */ @@ -523,14 +537,14 @@ static size_t HUF_compress_internal ( if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT; /* Scan input and build symbol stats */ - { CHECK_V_F(largest, FSE_count_wksp (table.count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace) ); + { CHECK_V_F(largest, FSE_count_wksp (table.count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) ); if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */ } /* Build Huffman Tree */ huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue); - { CHECK_V_F(maxBits, HUF_buildCTable (table.CTable, table.count, maxSymbolValue, huffLog) ); + { CHECK_V_F(maxBits, HUF_buildCTable_wksp (table.CTable, table.count, maxSymbolValue, huffLog, workSpace, wkspSize) ); huffLog = (U32)maxBits; } @@ -559,9 +573,10 @@ static size_t HUF_compress_internal ( size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned huffLog, unsigned* workSpace) + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize) { - return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace); + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize); } size_t HUF_compress1X (void* dst, size_t dstSize, @@ -569,14 +584,15 @@ size_t HUF_compress1X (void* dst, size_t dstSize, unsigned maxSymbolValue, unsigned huffLog) { unsigned workSpace[1024]; - return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace); + return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace)); } size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned huffLog, unsigned* workSpace) + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize) { - return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace); + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize); } size_t HUF_compress2 (void* dst, size_t dstSize, @@ -584,7 +600,7 @@ size_t HUF_compress2 (void* dst, size_t dstSize, unsigned maxSymbolValue, unsigned huffLog) { unsigned workSpace[1024]; - return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace); + return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace)); } size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 30296989b..665d09c0f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -471,8 +471,8 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc, singleStream = 1; cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable); } else { - cLitSize = singleStream ? HUF_compress1X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters) - : HUF_compress4X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters); + cLitSize = singleStream ? HUF_compress1X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters)) + : HUF_compress4X_wksp(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters)); } if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) From b89af20353c992cac7ef03d5a0e792acae8e1bdd Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 1 Dec 2016 18:24:59 -0800 Subject: [PATCH 116/185] reduced table sizes for HUF_readDTableX4 --- lib/common/entropy_common.c | 11 ++++++----- lib/common/huf.h | 17 +++++++++-------- lib/decompress/huf_decompress.c | 10 +++++----- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/common/entropy_common.c b/lib/common/entropy_common.c index 8a31c4696..83fd97154 100644 --- a/lib/common/entropy_common.c +++ b/lib/common/entropy_common.c @@ -159,6 +159,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t /*! HUF_readStats() : Read compact Huffman tree, saved by HUF_writeCTable(). `huffWeight` is destination buffer. + `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. @return : size read from `src` , or an error Code . Note : Needed by HUF_readCTable() and HUF_readDTableX?() . */ @@ -187,17 +188,17 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, huffWeight[n+1] = ip[n/2] & 15; } } } else { /* header compressed with FSE (normal case) */ - FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(5)]; /* 5 is max possible tableLog for HUF header */ + FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ if (iSize+1 > srcSize) return ERROR(srcSize_wrong); - oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 5); /* max (hwSize-1) values decoded, as last one is implied */ + oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ if (FSE_isError(oSize)) return oSize; } /* collect weight stats */ - memset(rankStats, 0, (HUF_TABLELOG_ABSOLUTEMAX + 1) * sizeof(U32)); + memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); weightTotal = 0; { U32 n; for (n=0; n= HUF_TABLELOG_ABSOLUTEMAX) return ERROR(corruption_detected); + if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected); rankStats[huffWeight[n]]++; weightTotal += (1 << huffWeight[n]) >> 1; } } @@ -205,7 +206,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, /* get last non-null symbol weight (implied, total must be 2^n) */ { U32 const tableLog = BIT_highbit32(weightTotal) + 1; - if (tableLog > HUF_TABLELOG_ABSOLUTEMAX) return ERROR(corruption_detected); + if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); *tableLogPtr = tableLog; /* determine last weight */ { U32 const total = 1 << tableLog; diff --git a/lib/common/huf.h b/lib/common/huf.h index 5087d36a2..35d6033ea 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -62,19 +62,19 @@ size_t HUF_compress(void* dst, size_t dstCapacity, HUF_decompress() : Decompress HUF data from buffer 'cSrc', of size 'cSrcSize', into already allocated buffer 'dst', of minimum size 'dstSize'. - `dstSize` : **must** be the ***exact*** size of original (uncompressed) data. + `originalSize` : **must** be the ***exact*** size of original (uncompressed) data. Note : in contrast with FSE, HUF_decompress can regenerate RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, because it knows size to regenerate. - @return : size of regenerated data (== dstSize), + @return : size of regenerated data (== originalSize), or an error code, which can be tested using HUF_isError() */ -size_t HUF_decompress(void* dst, size_t dstSize, +size_t HUF_decompress(void* dst, size_t originalSize, const void* cSrc, size_t cSrcSize); /* *** Tool functions *** */ -#define HUF_BLOCKSIZE_MAX (128 * 1024) +#define HUF_BLOCKSIZE_MAX (128 * 1024) /*< maximum input size for a single block compressed with HUF_compress */ size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ /* Error Management */ @@ -85,7 +85,8 @@ const char* HUF_getErrorName(size_t code); /**< provides error code string (us /* *** Advanced function *** */ /** HUF_compress2() : -* Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog` */ + * Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog` . + * `tableLog` must be `<= HUF_TABLELOG_MAX` . */ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); /** HUF_compress4X_wksp() : @@ -101,7 +102,7 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t s /* *** Constants *** */ -#define HUF_TABLELOG_ABSOLUTEMAX 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ #define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ #define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */ #define HUF_SYMBOLVALUE_MAX 255 @@ -128,9 +129,9 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t s typedef U32 HUF_DTable; #define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) #define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ - HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1)*0x1000001) } + HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } #define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \ - HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog)*0x1000001) } + HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } /* **************************************** diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index e94fa83cc..d212dd88e 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -398,14 +398,14 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co } } } -typedef U32 rankVal_t[HUF_TABLELOG_ABSOLUTEMAX][HUF_TABLELOG_ABSOLUTEMAX + 1]; +typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1]; static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog, const sortedSymbol_t* sortedList, const U32 sortedListSize, const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline) { - U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 rankVal[HUF_TABLELOG_MAX + 1]; const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ const U32 minBits = nbBitsBaseline - maxWeight; U32 s; @@ -446,8 +446,8 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) { BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; - U32 rankStats[HUF_TABLELOG_ABSOLUTEMAX + 1] = { 0 }; - U32 rankStart0[HUF_TABLELOG_ABSOLUTEMAX + 2] = { 0 }; + U32 rankStats[HUF_TABLELOG_MAX + 1] = { 0 }; + U32 rankStart0[HUF_TABLELOG_MAX + 2] = { 0 }; U32* const rankStart = rankStart0+1; rankVal_t rankVal; U32 tableLog, maxW, sizeOfSort, nbSymbols; @@ -458,7 +458,7 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr; HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compilation fails here, assertion is false */ - if (maxTableLog > HUF_TABLELOG_ABSOLUTEMAX) return ERROR(tableLog_tooLarge); + if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); From 4b504f131aff79cf9a427c970de239191c8455ee Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 2 Dec 2016 13:11:39 +0100 Subject: [PATCH 117/185] added gzip_open, gzip_close, gzip_read --- programs/fileio.c | 163 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 121 insertions(+), 42 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 535308e58..975a7cfdc 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -652,23 +652,107 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ #ifdef ZSTD_GZDECOMPRESS -static unsigned long long FIO_decompressGzFile(dRess_t ress, const char* srcFileName, gzFile gzSrcFile) +typedef struct gzipContext_s { + FILE *file; + int err; + char *msg; + z_stream strm; +} *gzipContext; + + +static gzipContext gzip_open(const char *path, int fd, const char *mode) { + gzipContext gzip = malloc(sizeof(struct gzipContext_s)); + if (gzip == NULL) + return NULL; + + gzip->file = (path == NULL) ? fdopen(fd, mode) : fopen(path, mode); + if (gzip->file == NULL) { + free(gzip); + return NULL; + } + + gzip->strm.zalloc = Z_NULL; + gzip->strm.zfree = Z_NULL; + gzip->strm.opaque = Z_NULL; + gzip->strm.next_in = 0; + gzip->strm.avail_in = Z_NULL; + if (inflateInit2(&(gzip->strm), 15 + 16) != Z_OK) { + fclose(gzip->file); + free(gzip); + return NULL; + } + gzip->err = 0; + gzip->msg = ""; + return gzip; +} + + +static int gzip_close(gzipContext gzip) +{ + if (gzip == NULL) return Z_STREAM_ERROR; + + inflateEnd(&(gzip->strm)); + fclose(gzip->file); + free(gzip); + return Z_OK; +} + + +int gzip_read(gzipContext gzip, dRess_t ress, size_t headBufSize) { + int ret; + unsigned readBytes; + unsigned char in[1]; + unsigned char* headBuf = (unsigned char*)ress.srcBuffer; + z_stream *strm; + + if (gzip == NULL || gzip->err) + return 0; + strm = &(gzip->strm); + strm->next_out = ress.dstBuffer; + strm->avail_out = ress.dstBufferSize; + + do { + if (headBufSize) { + headBufSize--; + in[0] = *headBuf++; + } else { + readBytes = fread(in, 1, 1, gzip->file); + if (readBytes == 0) + break; + } + strm->next_in = in; + strm->avail_in = 1; + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_DATA_ERROR) { + gzip->err = Z_DATA_ERROR; + gzip->msg = strm->msg; + return 0; + } + if (ret == Z_STREAM_END) + inflateReset(strm); + } while (strm->avail_out); + + return ress.dstBufferSize - strm->avail_out; +} + + +static unsigned long long FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, gzipContext gzipSrcFile) { unsigned long long filesize = 0; int readBytes; - if (gzSrcFile == NULL) { DISPLAY("zstd: %s: gzopen error \n", srcFileName); return 0; } + if (gzipSrcFile == NULL) { DISPLAY("zstd: %s: FIO_decompressGzFile error \n", srcFileName); return 0; } - do { - readBytes = gzread(gzSrcFile, ress.dstBuffer, ress.dstBufferSize); - if (readBytes < 0) { DISPLAY("zstd: %s: gzread error \n", srcFileName); return 0; } - if (readBytes > 0) { - size_t const sizeCheck = fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile); - if (sizeCheck != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file"); - filesize += readBytes; - } - } while ((size_t)readBytes == ress.dstBufferSize); + for ( ; ; ) { + readBytes = gzip_read(gzipSrcFile, ress, headBufSize); + printf("readBytes=%d dstBufferSize=%d\n", (int)readBytes, (int)ress.dstBufferSize); + if (readBytes < 0) EXM_THROW(33, "zstd: %s: gzip_read error: %s \n", srcFileName, gzipSrcFile->msg); + if (readBytes == 0) break; + + if (fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile) != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file"); + filesize += readBytes; + } - if (gzclose(gzSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzclose error \n", srcFileName); return 0; } + if (gzip_close(gzipSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzip_close error \n", srcFileName); return 0; } return filesize; } @@ -700,48 +784,43 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) /* for each frame */ for ( ; ; ) { - if (srcFile == stdin) { - int c = getc(srcFile); - if (c < 0) break; /* no more input */ - c = ungetc(c, srcFile); /* only one pushback is guaranteed */ - if (c == 31) { /* 31,139 = gz header */ - unsigned long long result = FIO_decompressGzFile(ress, srcFileName, gzdopen(fileno(srcFile), "rb")); - printf("result=%d\n", (int)result); - if (result == 0) return 1; - filesize += result; - continue; - } - } /* check magic number -> version */ { size_t const toRead = 4; size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); + const BYTE* buf = (const BYTE*)ress.srcBuffer; if (sizeCheck==0) { if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ break; /* no more input */ } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } - filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); + if (buf[0] == 31 && buf[1] == 139) { /* gz header */ + unsigned long long result = FIO_decompressGzFile(ress, toRead, srcFileName, gzip_open(NULL, fileno(srcFile), "rb")); + if (result == 0) return 1; + filesize += result; + } else { + if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { + if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ + return result; + } else { + DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); + fclose(srcFile); + return 1; + } } + filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); + } } } /* Close file */ if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ } else { #ifndef ZSTD_GZDECOMPRESS - DISPLAYLEVEL(1, "zstd: %s: gz file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); + DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); return 1; #else - unsigned long long result = FIO_decompressGzFile(ress, srcFileName, gzopen(srcFileName, "rb")); + unsigned long long result = FIO_decompressGzFile(ress, 0, srcFileName, gzip_open(srcFileName, 0, "rb")); if (result == 0) return 1; filesize += result; #endif @@ -819,7 +898,7 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles if (fclose(ress.dstFile)) EXM_THROW(72, "Write error : cannot properly close stdout"); } else { size_t const suffixSize = strlen(suffix); - size_t const gzSuffixSize = strlen(GZ_EXTENSION); + size_t const gzipSuffixSize = strlen(GZ_EXTENSION); size_t dfnSize = FNSPACE; unsigned u; char* dstFileName = (char*)malloc(FNSPACE); @@ -828,7 +907,7 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles const char* const srcFileName = srcNamesTable[u]; size_t const sfnSize = strlen(srcFileName); const char* const suffixPtr = srcFileName + sfnSize - suffixSize; - const char* const gzSuffixPtr = srcFileName + sfnSize - gzSuffixSize; + const char* const gzipSuffixPtr = srcFileName + sfnSize - gzipSuffixSize; if (dfnSize+suffixSize <= sfnSize+1) { free(dstFileName); dfnSize = sfnSize + 20; @@ -836,13 +915,13 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles if (dstFileName==NULL) EXM_THROW(74, "not enough memory for dstFileName"); } if (sfnSize <= suffixSize || strcmp(suffixPtr, suffix) != 0) { - if (sfnSize <= gzSuffixSize || strcmp(gzSuffixPtr, GZ_EXTENSION) != 0) { + if (sfnSize <= gzipSuffixSize || strcmp(gzipSuffixPtr, GZ_EXTENSION) != 0) { DISPLAYLEVEL(1, "zstd: %s: unknown suffix (%4s expected) -- ignored \n", srcFileName, suffix); skippedFiles++; continue; } else { - memcpy(dstFileName, srcFileName, sfnSize - gzSuffixSize); - dstFileName[sfnSize-gzSuffixSize] = '\0'; + memcpy(dstFileName, srcFileName, sfnSize - gzipSuffixSize); + dstFileName[sfnSize-gzipSuffixSize] = '\0'; } } else { memcpy(dstFileName, srcFileName, sfnSize - suffixSize); From b0f2ef21190ebf25ea7f18cbc86845a343b81ab6 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 2 Dec 2016 13:50:29 +0100 Subject: [PATCH 118/185] improved gzip_* functions --- programs/fileio.c | 57 ++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 975a7cfdc..16ae337b9 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -653,31 +653,26 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ #ifdef ZSTD_GZDECOMPRESS typedef struct gzipContext_s { - FILE *file; int err; char *msg; z_stream strm; } *gzipContext; -static gzipContext gzip_open(const char *path, int fd, const char *mode) { - gzipContext gzip = malloc(sizeof(struct gzipContext_s)); +static gzipContext gzip_create(void) +{ + gzipContext gzip; + + gzip = malloc(sizeof(struct gzipContext_s)); if (gzip == NULL) return NULL; - gzip->file = (path == NULL) ? fdopen(fd, mode) : fopen(path, mode); - if (gzip->file == NULL) { - free(gzip); - return NULL; - } - gzip->strm.zalloc = Z_NULL; gzip->strm.zfree = Z_NULL; gzip->strm.opaque = Z_NULL; gzip->strm.next_in = 0; gzip->strm.avail_in = Z_NULL; if (inflateInit2(&(gzip->strm), 15 + 16) != Z_OK) { - fclose(gzip->file); free(gzip); return NULL; } @@ -687,18 +682,18 @@ static gzipContext gzip_open(const char *path, int fd, const char *mode) { } -static int gzip_close(gzipContext gzip) +static int gzip_free(gzipContext gzip) { if (gzip == NULL) return Z_STREAM_ERROR; inflateEnd(&(gzip->strm)); - fclose(gzip->file); free(gzip); return Z_OK; } -int gzip_read(gzipContext gzip, dRess_t ress, size_t headBufSize) { +static int gzip_decompress(gzipContext gzip, FILE* file, dRess_t ress, size_t headBufSize) +{ int ret; unsigned readBytes; unsigned char in[1]; @@ -716,7 +711,7 @@ int gzip_read(gzipContext gzip, dRess_t ress, size_t headBufSize) { headBufSize--; in[0] = *headBuf++; } else { - readBytes = fread(in, 1, 1, gzip->file); + readBytes = fread(in, 1, 1, file); if (readBytes == 0) break; } @@ -736,23 +731,25 @@ int gzip_read(gzipContext gzip, dRess_t ress, size_t headBufSize) { } -static unsigned long long FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, gzipContext gzipSrcFile) +static unsigned long long FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, FILE* srcFile) { unsigned long long filesize = 0; int readBytes; - if (gzipSrcFile == NULL) { DISPLAY("zstd: %s: FIO_decompressGzFile error \n", srcFileName); return 0; } + gzipContext gzipCtx = gzip_create(); + + if (gzipCtx == NULL) { DISPLAY("zstd: %s: gzip_create error \n", srcFileName); return 0; } for ( ; ; ) { - readBytes = gzip_read(gzipSrcFile, ress, headBufSize); - printf("readBytes=%d dstBufferSize=%d\n", (int)readBytes, (int)ress.dstBufferSize); - if (readBytes < 0) EXM_THROW(33, "zstd: %s: gzip_read error: %s \n", srcFileName, gzipSrcFile->msg); + readBytes = gzip_decompress(gzipCtx, srcFile, ress, headBufSize); + printf("headBufSize=%d readBytes=%d dstBufferSize=%d\n", (int)headBufSize, (int)readBytes, (int)ress.dstBufferSize); + if (readBytes < 0) EXM_THROW(30, "zstd: %s: gzip_decompress error: %s \n", srcFileName, gzipCtx->msg); if (readBytes == 0) break; - if (fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile) != (size_t)readBytes) EXM_THROW(34, "Write error : cannot write to output file"); + if (fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile) != (size_t)readBytes) EXM_THROW(31, "Write error : cannot write to output file"); filesize += readBytes; } - if (gzip_close(gzipSrcFile) != Z_OK) { DISPLAY("zstd: %s: gzip_close error \n", srcFileName); return 0; } + if (gzip_free(gzipCtx) != Z_OK) { DISPLAY("zstd: %s: gzip_free error \n", srcFileName); return 0; } return filesize; } @@ -768,6 +765,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) { unsigned long long filesize = 0; FILE* const dstFile = ress.dstFile; + FILE* srcFile; unsigned readSomething = 0; size_t const suffixSize = strlen(GZ_EXTENSION); size_t const sfnSize = strlen(srcFileName); @@ -778,10 +776,10 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) return 1; } - if (sfnSize <= suffixSize || strcmp(suffixPtr, GZ_EXTENSION) != 0) { - FILE* srcFile = FIO_openSrcFile(srcFileName); - if (srcFile==0) return 1; + srcFile = FIO_openSrcFile(srcFileName); + if (srcFile==0) return 1; + if (sfnSize <= suffixSize || strcmp(suffixPtr, GZ_EXTENSION) != 0) { /* for each frame */ for ( ; ; ) { /* check magic number -> version */ @@ -795,7 +793,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) readSomething = 1; /* there is at least >= 4 bytes in srcFile */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ if (buf[0] == 31 && buf[1] == 139) { /* gz header */ - unsigned long long result = FIO_decompressGzFile(ress, toRead, srcFileName, gzip_open(NULL, fileno(srcFile), "rb")); + unsigned long long result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); if (result == 0) return 1; filesize += result; } else { @@ -813,14 +811,12 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) } } } - /* Close file */ - if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ } else { #ifndef ZSTD_GZDECOMPRESS DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); return 1; #else - unsigned long long result = FIO_decompressGzFile(ress, 0, srcFileName, gzip_open(srcFileName, 0, "rb")); + unsigned long long result = FIO_decompressGzFile(ress, 0, srcFileName, srcFile); if (result == 0) return 1; filesize += result; #endif @@ -830,8 +826,9 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize); - /* Remove source file */ - if (g_removeSrcFile) { if (remove(srcFileName)) EXM_THROW(35, "zstd: %s: %s", srcFileName, strerror(errno)); }; + /* Close file */ + if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ + if (g_removeSrcFile) { if (remove(srcFileName)) EXM_THROW(34, "zstd: %s: %s", srcFileName, strerror(errno)); }; return 0; } From c5eebca12814a08a1a8bb6e848df74b98e4d0c89 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 2 Dec 2016 15:01:31 +0100 Subject: [PATCH 119/185] rewritten FIO_decompressGzFile --- programs/fileio.c | 191 +++++++++++++++------------------------------- 1 file changed, 63 insertions(+), 128 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 16ae337b9..317483a96 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -652,106 +652,48 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ #ifdef ZSTD_GZDECOMPRESS -typedef struct gzipContext_s { - int err; - char *msg; - z_stream strm; -} *gzipContext; - - -static gzipContext gzip_create(void) -{ - gzipContext gzip; - - gzip = malloc(sizeof(struct gzipContext_s)); - if (gzip == NULL) - return NULL; - - gzip->strm.zalloc = Z_NULL; - gzip->strm.zfree = Z_NULL; - gzip->strm.opaque = Z_NULL; - gzip->strm.next_in = 0; - gzip->strm.avail_in = Z_NULL; - if (inflateInit2(&(gzip->strm), 15 + 16) != Z_OK) { - free(gzip); - return NULL; - } - gzip->err = 0; - gzip->msg = ""; - return gzip; -} - - -static int gzip_free(gzipContext gzip) -{ - if (gzip == NULL) return Z_STREAM_ERROR; - - inflateEnd(&(gzip->strm)); - free(gzip); - return Z_OK; -} - - -static int gzip_decompress(gzipContext gzip, FILE* file, dRess_t ress, size_t headBufSize) +static size_t FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, FILE* srcFile) { int ret; - unsigned readBytes; unsigned char in[1]; unsigned char* headBuf = (unsigned char*)ress.srcBuffer; - z_stream *strm; + size_t decompBytes, outFileSize = 0; + z_stream strm; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.next_in = 0; + strm.avail_in = Z_NULL; + if (inflateInit2(&strm, 15 + 16) != Z_OK) return 0; + + strm.next_out = ress.dstBuffer; + strm.avail_out = ress.dstBufferSize; - if (gzip == NULL || gzip->err) - return 0; - strm = &(gzip->strm); - strm->next_out = ress.dstBuffer; - strm->avail_out = ress.dstBufferSize; - - do { + for ( ; ; ) { if (headBufSize) { headBufSize--; in[0] = *headBuf++; } else { - readBytes = fread(in, 1, 1, file); - if (readBytes == 0) - break; + if (fread(in, 1, 1, srcFile) == 0) break; } - strm->next_in = in; - strm->avail_in = 1; - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_DATA_ERROR) { - gzip->err = Z_DATA_ERROR; - gzip->msg = strm->msg; - return 0; + strm.next_in = in; + strm.avail_in = 1; + ret = inflate(&strm, Z_NO_FLUSH); + if (ret == Z_STREAM_END) break; + if (ret != Z_OK) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; } + + decompBytes = ress.dstBufferSize - strm.avail_out; + if (decompBytes) { + if (fwrite(ress.dstBuffer, 1, decompBytes, ress.dstFile) != (size_t)decompBytes) EXM_THROW(31, "Write error : cannot write to output file"); + outFileSize += decompBytes; + strm.next_out = ress.dstBuffer; + strm.avail_out = ress.dstBufferSize; } - if (ret == Z_STREAM_END) - inflateReset(strm); - } while (strm->avail_out); - - return ress.dstBufferSize - strm->avail_out; -} - - -static unsigned long long FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, FILE* srcFile) -{ - unsigned long long filesize = 0; - int readBytes; - gzipContext gzipCtx = gzip_create(); - - if (gzipCtx == NULL) { DISPLAY("zstd: %s: gzip_create error \n", srcFileName); return 0; } - - for ( ; ; ) { - readBytes = gzip_decompress(gzipCtx, srcFile, ress, headBufSize); - printf("headBufSize=%d readBytes=%d dstBufferSize=%d\n", (int)headBufSize, (int)readBytes, (int)ress.dstBufferSize); - if (readBytes < 0) EXM_THROW(30, "zstd: %s: gzip_decompress error: %s \n", srcFileName, gzipCtx->msg); - if (readBytes == 0) break; - - if (fwrite(ress.dstBuffer, 1, readBytes, ress.dstFile) != (size_t)readBytes) EXM_THROW(31, "Write error : cannot write to output file"); - filesize += readBytes; } - if (gzip_free(gzipCtx) != Z_OK) { DISPLAY("zstd: %s: gzip_free error \n", srcFileName); return 0; } - - return filesize; + inflateEnd(&strm); + return outFileSize; } #endif @@ -767,9 +709,6 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) FILE* const dstFile = ress.dstFile; FILE* srcFile; unsigned readSomething = 0; - size_t const suffixSize = strlen(GZ_EXTENSION); - size_t const sfnSize = strlen(srcFileName); - const char* const suffixPtr = srcFileName + sfnSize - suffixSize; if (UTIL_isDirectory(srcFileName)) { DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName); @@ -779,47 +718,43 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) srcFile = FIO_openSrcFile(srcFileName); if (srcFile==0) return 1; - if (sfnSize <= suffixSize || strcmp(suffixPtr, GZ_EXTENSION) != 0) { - /* for each frame */ - for ( ; ; ) { - /* check magic number -> version */ - { size_t const toRead = 4; - size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); - const BYTE* buf = (const BYTE*)ress.srcBuffer; - if (sizeCheck==0) { - if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - break; /* no more input */ - } - readSomething = 1; /* there is at least >= 4 bytes in srcFile */ - if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - if (buf[0] == 31 && buf[1] == 139) { /* gz header */ - unsigned long long result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); - if (result == 0) return 1; - filesize += result; - } else { - if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } - filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); - } + /* for each frame */ + for ( ; ; ) { + /* check magic number -> version */ + { size_t const toRead = 4; + size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); + const BYTE* buf = (const BYTE*)ress.srcBuffer; + if (sizeCheck==0) { + if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + break; /* no more input */ } - } - } else { -#ifndef ZSTD_GZDECOMPRESS - DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); - return 1; + readSomething = 1; /* there is at least >= 4 bytes in srcFile */ + if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + if (buf[0] == 31 && buf[1] == 139) { /* gz header */ +#ifdef ZSTD_GZDECOMPRESS + size_t const result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); + printf("result=%d\n", (int)result); + if (result == 0) return 1; + filesize += result; #else - unsigned long long result = FIO_decompressGzFile(ress, 0, srcFileName, srcFile); - if (result == 0) return 1; - filesize += result; + DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); + return 1; #endif + } else { + if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { + if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ + return result; + } else { + DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); + fclose(srcFile); + return 1; + } } + filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); + } + printf("filesize=%d\n", (int)filesize); + } } /* Final Status */ From 4e49580407d2b4ed9a4864837235438948929b67 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 2 Dec 2016 15:19:00 +0100 Subject: [PATCH 120/185] removed testing artifacts --- programs/fileio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 317483a96..06728ae31 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -733,11 +733,10 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) if (buf[0] == 31 && buf[1] == 139) { /* gz header */ #ifdef ZSTD_GZDECOMPRESS size_t const result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); - printf("result=%d\n", (int)result); if (result == 0) return 1; filesize += result; #else - DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); + DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed -- ignored (zstd compiled without ZSTD_GZDECOMPRESS) \n", srcFileName); return 1; #endif } else { @@ -753,7 +752,6 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) } } filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); } - printf("filesize=%d\n", (int)filesize); } } From 821bf1febc8d2772ed093fa5e540471e9c260c5e Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 2 Dec 2016 16:13:41 +0100 Subject: [PATCH 121/185] fixed Doxygen trailing comment --- lib/common/huf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 35d6033ea..9427ae8cb 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -74,7 +74,7 @@ size_t HUF_decompress(void* dst, size_t originalSize, /* *** Tool functions *** */ -#define HUF_BLOCKSIZE_MAX (128 * 1024) /*< maximum input size for a single block compressed with HUF_compress */ +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ /* Error Management */ From 690753ea1aa8d82b7c9149920c3b31de3a6071ae Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 2 Dec 2016 16:20:16 +0100 Subject: [PATCH 122/185] improved formatting in FIO_decompressSrcFile --- programs/fileio.c | 55 +++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 06728ae31..3e30c1e5e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -721,37 +721,36 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) /* for each frame */ for ( ; ; ) { /* check magic number -> version */ - { size_t const toRead = 4; - size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); - const BYTE* buf = (const BYTE*)ress.srcBuffer; - if (sizeCheck==0) { - if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - break; /* no more input */ - } - readSomething = 1; /* there is at least >= 4 bytes in srcFile */ - if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - if (buf[0] == 31 && buf[1] == 139) { /* gz header */ + size_t const toRead = 4; + size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); + const BYTE* buf = (const BYTE*)ress.srcBuffer; + if (sizeCheck==0) { + if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + break; /* no more input */ + } + readSomething = 1; /* there is at least >= 4 bytes in srcFile */ + if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + if (buf[0] == 31 && buf[1] == 139) { /* gz header */ #ifdef ZSTD_GZDECOMPRESS - size_t const result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); - if (result == 0) return 1; - filesize += result; + size_t const result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); + if (result == 0) return 1; + filesize += result; #else - DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed -- ignored (zstd compiled without ZSTD_GZDECOMPRESS) \n", srcFileName); - return 1; + DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed -- ignored (zstd compiled without ZSTD_GZDECOMPRESS) \n", srcFileName); + return 1; #endif - } else { - if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } - filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); - } + } else { + if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { + if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ + return result; + } else { + DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); + fclose(srcFile); + return 1; + } } + filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); } } From 2238312c2f5f593a938c5410f9396a99254eb38a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 2 Dec 2016 11:36:11 -0800 Subject: [PATCH 123/185] fix dict loading --- NEWS | 3 ++- lib/decompress/huf_decompress.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 79ceec771..eaae710ce 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ v1.1.2 Improved : faster decompression speed at ultra compression settings and in 32-bits mode cli : new : preserve file attributes, by Przemyslaw Skibinski -cli : fixed : status displays total amount decoded when stream/file consists of multiple appended frames (like pzstd) +cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) API : changed : zbuff prototypes now generate deprecation warnings +Changed : reduced stack memory use v1.1.1 New : command -M#, --memory=, --memlimit=, --memlimit-decompress= to limit allowed memory consumption diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index d212dd88e..a342dfb1e 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -358,13 +358,15 @@ typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4; /* doubl typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t; +/* HUF_fillDTableX4Level2() : + * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed, const U32* rankValOrigin, const int minWeight, const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, U32 nbBitsBaseline, U16 baseSeq) { HUF_DEltX4 DElt; - U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 rankVal[HUF_TABLELOG_MAX + 1]; /* get pre-calculated rankVal */ memcpy(rankVal, rankValOrigin, sizeof(rankVal)); From 5bd4237beb789b6b1eeaea62a5db364a0272d80e Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 2 Dec 2016 12:40:57 -0800 Subject: [PATCH 124/185] minor refactor --- programs/Makefile | 22 ++++++++--------- programs/fileio.c | 60 ++++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 43 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index e44f11264..f0727b0e6 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -27,13 +27,13 @@ else ALIGN_LOOP = endif -CPPFLAGS= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/dictBuilder -CFLAGS ?= -O3 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ +CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/dictBuilder +CFLAGS ?= -O3 +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \ -Wpointer-arith -CFLAGS += $(MOREFLAGS) -FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) +CFLAGS += $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c @@ -82,7 +82,7 @@ zstd : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \ ifneq (,$(filter Windows%,$(OS))) windres\generate_res.bat endif - $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(LDFLAGS) + $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(LDFLAGS) zstd32 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) @@ -91,7 +91,7 @@ zstd32 : $(ZSTDDIR)/decompress/zstd_decompress.c $(ZSTD_FILES) $(ZSTDLEGACY_FILE ifneq (,$(filter Windows%,$(OS))) windres\generate_res.bat endif - $(CC) -m32 $(FLAGS) $^ $(RES32_FILE) -o $@$(EXT) + $(CC) -m32 $(FLAGS) $^ $(RES32_FILE) -o $@$(EXT) zstd-nolegacy : clean_decomp_o @@ -110,23 +110,23 @@ zstd-pgo : clean zstd $(MAKE) zstd MOREFLAGS=-fprofile-use zstd-frugal: $(ZSTDDECOMP_O) $(ZSTD_FILES) zstdcli.c fileio.c - $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT $^ -o zstd$(EXT) + $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT $^ -o zstd$(EXT) zstd-small: clean_decomp_o ZSTD_LEGACY_SUPPORT=0 CFLAGS="-Os -s" $(MAKE) zstd-frugal zstd-decompress-clean: $(ZSTDDECOMP_O) $(ZSTDCOMMON_FILES) $(ZSTDDECOMP_FILES) zstdcli.c fileio.c - $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS $^ -o zstd-decompress$(EXT) + $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS $^ -o zstd-decompress$(EXT) zstd-decompress: clean_decomp_o ZSTD_LEGACY_SUPPORT=0 $(MAKE) zstd-decompress-clean zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c - $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) + $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) gzstd: clean_decomp_o ifeq ($(shell ld -lz 2>/dev/null && echo -n true),true) - $(MAKE) zstd MOREFLAGS=-DZSTD_GZDECOMPRESS LDFLAGS="-lz" + CPPFLAGS=-DZSTD_GZDECOMPRESS LDFLAGS="-lz" $(MAKE) zstd else $(MAKE) zstd endif diff --git a/programs/fileio.c b/programs/fileio.c index 3e30c1e5e..446799af8 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -7,7 +7,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ - /* ************************************* * Compiler Options ***************************************/ @@ -587,7 +586,7 @@ static void FIO_fwriteSparseEnd(FILE* file, unsigned storedSkips) @return : size of decoded frame */ unsigned long long FIO_decompressFrame(dRess_t ress, - FILE* foutput, FILE* finput, size_t alreadyLoaded, + FILE* finput, size_t alreadyLoaded, U64 alreadyDecoded) { U64 frameSize = 0; @@ -610,7 +609,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress, if (ZSTD_isError(readSizeHint)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(readSizeHint)); /* Write block */ - storedSkips = FIO_fwriteSparse(foutput, ress.dstBuffer, outBuff.pos, storedSkips); + storedSkips = FIO_fwriteSparse(ress.dstFile, ress.dstBuffer, outBuff.pos, storedSkips); frameSize += outBuff.pos; DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)((alreadyDecoded+frameSize)>>20) ); @@ -623,7 +622,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress, if (readSize < toRead) EXM_THROW(39, "Read error : premature end"); } } - FIO_fwriteSparseEnd(foutput, storedSkips); + FIO_fwriteSparseEnd(ress.dstFile, storedSkips); return frameSize; } @@ -650,47 +649,45 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ return 0; } - #ifdef ZSTD_GZDECOMPRESS -static size_t FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* srcFileName, FILE* srcFile) +static unsigned long long FIO_decompressGzFrame(dRess_t ress, FILE* srcFile, const char* srcFileName, size_t alreadyLoaded) { - int ret; - unsigned char in[1]; unsigned char* headBuf = (unsigned char*)ress.srcBuffer; - size_t decompBytes, outFileSize = 0; + unsigned long long outFileSize = 0; z_stream strm; - + strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.next_in = 0; strm.avail_in = Z_NULL; - if (inflateInit2(&strm, 15 + 16) != Z_OK) return 0; - + if (inflateInit2(&strm, 15 /* maxWindowLogSize */ + 16 /* gzip only */) != Z_OK) return 0; /* see http://www.zlib.net/manual.html */ + strm.next_out = ress.dstBuffer; strm.avail_out = ress.dstBufferSize; for ( ; ; ) { - if (headBufSize) { - headBufSize--; + unsigned char in[1]; + if (alreadyLoaded) { + alreadyLoaded--; in[0] = *headBuf++; } else { if (fread(in, 1, 1, srcFile) == 0) break; } strm.next_in = in; strm.avail_in = 1; - ret = inflate(&strm, Z_NO_FLUSH); - if (ret == Z_STREAM_END) break; - if (ret != Z_OK) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; } - - decompBytes = ress.dstBufferSize - strm.avail_out; - if (decompBytes) { - if (fwrite(ress.dstBuffer, 1, decompBytes, ress.dstFile) != (size_t)decompBytes) EXM_THROW(31, "Write error : cannot write to output file"); - outFileSize += decompBytes; - strm.next_out = ress.dstBuffer; - strm.avail_out = ress.dstBufferSize; + { int const ret = inflate(&strm, Z_NO_FLUSH); + if (ret == Z_STREAM_END) break; + if (ret != Z_OK) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; } } - } + + { size_t const decompBytes = ress.dstBufferSize - strm.avail_out; + if (decompBytes) { + if (fwrite(ress.dstBuffer, 1, decompBytes, ress.dstFile) != decompBytes) EXM_THROW(31, "Write error : cannot write to output file"); + outFileSize += decompBytes; + strm.next_out = ress.dstBuffer; + strm.avail_out = ress.dstBufferSize; + } } } inflateEnd(&strm); return outFileSize; @@ -705,10 +702,9 @@ static size_t FIO_decompressGzFile(dRess_t ress, size_t headBufSize, const char* */ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) { - unsigned long long filesize = 0; - FILE* const dstFile = ress.dstFile; FILE* srcFile; unsigned readSomething = 0; + unsigned long long filesize = 0; if (UTIL_isDirectory(srcFileName)) { DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName); @@ -732,17 +728,17 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ if (buf[0] == 31 && buf[1] == 139) { /* gz header */ #ifdef ZSTD_GZDECOMPRESS - size_t const result = FIO_decompressGzFile(ress, toRead, srcFileName, srcFile); + unsigned long long const result = FIO_decompressGzFrame(ress, srcFile, srcFileName, toRead); if (result == 0) return 1; filesize += result; #else - DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed -- ignored (zstd compiled without ZSTD_GZDECOMPRESS) \n", srcFileName); + DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); return 1; #endif } else { if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + unsigned const result = FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ return result; } else { @@ -750,7 +746,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) fclose(srcFile); return 1; } } - filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead, filesize); + filesize += FIO_decompressFrame(ress, srcFile, toRead, filesize); } } @@ -771,7 +767,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) 1 : operation aborted (src not available, dst already taken, etc.) */ static int FIO_decompressDstFile(dRess_t ress, - const char* dstFileName, const char* srcFileName) + const char* dstFileName, const char* srcFileName) { int result; stat_t statbuf; From 743b33f57eb3fdd9f3dee1a056db4d323cf30b77 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 2 Dec 2016 15:18:57 -0800 Subject: [PATCH 125/185] fix zstdcat --- NEWS | 4 ++- programs/fileio.c | 10 +++--- programs/fileio.h | 2 +- programs/zstd.1 | 2 +- programs/zstdcli.c | 79 +++++++++++++++++++++++++--------------------- tests/playTests.sh | 6 ++-- 6 files changed, 57 insertions(+), 46 deletions(-) diff --git a/NEWS b/NEWS index eaae710ce..0b3dd92a5 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,9 @@ v1.1.2 Improved : faster decompression speed at ultra compression settings and in 32-bits mode -cli : new : preserve file attributes, by Przemyslaw Skibinski +cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski +cli : new : preserve file attributes cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) +cli : fixed : zstdcat API : changed : zbuff prototypes now generate deprecation warnings Changed : reduced stack memory use diff --git a/programs/fileio.c b/programs/fileio.c index 446799af8..dff4eae05 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -700,7 +700,7 @@ static unsigned long long FIO_decompressGzFrame(dRess_t ress, FILE* srcFile, con @return : 0 : OK 1 : operation not started */ -static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) +static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const char* srcFileName) { FILE* srcFile; unsigned readSomething = 0; @@ -737,7 +737,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) #endif } else { if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ unsigned const result = FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ return result; @@ -777,7 +777,7 @@ static int FIO_decompressDstFile(dRess_t ress, if (ress.dstFile==0) return 1; if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1; - result = FIO_decompressSrcFile(ress, srcFileName); + result = FIO_decompressSrcFile(ress, dstFileName, srcFileName); if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName); @@ -814,12 +814,12 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles if (suffix==NULL) EXM_THROW(70, "zstd: decompression: unknown dst"); /* should never happen */ - if (!strcmp(suffix, stdoutmark) || !strcmp(suffix, nulmark)) { + if (!strcmp(suffix, stdoutmark) || !strcmp(suffix, nulmark)) { /* special cases : -c or -t */ unsigned u; ress.dstFile = FIO_openDstFile(suffix); if (ress.dstFile == 0) EXM_THROW(71, "cannot open %s", suffix); for (u=0; u tmp1 +$ZSTD -dcf tmp1 $ECHO "\n**** frame concatenation **** " From efaf104b2d2c29dedfb853c7b318a88755e921a6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 2 Dec 2016 15:24:40 -0800 Subject: [PATCH 126/185] added zstdless --- NEWS | 1 + programs/Makefile | 9 +++++---- programs/zstdless | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100755 programs/zstdless diff --git a/NEWS b/NEWS index 0b3dd92a5..69b24e635 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ v1.1.2 Improved : faster decompression speed at ultra compression settings and in 32-bits mode cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski cli : new : preserve file attributes +cli : new : added zstdless cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat API : changed : zbuff prototypes now generate deprecation warnings diff --git a/programs/Makefile b/programs/Makefile index f0727b0e6..c78c369e2 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -153,9 +153,10 @@ ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD Dr install: zstd @echo Installing binaries @install -d -m 755 $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(MANDIR)/ - @install -m 755 zstd$(EXT) $(DESTDIR)$(BINDIR)/zstd$(EXT) - @ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdcat - @ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/unzstd + @install -m 755 zstd $(DESTDIR)$(BINDIR)/zstd + @ln -sf zstd $(DESTDIR)$(BINDIR)/zstdcat + @ln -sf zstd $(DESTDIR)$(BINDIR)/unzstd + @install -m 755 zstdless $(DESTDIR)$(BINDIR)/zstdless @echo Installing man pages @install -m 644 zstd.1 $(DESTDIR)$(MANDIR)/zstd.1 @ln -sf zstd.1 $(DESTDIR)$(MANDIR)/zstdcat.1 @@ -165,7 +166,7 @@ install: zstd uninstall: @$(RM) $(DESTDIR)$(BINDIR)/zstdcat @$(RM) $(DESTDIR)$(BINDIR)/unzstd - @$(RM) $(DESTDIR)$(BINDIR)/zstd$(EXT) + @$(RM) $(DESTDIR)$(BINDIR)/zstd @$(RM) $(DESTDIR)$(MANDIR)/zstdcat.1 @$(RM) $(DESTDIR)$(MANDIR)/unzstd.1 @$(RM) $(DESTDIR)$(MANDIR)/zstd.1 diff --git a/programs/zstdless b/programs/zstdless new file mode 100755 index 000000000..ab021405c --- /dev/null +++ b/programs/zstdless @@ -0,0 +1 @@ +zstdcat $@ | less From db85a6e09a7f82ca090ab00130c99c65465ec1fd Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 2 Dec 2016 15:57:07 -0800 Subject: [PATCH 127/185] added zstdgrep --- programs/Makefile | 3 ++ programs/zstdgrep | 124 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100755 programs/zstdgrep diff --git a/programs/Makefile b/programs/Makefile index c78c369e2..44eafbf63 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -157,6 +157,7 @@ install: zstd @ln -sf zstd $(DESTDIR)$(BINDIR)/zstdcat @ln -sf zstd $(DESTDIR)$(BINDIR)/unzstd @install -m 755 zstdless $(DESTDIR)$(BINDIR)/zstdless + @install -m 755 zstdgrep $(DESTDIR)$(BINDIR)/zstdgrep @echo Installing man pages @install -m 644 zstd.1 $(DESTDIR)$(MANDIR)/zstd.1 @ln -sf zstd.1 $(DESTDIR)$(MANDIR)/zstdcat.1 @@ -164,6 +165,8 @@ install: zstd @echo zstd installation completed uninstall: + @$(RM) $(DESTDIR)$(BINDIR)/zstdgrep + @$(RM) $(DESTDIR)$(BINDIR)/zstdless @$(RM) $(DESTDIR)$(BINDIR)/zstdcat @$(RM) $(DESTDIR)$(BINDIR)/unzstd @$(RM) $(DESTDIR)$(BINDIR)/zstd diff --git a/programs/zstdgrep b/programs/zstdgrep new file mode 100755 index 000000000..9f871c03f --- /dev/null +++ b/programs/zstdgrep @@ -0,0 +1,124 @@ +#!/bin/sh +# +# Copyright (c) 2003 Thomas Klausner. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +grep=grep +zcat=zstdcat + +endofopts=0 +pattern_found=0 +grep_args="" +hyphen=0 +silent=0 + +prg=$(basename $0) + +# handle being called 'zegrep' or 'zfgrep' +case ${prg} in + *zegrep) + grep_args="-E";; + *zfgrep) + grep_args="-F";; +esac + +# skip all options and pass them on to grep taking care of options +# with arguments, and if -e was supplied + +while [ $# -gt 0 -a ${endofopts} -eq 0 ] +do + case $1 in + # from GNU grep-2.5.1 -- keep in sync! + -[ABCDXdefm]) + if [ $# -lt 2 ] + then + echo "${prg}: missing argument for $1 flag" >&2 + exit 1 + fi + case $1 in + -e) + pattern="$2" + pattern_found=1 + shift 2 + break + ;; + *) + ;; + esac + grep_args="${grep_args} $1 $2" + shift 2 + ;; + --) + shift + endofopts=1 + ;; + -) + hyphen=1 + shift + ;; + -h) + silent=1 + shift + ;; + -*) + grep_args="${grep_args} $1" + shift + ;; + *) + # pattern to grep for + endofopts=1 + ;; + esac +done + +# if no -e option was found, take next argument as grep-pattern +if [ ${pattern_found} -lt 1 ] +then + if [ $# -ge 1 ]; then + pattern="$1" + shift + elif [ ${hyphen} -gt 0 ]; then + pattern="-" + else + echo "${prg}: missing pattern" >&2 + exit 1 + fi +fi + +# call grep ... +if [ $# -lt 1 ] +then + # ... on stdin + ${zcat} -fq - | ${grep} ${grep_args} -- "${pattern}" - +else + # ... on all files given on the command line + if [ ${silent} -lt 1 -a $# -gt 1 ]; then + grep_args="-H ${grep_args}" + fi + while [ $# -gt 0 ] + do + ${zcat} -fq -- "$1" | ${grep} --label="${1}" ${grep_args} -- "${pattern}" - + shift + done +fi + +exit 0 From 9ffbeea87507215a8c6846f179325ecb4662b5d6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 2 Dec 2016 18:37:38 -0800 Subject: [PATCH 128/185] API : changed : streaming decompression : implicit reset on starting new frames --- NEWS | 3 ++- lib/decompress/zstd_decompress.c | 3 ++- lib/zstd.h | 4 ++-- tests/zstreamtest.c | 19 +++++++++++++++---- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 69b24e635..580889542 100644 --- a/NEWS +++ b/NEWS @@ -2,10 +2,11 @@ v1.1.2 Improved : faster decompression speed at ultra compression settings and in 32-bits mode cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski cli : new : preserve file attributes -cli : new : added zstdless +cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat API : changed : zbuff prototypes now generate deprecation warnings +API : changed : streaming decompression implicit reset on starting new frame Changed : reduced stack memory use v1.1.1 diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 3106fa014..7c4f54bd3 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1959,7 +1959,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB switch(zds->stage) { case zdss_init : - return ERROR(init_missing); + ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ + /* fall-through */ case zdss_loadHeader : { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); diff --git a/lib/zstd.h b/lib/zstd.h index 607612026..b7a8bb989 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -299,8 +299,8 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output * If `output.pos < output.size`, decoder has flushed everything it could. * @return : 0 when a frame is completely decoded and fully flushed, * an error code, which can be tested using ZSTD_isError(), -* any other value > 0, which means there is still some work to do to complete the frame. -* The return value is a suggested next input size (just an hint, to help latency). +* any other value > 0, which means there is still some decoding to do to complete current frame. +* The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame. * *******************************************************************************/ /*===== Streaming decompression functions =====*/ diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index aa119e636..c21b9de9b 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -130,7 +130,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo U32 testNb=0; ZSTD_CStream* zc = ZSTD_createCStream_advanced(customMem); ZSTD_DStream* zd = ZSTD_createDStream_advanced(customMem); - ZSTD_inBuffer inBuff; + ZSTD_inBuffer inBuff, inBuff2; ZSTD_outBuffer outBuff; /* Create compressible test buffer */ @@ -183,12 +183,22 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo DISPLAYLEVEL(4, "OK \n"); /* Basic decompression test */ + inBuff2 = inBuff; DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH); ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB); { size_t const r = ZSTD_setDStreamParameter(zd, ZSTDdsp_maxWindowSize, 1000000000); /* large limit */ if (ZSTD_isError(r)) goto _output_error; } - { size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff); - if (r != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */ + { size_t const remaining = ZSTD_decompressStream(zd, &outBuff, &inBuff); + if (remaining != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */ + if (outBuff.pos != CNBufferSize) goto _output_error; /* should regenerate the same amount */ + if (inBuff.pos != inBuff.size) goto _output_error; /* should have read the entire frame */ + DISPLAYLEVEL(4, "OK \n"); + + /* Re-use without init */ + DISPLAYLEVEL(4, "test%3i : decompress again without init (re-use previous settings): ", testNb++); + outBuff.pos = 0; + { size_t const remaining = ZSTD_decompressStream(zd, &outBuff, &inBuff2); + if (remaining != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */ if (outBuff.pos != CNBufferSize) goto _output_error; /* should regenerate the same amount */ if (inBuff.pos != inBuff.size) goto _output_error; /* should have read the entire frame */ DISPLAYLEVEL(4, "OK \n"); @@ -553,8 +563,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres /* multi - fragments decompression test */ if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) { CHECK (ZSTD_isError(ZSTD_resetDStream(zd)), "ZSTD_resetDStream failed"); - } else + } else { ZSTD_initDStream_usingDict(zd, dict, dictSize); + } { size_t decompressionResult = 1; ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 }; ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 }; From 8489f184f61232f0f57abb4eaf28a92046dd7592 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 5 Dec 2016 13:47:00 +0100 Subject: [PATCH 129/185] improved detection of -lz --- programs/Makefile | 7 ++----- programs/fileio.c | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index 44eafbf63..393944920 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -125,11 +125,8 @@ zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) gzstd: clean_decomp_o -ifeq ($(shell ld -lz 2>/dev/null && echo -n true),true) - CPPFLAGS=-DZSTD_GZDECOMPRESS LDFLAGS="-lz" $(MAKE) zstd -else - $(MAKE) zstd -endif + echo "int main(){}" | $(CC) -o have_zlib -x c - -lz && echo found zlib || echo did not found zlib + if [ -s have_zlib ]; then echo building gzstd && rm have_zlib$(EXT) && CPPFLAGS=-DZSTD_GZDECOMPRESS LDFLAGS="-lz" $(MAKE) zstd; else echo building plain zstd && $(MAKE) zstd; fi generate_res: windres\generate_res.bat diff --git a/programs/fileio.c b/programs/fileio.c index dff4eae05..28c3d1206 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -726,6 +726,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + printf("buf[0]=%d buf[1]=%d toRead=%d\n", buf[0], buf[1], (int)toRead); if (buf[0] == 31 && buf[1] == 139) { /* gz header */ #ifdef ZSTD_GZDECOMPRESS unsigned long long const result = FIO_decompressGzFrame(ress, srcFile, srcFileName, toRead); @@ -841,7 +842,7 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles } if (sfnSize <= suffixSize || strcmp(suffixPtr, suffix) != 0) { if (sfnSize <= gzipSuffixSize || strcmp(gzipSuffixPtr, GZ_EXTENSION) != 0) { - DISPLAYLEVEL(1, "zstd: %s: unknown suffix (%4s expected) -- ignored \n", srcFileName, suffix); + DISPLAYLEVEL(1, "zstd: %s: unknown suffix (%s/%s expected) -- ignored \n", srcFileName, suffix, GZ_EXTENSION); skippedFiles++; continue; } else { From 3c69760275bc896c38adbbe1be9118dc5514b10e Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 5 Dec 2016 15:58:23 +0100 Subject: [PATCH 130/185] improved FIO_decompressGzFrame --- programs/fileio.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 28c3d1206..8c54e3c5e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -652,7 +652,6 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ #ifdef ZSTD_GZDECOMPRESS static unsigned long long FIO_decompressGzFrame(dRess_t ress, FILE* srcFile, const char* srcFileName, size_t alreadyLoaded) { - unsigned char* headBuf = (unsigned char*)ress.srcBuffer; unsigned long long outFileSize = 0; z_stream strm; @@ -667,15 +666,15 @@ static unsigned long long FIO_decompressGzFrame(dRess_t ress, FILE* srcFile, con strm.avail_out = ress.dstBufferSize; for ( ; ; ) { - unsigned char in[1]; if (alreadyLoaded) { - alreadyLoaded--; - in[0] = *headBuf++; + strm.avail_in = alreadyLoaded; + strm.next_in = (z_const unsigned char*)ress.srcBuffer; + alreadyLoaded = 0; } else { - if (fread(in, 1, 1, srcFile) == 0) break; + if (fread(ress.srcBuffer, 1, 1/*ress.srcBufferSize*/, srcFile) == 0) break; + strm.next_in = (z_const unsigned char*)ress.srcBuffer; + strm.avail_in = 1; } - strm.next_in = in; - strm.avail_in = 1; { int const ret = inflate(&strm, Z_NO_FLUSH); if (ret == Z_STREAM_END) break; if (ret != Z_OK) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; } @@ -726,11 +725,11 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - printf("buf[0]=%d buf[1]=%d toRead=%d\n", buf[0], buf[1], (int)toRead); if (buf[0] == 31 && buf[1] == 139) { /* gz header */ #ifdef ZSTD_GZDECOMPRESS unsigned long long const result = FIO_decompressGzFrame(ress, srcFile, srcFileName, toRead); if (result == 0) return 1; + printf("gzip=%d\n", (int)result); filesize += result; #else DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); @@ -740,6 +739,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ unsigned const result = FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + printf("pass-through=%d\n", (int)result); if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ return result; } else { @@ -748,6 +748,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch return 1; } } filesize += FIO_decompressFrame(ress, srcFile, toRead, filesize); + printf("zstd filesize=%d\n", (int)filesize); } } From b493e3b3d3d7c6c5f123fbfe6d5459e95ca8bddb Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 5 Dec 2016 17:39:38 +0100 Subject: [PATCH 131/185] introduced srcBufferLoaded --- programs/fileio.c | 156 ++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 8c54e3c5e..743a5ec5f 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -465,6 +465,7 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile ****************************************************************************/ typedef struct { void* srcBuffer; + size_t srcBufferLoaded; size_t srcBufferSize; void* dstBuffer; size_t dstBufferSize; @@ -582,51 +583,6 @@ static void FIO_fwriteSparseEnd(FILE* file, unsigned storedSkips) } } } -/** FIO_decompressFrame() : - @return : size of decoded frame -*/ -unsigned long long FIO_decompressFrame(dRess_t ress, - FILE* finput, size_t alreadyLoaded, - U64 alreadyDecoded) -{ - U64 frameSize = 0; - size_t readSize; - U32 storedSkips = 0; - - ZSTD_resetDStream(ress.dctx); - - /* Header loading (optional, saves one loop) */ - { size_t const toLoad = 9 - alreadyLoaded; /* assumption : 9 >= alreadyLoaded */ - size_t const loadedSize = fread(((char*)ress.srcBuffer) + alreadyLoaded, 1, toLoad, finput); - readSize = alreadyLoaded + loadedSize; - } - - /* Main decompression Loop */ - while (1) { - ZSTD_inBuffer inBuff = { ress.srcBuffer, readSize, 0 }; - ZSTD_outBuffer outBuff= { ress.dstBuffer, ress.dstBufferSize, 0 }; - size_t const readSizeHint = ZSTD_decompressStream(ress.dctx, &outBuff, &inBuff ); - if (ZSTD_isError(readSizeHint)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(readSizeHint)); - - /* Write block */ - storedSkips = FIO_fwriteSparse(ress.dstFile, ress.dstBuffer, outBuff.pos, storedSkips); - frameSize += outBuff.pos; - DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)((alreadyDecoded+frameSize)>>20) ); - - if (readSizeHint == 0) break; /* end of frame */ - if (inBuff.size != inBuff.pos) EXM_THROW(37, "Decoding error : should consume entire input"); - - /* Fill input buffer */ - { size_t const toRead = MIN(readSizeHint, ress.srcBufferSize); /* support large skippable frames */ - readSize = fread(ress.srcBuffer, 1, toRead, finput); - if (readSize < toRead) EXM_THROW(39, "Read error : premature end"); - } } - - FIO_fwriteSparseEnd(ress.dstFile, storedSkips); - - return frameSize; -} - /** FIO_passThrough() : just copy input into output, for compatibility with gzip -df mode @return : 0 (no error) */ @@ -649,8 +605,60 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ return 0; } + +/** FIO_decompressFrame() : + @return : size of decoded frame +*/ +unsigned long long FIO_decompressFrame(dRess_t* ress, + FILE* finput, + U64 alreadyDecoded) +{ + U64 frameSize = 0; + U32 storedSkips = 0; + + ZSTD_resetDStream(ress->dctx); + + /* Header loading (optional, saves one loop) */ + { size_t const toRead = 9; + if (ress->srcBufferLoaded < toRead) + ress->srcBufferLoaded += fread(((char*)ress->srcBuffer) + ress->srcBufferLoaded, 1, toRead - ress->srcBufferLoaded, finput); + } + + /* Main decompression Loop */ + while (1) { + ZSTD_inBuffer inBuff = { ress->srcBuffer, ress->srcBufferLoaded, 0 }; + ZSTD_outBuffer outBuff= { ress->dstBuffer, ress->dstBufferSize, 0 }; + size_t const readSizeHint = ZSTD_decompressStream(ress->dctx, &outBuff, &inBuff); + if (ZSTD_isError(readSizeHint)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(readSizeHint)); + + /* Write block */ + storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, storedSkips); + frameSize += outBuff.pos; + DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)((alreadyDecoded+frameSize)>>20) ); + + if (inBuff.pos > 0) { + memmove(ress->srcBuffer, (char*)ress->srcBuffer + inBuff.pos, inBuff.size - inBuff.pos); + ress->srcBufferLoaded -= inBuff.pos; + } + + if (readSizeHint == 0) break; /* end of frame */ + if (inBuff.size != inBuff.pos) EXM_THROW(37, "Decoding error : should consume entire input"); + + /* Fill input buffer */ + { size_t const toRead = MIN(readSizeHint, ress->srcBufferSize); /* support large skippable frames */ + if (ress->srcBufferLoaded < toRead) + ress->srcBufferLoaded += fread(((char*)ress->srcBuffer) + ress->srcBufferLoaded, 1, toRead - ress->srcBufferLoaded, finput); + if (ress->srcBufferLoaded < toRead) EXM_THROW(39, "Read error : premature end"); + } } + + FIO_fwriteSparseEnd(ress->dstFile, storedSkips); + + return frameSize; +} + + #ifdef ZSTD_GZDECOMPRESS -static unsigned long long FIO_decompressGzFrame(dRess_t ress, FILE* srcFile, const char* srcFileName, size_t alreadyLoaded) +static unsigned long long FIO_decompressGzFrame(dRess_t* ress, FILE* srcFile, const char* srcFileName) { unsigned long long outFileSize = 0; z_stream strm; @@ -662,32 +670,34 @@ static unsigned long long FIO_decompressGzFrame(dRess_t ress, FILE* srcFile, con strm.avail_in = Z_NULL; if (inflateInit2(&strm, 15 /* maxWindowLogSize */ + 16 /* gzip only */) != Z_OK) return 0; /* see http://www.zlib.net/manual.html */ - strm.next_out = ress.dstBuffer; - strm.avail_out = ress.dstBufferSize; + strm.next_out = ress->dstBuffer; + strm.avail_out = ress->dstBufferSize; + strm.avail_in = ress->srcBufferLoaded; + strm.next_in = (z_const unsigned char*)ress->srcBuffer; for ( ; ; ) { - if (alreadyLoaded) { - strm.avail_in = alreadyLoaded; - strm.next_in = (z_const unsigned char*)ress.srcBuffer; - alreadyLoaded = 0; - } else { - if (fread(ress.srcBuffer, 1, 1/*ress.srcBufferSize*/, srcFile) == 0) break; - strm.next_in = (z_const unsigned char*)ress.srcBuffer; - strm.avail_in = 1; + int ret; + if (strm.avail_in == 0) { + ress->srcBufferLoaded = fread(ress->srcBuffer, 1, ress->srcBufferSize, srcFile); + if (ress->srcBufferLoaded == 0) break; + strm.next_in = (z_const unsigned char*)ress->srcBuffer; + strm.avail_in = ress->srcBufferLoaded; } - { int const ret = inflate(&strm, Z_NO_FLUSH); - if (ret == Z_STREAM_END) break; - if (ret != Z_OK) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; } - } - - { size_t const decompBytes = ress.dstBufferSize - strm.avail_out; + ret = inflate(&strm, Z_NO_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; } + { size_t const decompBytes = ress->dstBufferSize - strm.avail_out; if (decompBytes) { - if (fwrite(ress.dstBuffer, 1, decompBytes, ress.dstFile) != decompBytes) EXM_THROW(31, "Write error : cannot write to output file"); + if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) EXM_THROW(31, "Write error : cannot write to output file"); outFileSize += decompBytes; - strm.next_out = ress.dstBuffer; - strm.avail_out = ress.dstBufferSize; - } } } + strm.next_out = ress->dstBuffer; + strm.avail_out = ress->dstBufferSize; + } + } + if (ret == Z_STREAM_END) break; + } + if (strm.avail_in > 0) memmove(ress->srcBuffer, strm.next_in, strm.avail_in); + ress->srcBufferLoaded = strm.avail_in; inflateEnd(&strm); return outFileSize; } @@ -717,19 +727,19 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch for ( ; ; ) { /* check magic number -> version */ size_t const toRead = 4; - size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile); const BYTE* buf = (const BYTE*)ress.srcBuffer; - if (sizeCheck==0) { + if (ress.srcBufferLoaded < toRead) + ress.srcBufferLoaded += fread((char*)ress.srcBuffer + ress.srcBufferLoaded, (size_t)1, toRead - ress.srcBufferLoaded, srcFile); + if (ress.srcBufferLoaded==0) { if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ break; /* no more input */ } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ - if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + if (ress.srcBufferLoaded < toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ if (buf[0] == 31 && buf[1] == 139) { /* gz header */ #ifdef ZSTD_GZDECOMPRESS - unsigned long long const result = FIO_decompressGzFrame(ress, srcFile, srcFileName, toRead); + unsigned long long const result = FIO_decompressGzFrame(&ress, srcFile, srcFileName); if (result == 0) return 1; - printf("gzip=%d\n", (int)result); filesize += result; #else DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); @@ -739,7 +749,6 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ unsigned const result = FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - printf("pass-through=%d\n", (int)result); if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ return result; } else { @@ -747,8 +756,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch fclose(srcFile); return 1; } } - filesize += FIO_decompressFrame(ress, srcFile, toRead, filesize); - printf("zstd filesize=%d\n", (int)filesize); + filesize += FIO_decompressFrame(&ress, srcFile, filesize); } } From 6b508b177090f2a830199b68735aa02f59a272e0 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 5 Dec 2016 18:02:40 +0100 Subject: [PATCH 132/185] updated test-gzstd --- programs/fileio.c | 5 ++++- tests/Makefile | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 743a5ec5f..f860145b4 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -35,6 +35,9 @@ #include "zstd.h" #ifdef ZSTD_GZDECOMPRESS #include "zlib.h" +#if !defined(z_const) + #define z_const +#endif #endif @@ -632,7 +635,7 @@ unsigned long long FIO_decompressFrame(dRess_t* ress, if (ZSTD_isError(readSizeHint)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(readSizeHint)); /* Write block */ - storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, storedSkips); + storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, storedSkips); frameSize += outBuff.pos; DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)((alreadyDecoded+frameSize)>>20) ); diff --git a/tests/Makefile b/tests/Makefile index ca899d2f8..ad367595a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -194,9 +194,14 @@ test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd test-zstd-nolegacy: zstd-nolegacy zstd-playTests test-gzstd: gzstd + $(PRGDIR)/zstd README.md test-zstd-speed.py gzip README.md test-zstd-speed.py + cat README.md.zst test-zstd-speed.py.gz >zstd_gz.zst + cat README.md.gz test-zstd-speed.py.zst >gz_zstd.gz $(PRGDIR)/zstd -d README.md.gz -o README2.md $(PRGDIR)/zstd -d README.md.gz test-zstd-speed.py.gz + $(PRGDIR)/zstd -d zstd_gz.zst gz_zstd.gz + diff -q zstd_gz gz_zstd test-fullbench: fullbench datagen $(QEMU_SYS) ./fullbench -i1 From 7c6bbc3298e2d3b9db62962d39b35d5e179508f9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 5 Dec 2016 18:31:14 +0100 Subject: [PATCH 133/185] updated FIO_passThrough --- programs/fileio.c | 10 +++++----- tests/Makefile | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index f860145b4..a493e97c5 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -589,15 +589,15 @@ static void FIO_fwriteSparseEnd(FILE* file, unsigned storedSkips) /** FIO_passThrough() : just copy input into output, for compatibility with gzip -df mode @return : 0 (no error) */ -static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_t bufferSize) +static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_t bufferSize, size_t alreadyLoaded) { size_t const blockSize = MIN(64 KB, bufferSize); size_t readFromInput = 1; unsigned storedSkips = 0; - /* assumption : first 4 bytes already loaded (magic number detection), and stored within buffer */ - { size_t const sizeCheck = fwrite(buffer, 1, 4, foutput); - if (sizeCheck != 4) EXM_THROW(50, "Pass-through write error"); } + /* assumption : ress->srcBufferLoaded bytes already loaded and stored within buffer */ + { size_t const sizeCheck = fwrite(buffer, 1, alreadyLoaded, foutput); + if (sizeCheck != alreadyLoaded) EXM_THROW(50, "Pass-through write error"); } while (readFromInput) { readFromInput = fread(buffer, 1, blockSize, finput); @@ -751,7 +751,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch } else { if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + unsigned const result = FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize, ress.srcBufferLoaded); if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ return result; } else { diff --git a/tests/Makefile b/tests/Makefile index ad367595a..50bb057dc 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -202,6 +202,12 @@ test-gzstd: gzstd $(PRGDIR)/zstd -d README.md.gz test-zstd-speed.py.gz $(PRGDIR)/zstd -d zstd_gz.zst gz_zstd.gz diff -q zstd_gz gz_zstd + echo Hello World ZSTD | $(PRGDIR)/zstd -c - >hello.zst + echo Hello World GZIP | gzip -c - >hello.gz + echo Hello World TEXT >hello.txt + cat hello.zst hello.gz hello.txt >hello_zst_gz_txt.gz + $(PRGDIR)/zstd -dcf hello.* + $(PRGDIR)/zstd -dcf - Date: Mon, 5 Dec 2016 16:21:06 -0800 Subject: [PATCH 134/185] added : dictID retrieval functions. added : unit tests for dictID retrieval functions --- NEWS | 2 ++ lib/decompress/zstd_decompress.c | 39 ++++++++++++++++++++++++++++++++ lib/zstd.h | 24 ++++++++++++++++++++ tests/fuzzer.c | 14 +++++++++++- 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 580889542..127d1ac8f 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ cli : fixed : status displays total amount decoded, even for file consisting of cli : fixed : zstdcat API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame +API : added experimental : dictID retrieval functions +zlib_wrapper : added support for gz* functions, by Przemyslaw Skibinski Changed : reduced stack memory use v1.1.1 diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 7c4f54bd3..1b235ed6d 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1778,6 +1778,45 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) return sizeof(*ddict) + sizeof(ddict->refContext) + ddict->dictSize; } +/*! ZSTD_getDictID_fromDict() : + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) +{ + if (dictSize < 8) return 0; + if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0; + return MEM_readLE32((const char*)dict + 4); +} + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; + return ZSTD_getDictID_fromDict(ddict->dict, ddict->dictSize); +} + +/*! ZSTD_getDictID_fromFrame() : + * Provides the dictID required to decompressed the frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary to be decoded (most common case). + * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */ +unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize) +{ + ZSTD_frameParams zfp; + size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize); + if (ZSTD_isError(hError)) return 0; + return zfp.dictID; +} + /*! ZSTD_decompress_usingDDict() : * Decompression using a pre-digested Dictionary diff --git a/lib/zstd.h b/lib/zstd.h index b7a8bb989..a1b0e62bc 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -462,6 +462,30 @@ ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx); * Gives the amount of memory used by a given ZSTD_DDict */ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); +/*! ZSTD_getDictID_fromDict() : + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize); + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict); + +/*! ZSTD_getDictID_fromFrame() : + * Provides the dictID required to decompressed the frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary to be decoded (most common case). + * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */ +unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); + /******************************************************************** * Advanced streaming functions diff --git a/tests/fuzzer.c b/tests/fuzzer.c index f8110498d..1c1ae470a 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -27,7 +27,7 @@ #include /* clock_t */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressContinue, ZSTD_compressBlock */ #include "zstd.h" /* ZSTD_VERSION_STRING */ -#include "zstd_errors.h" /* ZSTD_getErrorCode */ +#include "zstd_errors.h" /* ZSTD_getErrorCode */ #include "zdict.h" /* ZDICT_trainFromBuffer */ #include "datagen.h" /* RDG_genBuffer */ #include "mem.h" @@ -273,6 +273,18 @@ static int basicUnitTests(U32 seed, double compressibility) if (ZSTD_isError(cSize)) goto _output_error; DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(4, "test%3i : retrieve dictID from dictionary : ", testNb++); + { U32 const dictID = ZSTD_getDictID_fromDict(dictBuffer, dictSize); + if (dictID != 0) goto _output_error; /* non-conformant (content-only) dictionary */ + } + DISPLAYLEVEL(4, "OK \n"); + + DISPLAYLEVEL(4, "test%3i : retrieve dictID from frame : ", testNb++); + { U32 const dictID = ZSTD_getDictID_fromFrame(compressedBuffer, cSize); + if (dictID != 0) goto _output_error; /* non-conformant (content-only) dictionary */ + } + DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(4, "test%3i : frame built with dictionary should be decompressible : ", testNb++); CHECKPLUS(r, ZSTD_decompress_usingDict(dctx, decodedBuffer, CNBuffSize, From 8f8e2b0b4a310e039f875d7ad014593249081567 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 5 Dec 2016 18:00:50 -0800 Subject: [PATCH 135/185] fixed initialization warning --- lib/decompress/zstd_decompress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 1b235ed6d..70dd4ccaa 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1811,7 +1811,7 @@ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */ unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize) { - ZSTD_frameParams zfp; + ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 }; size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize); if (ZSTD_isError(hError)) return 0; return zfp.dictID; From 825dffbc4316728dd0acaa399d9845f2a1384daa Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 5 Dec 2016 19:28:19 -0800 Subject: [PATCH 136/185] moved zbuff source files into lib/deprecated --- NEWS | 1 + build/cmake/lib/CMakeLists.txt | 12 +++---- build/cmake/tests/CMakeLists.txt | 3 -- lib/Makefile | 26 +++++++------- lib/README.md | 8 ++--- lib/common/zstd_common.c | 8 +---- lib/{common => deprecated}/zbuff.h | 1 + lib/{compress => deprecated}/zbuff_compress.c | 0 .../zbuff_decompress.c | 0 lib/zstd.h | 3 +- tests/Makefile | 34 ++++++++++--------- 11 files changed, 44 insertions(+), 52 deletions(-) rename lib/{common => deprecated}/zbuff.h (99%) rename lib/{compress => deprecated}/zbuff_compress.c (100%) rename lib/{decompress => deprecated}/zbuff_decompress.c (100%) diff --git a/NEWS b/NEWS index 127d1ac8f..36aa45e91 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame API : added experimental : dictID retrieval functions zlib_wrapper : added support for gz* functions, by Przemyslaw Skibinski +Changed : zbuff source files moved to lib/deprecated Changed : reduced stack memory use v1.1.1 diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt index f970fe7e9..02cfb96bb 100644 --- a/build/cmake/lib/CMakeLists.txt +++ b/build/cmake/lib/CMakeLists.txt @@ -64,25 +64,25 @@ SET(Sources ${LIBRARY_DIR}/common/fse_decompress.c ${LIBRARY_DIR}/compress/fse_compress.c ${LIBRARY_DIR}/compress/huf_compress.c - ${LIBRARY_DIR}/compress/zbuff_compress.c ${LIBRARY_DIR}/compress/zstd_compress.c ${LIBRARY_DIR}/decompress/huf_decompress.c - ${LIBRARY_DIR}/decompress/zbuff_decompress.c ${LIBRARY_DIR}/decompress/zstd_decompress.c ${LIBRARY_DIR}/dictBuilder/divsufsort.c - ${LIBRARY_DIR}/dictBuilder/zdict.c) + ${LIBRARY_DIR}/dictBuilder/zdict.c + ${LIBRARY_DIR}/deprecated/zbuff_compress.c + ${LIBRARY_DIR}/deprecated/zbuff_decompress.c) SET(Headers + ${LIBRARY_DIR}/zstd.h ${LIBRARY_DIR}/common/bitstream.h ${LIBRARY_DIR}/common/error_private.h ${LIBRARY_DIR}/common/zstd_errors.h ${LIBRARY_DIR}/common/fse.h ${LIBRARY_DIR}/common/huf.h ${LIBRARY_DIR}/common/mem.h - ${LIBRARY_DIR}/common/zbuff.h ${LIBRARY_DIR}/common/zstd_internal.h - ${LIBRARY_DIR}/zstd.h - ${LIBRARY_DIR}/dictBuilder/zdict.h) + ${LIBRARY_DIR}/dictBuilder/zdict.h + ${LIBRARY_DIR}/deprecated/zbuff.h) IF (ZSTD_LEGACY_SUPPORT) SET(LIBRARY_LEGACY_DIR ${LIBRARY_DIR}/legacy) diff --git a/build/cmake/tests/CMakeLists.txt b/build/cmake/tests/CMakeLists.txt index f5ece894e..7f9c38e1a 100644 --- a/build/cmake/tests/CMakeLists.txt +++ b/build/cmake/tests/CMakeLists.txt @@ -50,9 +50,6 @@ ADD_EXECUTABLE(fuzzer ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/fuzzer.c) TARGET_LINK_LIBRARIES(fuzzer libzstd_static) IF (UNIX) - ADD_EXECUTABLE(zbufftest ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/zbufftest.c) - TARGET_LINK_LIBRARIES(zbufftest libzstd_static) - ADD_EXECUTABLE(paramgrill ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/paramgrill.c) TARGET_LINK_LIBRARIES(paramgrill libzstd_static m) #m is math library diff --git a/lib/Makefile b/lib/Makefile index 8f316aa68..bf1088d68 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -23,24 +23,22 @@ PREFIX ?= /usr/local LIBDIR ?= $(PREFIX)/lib INCLUDEDIR=$(PREFIX)/include -CPPFLAGS= -I. -I./common -DXXH_NAMESPACE=XXH_ -CFLAGS ?= -O3 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ - -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \ - -Wpointer-arith -FLAGS = $(CPPFLAGS) $(CFLAGS) $(MOREFLAGS) +CPPFLAGS+= -I. -I./common -DXXH_NAMESPACE=ZSTD_ +CFLAGS ?= -O3 +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \ + -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \ + -Wpointer-arith +CFLAGS += $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) -ZSTD_FILES := $(wildcard common/*.c compress/*.c decompress/*.c dictBuilder/*.c) -ZSTD_EXCLUDE := compress/zbuff_compress.c decompress/zbuff_decompress.c -ZSTD_FILES := $(filter-out $(ZSTD_EXCLUDE), $(ZSTD_FILES)) - +ZSTD_FILES := $(wildcard common/*.c compress/*.c decompress/*.c dictBuilder/*.c deprecated/*.c) ifeq ($(ZSTD_LEGACY_SUPPORT), 0) CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0 else -ZSTD_FILES+= legacy/*.c CPPFLAGS += -I./legacy -DZSTD_LEGACY_SUPPORT=1 +ZSTD_FILES+= $(wildcard legacy/*.c) endif # OS X linker doesn't support -soname, and use different extension @@ -90,8 +88,8 @@ libzstd : $(LIBZSTD) lib: libzstd.a libzstd clean: - @$(RM) -f core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc dll/libzstd.dll dll/libzstd.lib - @$(RM) -f decompress/*.o + @$(RM) core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc dll/libzstd.dll dll/libzstd.lib + @$(RM) decompress/*.o @echo Cleaning library completed #------------------------------------------------------------------------ @@ -116,7 +114,7 @@ install: libzstd.a libzstd libzstd.pc @install -m 644 libzstd.a $(DESTDIR)$(LIBDIR)/libzstd.a @install -m 644 zstd.h $(DESTDIR)$(INCLUDEDIR)/zstd.h @install -m 644 common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h - @install -m 644 common/zbuff.h $(DESTDIR)$(INCLUDEDIR)/zbuff.h + @install -m 644 deprecated/zbuff.h $(DESTDIR)$(INCLUDEDIR)/zbuff.h # prototypes generate deprecation warnings @install -m 644 dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)/zdict.h @echo zstd static and shared library installed diff --git a/lib/README.md b/lib/README.md index d33ad52c2..3357e3d87 100644 --- a/lib/README.md +++ b/lib/README.md @@ -56,15 +56,15 @@ file it should be linked with `dll\libzstd.dll`. For example: ``` gcc $(CFLAGS) -Iinclude/ test-dll.c -o test-dll dll\libzstd.dll ``` -The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. +The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. #### Obsolete streaming API Streaming is now provided within `zstd.h`. -Older streaming API is still available within `common/zbuff.h`. -It is now deprecated, and will be removed in a future version. -Consider migrating towards newer streaming API in `zstd.h`. +Older streaming API is still available within `deprecated/zbuff.h`. +It will be removed in a future version. +Consider migrating code towards newer streaming API in `zstd.h`. #### Miscellaneous diff --git a/lib/common/zstd_common.c b/lib/common/zstd_common.c index 54bc91c89..f30128c79 100644 --- a/lib/common/zstd_common.c +++ b/lib/common/zstd_common.c @@ -16,7 +16,6 @@ #include "error_private.h" #define ZSTD_STATIC_LINKING_ONLY #include "zstd.h" /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */ -#include "zbuff.h" /* declaration of ZBUFF_isError, ZBUFF_getErrorName */ /*-**************************************** @@ -44,16 +43,11 @@ ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } * provides error code string from enum */ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorName(code); } - -/* ************************************************************** -* ZBUFF Error Management -****************************************************************/ +/* --- ZBUFF Error Management (deprecated) --- */ unsigned ZBUFF_isError(size_t errorCode) { return ERR_isError(errorCode); } - const char* ZBUFF_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); } - /*=************************************************************** * Custom allocator ****************************************************************/ diff --git a/lib/common/zbuff.h b/lib/deprecated/zbuff.h similarity index 99% rename from lib/common/zbuff.h rename to lib/deprecated/zbuff.h index e8af504de..8e55c39a5 100644 --- a/lib/common/zbuff.h +++ b/lib/deprecated/zbuff.h @@ -202,6 +202,7 @@ ZBUFF_DEPRECATED("use ZSTD_initDStream_usingDict") size_t ZBUFF_compressInit_adv const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); + #endif /* ZBUFF_STATIC_LINKING_ONLY */ diff --git a/lib/compress/zbuff_compress.c b/lib/deprecated/zbuff_compress.c similarity index 100% rename from lib/compress/zbuff_compress.c rename to lib/deprecated/zbuff_compress.c diff --git a/lib/decompress/zbuff_decompress.c b/lib/deprecated/zbuff_decompress.c similarity index 100% rename from lib/decompress/zbuff_decompress.c rename to lib/deprecated/zbuff_decompress.c diff --git a/lib/zstd.h b/lib/zstd.h index a1b0e62bc..a10a9eaab 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -53,8 +53,6 @@ extern "C" { *********************************************************************************************************/ /*------ Version ------*/ -ZSTDLIB_API unsigned ZSTD_versionNumber (void); /**< returns version number of ZSTD */ - #define ZSTD_VERSION_MAJOR 1 #define ZSTD_VERSION_MINOR 1 #define ZSTD_VERSION_RELEASE 2 @@ -65,6 +63,7 @@ ZSTDLIB_API unsigned ZSTD_versionNumber (void); /**< returns version number of #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) +ZSTDLIB_API unsigned ZSTD_versionNumber (void); /*************************************** diff --git a/tests/Makefile b/tests/Makefile index 50bb057dc..fbee21448 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -37,10 +37,10 @@ FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c -ZSTDCOMP_FILES := $(ZSTDDIR)/compress/zstd_compress.c $(ZSTDDIR)/compress/fse_compress.c $(ZSTDDIR)/compress/huf_compress.c -ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/zstd_decompress.c $(ZSTDDIR)/decompress/huf_decompress.c +ZSTDCOMP_FILES := $(ZSTDDIR)/compress/*.c +ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/*.c ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) -ZBUFF_FILES := $(ZSTDDIR)/compress/zbuff_compress.c $(ZSTDDIR)/decompress/zbuff_decompress.c +ZBUFF_FILES := $(ZSTDDIR)/deprecated/*.c ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c @@ -53,7 +53,7 @@ EXT = endif VOID = /dev/null -ZBUFFTEST = -T2mn +ZSTREAM_TESTTIME = -T2mn FUZZERTEST= -T5mn ZSTDRTTEST= --test-large-data @@ -61,9 +61,9 @@ ZSTDRTTEST= --test-large-data default: fullbench -all: fullbench fuzzer zstreamtest paramgrill datagen +all: fullbench fuzzer zstreamtest paramgrill datagen zbufftest -all32: fullbench32 fuzzer32 zstreamtest32 +all32: fullbench32 fuzzer32 zstreamtest32 zbufftest32 @@ -93,19 +93,21 @@ fullbench-dll: $(PRGDIR)/datagen.c fullbench.c $(MAKE) -C $(ZSTDDIR) libzstd $(CC) $(FLAGS) $^ -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll -fuzzer : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder fuzzer : $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c $(CC) $(FLAGS) $^ -o $@$(EXT) -fuzzer32 : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder fuzzer32 : $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c $(CC) -m32 $(FLAGS) $^ -o $@$(EXT) -zbufftest : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c - $(CC) $(FLAGS) $^ -o $@$(EXT) +zbufftest : CPPFLAGS += -I$(ZSTDDIR)/deprecated +zbufftest : CFLAGS += -Wno-deprecated-declarations +zbufftest : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c + $(CC) $(FLAGS) $^ -o $@$(EXT) # flag required to silence deprecation warnings -zbufftest32 : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c - $(CC) -m32 $(FLAGS) $^ -o $@$(EXT) +zbufftest32 : CPPFLAGS += -I$(ZSTDDIR)/deprecated +zbufftest32 : CFLAGS += -Wno-deprecated-declarations -m32 +zbufftest32 : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c + $(CC) $(FLAGS) $^ -o $@$(EXT) zstreamtest : $(ZSTD_FILES) $(PRGDIR)/datagen.c zstreamtest.c $(CC) $(FLAGS) $^ -o $@$(EXT) @@ -224,15 +226,15 @@ test-fuzzer32: fuzzer32 $(QEMU_SYS) ./fuzzer32 $(FUZZERTEST) test-zbuff: zbufftest - $(QEMU_SYS) ./zbufftest $(ZBUFFTEST) + $(QEMU_SYS) ./zbufftest $(ZSTREAM_TESTTIME) test-zbuff32: zbufftest32 - $(QEMU_SYS) ./zbufftest32 $(ZBUFFTEST) + $(QEMU_SYS) ./zbufftest32 $(ZSTREAM_TESTTIME) test-zstream: zstreamtest - $(QEMU_SYS) ./zstreamtest $(ZBUFFTEST) + $(QEMU_SYS) ./zstreamtest $(ZSTREAM_TESTTIME) test-zstream32: zstreamtest32 - $(QEMU_SYS) ./zstreamtest32 $(ZBUFFTEST) + $(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) endif From f586bdfe230395ff3a1731acff17fdd8f98caec0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 06:11:46 +0100 Subject: [PATCH 137/185] fixed fuzzer test --- tests/fuzzer.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 1c1ae470a..86d4c6beb 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -246,6 +246,7 @@ static int basicUnitTests(U32 seed, double compressibility) size_t const sampleUnitSize = 8 KB; U32 const nbSamples = (U32)(totalSampleSize / sampleUnitSize); size_t* const samplesSizes = (size_t*) malloc(nbSamples * sizeof(size_t)); + U32 dictID; if (dictBuffer==NULL || samplesSizes==NULL) { free(dictBuffer); @@ -261,10 +262,9 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(4, "OK, created dictionary of size %u \n", (U32)dictSize); DISPLAYLEVEL(4, "test%3i : check dictID : ", testNb++); - { U32 const dictID = ZDICT_getDictID(dictBuffer, dictSize); - if (dictID==0) goto _output_error; - DISPLAYLEVEL(4, "OK : %u \n", dictID); - } + dictID = ZDICT_getDictID(dictBuffer, dictSize); + if (dictID==0) goto _output_error; + DISPLAYLEVEL(4, "OK : %u \n", dictID); DISPLAYLEVEL(4, "test%3i : compress with dictionary : ", testNb++); cSize = ZSTD_compress_usingDict(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize), @@ -274,14 +274,14 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); DISPLAYLEVEL(4, "test%3i : retrieve dictID from dictionary : ", testNb++); - { U32 const dictID = ZSTD_getDictID_fromDict(dictBuffer, dictSize); - if (dictID != 0) goto _output_error; /* non-conformant (content-only) dictionary */ + { U32 const did = ZSTD_getDictID_fromDict(dictBuffer, dictSize); + if (did != dictID) goto _output_error; /* non-conformant (content-only) dictionary */ } DISPLAYLEVEL(4, "OK \n"); DISPLAYLEVEL(4, "test%3i : retrieve dictID from frame : ", testNb++); - { U32 const dictID = ZSTD_getDictID_fromFrame(compressedBuffer, cSize); - if (dictID != 0) goto _output_error; /* non-conformant (content-only) dictionary */ + { U32 const did = ZSTD_getDictID_fromFrame(compressedBuffer, cSize); + if (did != dictID) goto _output_error; /* non-conformant (content-only) dictionary */ } DISPLAYLEVEL(4, "OK \n"); From 2f902f946c828f8338e341281eedbd913816a4d3 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 08:52:53 +0100 Subject: [PATCH 138/185] fixed zlibwrapper use of xxh --- zlibWrapper/.gitignore | 3 +++ zlibWrapper/Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/.gitignore b/zlibWrapper/.gitignore index c3376bad8..8ce15613c 100644 --- a/zlibWrapper/.gitignore +++ b/zlibWrapper/.gitignore @@ -2,11 +2,14 @@ _* example.* example_zstd.* +example_gz.* fitblk.* fitblk_zstd.* zwrapbench.* foo.gz +minigzip +minigzip_zstd example example_zstd fitblk diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 49d44e35a..a0e641d94 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -13,12 +13,12 @@ ZLIB_PATH ?= . ZSTDLIBDIR = ../lib ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.a ZLIBWRAPPER_PATH = . -GZFILES = gzclose.o gzlib.o gzread.o gzwrite.o +GZFILES = gzclose.o gzlib.o gzread.o gzwrite.o EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md -CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) +CPPFLAGS = -DXXH_NAMESPACE=ZSTD_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -Wstrict-aliasing=1 From 73ab42252b5dc1e6e995088bb70306f2551ddca8 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 09:08:43 +0100 Subject: [PATCH 139/185] fixed zbuff in VS2005 projects --- build/VS2005/fullbench/fullbench.vcproj | 12 ------------ build/VS2005/fuzzer/fuzzer.vcproj | 4 ---- build/VS2005/zstd/zstd.vcproj | 16 ---------------- build/VS2005/zstdlib/zstdlib.vcproj | 8 ++------ 4 files changed, 2 insertions(+), 38 deletions(-) diff --git a/build/VS2005/fullbench/fullbench.vcproj b/build/VS2005/fullbench/fullbench.vcproj index c28d1f696..c67490c6f 100644 --- a/build/VS2005/fullbench/fullbench.vcproj +++ b/build/VS2005/fullbench/fullbench.vcproj @@ -363,14 +363,6 @@ RelativePath="..\..\..\lib\decompress\huf_decompress.c" > - - - - @@ -425,10 +417,6 @@ RelativePath="..\..\..\lib\common\mem.h" > - - diff --git a/build/VS2005/fuzzer/fuzzer.vcproj b/build/VS2005/fuzzer/fuzzer.vcproj index dd7450faa..b1ac81365 100644 --- a/build/VS2005/fuzzer/fuzzer.vcproj +++ b/build/VS2005/fuzzer/fuzzer.vcproj @@ -429,10 +429,6 @@ RelativePath="..\..\..\lib\common\xxhash.h" > - - diff --git a/build/VS2005/zstd/zstd.vcproj b/build/VS2005/zstd/zstd.vcproj index 223285ef1..9f49e3cb6 100644 --- a/build/VS2005/zstd/zstd.vcproj +++ b/build/VS2005/zstd/zstd.vcproj @@ -379,14 +379,6 @@ RelativePath="..\..\..\lib\common\xxhash.c" > - - - - @@ -481,14 +473,6 @@ RelativePath="..\..\..\lib\common\xxhash.h" > - - - - diff --git a/build/VS2005/zstdlib/zstdlib.vcproj b/build/VS2005/zstdlib/zstdlib.vcproj index 7a0a76e67..1b78986b2 100644 --- a/build/VS2005/zstdlib/zstdlib.vcproj +++ b/build/VS2005/zstdlib/zstdlib.vcproj @@ -360,11 +360,11 @@ > - - From a0d4031e7cd097c515973b368d864bf2b79641ab Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 09:46:14 +0100 Subject: [PATCH 140/185] fixed cmake build --- build/cmake/lib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt index 02cfb96bb..d22ddeada 100644 --- a/build/cmake/lib/CMakeLists.txt +++ b/build/cmake/lib/CMakeLists.txt @@ -165,7 +165,7 @@ IF (UNIX) SET(INSTALL_INCLUDE_DIR ${PREFIX}/include) # install target - INSTALL(FILES ${LIBRARY_DIR}/zstd.h ${LIBRARY_DIR}/common/zbuff.h ${LIBRARY_DIR}/dictBuilder/zdict.h DESTINATION ${INSTALL_INCLUDE_DIR}) + INSTALL(FILES ${LIBRARY_DIR}/zstd.h ${LIBRARY_DIR}/deprecated/zbuff.h ${LIBRARY_DIR}/dictBuilder/zdict.h DESTINATION ${INSTALL_INCLUDE_DIR}) INSTALL(TARGETS libzstd_static DESTINATION ${INSTALL_LIBRARY_DIR}) INSTALL(TARGETS libzstd_shared LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}) From 95f34e056a10f1645c4e40ac82c348995d7a92d2 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 6 Dec 2016 11:36:24 +0100 Subject: [PATCH 141/185] zlibWrapper/README.md: updated info about gzip file access functions --- zlibWrapper/Makefile | 4 ++-- zlibWrapper/README.md | 22 +++++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index a0e641d94..5a6378767 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -42,10 +42,10 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip minigzip_zstd ./fitblk_zstd 40960 <$(TEST_FILE) @echo ---- minigzip start ---- ./minigzip_zstd example$(EXT) - cp example$(EXT).gz example$(EXT)_zstd.gz + #cp example$(EXT).gz example$(EXT)_zstd.gz ./minigzip_zstd -d example$(EXT).gz ./minigzip example$(EXT) - cp example$(EXT).gz example$(EXT)_gz.gz + #cp example$(EXT).gz example$(EXT)_gz.gz ./minigzip_zstd -d example$(EXT).gz @echo ---- minigzip end ---- ./zwrapbench -qb3B1K $(TEST_FILE) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index cbf1b1b30..164b69ace 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -10,6 +10,8 @@ To build the zstd wrapper for zlib the following files are required: - a static or dynamic zlib library - zlibWrapper/zstd_zlibwrapper.h - zlibWrapper/zstd_zlibwrapper.c +- zlibWrapper/gz*.c files (gzclose.c, gzlib.c, gzread.c, gzwrite.c) +- zlibWrapper/gz*.h files (gzcompatibility.h, gzguts.h) - a static or dynamic zstd library The first two files are required by all projects using zlib and they are not included with the zstd distribution. @@ -22,26 +24,26 @@ Let's assume that your project that uses zlib is compiled with: ```gcc project.o -lz``` To compile the zstd wrapper with your project you have to do the following: -- change all references with ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"``` -- compile your project with `zstd_zlibwrapper.c` and a static or dynamic zstd library +- change all references with `#include "zlib.h"` to `#include "zstd_zlibwrapper.h"` +- compile your project with `zstd_zlibwrapper.c`, `gz*.c` and a static or dynamic zstd library The linking should be changed to: -```gcc project.o zstd_zlibwrapper.o -lz -lzstd``` +```gcc project.o zstd_zlibwrapper.o gz*.c -lz -lzstd``` #### Enabling zstd compression within your project After embedding the zstd wrapper within your project the zstd library is turned off by default. Your project should work as before with zlib. There are two options to enable zstd compression: -- compilation with ```-DZWRAP_USE_ZSTD=1``` (or using ```#define ZWRAP_USE_ZSTD 1``` before ```#include "zstd_zlibwrapper.h"```) -- using the ```void ZWRAP_useZSTDcompression(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```) +- compilation with `-DZWRAP_USE_ZSTD=1` (or using `#define ZWRAP_USE_ZSTD 1` before `#include "zstd_zlibwrapper.h"`) +- using the `void ZWRAP_useZSTDcompression(int turn_on)` function (declared in `#include "zstd_zlibwrapper.h"`) During decompression zlib and zstd streams are automatically detected and decompressed using a proper library. This behavior can be changed using `ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB)` what will make zlib decompression slightly faster. #### Example -We have take the file ```test/example.c``` from [the zlib library distribution](http://zlib.net/) and copied it to [zlibWrapper/examples/example.c](examples/example.c). +We have take the file `test/example.c` from [the zlib library distribution](http://zlib.net/) and copied it to [zlibWrapper/examples/example.c](examples/example.c). After compilation and execution it shows the following results: ``` zlib version 1.2.8 = 0x1280, compile flags = 0x65 @@ -53,13 +55,15 @@ large_inflate(): OK after inflateSync(): hello, hello! inflate with dictionary: hello, hello! ``` -Then we have changed ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```, compiled the [example.c](examples/example.c) file -with ```-DZWRAP_USE_ZSTD=1``` and linked with additional ```zstd_zlibwrapper.o -lzstd```. -We were forced to turn off the following functions: ```test_gzio```, ```test_flush```, ```test_sync``` which use currently unsupported features. +Then we have changed `#include "zlib.h"` to `#include "zstd_zlibwrapper.h"`, compiled the [example.c](examples/example.c) file +with `-DZWRAP_USE_ZSTD=1` and linked with additional `zstd_zlibwrapper.o gz*.c -lzstd`. +We were forced to turn off the following functions: `test_flush`, `test_sync` which use currently unsupported features. After running it shows the following results: ``` zlib version 1.2.8 = 0x1280, compile flags = 0x65 uncompress(): hello, hello! +gzread(): hello, hello! +gzgets() after gzseek: hello! inflate(): hello, hello! large_inflate(): OK inflate with dictionary: hello, hello! From 9dfd0af164b86ca9030a29170b57841c61816c84 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 17:16:41 +0100 Subject: [PATCH 142/185] ZBUFF_ as a wrapper to ZSTD streaming API. --- lib/deprecated/zbuff.h | 23 ++- lib/deprecated/zbuff_compress.c | 248 +++++------------------------- lib/deprecated/zbuff_decompress.c | 218 +++----------------------- 3 files changed, 72 insertions(+), 417 deletions(-) diff --git a/lib/deprecated/zbuff.h b/lib/deprecated/zbuff.h index 8e55c39a5..4956aaaa4 100644 --- a/lib/deprecated/zbuff.h +++ b/lib/deprecated/zbuff.h @@ -15,17 +15,19 @@ * See 'lib/README.md'. *****************************************************************/ -#ifndef ZSTD_BUFFERED_H_23987 -#define ZSTD_BUFFERED_H_23987 #if defined (__cplusplus) extern "C" { #endif +#ifndef ZSTD_BUFFERED_H_23987 +#define ZSTD_BUFFERED_H_23987 + /* ************************************* * Dependencies ***************************************/ #include /* size_t */ +#include /* ZSTD_CStream, ZSTD_DStream */ /* *************************************************************** @@ -48,7 +50,7 @@ extern "C" { #ifdef ZBUFF_DISABLE_DEPRECATE_WARNINGS # define ZBUFF_DEPRECATED(message) /* disable deprecation warnings */ #else -# if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) +# if (defined(__GNUC__) && (__GNUC__ >= 5)) || defined(__clang__) # define ZBUFF_DEPRECATED(message) __attribute__((deprecated(message))) # elif defined(__GNUC__) && (__GNUC__ >= 3) # define ZBUFF_DEPRECATED(message) __attribute__((deprecated)) @@ -70,7 +72,7 @@ extern "C" { * ZBUFF and ZSTD are 100% interoperable, * frames created by one can be decoded by the other one */ -typedef struct ZBUFF_CCtx_s ZBUFF_CCtx; +typedef ZSTD_CStream ZBUFF_CCtx; ZBUFF_DEPRECATED("use ZSTD_createCStream") ZBUFF_CCtx* ZBUFF_createCCtx(void); ZBUFF_DEPRECATED("use ZSTD_freeCStream") size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx); @@ -122,7 +124,7 @@ ZBUFF_DEPRECATED("use ZSTD_endStream") size_t ZBUFF_compressEnd(ZBUFF_CCtx* * **************************************************/ -typedef struct ZBUFF_DCtx_s ZBUFF_DCtx; +typedef ZSTD_DStream ZBUFF_DCtx; ZBUFF_DEPRECATED("use ZSTD_createDStream") ZBUFF_DCtx* ZBUFF_createDCtx(void); ZBUFF_DEPRECATED("use ZSTD_freeDStream") size_t ZBUFF_freeDCtx(ZBUFF_DCtx* dctx); @@ -172,9 +174,14 @@ ZBUFF_DEPRECATED("use ZSTD_CStreamOutSize") size_t ZBUFF_recommendedCOutSize(voi ZBUFF_DEPRECATED("use ZSTD_DStreamInSize") size_t ZBUFF_recommendedDInSize(void); ZBUFF_DEPRECATED("use ZSTD_DStreamOutSize") size_t ZBUFF_recommendedDOutSize(void); +#endif /* ZSTD_BUFFERED_H_23987 */ + #ifdef ZBUFF_STATIC_LINKING_ONLY +#ifndef ZBUFF_STATIC_H_30298098432 +#define ZBUFF_STATIC_H_30298098432 + /* ==================================================================================== * The definitions in this section are considered experimental. * They should never be used in association with a dynamic library, as they may change in the future. @@ -203,11 +210,11 @@ ZBUFF_DEPRECATED("use ZSTD_initDStream_usingDict") size_t ZBUFF_compressInit_adv ZSTD_parameters params, unsigned long long pledgedSrcSize); -#endif /* ZBUFF_STATIC_LINKING_ONLY */ +#endif /* ZBUFF_STATIC_H_30298098432 */ + +#endif /* ZBUFF_STATIC_LINKING_ONLY */ #if defined (__cplusplus) } #endif - -#endif /* ZSTD_BUFFERED_H_23987 */ diff --git a/lib/deprecated/zbuff_compress.c b/lib/deprecated/zbuff_compress.c index 5095b43e6..5a37a0027 100644 --- a/lib/deprecated/zbuff_compress.c +++ b/lib/deprecated/zbuff_compress.c @@ -12,19 +12,10 @@ /* ************************************* * Dependencies ***************************************/ -#include -#include "error_private.h" -#include "zstd_internal.h" /* MIN, ZSTD_BLOCKHEADERSIZE, defaultCustomMem */ #define ZBUFF_STATIC_LINKING_ONLY #include "zbuff.h" -/* ************************************* -* Constants -***************************************/ -static size_t const ZBUFF_endFrameSize = ZSTD_BLOCKHEADERSIZE; - - /*-*********************************************************** * Streaming compression * @@ -58,59 +49,19 @@ static size_t const ZBUFF_endFrameSize = ZSTD_BLOCKHEADERSIZE; * output : ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize : ensures it's always possible to write/flush/end a full block at best speed. * ***********************************************************/ -typedef enum { ZBUFFcs_init, ZBUFFcs_load, ZBUFFcs_flush, ZBUFFcs_final } ZBUFF_cStage; - -/* *** Resources *** */ -struct ZBUFF_CCtx_s { - ZSTD_CCtx* zc; - char* inBuff; - size_t inBuffSize; - size_t inToCompress; - size_t inBuffPos; - size_t inBuffTarget; - size_t blockSize; - char* outBuff; - size_t outBuffSize; - size_t outBuffContentSize; - size_t outBuffFlushedSize; - ZBUFF_cStage stage; - U32 checksum; - U32 frameEnded; - ZSTD_customMem customMem; -}; /* typedef'd tp ZBUFF_CCtx within "zbuff.h" */ - ZBUFF_CCtx* ZBUFF_createCCtx(void) { - return ZBUFF_createCCtx_advanced(defaultCustomMem); + return ZSTD_createCStream(); } ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem) { - ZBUFF_CCtx* zbc; - - if (!customMem.customAlloc && !customMem.customFree) - customMem = defaultCustomMem; - - if (!customMem.customAlloc || !customMem.customFree) - return NULL; - - zbc = (ZBUFF_CCtx*)customMem.customAlloc(customMem.opaque, sizeof(ZBUFF_CCtx)); - if (zbc==NULL) return NULL; - memset(zbc, 0, sizeof(ZBUFF_CCtx)); - memcpy(&zbc->customMem, &customMem, sizeof(ZSTD_customMem)); - zbc->zc = ZSTD_createCCtx_advanced(customMem); - if (zbc->zc == NULL) { ZBUFF_freeCCtx(zbc); return NULL; } - return zbc; + return ZSTD_createCStream_advanced(customMem); } size_t ZBUFF_freeCCtx(ZBUFF_CCtx* zbc) { - if (zbc==NULL) return 0; /* support free on NULL */ - ZSTD_freeCCtx(zbc->zc); - if (zbc->inBuff) zbc->customMem.customFree(zbc->customMem.opaque, zbc->inBuff); - if (zbc->outBuff) zbc->customMem.customFree(zbc->customMem.opaque, zbc->outBuff); - zbc->customMem.customFree(zbc->customMem.opaque, zbc); - return 0; + return ZSTD_freeCStream(zbc); } @@ -120,148 +71,40 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize) { - /* allocate buffers */ - { size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog; - if (zbc->inBuffSize < neededInBuffSize) { - zbc->inBuffSize = neededInBuffSize; - zbc->customMem.customFree(zbc->customMem.opaque, zbc->inBuff); /* should not be necessary */ - zbc->inBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, neededInBuffSize); - if (zbc->inBuff == NULL) return ERROR(memory_allocation); - } - zbc->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize); - } - if (zbc->outBuffSize < ZSTD_compressBound(zbc->blockSize)+1) { - zbc->outBuffSize = ZSTD_compressBound(zbc->blockSize)+1; - zbc->customMem.customFree(zbc->customMem.opaque, zbc->outBuff); /* should not be necessary */ - zbc->outBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, zbc->outBuffSize); - if (zbc->outBuff == NULL) return ERROR(memory_allocation); - } - - { size_t const errorCode = ZSTD_compressBegin_advanced(zbc->zc, dict, dictSize, params, pledgedSrcSize); - if (ZSTD_isError(errorCode)) return errorCode; } - - zbc->inToCompress = 0; - zbc->inBuffPos = 0; - zbc->inBuffTarget = zbc->blockSize; - zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0; - zbc->stage = ZBUFFcs_load; - zbc->checksum = params.fParams.checksumFlag > 0; - zbc->frameEnded = 0; - return 0; /* ready to go */ + return ZSTD_initCStream_advanced(zbc, dict, dictSize, params, pledgedSrcSize); } size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel) { - ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize); - return ZBUFF_compressInit_advanced(zbc, dict, dictSize, params, 0); + return ZSTD_initCStream_usingDict(zbc, dict, dictSize, compressionLevel); } size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel) { - return ZBUFF_compressInitDictionary(zbc, NULL, 0, compressionLevel); + return ZSTD_initCStream(zbc, compressionLevel); } - -/* internal util function */ -MEM_STATIC size_t ZBUFF_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize) -{ - size_t const length = MIN(dstCapacity, srcSize); - memcpy(dst, src, length); - return length; -} - - /* ====== Compression ====== */ -typedef enum { zbf_gather, zbf_flush, zbf_end } ZBUFF_flush_e; - -static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc, - void* dst, size_t* dstCapacityPtr, - const void* src, size_t* srcSizePtr, - ZBUFF_flush_e const flush) -{ - U32 someMoreWork = 1; - const char* const istart = (const char*)src; - const char* const iend = istart + *srcSizePtr; - const char* ip = istart; - char* const ostart = (char*)dst; - char* const oend = ostart + *dstCapacityPtr; - char* op = ostart; - - while (someMoreWork) { - switch(zbc->stage) - { - case ZBUFFcs_init: return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */ - - case ZBUFFcs_load: - /* complete inBuffer */ - { size_t const toLoad = zbc->inBuffTarget - zbc->inBuffPos; - size_t const loaded = ZBUFF_limitCopy(zbc->inBuff + zbc->inBuffPos, toLoad, ip, iend-ip); - zbc->inBuffPos += loaded; - ip += loaded; - if ( (zbc->inBuffPos==zbc->inToCompress) || (!flush && (toLoad != loaded)) ) { - someMoreWork = 0; break; /* not enough input to get a full block : stop there, wait for more */ - } } - /* compress current block (note : this stage cannot be stopped in the middle) */ - { void* cDst; - size_t cSize; - size_t const iSize = zbc->inBuffPos - zbc->inToCompress; - size_t oSize = oend-op; - if (oSize >= ZSTD_compressBound(iSize)) - cDst = op; /* compress directly into output buffer (avoid flush stage) */ - else - cDst = zbc->outBuff, oSize = zbc->outBuffSize; - cSize = (flush == zbf_end) ? - ZSTD_compressEnd(zbc->zc, cDst, oSize, zbc->inBuff + zbc->inToCompress, iSize) : - ZSTD_compressContinue(zbc->zc, cDst, oSize, zbc->inBuff + zbc->inToCompress, iSize); - if (ZSTD_isError(cSize)) return cSize; - if (flush == zbf_end) zbc->frameEnded = 1; - /* prepare next block */ - zbc->inBuffTarget = zbc->inBuffPos + zbc->blockSize; - if (zbc->inBuffTarget > zbc->inBuffSize) - zbc->inBuffPos = 0, zbc->inBuffTarget = zbc->blockSize; /* note : inBuffSize >= blockSize */ - zbc->inToCompress = zbc->inBuffPos; - if (cDst == op) { op += cSize; break; } /* no need to flush */ - zbc->outBuffContentSize = cSize; - zbc->outBuffFlushedSize = 0; - zbc->stage = ZBUFFcs_flush; /* continue to flush stage */ - } - - case ZBUFFcs_flush: - { size_t const toFlush = zbc->outBuffContentSize - zbc->outBuffFlushedSize; - size_t const flushed = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outBuffFlushedSize, toFlush); - op += flushed; - zbc->outBuffFlushedSize += flushed; - if (toFlush!=flushed) { someMoreWork = 0; break; } /* dst too small to store flushed data : stop there */ - zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0; - zbc->stage = ZBUFFcs_load; - break; - } - - case ZBUFFcs_final: - someMoreWork = 0; /* do nothing */ - break; - - default: - return ERROR(GENERIC); /* impossible */ - } - } - - *srcSizePtr = ip - istart; - *dstCapacityPtr = op - ostart; - if (zbc->frameEnded) return 0; - { size_t hintInSize = zbc->inBuffTarget - zbc->inBuffPos; - if (hintInSize==0) hintInSize = zbc->blockSize; - return hintInSize; - } -} size_t ZBUFF_compressContinue(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr, const void* src, size_t* srcSizePtr) { - return ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, src, srcSizePtr, zbf_gather); + size_t result; + ZSTD_outBuffer outBuff; + ZSTD_inBuffer inBuff; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + inBuff.src = src; + inBuff.pos = 0; + inBuff.size = *srcSizePtr; + result = ZSTD_compressStream(zbc, &outBuff, &inBuff); + *dstCapacityPtr = outBuff.pos; + *srcSizePtr = inBuff.pos; + return result; } @@ -270,44 +113,27 @@ size_t ZBUFF_compressContinue(ZBUFF_CCtx* zbc, size_t ZBUFF_compressFlush(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr) { - size_t srcSize = 0; - ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, &srcSize, &srcSize, zbf_flush); /* use a valid src address instead of NULL */ - return zbc->outBuffContentSize - zbc->outBuffFlushedSize; + size_t result; + ZSTD_outBuffer outBuff; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + result = ZSTD_flushStream(zbc, &outBuff); + *dstCapacityPtr = outBuff.pos; + return result; } size_t ZBUFF_compressEnd(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr) { - BYTE* const ostart = (BYTE*)dst; - BYTE* const oend = ostart + *dstCapacityPtr; - BYTE* op = ostart; - - if (zbc->stage != ZBUFFcs_final) { - /* flush whatever remains */ - size_t outSize = *dstCapacityPtr; - size_t srcSize = 0; - size_t const notEnded = ZBUFF_compressContinue_generic(zbc, dst, &outSize, &srcSize, &srcSize, zbf_end); /* use a valid address instead of NULL */ - size_t const remainingToFlush = zbc->outBuffContentSize - zbc->outBuffFlushedSize; - op += outSize; - if (remainingToFlush) { - *dstCapacityPtr = op-ostart; - return remainingToFlush + ZBUFF_endFrameSize + (zbc->checksum * 4); - } - /* create epilogue */ - zbc->stage = ZBUFFcs_final; - zbc->outBuffContentSize = !notEnded ? 0 : - ZSTD_compressEnd(zbc->zc, zbc->outBuff, zbc->outBuffSize, NULL, 0); /* write epilogue into outBuff */ - } - - /* flush epilogue */ - { size_t const toFlush = zbc->outBuffContentSize - zbc->outBuffFlushedSize; - size_t const flushed = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outBuffFlushedSize, toFlush); - op += flushed; - zbc->outBuffFlushedSize += flushed; - *dstCapacityPtr = op-ostart; - if (toFlush==flushed) zbc->stage = ZBUFFcs_init; /* end reached */ - return toFlush - flushed; - } + size_t result; + ZSTD_outBuffer outBuff; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + result = ZSTD_endStream(zbc, &outBuff); + *dstCapacityPtr = outBuff.pos; + return result; } @@ -315,5 +141,5 @@ size_t ZBUFF_compressEnd(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr) /* ************************************* * Tool functions ***************************************/ -size_t ZBUFF_recommendedCInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; } -size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize; } +size_t ZBUFF_recommendedCInSize(void) { return ZSTD_CStreamInSize(); } +size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_CStreamOutSize(); } diff --git a/lib/deprecated/zbuff_decompress.c b/lib/deprecated/zbuff_decompress.c index b20ee9705..d9c155e08 100644 --- a/lib/deprecated/zbuff_decompress.c +++ b/lib/deprecated/zbuff_decompress.c @@ -12,68 +12,23 @@ /* ************************************* * Dependencies ***************************************/ -#include -#include "error_private.h" -#include "zstd_internal.h" /* MIN, ZSTD_blockHeaderSize, ZSTD_BLOCKSIZE_MAX */ #define ZBUFF_STATIC_LINKING_ONLY #include "zbuff.h" -typedef enum { ZBUFFds_init, ZBUFFds_loadHeader, - ZBUFFds_read, ZBUFFds_load, ZBUFFds_flush } ZBUFF_dStage; - -/* *** Resource management *** */ -struct ZBUFF_DCtx_s { - ZSTD_DCtx* zd; - ZSTD_frameParams fParams; - ZBUFF_dStage stage; - char* inBuff; - size_t inBuffSize; - size_t inPos; - char* outBuff; - size_t outBuffSize; - size_t outStart; - size_t outEnd; - size_t blockSize; - BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; - size_t lhSize; - ZSTD_customMem customMem; -}; /* typedef'd to ZBUFF_DCtx within "zbuff.h" */ - - ZBUFF_DCtx* ZBUFF_createDCtx(void) { - return ZBUFF_createDCtx_advanced(defaultCustomMem); + return ZSTD_createDStream(); } ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem) { - ZBUFF_DCtx* zbd; - - if (!customMem.customAlloc && !customMem.customFree) - customMem = defaultCustomMem; - - if (!customMem.customAlloc || !customMem.customFree) - return NULL; - - zbd = (ZBUFF_DCtx*)customMem.customAlloc(customMem.opaque, sizeof(ZBUFF_DCtx)); - if (zbd==NULL) return NULL; - memset(zbd, 0, sizeof(ZBUFF_DCtx)); - memcpy(&zbd->customMem, &customMem, sizeof(ZSTD_customMem)); - zbd->zd = ZSTD_createDCtx_advanced(customMem); - if (zbd->zd == NULL) { ZBUFF_freeDCtx(zbd); return NULL; } - zbd->stage = ZBUFFds_init; - return zbd; + return ZSTD_createDStream_advanced(customMem); } size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbd) { - if (zbd==NULL) return 0; /* support free on null */ - ZSTD_freeDCtx(zbd->zd); - if (zbd->inBuff) zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff); - if (zbd->outBuff) zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff); - zbd->customMem.customFree(zbd->customMem.opaque, zbd); - return 0; + return ZSTD_freeDStream(zbd); } @@ -81,23 +36,12 @@ size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbd) size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* zbd, const void* dict, size_t dictSize) { - zbd->stage = ZBUFFds_loadHeader; - zbd->lhSize = zbd->inPos = zbd->outStart = zbd->outEnd = 0; - return ZSTD_decompressBegin_usingDict(zbd->zd, dict, dictSize); + return ZSTD_initDStream_usingDict(zbd, dict, dictSize); } size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbd) { - return ZBUFF_decompressInitDictionary(zbd, NULL, 0); -} - - -/* internal util function */ -MEM_STATIC size_t ZBUFF_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize) -{ - size_t const length = MIN(dstCapacity, srcSize); - memcpy(dst, src, length); - return length; + return ZSTD_initDStream(zbd); } @@ -107,146 +51,24 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd, void* dst, size_t* dstCapacityPtr, const void* src, size_t* srcSizePtr) { - const char* const istart = (const char*)src; - const char* const iend = istart + *srcSizePtr; - const char* ip = istart; - char* const ostart = (char*)dst; - char* const oend = ostart + *dstCapacityPtr; - char* op = ostart; - U32 someMoreWork = 1; - - while (someMoreWork) { - switch(zbd->stage) - { - case ZBUFFds_init : - return ERROR(init_missing); - - case ZBUFFds_loadHeader : - { size_t const hSize = ZSTD_getFrameParams(&(zbd->fParams), zbd->headerBuffer, zbd->lhSize); - if (ZSTD_isError(hSize)) return hSize; - if (hSize != 0) { /* need more input */ - size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */ - if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */ - memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip); - zbd->lhSize += iend-ip; - *dstCapacityPtr = 0; - return (hSize - zbd->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ - } - memcpy(zbd->headerBuffer + zbd->lhSize, ip, toLoad); zbd->lhSize = hSize; ip += toLoad; - break; - } } - - /* Consume header */ - { size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zbd->zd); /* == ZSTD_frameHeaderSize_min */ - size_t const h1Result = ZSTD_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer, h1Size); - if (ZSTD_isError(h1Result)) return h1Result; /* should not happen : already checked */ - if (h1Size < zbd->lhSize) { /* long header */ - size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zbd->zd); - size_t const h2Result = ZSTD_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer+h1Size, h2Size); - if (ZSTD_isError(h2Result)) return h2Result; - } } - - zbd->fParams.windowSize = MAX(zbd->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); - - /* Frame header instruct buffer sizes */ - { size_t const blockSize = MIN(zbd->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); - size_t const neededOutSize = zbd->fParams.windowSize + blockSize; - zbd->blockSize = blockSize; - if (zbd->inBuffSize < blockSize) { - zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff); - zbd->inBuffSize = blockSize; - zbd->inBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, blockSize); - if (zbd->inBuff == NULL) return ERROR(memory_allocation); - } - if (zbd->outBuffSize < neededOutSize) { - zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff); - zbd->outBuffSize = neededOutSize; - zbd->outBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, neededOutSize); - if (zbd->outBuff == NULL) return ERROR(memory_allocation); - } } - zbd->stage = ZBUFFds_read; - /* pass-through */ - - case ZBUFFds_read: - { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd); - if (neededInSize==0) { /* end of frame */ - zbd->stage = ZBUFFds_init; - someMoreWork = 0; - break; - } - if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */ - const int isSkipFrame = ZSTD_isSkipFrame(zbd->zd); - size_t const decodedSize = ZSTD_decompressContinue(zbd->zd, - zbd->outBuff + zbd->outStart, (isSkipFrame ? 0 : zbd->outBuffSize - zbd->outStart), - ip, neededInSize); - if (ZSTD_isError(decodedSize)) return decodedSize; - ip += neededInSize; - if (!decodedSize && !isSkipFrame) break; /* this was just a header */ - zbd->outEnd = zbd->outStart + decodedSize; - zbd->stage = ZBUFFds_flush; - break; - } - if (ip==iend) { someMoreWork = 0; break; } /* no more input */ - zbd->stage = ZBUFFds_load; - /* pass-through */ - } - - case ZBUFFds_load: - { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd); - size_t const toLoad = neededInSize - zbd->inPos; /* should always be <= remaining space within inBuff */ - size_t loadedSize; - if (toLoad > zbd->inBuffSize - zbd->inPos) return ERROR(corruption_detected); /* should never happen */ - loadedSize = ZBUFF_limitCopy(zbd->inBuff + zbd->inPos, toLoad, ip, iend-ip); - ip += loadedSize; - zbd->inPos += loadedSize; - if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */ - - /* decode loaded input */ - { const int isSkipFrame = ZSTD_isSkipFrame(zbd->zd); - size_t const decodedSize = ZSTD_decompressContinue(zbd->zd, - zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart, - zbd->inBuff, neededInSize); - if (ZSTD_isError(decodedSize)) return decodedSize; - zbd->inPos = 0; /* input is consumed */ - if (!decodedSize && !isSkipFrame) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */ - zbd->outEnd = zbd->outStart + decodedSize; - zbd->stage = ZBUFFds_flush; - /* pass-through */ - } } - - case ZBUFFds_flush: - { size_t const toFlushSize = zbd->outEnd - zbd->outStart; - size_t const flushedSize = ZBUFF_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize); - op += flushedSize; - zbd->outStart += flushedSize; - if (flushedSize == toFlushSize) { /* flush completed */ - zbd->stage = ZBUFFds_read; - if (zbd->outStart + zbd->blockSize > zbd->outBuffSize) - zbd->outStart = zbd->outEnd = 0; - break; - } - /* cannot flush everything */ - someMoreWork = 0; - break; - } - default: return ERROR(GENERIC); /* impossible */ - } } - - /* result */ - *srcSizePtr = ip-istart; - *dstCapacityPtr = op-ostart; - { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd); - if (!nextSrcSizeHint) return (zbd->outEnd != zbd->outStart); /* return 0 only if fully flushed too */ - nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zbd->zd) == ZSTDnit_block); - if (zbd->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */ - nextSrcSizeHint -= zbd->inPos; /* already loaded*/ - return nextSrcSizeHint; - } + ZSTD_outBuffer outBuff; + ZSTD_inBuffer inBuff; + size_t result; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + inBuff.src = src; + inBuff.pos = 0; + inBuff.size = *srcSizePtr; + result = ZSTD_decompressStream(zbd, &outBuff, &inBuff); + *dstCapacityPtr = outBuff.pos; + *srcSizePtr = inBuff.pos; + return result; } /* ************************************* * Tool functions ***************************************/ -size_t ZBUFF_recommendedDInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize /* block header size*/ ; } -size_t ZBUFF_recommendedDOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; } +size_t ZBUFF_recommendedDInSize(void) { return ZSTD_DStreamInSize(); } +size_t ZBUFF_recommendedDOutSize(void) { return ZSTD_DStreamOutSize(); } From 379908be3d3e5d8b0c08a2ab8ea9cb7cf540945d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 10:36:15 -0800 Subject: [PATCH 143/185] fixed zstd.h for manual --- contrib/gen_html/.gitignore | 2 + contrib/gen_html/zstd_manual.html | 564 ++++++++++++++++++++++++++++++ lib/zstd.h | 6 +- 3 files changed, 569 insertions(+), 3 deletions(-) create mode 100644 contrib/gen_html/.gitignore create mode 100644 contrib/gen_html/zstd_manual.html diff --git a/contrib/gen_html/.gitignore b/contrib/gen_html/.gitignore new file mode 100644 index 000000000..ccf28c1d6 --- /dev/null +++ b/contrib/gen_html/.gitignore @@ -0,0 +1,2 @@ +# make artefact +gen_html diff --git a/contrib/gen_html/zstd_manual.html b/contrib/gen_html/zstd_manual.html new file mode 100644 index 000000000..d6465c0b4 --- /dev/null +++ b/contrib/gen_html/zstd_manual.html @@ -0,0 +1,564 @@ + + + +zstd 1.1.2 Manual + + +

zstd 1.1.2 Manual

+
+

Contents

+
    +
  1. Introduction
  2. +
  3. Version
  4. +
  5. Simple API
  6. +
  7. Explicit memory management
  8. +
  9. Simple dictionary API
  10. +
  11. Fast dictionary API
  12. +
  13. Streaming
  14. +
  15. Streaming compression - HowTo
  16. +
  17. Streaming decompression - HowTo
  18. +
  19. START OF ADVANCED AND EXPERIMENTAL FUNCTIONS
  20. +
  21. Advanced types
  22. +
  23. Advanced compression functions
  24. +
  25. Advanced decompression functions
  26. +
  27. Advanced streaming functions
  28. +
  29. Buffer-less and synchronous inner streaming functions
  30. +
  31. Buffer-less streaming compression (synchronous mode)
  32. +
  33. Buffer-less streaming decompression (synchronous mode)
  34. +
  35. Block functions
  36. +
+
+

Introduction

+  zstd, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios
+  at zlib-level and better compression ratios. The zstd compression library provides in-memory compression and
+  decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
+  Levels >= 20, labelled `--ultra`, should be used with caution, as they require more memory.
+  Compression can be done in:
+    - a single step (described as Simple API)
+    - a single step, reusing a context (described as Explicit memory management)
+    - unbounded multiple steps (described as Streaming compression)
+  The compression ratio achievable on small data can be highly improved using compression with a dictionary in:
+    - a single step (described as Simple dictionary API)
+    - a single step, reusing a dictionary (described as Fast dictionary API)
+
+  Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h.
+  These APIs shall never be used with a dynamic library.
+  They are not "stable", their definition may change in the future. Only static linking is allowed.
+
+ +

Version


+
+
unsigned ZSTD_versionNumber(void);   /**< library version number; to be used when checking dll version  */
+

+

Simple API


+
+
size_t ZSTD_compress( void* dst, size_t dstCapacity,
+                            const void* src, size_t srcSize,
+                                  int compressionLevel);
+

Compresses `src` content as a single zstd compressed frame into already allocated `dst`. + Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. + @return : compressed size written into `dst` (<= `dstCapacity), + or an error code if it fails (which can be tested using ZSTD_isError()). +


+ +
size_t ZSTD_decompress( void* dst, size_t dstCapacity,
+                              const void* src, size_t compressedSize);
+

`compressedSize` : must be the _exact_ size of a single compressed frame. + `dstCapacity` is an upper bound of originalSize. + If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. + @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), + or an errorCode if it fails (which can be tested using ZSTD_isError()). +


+ +
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
+

'src' is the start of a zstd compressed frame. + @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise. + note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. + When `return==0`, data to decompress could be any size. + In which case, it's necessary to use streaming mode to decompress data. + Optionally, application can still use ZSTD_decompress() while relying on implied limits. + (For example, data may be necessarily cut into blocks <= 16 KB). + note 2 : decompressed size is always present when compression is done with ZSTD_compress() + note 3 : decompressed size can be very large (64-bits value), + potentially larger than what local system can handle as a single memory segment. + In which case, it's necessary to use streaming mode to decompress data. + note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. + Always ensure result fits within application's authorized limits. + Each application can set its own limits. + note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. +


+ +

Helper functions

int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
+size_t      ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
+unsigned    ZSTD_isError(size_t code);          /*!< tells if a `size_t` function result is an error code */
+const char* ZSTD_getErrorName(size_t code);     /*!< provides readable string from an error code */
+

+

Explicit memory management


+
+
size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
+

Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). +


+ +

Decompression context

typedef struct ZSTD_DCtx_s ZSTD_DCtx;
+ZSTD_DCtx* ZSTD_createDCtx(void);
+size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
+

+
size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+

Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). +


+ +

Simple dictionary API


+
+
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
+                                           void* dst, size_t dstCapacity,
+                                     const void* src, size_t srcSize,
+                                     const void* dict,size_t dictSize,
+                                           int compressionLevel);
+

Compression using a predefined Dictionary (see dictBuilder/zdict.h). + Note : This function loads the dictionary, resulting in significant startup delay. + Note : When `dict == NULL || dictSize < 8` no dictionary is used. +


+ +
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
+                                             void* dst, size_t dstCapacity,
+                                       const void* src, size_t srcSize,
+                                       const void* dict,size_t dictSize);
+

Decompression using a predefined Dictionary (see dictBuilder/zdict.h). + Dictionary must be identical to the one used during compression. + Note : This function loads the dictionary, resulting in significant startup delay. + Note : When `dict == NULL || dictSize < 8` no dictionary is used. +


+ +

Fast dictionary API


+
+
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel);
+

When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. + ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. + ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only. + `dict` can be released after ZSTD_CDict creation. +


+ +
size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);
+

Function frees memory allocated by ZSTD_createCDict(). +


+ +
size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
+                                            void* dst, size_t dstCapacity,
+                                      const void* src, size_t srcSize,
+                                      const ZSTD_CDict* cdict);
+

Compression using a digested Dictionary. + Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. + Note that compression level is decided during dictionary creation. +


+ +
ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize);
+

Create a digested dictionary, ready to start decompression operation without startup delay. + `dict` can be released after creation. +


+ +
size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);
+

Function frees memory allocated with ZSTD_createDDict() +


+ +
size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
+                                              void* dst, size_t dstCapacity,
+                                        const void* src, size_t srcSize,
+                                        const ZSTD_DDict* ddict);
+

Decompression using a digested Dictionary. + Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. +


+ +

Streaming


+
+
typedef struct ZSTD_inBuffer_s {
+  const void* src;    /**< start of input buffer */
+  size_t size;        /**< size of input buffer */
+  size_t pos;         /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_inBuffer;
+

+
typedef struct ZSTD_outBuffer_s {
+  void*  dst;         /**< start of output buffer */
+  size_t size;        /**< size of output buffer */
+  size_t pos;         /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_outBuffer;
+

+

Streaming compression - HowTo

+  A ZSTD_CStream object is required to track streaming operation.
+  Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
+  ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
+  It is recommended to re-use ZSTD_CStream in situations where many streaming operations will be achieved consecutively,
+  since it will play nicer with system's memory, by re-using already allocated memory.
+  Use one separate ZSTD_CStream per thread for parallel execution.
+
+  Start a new compression by initializing ZSTD_CStream.
+  Use ZSTD_initCStream() to start a new compression operation.
+  Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary.
+
+  Use ZSTD_compressStream() repetitively to consume input stream.
+  The function will automatically update both `pos` fields.
+  Note that it may not consume the entire input, in which case `pos < size`,
+  and it's up to the caller to present again remaining data.
+  @return : a size hint, preferred nb of bytes to use as input for next function call
+           (it's just a hint, to help latency a little, any other value will work fine)
+           (note : the size hint is guaranteed to be <= ZSTD_CStreamInSize() )
+            or an error code, which can be tested using ZSTD_isError().
+
+  At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream().
+  `output->pos` will be updated.
+  Note some content might still be left within internal buffer if `output->size` is too small.
+  @return : nb of bytes still present within internal buffer (0 if it's empty)
+            or an error code, which can be tested using ZSTD_isError().
+
+  ZSTD_endStream() instructs to finish a frame.
+  It will perform a flush and write frame epilogue.
+  The epilogue is required for decoders to consider a frame completed.
+  Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
+  In which case, call again ZSTD_endStream() to complete the flush.
+  @return : nb of bytes still present within internal buffer (0 if it's empty)
+            or an error code, which can be tested using ZSTD_isError().
+
+ 
+
+ +

Streaming compression functions

typedef struct ZSTD_CStream_s ZSTD_CStream;
+ZSTD_CStream* ZSTD_createCStream(void);
+size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
+size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
+size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+

+
size_t ZSTD_CStreamInSize(void);    /**< recommended size for input buffer */
+

+
size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
+

+

Streaming decompression - HowTo

+  A ZSTD_DStream object is required to track streaming operations.
+  Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
+  ZSTD_DStream objects can be re-used multiple times.
+
+  Use ZSTD_initDStream() to start a new decompression operation,
+   or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
+   @return : recommended first input size
+
+  Use ZSTD_decompressStream() repetitively to consume your input.
+  The function will update both `pos` fields.
+  If `input.pos < input.size`, some input has not been consumed.
+  It's up to the caller to present again remaining data.
+  If `output.pos < output.size`, decoder has flushed everything it could.
+  @return : 0 when a frame is completely decoded and fully flushed,
+            an error code, which can be tested using ZSTD_isError(),
+            any other value > 0, which means there is still some decoding to do to complete current frame.
+            The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
+ 
+
+ +

Streaming decompression functions

typedef struct ZSTD_DStream_s ZSTD_DStream;
+ZSTD_DStream* ZSTD_createDStream(void);
+size_t ZSTD_freeDStream(ZSTD_DStream* zds);
+size_t ZSTD_initDStream(ZSTD_DStream* zds);
+size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+

+
size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */
+

+
size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
+

+

START OF ADVANCED AND EXPERIMENTAL FUNCTIONS

 The definitions in this section are considered experimental.
+ They should never be used with a dynamic library, as they may change in the future.
+ They are provided for advanced usages.
+ Use them only in association with static linking.
+ 
+
+ +

Advanced types


+
+
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy;   /* from faster to stronger */
+

+
typedef struct {
+    unsigned windowLog;      /**< largest match distance : larger == more compression, more memory needed during decompression */
+    unsigned chainLog;       /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
+    unsigned hashLog;        /**< dispatch table : larger == faster, more memory */
+    unsigned searchLog;      /**< nb of searches : larger == more compression, slower */
+    unsigned searchLength;   /**< match length searched : larger == faster decompression, sometimes less compression */
+    unsigned targetLength;   /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
+    ZSTD_strategy strategy;
+} ZSTD_compressionParameters;
+

+
typedef struct {
+    unsigned contentSizeFlag; /**< 1: content size will be in frame header (if known). */
+    unsigned checksumFlag;    /**< 1: will generate a 22-bits checksum at end of frame, to be used for error detection by decompressor */
+    unsigned noDictIDFlag;    /**< 1: no dict ID will be saved into frame header (if dictionary compression) */
+} ZSTD_frameParameters;
+

+
typedef struct {
+    ZSTD_compressionParameters cParams;
+    ZSTD_frameParameters fParams;
+} ZSTD_parameters;
+

+

Custom memory allocation functions

typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
+typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
+typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
+

+

Advanced compression functions


+
+
size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
+

Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters. + `frameContentSize` is an optional parameter, provide `0` if unknown +


+ +
ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
+

Create a ZSTD compression context using external alloc and free functions +


+ +
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
+

Gives the amount of memory used by a given ZSTD_CCtx +


+ +
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
+                                                  ZSTD_parameters params, ZSTD_customMem customMem);
+

Create a ZSTD_CDict using external alloc and free, and customized compression parameters +


+ +
size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
+

Gives the amount of memory used by a given ZSTD_sizeof_CDict +


+ +
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
+

same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`. + All fields of `ZSTD_frameParameters` are set to default (0) +


+ +
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
+

@return ZSTD_compressionParameters structure for a selected compression level and srcSize. + `srcSize` value is optional, select 0 if not known +


+ +
size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
+

Ensure param values remain within authorized range +


+ +
ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
+

optimize params for a given `srcSize` and `dictSize`. + both values are optional, select `0` if unknown. +


+ +
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
+                                           void* dst, size_t dstCapacity,
+                                     const void* src, size_t srcSize,
+                                     const void* dict,size_t dictSize,
+                                           ZSTD_parameters params);
+

Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter +


+ +

Advanced decompression functions


+
+
unsigned ZSTD_isFrame(const void* buffer, size_t size);
+

Tells if the content of `buffer` starts with a valid Frame Identifier. + Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + Note 3 : Skippable Frame Identifiers are considered valid. +


+ +
size_t ZSTD_estimateDCtxSize(void);
+

Gives the potential amount of memory allocated to create a ZSTD_DCtx +


+ +
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
+

Create a ZSTD decompression context using external alloc and free functions +


+ +
size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
+

Gives the amount of memory used by a given ZSTD_DCtx +


+ +
size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
+

Gives the amount of memory used by a given ZSTD_DDict +


+ +
unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
+

Provides the dictID stored within dictionary. + if @return == 0, the dictionary is not conformant with Zstandard specification. + It can still be loaded, but as a content-only dictionary. +


+ +
unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
+

Provides the dictID of the dictionary loaded into `ddict`. + If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + Non-conformant dictionaries can still be loaded, but as content-only dictionaries. +


+ +
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
+

Provides the dictID required to decompressed the frame stored within `src`. + If @return == 0, the dictID could not be decoded. + This could for one of the following reasons : + - The frame does not require a dictionary to be decoded (most common case). + - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. + Note : this use case also happens when using a non-conformant dictionary. + - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + - This is not a Zstandard frame. + When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. +


+ +

Advanced streaming functions


+
+

Advanced Streaming compression functions

ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
+size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
+size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
+                                             ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be zero == unknown */
+size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
+size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);  /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before */
+size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
+

+

Advanced Streaming decompression functions

typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
+ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
+size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
+size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
+size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
+size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
+size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
+

+

Buffer-less and synchronous inner streaming functions

+  This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
+  But it's also a complex one, with many restrictions (documented below).
+  Prefer using normal streaming API for an easier experience
+ 
+
+ +

Buffer-less streaming compression (synchronous mode)

+  A ZSTD_CCtx object is required to track streaming operations.
+  Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
+  ZSTD_CCtx object can be re-used multiple times within successive compression operations.
+
+  Start by initializing a context.
+  Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
+  or ZSTD_compressBegin_advanced(), for finer parameter control.
+  It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
+
+  Then, consume your input using ZSTD_compressContinue().
+  There are some important considerations to keep in mind when using this advanced function :
+  - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
+  - Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks.
+  - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
+    Worst case evaluation is provided by ZSTD_compressBound().
+    ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
+  - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
+    It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
+  - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
+    In which case, it will "discard" the relevant memory section from its history.
+
+  Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
+  It's possible to use a NULL,0 src content, in which case, it will write a final empty block to end the frame,
+  Without last block mark, frames will be considered unfinished (broken) by decoders.
+
+  You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
+
+ +

Buffer-less streaming compression functions

size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
+size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
+size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize);
+size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+

+

Buffer-less streaming decompression (synchronous mode)

+  A ZSTD_DCtx object is required to track streaming operations.
+  Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
+  A ZSTD_DCtx object can be re-used multiple times.
+
+  First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
+  It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
+  such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
+  and the dictionary ID used.
+  (Note : content size is optional, it may not be present. 0 means : content size unknown).
+  Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
+  As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
+  Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
+  Frame parameters are extracted from the beginning of the compressed frame.
+  Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
+  @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
+           >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
+           errorCode, which can be tested using ZSTD_isError().
+
+  Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
+  Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
+
+  Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
+  ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
+  ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
+
+  @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
+  It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some metadata item.
+  It can also be an error code, which can be tested with ZSTD_isError().
+
+  ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
+  They should preferably be located contiguously, prior to current block.
+  Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
+  ZSTD_decompressContinue() is very sensitive to contiguity,
+  if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
+  or that previous contiguous segment is large enough to properly handle maximum back-reference.
+
+  A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
+  Context can then be reset to start a new decompression.
+
+  Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
+  This information is not required to properly decode a frame.
+
+  == Special case : skippable frames ==
+
+  Skippable frames allow integration of user-defined data into a flow of concatenated frames.
+  Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
+  a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
+  b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
+  c) Frame Content - any content (User Data) of length equal to Frame Size
+  For skippable frames ZSTD_decompressContinue() always returns 0.
+  For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
+  It also returns Frame Size as fparamsPtr->frameContentSize.
+
+ +
typedef struct {
+    unsigned long long frameContentSize;
+    unsigned windowSize;
+    unsigned dictID;
+    unsigned checksumFlag;
+} ZSTD_frameParams;
+

+

Buffer-less streaming decompression functions

size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
+size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
+size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
+void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
+size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
+size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
+ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
+

+

Block functions

+    Block functions produce and decode raw zstd blocks, without frame metadata.
+    Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
+    User will have to take in charge required information to regenerate data, such as compressed and content sizes.
+
+    A few rules to respect :
+    - Compressing and decompressing require a context structure
+      + Use ZSTD_createCCtx() and ZSTD_createDCtx()
+    - It is necessary to init context before starting
+      + compression : ZSTD_compressBegin()
+      + decompression : ZSTD_decompressBegin()
+      + variants _usingDict() are also allowed
+      + copyCCtx() and copyDCtx() work too
+    - Block size is limited, it must be <= ZSTD_getBlockSizeMax()
+      + If you need to compress more, cut data into multiple blocks
+      + Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large.
+    - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
+      In which case, nothing is produced into `dst`.
+      + User must test for such outcome and deal directly with uncompressed data
+      + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
+      + In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
+        Use ZSTD_insertBlock() in such a case.
+
+ +

Raw zstd block functions

size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
+size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
+

+ + diff --git a/lib/zstd.h b/lib/zstd.h index a10a9eaab..3989cc307 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -63,7 +63,7 @@ extern "C" { #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) -ZSTDLIB_API unsigned ZSTD_versionNumber (void); +ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< library version number; to be used when checking dll version */ /*************************************** @@ -117,9 +117,9 @@ ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readab * Explicit memory management ***************************************/ /*= Compression context -* When compressing many messages / blocks, +* When compressing many times, * it is recommended to allocate a context just once, and re-use it for each successive compression operation. -* This will make the situation much easier for the system's memory. +* This will make workload friendlier for system's memory. * Use one context per thread for parallel execution in multi-threaded environments. */ typedef struct ZSTD_CCtx_s ZSTD_CCtx; ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void); From 6b9a98326114a0c4bb1d8d27ce7a1887c77463da Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 11:23:15 -0800 Subject: [PATCH 144/185] changed gzstd build messages --- programs/Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index 393944920..e7ff3e5a0 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -125,8 +125,15 @@ zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) gzstd: clean_decomp_o - echo "int main(){}" | $(CC) -o have_zlib -x c - -lz && echo found zlib || echo did not found zlib - if [ -s have_zlib ]; then echo building gzstd && rm have_zlib$(EXT) && CPPFLAGS=-DZSTD_GZDECOMPRESS LDFLAGS="-lz" $(MAKE) zstd; else echo building plain zstd && $(MAKE) zstd; fi + @echo "int main(){}" | $(CC) -o have_zlib -x c - -lz && echo found zlib || echo did not found zlib + @if [ -s have_zlib ]; then \ + echo building gzstd with .gz decompression support \ + && rm have_zlib$(EXT) \ + && CPPFLAGS=-DZSTD_GZDECOMPRESS LDFLAGS="-lz" $(MAKE) zstd; \ + else \ + echo "WARNING : no zlib, building gzstd with only .zst files support : NO .gz SUPPORT !!!" \ + && $(MAKE) zstd; \ + fi generate_res: windres\generate_res.bat From 94d1a93d28a9908c8a93f2a0f326233d7d131451 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 12:02:56 -0800 Subject: [PATCH 145/185] changed environment variable comparison to sh compatible --- tests/playTests.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index dfca1de87..6179265e7 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -31,10 +31,10 @@ case "$OS" in ;; esac -MD5SUM="md5sum" -if [[ "$OSTYPE" == "darwin"* ]]; then - MD5SUM="md5 -r" -fi +case "$OSTYPE" in + darwin*) MD5SUM="md5 -r" ;; + *) MD5SUM="md5sum" ;; +esac $ECHO "\nStarting playTests.sh isWindows=$isWindows ZSTD='$ZSTD'" @@ -228,11 +228,10 @@ cp ../programs/*.h dirTestDict $MD5SUM dirTestDict/* > tmph1 $ZSTD -f --rm dirTestDict/* -D tmpDictC $ZSTD -d --rm dirTestDict/*.zst -D tmpDictC # note : use internal checksum by default -if [[ "$OSTYPE" == "darwin"* ]]; then - $ECHO "md5sum -c not supported on OS-X : test skipped" # not compatible with OS-X's md5 -else - $MD5SUM -c tmph1 -fi +case "$OSTYPE" in + darwin*) $ECHO "md5sum -c not supported on OS-X : test skipped" ;; # not compatible with OS-X's md5 + *) $MD5SUM -c tmph1 ;; +esac rm -rf dirTestDict rm tmp* From 1628fe08fcf25e624846d2803df315c54e5b6ee9 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 13:45:42 -0800 Subject: [PATCH 146/185] cmake : SHARED_LIBRARY_OUTPUT_NAME is user-selectable, by @aparamon (#469) --- build/cmake/lib/CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt index d22ddeada..abcf4ffe2 100644 --- a/build/cmake/lib/CMakeLists.txt +++ b/build/cmake/lib/CMakeLists.txt @@ -130,20 +130,20 @@ ELSE () SET(LIBRARY_BASE_NAME libzstd) ENDIF (MSVC) -# Define static and shared library names -SET(STATIC_LIBRARY_OUTPUT_NAME ${LIBRARY_BASE_NAME}) -SET(SHARED_LIBRARY_OUTPUT_NAME ${LIBRARY_BASE_NAME}.${LIBVER_MAJOR}.${LIBVER_MINOR}.${LIBVER_RELEASE}) - IF (MSVC) IF (CMAKE_SIZEOF_VOID_P MATCHES "8") - SET(STATIC_LIBRARY_OUTPUT_NAME ${STATIC_LIBRARY_OUTPUT_NAME}_x64) - SET(SHARED_LIBRARY_OUTPUT_NAME ${SHARED_LIBRARY_OUTPUT_NAME}_x64) + SET(LIBRARY_ARCH_SUFFIX "_x64") ELSE () - SET(STATIC_LIBRARY_OUTPUT_NAME ${STATIC_LIBRARY_OUTPUT_NAME}_x86) - SET(SHARED_LIBRARY_OUTPUT_NAME ${SHARED_LIBRARY_OUTPUT_NAME}_x86) + SET(LIBRARY_ARCH_SUFFIX "_x86") ENDIF (CMAKE_SIZEOF_VOID_P MATCHES "8") +ELSE () + SET(LIBRARY_ARCH_SUFFIX "") ENDIF (MSVC) +# Define static and shared library names +SET(STATIC_LIBRARY_OUTPUT_NAME ${LIBRARY_BASE_NAME}${LIBRARY_ARCH_SUFFIX} CACHE STRING "Static library output name") +SET(SHARED_LIBRARY_OUTPUT_NAME ${LIBRARY_BASE_NAME}.${LIBVER_MAJOR}.${LIBVER_MINOR}.${LIBVER_RELEASE}${LIBRARY_ARCH_SUFFIX} CACHE STRING "Shared library output name") + SET_TARGET_PROPERTIES( libzstd_static PROPERTIES From d946501d2cc21711318d4ba1608f71ec4546eccc Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 16:49:23 -0800 Subject: [PATCH 147/185] decode benchmark - single file (hidden option) --- programs/bench.c | 151 ++++++++++++++++++++++++++------------------- programs/bench.h | 5 +- programs/zstdcli.c | 6 +- 3 files changed, 96 insertions(+), 66 deletions(-) diff --git a/programs/bench.c b/programs/bench.c index a66f4b345..b51e7106f 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -74,7 +74,7 @@ static clock_t g_time = 0; DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \ DISPLAYLEVEL(1, "Error %i : ", error); \ DISPLAYLEVEL(1, __VA_ARGS__); \ - DISPLAYLEVEL(1, "\n"); \ + DISPLAYLEVEL(1, " \n"); \ exit(error); \ } @@ -84,7 +84,8 @@ static clock_t g_time = 0; ***************************************/ static U32 g_nbSeconds = NBSECONDS; static size_t g_blockSize = 0; -int g_additionalParam = 0; +static int g_additionalParam = 0; +static U32 g_decodeOnly = 0; void BMK_setNotificationLevel(unsigned level) { g_displayLevel=level; } @@ -102,18 +103,18 @@ void BMK_SetBlockSize(size_t blockSize) DISPLAYLEVEL(2, "using blocks of size %u KB \n", (U32)(blockSize>>10)); } +void BMK_setDecodeOnly(unsigned decodeFlag) { g_decodeOnly = (decodeFlag>0); } /* ******************************************************** * Bench functions **********************************************************/ -typedef struct -{ - const char* srcPtr; +typedef struct { + const void* srcPtr; size_t srcSize; - char* cPtr; + void* cPtr; size_t cRoom; size_t cSize; - char* resPtr; + void* resPtr; size_t resSize; } blockParam_t; @@ -132,7 +133,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, blockParam_t* const blockTable = (blockParam_t*) malloc(maxNbBlocks * sizeof(blockParam_t)); size_t const maxCompressedSize = ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024); /* add some room for safety */ void* const compressedBuffer = malloc(maxCompressedSize); - void* const resultBuffer = malloc(srcSize); + void* resultBuffer = malloc(srcSize); ZSTD_CCtx* const ctx = ZSTD_createCCtx(); ZSTD_DCtx* const dctx = ZSTD_createDCtx(); U32 nbBlocks; @@ -147,7 +148,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, UTIL_initTimer(&ticksPerSecond); /* Init blockTable data */ - { const char* srcPtr = (const char*)srcBuffer; + if (!g_decodeOnly) { + const char* srcPtr = (const char*)srcBuffer; char* cPtr = (char*)compressedBuffer; char* resPtr = (char*)resultBuffer; U32 fileNb; @@ -157,27 +159,45 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, U32 const blockEnd = nbBlocks + nbBlocksforThisFile; for ( ; nbBlocks decodedSize) EXM_THROW(32, "original size is too large"); + if (decodedSize==0) EXM_THROW(32, "Impossible to determine original size "); + free(resultBuffer); + resultBuffer = malloc(decodedSize); + if (!resultBuffer) EXM_THROW(33, "not enough memory"); + nbBlocks = 1; + blockTable[nbBlocks].srcPtr = srcBuffer; + blockTable[0].srcSize = decodedSize; + blockTable[0].cPtr = compressedBuffer; + blockTable[0].cSize = srcSize; + blockTable[0].cRoom = maxCompressedSize; + blockTable[0].resPtr = resultBuffer; + blockTable[0].resSize = decodedSize; + srcSize = decodedSize; + } /* warmimg up memory */ RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1); /* Bench */ { U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL); - U64 const crcOrig = XXH64(srcBuffer, srcSize, 0); + U64 const crcOrig = g_decodeOnly ? 0 : XXH64(srcBuffer, srcSize, 0); UTIL_time_t coolTime; U64 const maxTime = (g_nbSeconds * TIMELOOP_MICROSEC) + 1; U64 totalCTime=0, totalDTime=0; - U32 cCompleted=0, dCompleted=0; + U32 cCompleted=g_decodeOnly, dCompleted=0; # define NB_MARKS 4 const char* const marks[NB_MARKS] = { " |", " /", " =", "\\" }; U32 markNb = 0; @@ -186,9 +206,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, UTIL_getTime(&coolTime); DISPLAYLEVEL(2, "\r%79s\r", ""); - while (!cCompleted | !dCompleted) { + while (!cCompleted || !dCompleted) { UTIL_time_t clockStart; - U64 clockLoop = g_nbSeconds ? TIMELOOP_MICROSEC : 1; /* overheat protection */ if (UTIL_clockSpanMicro(coolTime, ticksPerSecond) > ACTIVEPERIOD_MICROSEC) { @@ -197,53 +216,58 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, UTIL_getTime(&coolTime); } - /* Compression */ - DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (U32)srcSize); - if (!cCompleted) memset(compressedBuffer, 0xE5, maxCompressedSize); /* warm up and erase result buffer */ + if (!g_decodeOnly) { + /* Compression */ + DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (U32)srcSize); + if (!cCompleted) memset(compressedBuffer, 0xE5, maxCompressedSize); /* warm up and erase result buffer */ - UTIL_sleepMilli(1); /* give processor time to other processes */ - UTIL_waitForNextTick(ticksPerSecond); - UTIL_getTime(&clockStart); + UTIL_sleepMilli(1); /* give processor time to other processes */ + UTIL_waitForNextTick(ticksPerSecond); + UTIL_getTime(&clockStart); - if (!cCompleted) { /* still some time to do compression tests */ - ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize); - ZSTD_customMem const cmem = { NULL, NULL, NULL }; - U32 nbLoops = 0; - ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, zparams, cmem); - if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure"); - do { - U32 blockNb; - size_t rSize; - for (blockNb=0; blockNb= maxTime); - } } + nbLoops++; + } while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop); + ZSTD_freeCDict(cdict); + { U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond); + if (clockSpan < fastestC*nbLoops) fastestC = clockSpan / nbLoops; + totalCTime += clockSpan; + cCompleted = (totalCTime >= maxTime); + } } - cSize = 0; - { U32 blockNb; for (blockNb=0; blockNb%10u (%5.3f),%6.1f MB/s\r", - marks[markNb], displayName, (U32)srcSize, (U32)cSize, ratio, - (double)srcSize / fastestC ); + cSize = 0; + { U32 blockNb; for (blockNb=0; blockNb%10u (%5.3f),%6.1f MB/s\r", + marks[markNb], displayName, (U32)srcSize, (U32)cSize, ratio, + (double)srcSize / fastestC ); + } else { /* g_decodeOnly */ + memcpy(compressedBuffer, srcBuffer, blockTable[0].cSize); + } (void)fastestD; (void)crcOrig; /* unused when decompression disabled */ #if 1 @@ -255,8 +279,9 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, UTIL_getTime(&clockStart); if (!dCompleted) { + U64 clockLoop = g_nbSeconds ? TIMELOOP_MICROSEC : 1; U32 nbLoops = 0; - ZSTD_DDict* ddict = ZSTD_createDDict(dictBuffer, dictBufferSize); + ZSTD_DDict* const ddict = ZSTD_createDDict(dictBuffer, dictBufferSize); if (!ddict) EXM_THROW(2, "ZSTD_createDDict() allocation failure"); do { U32 blockNb; @@ -290,7 +315,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, /* CRC Checking */ { U64 const crcCheck = XXH64(resultBuffer, srcSize, 0); - if (crcOrig!=crcCheck) { + if (!g_decodeOnly && (crcOrig!=crcCheck)) { size_t u; DISPLAY("!!! WARNING !!! %14s : Invalid Checksum : %x != %x \n", displayName, (unsigned)crcOrig, (unsigned)crcCheck); for (u=0; u ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel(); if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel(); if (cLevelLast < cLevel) cLevelLast = cLevel; - if (cLevelLast > cLevel) DISPLAYLEVEL(2, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast); + if (cLevelLast > cLevel) DISPLAYLEVEL(2, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast); if (nbFiles == 0) BMK_syntheticTest(cLevel, cLevelLast, compressibility); diff --git a/programs/bench.h b/programs/bench.h index 1e3e3812b..7009dc2f6 100644 --- a/programs/bench.h +++ b/programs/bench.h @@ -11,7 +11,7 @@ #ifndef BENCH_H_121279284357 #define BENCH_H_121279284357 -#include +#include /* size_t */ int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, const char* dictFileName, int cLevel, int cLevelLast); @@ -21,5 +21,6 @@ void BMK_SetNbSeconds(unsigned nbLoops); void BMK_SetBlockSize(size_t blockSize); void BMK_setAdditionalParam(int additionalParam); void BMK_setNotificationLevel(unsigned level); +void BMK_setDecodeOnly(unsigned decodeFlag); - #endif /* BENCH_H_121279284357 */ +#endif /* BENCH_H_121279284357 */ diff --git a/programs/zstdcli.c b/programs/zstdcli.c index c7c682bb3..29bcc7763 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -334,7 +334,11 @@ int main(int argCount, const char* argv[]) case 'z': operation=zom_compress; argument++; break; /* Decoding */ - case 'd': operation=zom_decompress; argument++; break; + case 'd': if (operation==zom_bench) { + BMK_setDecodeOnly(1); argument++; break; /* benchmark decode (hidden option) */ + } else { + operation=zom_decompress; argument++; break; + } /* Force stdout, even if stdout==console */ case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break; From e63c631aaf445dc5c7479ef3860432f2a326865e Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 6 Dec 2016 17:46:49 -0800 Subject: [PATCH 148/185] decode benchmark, multi-files --- programs/bench.c | 61 ++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/programs/bench.c b/programs/bench.c index b51e7106f..9104ea89c 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -127,7 +127,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, const size_t* fileSizes, U32 nbFiles, const void* dictBuffer, size_t dictBufferSize) { - size_t const blockSize = (g_blockSize>=32 ? g_blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ; + size_t const blockSize = ((g_blockSize>=32 && !g_decodeOnly) ? g_blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ; size_t const avgSize = MIN(g_blockSize, (srcSize / nbFiles)); U32 const maxNbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize) + nbFiles; blockParam_t* const blockTable = (blockParam_t*) malloc(maxNbBlocks * sizeof(blockParam_t)); @@ -136,6 +136,9 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, void* resultBuffer = malloc(srcSize); ZSTD_CCtx* const ctx = ZSTD_createCCtx(); ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + size_t const loadedCompressedSize = srcSize; + size_t cSize = 0; + double ratio = 0.; U32 nbBlocks; UTIL_time_t ticksPerSecond; @@ -147,46 +150,50 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (strlen(displayName)>17) displayName += strlen(displayName)-17; /* can only display 17 characters */ UTIL_initTimer(&ticksPerSecond); + if (g_decodeOnly) { + const char* srcPtr = (const char*) srcBuffer; + U64 dSize64 = 0; + U32 fileNb; + for (fileNb=0; fileNb decodedSize) EXM_THROW(32, "original size is too large"); + if (decodedSize==0) EXM_THROW(32, "Impossible to determine original size "); + free(resultBuffer); + resultBuffer = malloc(decodedSize); + if (!resultBuffer) EXM_THROW(33, "not enough memory"); + cSize = srcSize; + srcSize = decodedSize; + ratio = (double)srcSize / (double)cSize; + } } + /* Init blockTable data */ - if (!g_decodeOnly) { - const char* srcPtr = (const char*)srcBuffer; + { const char* srcPtr = (const char*)srcBuffer; char* cPtr = (char*)compressedBuffer; char* resPtr = (char*)resultBuffer; U32 fileNb; for (nbBlocks=0, fileNb=0; fileNb decodedSize) EXM_THROW(32, "original size is too large"); - if (decodedSize==0) EXM_THROW(32, "Impossible to determine original size "); - free(resultBuffer); - resultBuffer = malloc(decodedSize); - if (!resultBuffer) EXM_THROW(33, "not enough memory"); - nbBlocks = 1; - blockTable[nbBlocks].srcPtr = srcBuffer; - blockTable[0].srcSize = decodedSize; - blockTable[0].cPtr = compressedBuffer; - blockTable[0].cSize = srcSize; - blockTable[0].cRoom = maxCompressedSize; - blockTable[0].resPtr = resultBuffer; - blockTable[0].resSize = decodedSize; - srcSize = decodedSize; - } + } } } /* warmimg up memory */ RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1); @@ -201,8 +208,6 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, # define NB_MARKS 4 const char* const marks[NB_MARKS] = { " |", " /", " =", "\\" }; U32 markNb = 0; - size_t cSize = 0; - double ratio = 0.; UTIL_getTime(&coolTime); DISPLAYLEVEL(2, "\r%79s\r", ""); @@ -266,7 +271,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, marks[markNb], displayName, (U32)srcSize, (U32)cSize, ratio, (double)srcSize / fastestC ); } else { /* g_decodeOnly */ - memcpy(compressedBuffer, srcBuffer, blockTable[0].cSize); + memcpy(compressedBuffer, srcBuffer, loadedCompressedSize); } (void)fastestD; (void)crcOrig; /* unused when decompression disabled */ @@ -287,7 +292,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, U32 blockNb; for (blockNb=0; blockNb Date: Tue, 6 Dec 2016 17:56:20 -0800 Subject: [PATCH 149/185] compatibility with zstd-frugal (noBench mode) --- programs/zstdcli.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 29bcc7763..7ffb0bb62 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -334,11 +334,11 @@ int main(int argCount, const char* argv[]) case 'z': operation=zom_compress; argument++; break; /* Decoding */ - case 'd': if (operation==zom_bench) { - BMK_setDecodeOnly(1); argument++; break; /* benchmark decode (hidden option) */ - } else { + case 'd': +#ifndef ZSTD_NOBENCH + if (operation==zom_bench) { BMK_setDecodeOnly(1); argument++; break; } /* benchmark decode (hidden option) */ +#endif operation=zom_decompress; argument++; break; - } /* Force stdout, even if stdout==console */ case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break; From abd9ec0d5386d28d047446bf117dadcf8bc1bbf0 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 7 Dec 2016 11:13:20 +0100 Subject: [PATCH 150/185] gen_html: comments of type /*= and /**= can be longer than a single line --- contrib/gen_html/.gitignore | 1 + contrib/gen_html/gen_html.cpp | 47 +-- contrib/gen_html/zstd_manual.html | 564 ------------------------------ 3 files changed, 26 insertions(+), 586 deletions(-) delete mode 100644 contrib/gen_html/zstd_manual.html diff --git a/contrib/gen_html/.gitignore b/contrib/gen_html/.gitignore index ccf28c1d6..344611428 100644 --- a/contrib/gen_html/.gitignore +++ b/contrib/gen_html/.gitignore @@ -1,2 +1,3 @@ # make artefact gen_html +zstd_manual.html diff --git a/contrib/gen_html/gen_html.cpp b/contrib/gen_html/gen_html.cpp index d3ab265a6..987b7917b 100644 --- a/contrib/gen_html/gen_html.cpp +++ b/contrib/gen_html/gen_html.cpp @@ -133,36 +133,28 @@ int main(int argc, char *argv[]) { continue; } - /* comments of type /*= and /**= mean: use a

header and show also all functions until first empty line */ - if ((line.substr(0,3) == "/*=" || line.substr(0,4) == "/**=") && line.find("*/")!=string::npos) { - trim_comments(line); - trim(line, "= "); - sout << "

" << line << "

";
-            lines = get_lines(input, ++linenum, "");
-            for (l=0; l

" << endl; - continue; + spos = line.find("/**="); + if (spos==string::npos) { + spos = line.find("/*!"); + if (spos==string::npos) + spos = line.find("/**"); + if (spos==string::npos) + spos = line.find("/*-"); + if (spos==string::npos) + spos = line.find("/*="); + if (spos==string::npos) + continue; + exclam = line[spos+2]; } + else exclam = '='; - spos = line.find("/*!"); - if (spos==string::npos) - spos = line.find("/**"); - if (spos==string::npos) - spos = line.find("/*-"); - - if (spos==string::npos) - continue; - - exclam = line[spos+2]; comments = get_lines(input, linenum, "*/"); if (!comments.empty()) comments[0] = line.substr(spos+3); if (!comments.empty()) comments[comments.size()-1] = comments[comments.size()-1].substr(0, comments[comments.size()-1].find("*/")); for (l=0; l
" << endl << endl; + } else if (exclam == '=') { /* comments of type /*= and /**= mean: use a

header and show also all functions until first empty line */ + sout << "

" << comments[0] << "

";
+            for (l=1; l
";
+            lines = get_lines(input, ++linenum, "");
+            for (l=0; l
" << endl; } else { /* comments of type /** and /*- mean: this is a comment; use a

header for the first line */ if (comments.empty()) continue; diff --git a/contrib/gen_html/zstd_manual.html b/contrib/gen_html/zstd_manual.html deleted file mode 100644 index d6465c0b4..000000000 --- a/contrib/gen_html/zstd_manual.html +++ /dev/null @@ -1,564 +0,0 @@ - - - -zstd 1.1.2 Manual - - -

zstd 1.1.2 Manual

-
-

Contents

-
    -
  1. Introduction
  2. -
  3. Version
  4. -
  5. Simple API
  6. -
  7. Explicit memory management
  8. -
  9. Simple dictionary API
  10. -
  11. Fast dictionary API
  12. -
  13. Streaming
  14. -
  15. Streaming compression - HowTo
  16. -
  17. Streaming decompression - HowTo
  18. -
  19. START OF ADVANCED AND EXPERIMENTAL FUNCTIONS
  20. -
  21. Advanced types
  22. -
  23. Advanced compression functions
  24. -
  25. Advanced decompression functions
  26. -
  27. Advanced streaming functions
  28. -
  29. Buffer-less and synchronous inner streaming functions
  30. -
  31. Buffer-less streaming compression (synchronous mode)
  32. -
  33. Buffer-less streaming decompression (synchronous mode)
  34. -
  35. Block functions
  36. -
-
-

Introduction

-  zstd, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios
-  at zlib-level and better compression ratios. The zstd compression library provides in-memory compression and
-  decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
-  Levels >= 20, labelled `--ultra`, should be used with caution, as they require more memory.
-  Compression can be done in:
-    - a single step (described as Simple API)
-    - a single step, reusing a context (described as Explicit memory management)
-    - unbounded multiple steps (described as Streaming compression)
-  The compression ratio achievable on small data can be highly improved using compression with a dictionary in:
-    - a single step (described as Simple dictionary API)
-    - a single step, reusing a dictionary (described as Fast dictionary API)
-
-  Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h.
-  These APIs shall never be used with a dynamic library.
-  They are not "stable", their definition may change in the future. Only static linking is allowed.
-
- -

Version


-
-
unsigned ZSTD_versionNumber(void);   /**< library version number; to be used when checking dll version  */
-

-

Simple API


-
-
size_t ZSTD_compress( void* dst, size_t dstCapacity,
-                            const void* src, size_t srcSize,
-                                  int compressionLevel);
-

Compresses `src` content as a single zstd compressed frame into already allocated `dst`. - Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. - @return : compressed size written into `dst` (<= `dstCapacity), - or an error code if it fails (which can be tested using ZSTD_isError()). -


- -
size_t ZSTD_decompress( void* dst, size_t dstCapacity,
-                              const void* src, size_t compressedSize);
-

`compressedSize` : must be the _exact_ size of a single compressed frame. - `dstCapacity` is an upper bound of originalSize. - If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. - @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), - or an errorCode if it fails (which can be tested using ZSTD_isError()). -


- -
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
-

'src' is the start of a zstd compressed frame. - @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise. - note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. - When `return==0`, data to decompress could be any size. - In which case, it's necessary to use streaming mode to decompress data. - Optionally, application can still use ZSTD_decompress() while relying on implied limits. - (For example, data may be necessarily cut into blocks <= 16 KB). - note 2 : decompressed size is always present when compression is done with ZSTD_compress() - note 3 : decompressed size can be very large (64-bits value), - potentially larger than what local system can handle as a single memory segment. - In which case, it's necessary to use streaming mode to decompress data. - note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. - Always ensure result fits within application's authorized limits. - Each application can set its own limits. - note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. -


- -

Helper functions

int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
-size_t      ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
-unsigned    ZSTD_isError(size_t code);          /*!< tells if a `size_t` function result is an error code */
-const char* ZSTD_getErrorName(size_t code);     /*!< provides readable string from an error code */
-

-

Explicit memory management


-
-
size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
-

Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). -


- -

Decompression context

typedef struct ZSTD_DCtx_s ZSTD_DCtx;
-ZSTD_DCtx* ZSTD_createDCtx(void);
-size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
-

-
size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-

Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). -


- -

Simple dictionary API


-
-
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
-                                           void* dst, size_t dstCapacity,
-                                     const void* src, size_t srcSize,
-                                     const void* dict,size_t dictSize,
-                                           int compressionLevel);
-

Compression using a predefined Dictionary (see dictBuilder/zdict.h). - Note : This function loads the dictionary, resulting in significant startup delay. - Note : When `dict == NULL || dictSize < 8` no dictionary is used. -


- -
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
-                                             void* dst, size_t dstCapacity,
-                                       const void* src, size_t srcSize,
-                                       const void* dict,size_t dictSize);
-

Decompression using a predefined Dictionary (see dictBuilder/zdict.h). - Dictionary must be identical to the one used during compression. - Note : This function loads the dictionary, resulting in significant startup delay. - Note : When `dict == NULL || dictSize < 8` no dictionary is used. -


- -

Fast dictionary API


-
-
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel);
-

When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. - ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. - ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only. - `dict` can be released after ZSTD_CDict creation. -


- -
size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);
-

Function frees memory allocated by ZSTD_createCDict(). -


- -
size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
-                                            void* dst, size_t dstCapacity,
-                                      const void* src, size_t srcSize,
-                                      const ZSTD_CDict* cdict);
-

Compression using a digested Dictionary. - Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. - Note that compression level is decided during dictionary creation. -


- -
ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize);
-

Create a digested dictionary, ready to start decompression operation without startup delay. - `dict` can be released after creation. -


- -
size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);
-

Function frees memory allocated with ZSTD_createDDict() -


- -
size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
-                                              void* dst, size_t dstCapacity,
-                                        const void* src, size_t srcSize,
-                                        const ZSTD_DDict* ddict);
-

Decompression using a digested Dictionary. - Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. -


- -

Streaming


-
-
typedef struct ZSTD_inBuffer_s {
-  const void* src;    /**< start of input buffer */
-  size_t size;        /**< size of input buffer */
-  size_t pos;         /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
-} ZSTD_inBuffer;
-

-
typedef struct ZSTD_outBuffer_s {
-  void*  dst;         /**< start of output buffer */
-  size_t size;        /**< size of output buffer */
-  size_t pos;         /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
-} ZSTD_outBuffer;
-

-

Streaming compression - HowTo

-  A ZSTD_CStream object is required to track streaming operation.
-  Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
-  ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
-  It is recommended to re-use ZSTD_CStream in situations where many streaming operations will be achieved consecutively,
-  since it will play nicer with system's memory, by re-using already allocated memory.
-  Use one separate ZSTD_CStream per thread for parallel execution.
-
-  Start a new compression by initializing ZSTD_CStream.
-  Use ZSTD_initCStream() to start a new compression operation.
-  Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary.
-
-  Use ZSTD_compressStream() repetitively to consume input stream.
-  The function will automatically update both `pos` fields.
-  Note that it may not consume the entire input, in which case `pos < size`,
-  and it's up to the caller to present again remaining data.
-  @return : a size hint, preferred nb of bytes to use as input for next function call
-           (it's just a hint, to help latency a little, any other value will work fine)
-           (note : the size hint is guaranteed to be <= ZSTD_CStreamInSize() )
-            or an error code, which can be tested using ZSTD_isError().
-
-  At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream().
-  `output->pos` will be updated.
-  Note some content might still be left within internal buffer if `output->size` is too small.
-  @return : nb of bytes still present within internal buffer (0 if it's empty)
-            or an error code, which can be tested using ZSTD_isError().
-
-  ZSTD_endStream() instructs to finish a frame.
-  It will perform a flush and write frame epilogue.
-  The epilogue is required for decoders to consider a frame completed.
-  Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
-  In which case, call again ZSTD_endStream() to complete the flush.
-  @return : nb of bytes still present within internal buffer (0 if it's empty)
-            or an error code, which can be tested using ZSTD_isError().
-
- 
-
- -

Streaming compression functions

typedef struct ZSTD_CStream_s ZSTD_CStream;
-ZSTD_CStream* ZSTD_createCStream(void);
-size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
-size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
-size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-

-
size_t ZSTD_CStreamInSize(void);    /**< recommended size for input buffer */
-

-
size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
-

-

Streaming decompression - HowTo

-  A ZSTD_DStream object is required to track streaming operations.
-  Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
-  ZSTD_DStream objects can be re-used multiple times.
-
-  Use ZSTD_initDStream() to start a new decompression operation,
-   or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
-   @return : recommended first input size
-
-  Use ZSTD_decompressStream() repetitively to consume your input.
-  The function will update both `pos` fields.
-  If `input.pos < input.size`, some input has not been consumed.
-  It's up to the caller to present again remaining data.
-  If `output.pos < output.size`, decoder has flushed everything it could.
-  @return : 0 when a frame is completely decoded and fully flushed,
-            an error code, which can be tested using ZSTD_isError(),
-            any other value > 0, which means there is still some decoding to do to complete current frame.
-            The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
- 
-
- -

Streaming decompression functions

typedef struct ZSTD_DStream_s ZSTD_DStream;
-ZSTD_DStream* ZSTD_createDStream(void);
-size_t ZSTD_freeDStream(ZSTD_DStream* zds);
-size_t ZSTD_initDStream(ZSTD_DStream* zds);
-size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-

-
size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */
-

-
size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
-

-

START OF ADVANCED AND EXPERIMENTAL FUNCTIONS

 The definitions in this section are considered experimental.
- They should never be used with a dynamic library, as they may change in the future.
- They are provided for advanced usages.
- Use them only in association with static linking.
- 
-
- -

Advanced types


-
-
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy;   /* from faster to stronger */
-

-
typedef struct {
-    unsigned windowLog;      /**< largest match distance : larger == more compression, more memory needed during decompression */
-    unsigned chainLog;       /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
-    unsigned hashLog;        /**< dispatch table : larger == faster, more memory */
-    unsigned searchLog;      /**< nb of searches : larger == more compression, slower */
-    unsigned searchLength;   /**< match length searched : larger == faster decompression, sometimes less compression */
-    unsigned targetLength;   /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
-    ZSTD_strategy strategy;
-} ZSTD_compressionParameters;
-

-
typedef struct {
-    unsigned contentSizeFlag; /**< 1: content size will be in frame header (if known). */
-    unsigned checksumFlag;    /**< 1: will generate a 22-bits checksum at end of frame, to be used for error detection by decompressor */
-    unsigned noDictIDFlag;    /**< 1: no dict ID will be saved into frame header (if dictionary compression) */
-} ZSTD_frameParameters;
-

-
typedef struct {
-    ZSTD_compressionParameters cParams;
-    ZSTD_frameParameters fParams;
-} ZSTD_parameters;
-

-

Custom memory allocation functions

typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
-typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
-typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
-

-

Advanced compression functions


-
-
size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
-

Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters. - `frameContentSize` is an optional parameter, provide `0` if unknown -


- -
ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
-

Create a ZSTD compression context using external alloc and free functions -


- -
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
-

Gives the amount of memory used by a given ZSTD_CCtx -


- -
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
-                                                  ZSTD_parameters params, ZSTD_customMem customMem);
-

Create a ZSTD_CDict using external alloc and free, and customized compression parameters -


- -
size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
-

Gives the amount of memory used by a given ZSTD_sizeof_CDict -


- -
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
-

same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`. - All fields of `ZSTD_frameParameters` are set to default (0) -


- -
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
-

@return ZSTD_compressionParameters structure for a selected compression level and srcSize. - `srcSize` value is optional, select 0 if not known -


- -
size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
-

Ensure param values remain within authorized range -


- -
ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
-

optimize params for a given `srcSize` and `dictSize`. - both values are optional, select `0` if unknown. -


- -
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
-                                           void* dst, size_t dstCapacity,
-                                     const void* src, size_t srcSize,
-                                     const void* dict,size_t dictSize,
-                                           ZSTD_parameters params);
-

Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter -


- -

Advanced decompression functions


-
-
unsigned ZSTD_isFrame(const void* buffer, size_t size);
-

Tells if the content of `buffer` starts with a valid Frame Identifier. - Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. - Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. - Note 3 : Skippable Frame Identifiers are considered valid. -


- -
size_t ZSTD_estimateDCtxSize(void);
-

Gives the potential amount of memory allocated to create a ZSTD_DCtx -


- -
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
-

Create a ZSTD decompression context using external alloc and free functions -


- -
size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
-

Gives the amount of memory used by a given ZSTD_DCtx -


- -
size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
-

Gives the amount of memory used by a given ZSTD_DDict -


- -
unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
-

Provides the dictID stored within dictionary. - if @return == 0, the dictionary is not conformant with Zstandard specification. - It can still be loaded, but as a content-only dictionary. -


- -
unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
-

Provides the dictID of the dictionary loaded into `ddict`. - If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. - Non-conformant dictionaries can still be loaded, but as content-only dictionaries. -


- -
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
-

Provides the dictID required to decompressed the frame stored within `src`. - If @return == 0, the dictID could not be decoded. - This could for one of the following reasons : - - The frame does not require a dictionary to be decoded (most common case). - - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. - Note : this use case also happens when using a non-conformant dictionary. - - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). - - This is not a Zstandard frame. - When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. -


- -

Advanced streaming functions


-
-

Advanced Streaming compression functions

ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
-size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
-size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
-                                             ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be zero == unknown */
-size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
-size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);  /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before */
-size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
-

-

Advanced Streaming decompression functions

typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
-ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
-size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
-size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
-size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
-size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
-size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
-

-

Buffer-less and synchronous inner streaming functions

-  This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
-  But it's also a complex one, with many restrictions (documented below).
-  Prefer using normal streaming API for an easier experience
- 
-
- -

Buffer-less streaming compression (synchronous mode)

-  A ZSTD_CCtx object is required to track streaming operations.
-  Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
-  ZSTD_CCtx object can be re-used multiple times within successive compression operations.
-
-  Start by initializing a context.
-  Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
-  or ZSTD_compressBegin_advanced(), for finer parameter control.
-  It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
-
-  Then, consume your input using ZSTD_compressContinue().
-  There are some important considerations to keep in mind when using this advanced function :
-  - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
-  - Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks.
-  - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
-    Worst case evaluation is provided by ZSTD_compressBound().
-    ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
-  - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
-    It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
-  - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
-    In which case, it will "discard" the relevant memory section from its history.
-
-  Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
-  It's possible to use a NULL,0 src content, in which case, it will write a final empty block to end the frame,
-  Without last block mark, frames will be considered unfinished (broken) by decoders.
-
-  You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
-
- -

Buffer-less streaming compression functions

size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
-size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
-size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
-size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize);
-size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-

-

Buffer-less streaming decompression (synchronous mode)

-  A ZSTD_DCtx object is required to track streaming operations.
-  Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
-  A ZSTD_DCtx object can be re-used multiple times.
-
-  First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
-  It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
-  such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
-  and the dictionary ID used.
-  (Note : content size is optional, it may not be present. 0 means : content size unknown).
-  Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
-  As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
-  Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
-  Frame parameters are extracted from the beginning of the compressed frame.
-  Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
-  @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
-           >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
-           errorCode, which can be tested using ZSTD_isError().
-
-  Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
-  Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
-
-  Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
-  ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
-  ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
-
-  @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
-  It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some metadata item.
-  It can also be an error code, which can be tested with ZSTD_isError().
-
-  ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
-  They should preferably be located contiguously, prior to current block.
-  Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
-  ZSTD_decompressContinue() is very sensitive to contiguity,
-  if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
-  or that previous contiguous segment is large enough to properly handle maximum back-reference.
-
-  A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
-  Context can then be reset to start a new decompression.
-
-  Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
-  This information is not required to properly decode a frame.
-
-  == Special case : skippable frames ==
-
-  Skippable frames allow integration of user-defined data into a flow of concatenated frames.
-  Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
-  a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
-  b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
-  c) Frame Content - any content (User Data) of length equal to Frame Size
-  For skippable frames ZSTD_decompressContinue() always returns 0.
-  For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
-  It also returns Frame Size as fparamsPtr->frameContentSize.
-
- -
typedef struct {
-    unsigned long long frameContentSize;
-    unsigned windowSize;
-    unsigned dictID;
-    unsigned checksumFlag;
-} ZSTD_frameParams;
-

-

Buffer-less streaming decompression functions

size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
-size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
-size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
-void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
-size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
-size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
-ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
-

-

Block functions

-    Block functions produce and decode raw zstd blocks, without frame metadata.
-    Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
-    User will have to take in charge required information to regenerate data, such as compressed and content sizes.
-
-    A few rules to respect :
-    - Compressing and decompressing require a context structure
-      + Use ZSTD_createCCtx() and ZSTD_createDCtx()
-    - It is necessary to init context before starting
-      + compression : ZSTD_compressBegin()
-      + decompression : ZSTD_decompressBegin()
-      + variants _usingDict() are also allowed
-      + copyCCtx() and copyDCtx() work too
-    - Block size is limited, it must be <= ZSTD_getBlockSizeMax()
-      + If you need to compress more, cut data into multiple blocks
-      + Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large.
-    - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
-      In which case, nothing is produced into `dst`.
-      + User must test for such outcome and deal directly with uncompressed data
-      + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
-      + In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
-        Use ZSTD_insertBlock() in such a case.
-
- -

Raw zstd block functions

size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
-size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
-

- - From 4da53219a07c07c3a3e1456c5acc74fa9faa3f73 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 7 Dec 2016 11:18:40 +0100 Subject: [PATCH 151/185] zstd Manual updated to 1.1.2 --- contrib/gen_html/gen_html.cpp | 1 + doc/zstd_manual.html | 91 +++++++++++++++++++++++++---------- lib/zstd.h | 2 +- 3 files changed, 67 insertions(+), 27 deletions(-) diff --git a/contrib/gen_html/gen_html.cpp b/contrib/gen_html/gen_html.cpp index 987b7917b..22ff65b10 100644 --- a/contrib/gen_html/gen_html.cpp +++ b/contrib/gen_html/gen_html.cpp @@ -176,6 +176,7 @@ int main(int argc, char *argv[]) { } sout << "


" << endl << endl; } else if (exclam == '=') { /* comments of type /*= and /**= mean: use a

header and show also all functions until first empty line */ + trim(comments[0], " "); sout << "

" << comments[0] << "

";
             for (l=1; l
 
 
-zstd 1.1.1 Manual
+zstd 1.1.2 Manual
 
 
-

zstd 1.1.1 Manual

+

zstd 1.1.2 Manual


Contents

    @@ -48,7 +48,7 @@

    Version

    
     
    -
    unsigned ZSTD_versionNumber (void);  /**< returns version number of ZSTD */
    +
    unsigned ZSTD_versionNumber(void);   /**< library version number; to be used when checking dll version */
     

    Simple API

    
     
    @@ -88,21 +88,29 @@
         note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. 
     


    -

    Helper functions

    int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
    +

    Helper functions

    int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
     size_t      ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
     unsigned    ZSTD_isError(size_t code);          /*!< tells if a `size_t` function result is an error code */
     const char* ZSTD_getErrorName(size_t code);     /*!< provides readable string from an error code */
    -

    +

    Explicit memory management

    
     
    +

    Compression context

       When compressing many times,
    +   it is recommended to allocate a context just once, and re-use it for each successive compression operation.
    +   This will make workload friendlier for system's memory.
    +   Use one context per thread for parallel execution in multi-threaded environments. 
    +
    typedef struct ZSTD_CCtx_s ZSTD_CCtx;
    +ZSTD_CCtx* ZSTD_createCCtx(void);
    +size_t     ZSTD_freeCCtx(ZSTD_CCtx* cctx);
    +

    size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
     

    Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()).


    -

    Decompression context

    typedef struct ZSTD_DCtx_s ZSTD_DCtx;
    +

    Decompression context

    typedef struct ZSTD_DCtx_s ZSTD_DCtx;
     ZSTD_DCtx* ZSTD_createDCtx(void);
     size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
    -

    +

    size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     

    Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()).


    @@ -220,14 +228,14 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
-

Streaming compression functions

typedef struct ZSTD_CStream_s ZSTD_CStream;
+

Streaming compression functions

typedef struct ZSTD_CStream_s ZSTD_CStream;
 ZSTD_CStream* ZSTD_createCStream(void);
 size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
 size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
 size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
 size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-

+

size_t ZSTD_CStreamInSize(void);    /**< recommended size for input buffer */
 

size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
@@ -248,17 +256,17 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
   If `output.pos < output.size`, decoder has flushed everything it could.
   @return : 0 when a frame is completely decoded and fully flushed,
             an error code, which can be tested using ZSTD_isError(),
-            any other value > 0, which means there is still some work to do to complete the frame.
-            The return value is a suggested next input size (just an hint, to help latency).
+            any other value > 0, which means there is still some decoding to do to complete current frame.
+            The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
  
 
-

Streaming decompression functions

typedef struct ZSTD_DStream_s ZSTD_DStream;
+

Streaming decompression functions

typedef struct ZSTD_DStream_s ZSTD_DStream;
 ZSTD_DStream* ZSTD_createDStream(void);
 size_t ZSTD_freeDStream(ZSTD_DStream* zds);
 size_t ZSTD_initDStream(ZSTD_DStream* zds);
 size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-

+

size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */
 

size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
@@ -295,10 +303,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     ZSTD_frameParameters fParams;
 } ZSTD_parameters;
 

-

Custom memory allocation functions

typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
+

Custom memory allocation functions

typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
 typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
 typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
-

+

Advanced compression functions


 
 
size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
@@ -352,6 +360,13 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
 
 

Advanced decompression functions


 
+
unsigned ZSTD_isFrame(const void* buffer, size_t size);
+

Tells if the content of `buffer` starts with a valid Frame Identifier. + Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + Note 3 : Skippable Frame Identifiers are considered valid. +


+
size_t ZSTD_estimateDCtxSize(void);
 

Gives the potential amount of memory allocated to create a ZSTD_DCtx


@@ -368,24 +383,48 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

Gives the amount of memory used by a given ZSTD_DDict


+
unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
+

Provides the dictID stored within dictionary. + if @return == 0, the dictionary is not conformant with Zstandard specification. + It can still be loaded, but as a content-only dictionary. +


+ +
unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
+

Provides the dictID of the dictionary loaded into `ddict`. + If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + Non-conformant dictionaries can still be loaded, but as content-only dictionaries. +


+ +
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
+

Provides the dictID required to decompressed the frame stored within `src`. + If @return == 0, the dictID could not be decoded. + This could for one of the following reasons : + - The frame does not require a dictionary to be decoded (most common case). + - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. + Note : this use case also happens when using a non-conformant dictionary. + - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + - This is not a Zstandard frame. + When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. +


+

Advanced streaming functions


 
-

Advanced Streaming compression functions

ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
+

Advanced Streaming compression functions

ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
 size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                              ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be zero == unknown */
 size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);  /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before */
 size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
-

-

Advanced Streaming decompression functions

typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
+

+

Advanced Streaming decompression functions

typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
 ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
 size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
 size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
 size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
 size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
 size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
-

+

Buffer-less and synchronous inner streaming functions

   This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
   But it's also a complex one, with many restrictions (documented below).
@@ -422,13 +461,13 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
   You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
 
-

Buffer-less streaming compression functions

size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+

Buffer-less streaming compression functions

size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
 size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
 size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize);
 size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-

+

Buffer-less streaming decompression (synchronous mode)

   A ZSTD_DCtx object is required to track streaming operations.
   Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
@@ -472,7 +511,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const vo
   Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
   This information is not required to properly decode a frame.
 
-  == Special case : skippable frames ==
+  == Special case : skippable frames == 
 
   Skippable frames allow integration of user-defined data into a flow of concatenated frames.
   Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
@@ -491,7 +530,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const vo
     unsigned checksumFlag;
 } ZSTD_frameParams;
 

-

Buffer-less streaming decompression functions

size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
+

Buffer-less streaming decompression functions

size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
 size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
 void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
@@ -499,7 +538,7 @@ size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
 size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
 ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
-

+

Block functions

     Block functions produce and decode raw zstd blocks, without frame metadata.
     Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
@@ -524,10 +563,10 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
         Use ZSTD_insertBlock() in such a case.
 
-

Raw zstd block functions

size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
+

Raw zstd block functions

size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
 size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
-

+

diff --git a/lib/zstd.h b/lib/zstd.h index 3989cc307..66ce13604 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -604,7 +604,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). This information is not required to properly decode a frame. - == Special case : skippable frames == + == Special case : skippable frames == Skippable frames allow integration of user-defined data into a flow of concatenated frames. Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows : From 08611a9f64bc6387e3a1d99a3d16bc0a4f3ee5c7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 7 Dec 2016 14:04:39 +0100 Subject: [PATCH 152/185] removed make artefact --- contrib/gen_html/zstd_manual.html | 564 ------------------------------ 1 file changed, 564 deletions(-) delete mode 100644 contrib/gen_html/zstd_manual.html diff --git a/contrib/gen_html/zstd_manual.html b/contrib/gen_html/zstd_manual.html deleted file mode 100644 index d6465c0b4..000000000 --- a/contrib/gen_html/zstd_manual.html +++ /dev/null @@ -1,564 +0,0 @@ - - - -zstd 1.1.2 Manual - - -

zstd 1.1.2 Manual

-
-

Contents

-
    -
  1. Introduction
  2. -
  3. Version
  4. -
  5. Simple API
  6. -
  7. Explicit memory management
  8. -
  9. Simple dictionary API
  10. -
  11. Fast dictionary API
  12. -
  13. Streaming
  14. -
  15. Streaming compression - HowTo
  16. -
  17. Streaming decompression - HowTo
  18. -
  19. START OF ADVANCED AND EXPERIMENTAL FUNCTIONS
  20. -
  21. Advanced types
  22. -
  23. Advanced compression functions
  24. -
  25. Advanced decompression functions
  26. -
  27. Advanced streaming functions
  28. -
  29. Buffer-less and synchronous inner streaming functions
  30. -
  31. Buffer-less streaming compression (synchronous mode)
  32. -
  33. Buffer-less streaming decompression (synchronous mode)
  34. -
  35. Block functions
  36. -
-
-

Introduction

-  zstd, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios
-  at zlib-level and better compression ratios. The zstd compression library provides in-memory compression and
-  decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
-  Levels >= 20, labelled `--ultra`, should be used with caution, as they require more memory.
-  Compression can be done in:
-    - a single step (described as Simple API)
-    - a single step, reusing a context (described as Explicit memory management)
-    - unbounded multiple steps (described as Streaming compression)
-  The compression ratio achievable on small data can be highly improved using compression with a dictionary in:
-    - a single step (described as Simple dictionary API)
-    - a single step, reusing a dictionary (described as Fast dictionary API)
-
-  Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h.
-  These APIs shall never be used with a dynamic library.
-  They are not "stable", their definition may change in the future. Only static linking is allowed.
-
- -

Version


-
-
unsigned ZSTD_versionNumber(void);   /**< library version number; to be used when checking dll version  */
-

-

Simple API


-
-
size_t ZSTD_compress( void* dst, size_t dstCapacity,
-                            const void* src, size_t srcSize,
-                                  int compressionLevel);
-

Compresses `src` content as a single zstd compressed frame into already allocated `dst`. - Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. - @return : compressed size written into `dst` (<= `dstCapacity), - or an error code if it fails (which can be tested using ZSTD_isError()). -


- -
size_t ZSTD_decompress( void* dst, size_t dstCapacity,
-                              const void* src, size_t compressedSize);
-

`compressedSize` : must be the _exact_ size of a single compressed frame. - `dstCapacity` is an upper bound of originalSize. - If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. - @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), - or an errorCode if it fails (which can be tested using ZSTD_isError()). -


- -
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
-

'src' is the start of a zstd compressed frame. - @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise. - note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. - When `return==0`, data to decompress could be any size. - In which case, it's necessary to use streaming mode to decompress data. - Optionally, application can still use ZSTD_decompress() while relying on implied limits. - (For example, data may be necessarily cut into blocks <= 16 KB). - note 2 : decompressed size is always present when compression is done with ZSTD_compress() - note 3 : decompressed size can be very large (64-bits value), - potentially larger than what local system can handle as a single memory segment. - In which case, it's necessary to use streaming mode to decompress data. - note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. - Always ensure result fits within application's authorized limits. - Each application can set its own limits. - note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. -


- -

Helper functions

int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
-size_t      ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
-unsigned    ZSTD_isError(size_t code);          /*!< tells if a `size_t` function result is an error code */
-const char* ZSTD_getErrorName(size_t code);     /*!< provides readable string from an error code */
-

-

Explicit memory management


-
-
size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
-

Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). -


- -

Decompression context

typedef struct ZSTD_DCtx_s ZSTD_DCtx;
-ZSTD_DCtx* ZSTD_createDCtx(void);
-size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
-

-
size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-

Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). -


- -

Simple dictionary API


-
-
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
-                                           void* dst, size_t dstCapacity,
-                                     const void* src, size_t srcSize,
-                                     const void* dict,size_t dictSize,
-                                           int compressionLevel);
-

Compression using a predefined Dictionary (see dictBuilder/zdict.h). - Note : This function loads the dictionary, resulting in significant startup delay. - Note : When `dict == NULL || dictSize < 8` no dictionary is used. -


- -
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
-                                             void* dst, size_t dstCapacity,
-                                       const void* src, size_t srcSize,
-                                       const void* dict,size_t dictSize);
-

Decompression using a predefined Dictionary (see dictBuilder/zdict.h). - Dictionary must be identical to the one used during compression. - Note : This function loads the dictionary, resulting in significant startup delay. - Note : When `dict == NULL || dictSize < 8` no dictionary is used. -


- -

Fast dictionary API


-
-
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel);
-

When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. - ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. - ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only. - `dict` can be released after ZSTD_CDict creation. -


- -
size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);
-

Function frees memory allocated by ZSTD_createCDict(). -


- -
size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
-                                            void* dst, size_t dstCapacity,
-                                      const void* src, size_t srcSize,
-                                      const ZSTD_CDict* cdict);
-

Compression using a digested Dictionary. - Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. - Note that compression level is decided during dictionary creation. -


- -
ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize);
-

Create a digested dictionary, ready to start decompression operation without startup delay. - `dict` can be released after creation. -


- -
size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);
-

Function frees memory allocated with ZSTD_createDDict() -


- -
size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
-                                              void* dst, size_t dstCapacity,
-                                        const void* src, size_t srcSize,
-                                        const ZSTD_DDict* ddict);
-

Decompression using a digested Dictionary. - Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. -


- -

Streaming


-
-
typedef struct ZSTD_inBuffer_s {
-  const void* src;    /**< start of input buffer */
-  size_t size;        /**< size of input buffer */
-  size_t pos;         /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
-} ZSTD_inBuffer;
-

-
typedef struct ZSTD_outBuffer_s {
-  void*  dst;         /**< start of output buffer */
-  size_t size;        /**< size of output buffer */
-  size_t pos;         /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
-} ZSTD_outBuffer;
-

-

Streaming compression - HowTo

-  A ZSTD_CStream object is required to track streaming operation.
-  Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
-  ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
-  It is recommended to re-use ZSTD_CStream in situations where many streaming operations will be achieved consecutively,
-  since it will play nicer with system's memory, by re-using already allocated memory.
-  Use one separate ZSTD_CStream per thread for parallel execution.
-
-  Start a new compression by initializing ZSTD_CStream.
-  Use ZSTD_initCStream() to start a new compression operation.
-  Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary.
-
-  Use ZSTD_compressStream() repetitively to consume input stream.
-  The function will automatically update both `pos` fields.
-  Note that it may not consume the entire input, in which case `pos < size`,
-  and it's up to the caller to present again remaining data.
-  @return : a size hint, preferred nb of bytes to use as input for next function call
-           (it's just a hint, to help latency a little, any other value will work fine)
-           (note : the size hint is guaranteed to be <= ZSTD_CStreamInSize() )
-            or an error code, which can be tested using ZSTD_isError().
-
-  At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream().
-  `output->pos` will be updated.
-  Note some content might still be left within internal buffer if `output->size` is too small.
-  @return : nb of bytes still present within internal buffer (0 if it's empty)
-            or an error code, which can be tested using ZSTD_isError().
-
-  ZSTD_endStream() instructs to finish a frame.
-  It will perform a flush and write frame epilogue.
-  The epilogue is required for decoders to consider a frame completed.
-  Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
-  In which case, call again ZSTD_endStream() to complete the flush.
-  @return : nb of bytes still present within internal buffer (0 if it's empty)
-            or an error code, which can be tested using ZSTD_isError().
-
- 
-
- -

Streaming compression functions

typedef struct ZSTD_CStream_s ZSTD_CStream;
-ZSTD_CStream* ZSTD_createCStream(void);
-size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
-size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
-size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-

-
size_t ZSTD_CStreamInSize(void);    /**< recommended size for input buffer */
-

-
size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
-

-

Streaming decompression - HowTo

-  A ZSTD_DStream object is required to track streaming operations.
-  Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
-  ZSTD_DStream objects can be re-used multiple times.
-
-  Use ZSTD_initDStream() to start a new decompression operation,
-   or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
-   @return : recommended first input size
-
-  Use ZSTD_decompressStream() repetitively to consume your input.
-  The function will update both `pos` fields.
-  If `input.pos < input.size`, some input has not been consumed.
-  It's up to the caller to present again remaining data.
-  If `output.pos < output.size`, decoder has flushed everything it could.
-  @return : 0 when a frame is completely decoded and fully flushed,
-            an error code, which can be tested using ZSTD_isError(),
-            any other value > 0, which means there is still some decoding to do to complete current frame.
-            The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
- 
-
- -

Streaming decompression functions

typedef struct ZSTD_DStream_s ZSTD_DStream;
-ZSTD_DStream* ZSTD_createDStream(void);
-size_t ZSTD_freeDStream(ZSTD_DStream* zds);
-size_t ZSTD_initDStream(ZSTD_DStream* zds);
-size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-

-
size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */
-

-
size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
-

-

START OF ADVANCED AND EXPERIMENTAL FUNCTIONS

 The definitions in this section are considered experimental.
- They should never be used with a dynamic library, as they may change in the future.
- They are provided for advanced usages.
- Use them only in association with static linking.
- 
-
- -

Advanced types


-
-
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy;   /* from faster to stronger */
-

-
typedef struct {
-    unsigned windowLog;      /**< largest match distance : larger == more compression, more memory needed during decompression */
-    unsigned chainLog;       /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
-    unsigned hashLog;        /**< dispatch table : larger == faster, more memory */
-    unsigned searchLog;      /**< nb of searches : larger == more compression, slower */
-    unsigned searchLength;   /**< match length searched : larger == faster decompression, sometimes less compression */
-    unsigned targetLength;   /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
-    ZSTD_strategy strategy;
-} ZSTD_compressionParameters;
-

-
typedef struct {
-    unsigned contentSizeFlag; /**< 1: content size will be in frame header (if known). */
-    unsigned checksumFlag;    /**< 1: will generate a 22-bits checksum at end of frame, to be used for error detection by decompressor */
-    unsigned noDictIDFlag;    /**< 1: no dict ID will be saved into frame header (if dictionary compression) */
-} ZSTD_frameParameters;
-

-
typedef struct {
-    ZSTD_compressionParameters cParams;
-    ZSTD_frameParameters fParams;
-} ZSTD_parameters;
-

-

Custom memory allocation functions

typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
-typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
-typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
-

-

Advanced compression functions


-
-
size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
-

Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters. - `frameContentSize` is an optional parameter, provide `0` if unknown -


- -
ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
-

Create a ZSTD compression context using external alloc and free functions -


- -
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
-

Gives the amount of memory used by a given ZSTD_CCtx -


- -
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
-                                                  ZSTD_parameters params, ZSTD_customMem customMem);
-

Create a ZSTD_CDict using external alloc and free, and customized compression parameters -


- -
size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
-

Gives the amount of memory used by a given ZSTD_sizeof_CDict -


- -
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
-

same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`. - All fields of `ZSTD_frameParameters` are set to default (0) -


- -
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
-

@return ZSTD_compressionParameters structure for a selected compression level and srcSize. - `srcSize` value is optional, select 0 if not known -


- -
size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
-

Ensure param values remain within authorized range -


- -
ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
-

optimize params for a given `srcSize` and `dictSize`. - both values are optional, select `0` if unknown. -


- -
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
-                                           void* dst, size_t dstCapacity,
-                                     const void* src, size_t srcSize,
-                                     const void* dict,size_t dictSize,
-                                           ZSTD_parameters params);
-

Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter -


- -

Advanced decompression functions


-
-
unsigned ZSTD_isFrame(const void* buffer, size_t size);
-

Tells if the content of `buffer` starts with a valid Frame Identifier. - Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. - Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. - Note 3 : Skippable Frame Identifiers are considered valid. -


- -
size_t ZSTD_estimateDCtxSize(void);
-

Gives the potential amount of memory allocated to create a ZSTD_DCtx -


- -
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
-

Create a ZSTD decompression context using external alloc and free functions -


- -
size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
-

Gives the amount of memory used by a given ZSTD_DCtx -


- -
size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
-

Gives the amount of memory used by a given ZSTD_DDict -


- -
unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
-

Provides the dictID stored within dictionary. - if @return == 0, the dictionary is not conformant with Zstandard specification. - It can still be loaded, but as a content-only dictionary. -


- -
unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
-

Provides the dictID of the dictionary loaded into `ddict`. - If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. - Non-conformant dictionaries can still be loaded, but as content-only dictionaries. -


- -
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
-

Provides the dictID required to decompressed the frame stored within `src`. - If @return == 0, the dictID could not be decoded. - This could for one of the following reasons : - - The frame does not require a dictionary to be decoded (most common case). - - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. - Note : this use case also happens when using a non-conformant dictionary. - - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). - - This is not a Zstandard frame. - When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. -


- -

Advanced streaming functions


-
-

Advanced Streaming compression functions

ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
-size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
-size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
-                                             ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be zero == unknown */
-size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
-size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);  /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before */
-size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
-

-

Advanced Streaming decompression functions

typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
-ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
-size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
-size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
-size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
-size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
-size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
-

-

Buffer-less and synchronous inner streaming functions

-  This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
-  But it's also a complex one, with many restrictions (documented below).
-  Prefer using normal streaming API for an easier experience
- 
-
- -

Buffer-less streaming compression (synchronous mode)

-  A ZSTD_CCtx object is required to track streaming operations.
-  Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
-  ZSTD_CCtx object can be re-used multiple times within successive compression operations.
-
-  Start by initializing a context.
-  Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
-  or ZSTD_compressBegin_advanced(), for finer parameter control.
-  It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
-
-  Then, consume your input using ZSTD_compressContinue().
-  There are some important considerations to keep in mind when using this advanced function :
-  - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
-  - Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks.
-  - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
-    Worst case evaluation is provided by ZSTD_compressBound().
-    ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
-  - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
-    It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
-  - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
-    In which case, it will "discard" the relevant memory section from its history.
-
-  Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
-  It's possible to use a NULL,0 src content, in which case, it will write a final empty block to end the frame,
-  Without last block mark, frames will be considered unfinished (broken) by decoders.
-
-  You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
-
- -

Buffer-less streaming compression functions

size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
-size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
-size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
-size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize);
-size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-

-

Buffer-less streaming decompression (synchronous mode)

-  A ZSTD_DCtx object is required to track streaming operations.
-  Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
-  A ZSTD_DCtx object can be re-used multiple times.
-
-  First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
-  It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
-  such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
-  and the dictionary ID used.
-  (Note : content size is optional, it may not be present. 0 means : content size unknown).
-  Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
-  As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
-  Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
-  Frame parameters are extracted from the beginning of the compressed frame.
-  Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
-  @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
-           >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
-           errorCode, which can be tested using ZSTD_isError().
-
-  Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
-  Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
-
-  Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
-  ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
-  ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
-
-  @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
-  It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some metadata item.
-  It can also be an error code, which can be tested with ZSTD_isError().
-
-  ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
-  They should preferably be located contiguously, prior to current block.
-  Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
-  ZSTD_decompressContinue() is very sensitive to contiguity,
-  if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
-  or that previous contiguous segment is large enough to properly handle maximum back-reference.
-
-  A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
-  Context can then be reset to start a new decompression.
-
-  Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
-  This information is not required to properly decode a frame.
-
-  == Special case : skippable frames ==
-
-  Skippable frames allow integration of user-defined data into a flow of concatenated frames.
-  Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
-  a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
-  b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
-  c) Frame Content - any content (User Data) of length equal to Frame Size
-  For skippable frames ZSTD_decompressContinue() always returns 0.
-  For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
-  It also returns Frame Size as fparamsPtr->frameContentSize.
-
- -
typedef struct {
-    unsigned long long frameContentSize;
-    unsigned windowSize;
-    unsigned dictID;
-    unsigned checksumFlag;
-} ZSTD_frameParams;
-

-

Buffer-less streaming decompression functions

size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
-size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
-size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
-void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
-size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
-size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
-ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
-

-

Block functions

-    Block functions produce and decode raw zstd blocks, without frame metadata.
-    Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
-    User will have to take in charge required information to regenerate data, such as compressed and content sizes.
-
-    A few rules to respect :
-    - Compressing and decompressing require a context structure
-      + Use ZSTD_createCCtx() and ZSTD_createDCtx()
-    - It is necessary to init context before starting
-      + compression : ZSTD_compressBegin()
-      + decompression : ZSTD_decompressBegin()
-      + variants _usingDict() are also allowed
-      + copyCCtx() and copyDCtx() work too
-    - Block size is limited, it must be <= ZSTD_getBlockSizeMax()
-      + If you need to compress more, cut data into multiple blocks
-      + Consider using the regular ZSTD_compress() instead, as frame metadata costs become negligible when source size is large.
-    - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
-      In which case, nothing is produced into `dst`.
-      + User must test for such outcome and deal directly with uncompressed data
-      + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
-      + In case of multiple successive blocks, decoder must be informed of uncompressed block existence to follow proper history.
-        Use ZSTD_insertBlock() in such a case.
-
- -

Raw zstd block functions

size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
-size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
-

- - From c0a1d6deb06610dde890bdd58b1ac4ebaa397152 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 7 Dec 2016 15:58:32 -0800 Subject: [PATCH 153/185] better cleaning --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7d36ab2aa..bb3a4e4ce 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ clean: @$(MAKE) -C $(PRGDIR) $@ > $(VOID) @$(MAKE) -C $(TESTDIR) $@ > $(VOID) @$(MAKE) -C $(ZWRAPDIR) $@ > $(VOID) - @$(RM) zstd$(EXT) + @$(RM) zstd$(EXT) tmp* @echo Cleaning completed From 426a9d4b7128ef54d79627cff346173e833f733a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 7 Dec 2016 16:39:34 -0800 Subject: [PATCH 154/185] changed : dll : only approved ZSTD symbols are now exposed. All other symbols remain internal. --- lib/Makefile | 2 +- lib/deprecated/zbuff.h | 20 ++++++-------------- lib/zstd.h | 10 ++++------ 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index bf1088d68..44c64b8ed 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -70,7 +70,7 @@ libzstd.a: $(ZSTD_FILES) @$(CC) $(FLAGS) -c $^ @$(AR) $(ARFLAGS) $@ *.o -$(LIBZSTD): LDFLAGS += -shared -fPIC +$(LIBZSTD): LDFLAGS += -shared -fPIC -fvisibility=hidden $(LIBZSTD): $(ZSTD_FILES) @echo compiling dynamic library $(LIBVER) ifneq (,$(filter Windows%,$(OS))) diff --git a/lib/deprecated/zbuff.h b/lib/deprecated/zbuff.h index 4956aaaa4..8296dc64a 100644 --- a/lib/deprecated/zbuff.h +++ b/lib/deprecated/zbuff.h @@ -27,20 +27,12 @@ extern "C" { * Dependencies ***************************************/ #include /* size_t */ -#include /* ZSTD_CStream, ZSTD_DStream */ +#include /* ZSTD_CStream, ZSTD_DStream, ZSTDLIB_API */ /* *************************************************************** * Compiler specifics *****************************************************************/ -/* ZSTD_DLL_EXPORT : -* Enable exporting of functions when building a Windows DLL */ -#if defined(_WIN32) && defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) -# define ZSTDLIB_API __declspec(dllexport) -#else -# define ZSTDLIB_API -#endif - /* Deprecation warnings */ /* Should these warnings be a problem, it is generally possible to disable them, @@ -48,17 +40,17 @@ extern "C" { or _CRT_SECURE_NO_WARNINGS in Visual. Otherwise, it's also possible to define ZBUFF_DISABLE_DEPRECATE_WARNINGS */ #ifdef ZBUFF_DISABLE_DEPRECATE_WARNINGS -# define ZBUFF_DEPRECATED(message) /* disable deprecation warnings */ +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API /* disable deprecation warnings */ #else # if (defined(__GNUC__) && (__GNUC__ >= 5)) || defined(__clang__) -# define ZBUFF_DEPRECATED(message) __attribute__((deprecated(message))) +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated(message))) # elif defined(__GNUC__) && (__GNUC__ >= 3) -# define ZBUFF_DEPRECATED(message) __attribute__((deprecated)) +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated)) # elif defined(_MSC_VER) -# define ZBUFF_DEPRECATED(message) __declspec(deprecated(message)) +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API __declspec(deprecated(message)) # else # pragma message("WARNING: You need to implement ZBUFF_DEPRECATED for this compiler") -# define ZBUFF_DEPRECATED(message) +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API # endif #endif /* ZBUFF_DISABLE_DEPRECATE_WARNINGS */ diff --git a/lib/zstd.h b/lib/zstd.h index 3989cc307..b696d643c 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -18,12 +18,10 @@ extern "C" { #include /* size_t */ -/* ====== Export for Windows ======*/ -/* -* ZSTD_DLL_EXPORT : -* Enable exporting of functions when building a Windows DLL -*/ -#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +/* ===== ZSTDLIB_API : control library symbols visibility ===== */ +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define ZSTDLIB_API __attribute__ ((visibility ("default"))) +#elif defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) # define ZSTDLIB_API __declspec(dllexport) #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) # define ZSTDLIB_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ From d2908b9215f7c991206edfe6047f3e413763ed18 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 7 Dec 2016 16:41:33 -0800 Subject: [PATCH 155/185] updated NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 36aa45e91..b4a200ad6 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat +library : changed : only public ZSTD_ symbols are now exposed API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame API : added experimental : dictID retrieval functions From 6323d0050fa1e2ebdb9c0fbbb3f2feb8c9500d63 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 8 Dec 2016 09:06:00 +0100 Subject: [PATCH 156/185] VS projects: restored zbuff for libzstd* --- build/VS2010/libzstd-dll/libzstd-dll.vcxproj | 3 +++ build/VS2010/libzstd/libzstd.vcxproj | 3 +++ 2 files changed, 6 insertions(+) diff --git a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj index 81da84c7d..f85271970 100644 --- a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj +++ b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj @@ -29,6 +29,8 @@ + + @@ -47,6 +49,7 @@ + diff --git a/build/VS2010/libzstd/libzstd.vcxproj b/build/VS2010/libzstd/libzstd.vcxproj index 661c20dfc..f5f30d733 100644 --- a/build/VS2010/libzstd/libzstd.vcxproj +++ b/build/VS2010/libzstd/libzstd.vcxproj @@ -29,6 +29,8 @@ + + @@ -47,6 +49,7 @@ + From 13de72e0cc499b7e509fb7b07d125e4af19de324 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 8 Dec 2016 10:43:55 +0100 Subject: [PATCH 157/185] programs\Makefile: use Linux paths --- programs/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index e7ff3e5a0..2b89ddb57 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -56,8 +56,8 @@ endif # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) EXT =.exe -RES64_FILE = windres\zstd64.res -RES32_FILE = windres\zstd32.res +RES64_FILE = windres/zstd64.res +RES32_FILE = windres/zstd32.res ifneq (,$(filter x86_64%,$(shell $(CC) -dumpmachine))) RES_FILE = $(RES64_FILE) else @@ -80,7 +80,7 @@ zstd : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) zstd : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \ zstdcli.c fileio.c bench.c datagen.c dibio.c ifneq (,$(filter Windows%,$(OS))) - windres\generate_res.bat + windres/generate_res.bat endif $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(LDFLAGS) @@ -89,7 +89,7 @@ zstd32 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) zstd32 : $(ZSTDDIR)/decompress/zstd_decompress.c $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \ zstdcli.c fileio.c bench.c datagen.c dibio.c ifneq (,$(filter Windows%,$(OS))) - windres\generate_res.bat + windres/generate_res.bat endif $(CC) -m32 $(FLAGS) $^ $(RES32_FILE) -o $@$(EXT) @@ -136,7 +136,7 @@ gzstd: clean_decomp_o fi generate_res: - windres\generate_res.bat + windres/generate_res.bat clean: $(MAKE) -C ../lib clean From 128acb35dbcf5ca5de0a62a80815d7699b8a0d7b Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 8 Dec 2016 10:49:59 +0100 Subject: [PATCH 158/185] improved MSYS support --- programs/windres/generate_res.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/windres/generate_res.bat b/programs/windres/generate_res.bat index 76e47fa0a..7ff9aef51 100644 --- a/programs/windres/generate_res.bat +++ b/programs/windres/generate_res.bat @@ -6,6 +6,6 @@ IF ERRORLEVEL 1 ( ECHO The windres.exe is missing. Ensure it is installed and placed in your PATH. EXIT /B ) ELSE ( - windres.exe -I ..\lib -I windres -i windres\zstd.rc -O coff -F pe-x86-64 -o windres\zstd64.res - windres.exe -I ..\lib -I windres -i windres\zstd.rc -O coff -F pe-i386 -o windres\zstd32.res + windres.exe -I ../lib -I windres -i windres/zstd.rc -O coff -F pe-x86-64 -o windres/zstd64.res + windres.exe -I ../lib -I windres -i windres/zstd.rc -O coff -F pe-i386 -o windres/zstd32.res ) From 1d54feb171b279ff6dc121026a706605341e54c6 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 8 Dec 2016 14:00:09 +0100 Subject: [PATCH 159/185] use newer make with AppVeyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index f49d7cf42..27c83c04e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,7 +28,7 @@ install: SET "CLANG_PARAMS=-C tests zstd fullbench fuzzer paramgrill datagen CC=clang MOREFLAGS="--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion"" && SET "PATH_MINGW32=c:\MinGW\bin;c:\MinGW\usr\bin" && SET "PATH_MINGW64=c:\msys64\mingw64\bin;c:\msys64\usr\bin" && - COPY C:\MinGW\bin\mingw32-make.exe C:\MinGW\bin\make.exe && + COPY C:\msys64\usr\bin\make.exe C:\MinGW\bin\make.exe && COPY C:\MinGW\bin\gcc.exe C:\MinGW\bin\cc.exe ) else ( IF [%PLATFORM%]==[x64] (SET ADDITIONALPARAM=/p:LibraryPath="C:\Program Files\Microsoft SDKs\Windows\v7.1\lib\x64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\lib\amd64;") From 16a57525884b3d1445d48ac56918530fe0efa562 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 8 Dec 2016 17:28:26 -0800 Subject: [PATCH 160/185] streaming example uses stable API --- examples/streaming_compression.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index 108a63c83..4c2c1a1d8 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -7,11 +7,9 @@ */ -#include // malloc, exit -#include // fprintf, perror, feof -#include // strerror -#include // errno -#define ZSTD_STATIC_LINKING_ONLY // streaming API defined as "experimental" for the time being +#include // malloc, free, exit +#include // fprintf, perror, feof, fopen, etc. +#include // strlen, memset, strcat #include // presumes zstd library is installed @@ -82,7 +80,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; toRead = ZSTD_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */ if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); } - if (toRead > buffInSize) toRead = buffInSize; /* Safely handle when `buffInSize` is manually changed to a smaller value */ + if (toRead > buffInSize) toRead = buffInSize; /* Safely handle case when `buffInSize` is manually changed to a value < ZSTD_CStreamInSize()*/ fwrite_orDie(buffOut, output.pos, fout); } } From 6e754fe76addd34ad238c0c131b4aede73b442f0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 8 Dec 2016 18:25:36 -0800 Subject: [PATCH 161/185] fixed lib soname. example : simple_compression : size overflow check --- NEWS | 3 ++- examples/simple_compression.c | 21 +++++++++++++-------- lib/Makefile | 4 ++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index b4a200ad6..f6f1ad90b 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,8 @@ cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat -library : changed : only public ZSTD_ symbols are now exposed +lib : changed : only public ZSTD_ symbols are now exposed +lib : fixed : soname API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame API : added experimental : dictID retrieval functions diff --git a/examples/simple_compression.c b/examples/simple_compression.c index 332ce721b..deb0bbfc4 100644 --- a/examples/simple_compression.c +++ b/examples/simple_compression.c @@ -8,9 +8,9 @@ -#include // malloc, exit -#include // fprintf, perror -#include // strerror +#include // malloc, free, exit +#include // fprintf, perror, fopen, etc. +#include // strlen, strcat, memset, strerror #include // errno #include // stat #include // presumes zstd library is installed @@ -45,13 +45,18 @@ static void* malloc_orDie(size_t size) static void* loadFile_orDie(const char* fileName, size_t* size) { - off_t const buffSize = fsize_orDie(fileName); + off_t const fileSize = fsize_orDie(fileName); + size_t const buffSize = (size_t)fileSize; + if ((off_t)buffSize < fileSize) { /* narrowcast overflow */ + fprintf(stderr, "%s : filesize too large \n", fileName); + exit(4); + } FILE* const inFile = fopen_orDie(fileName, "rb"); void* const buffer = malloc_orDie(buffSize); size_t const readSize = fread(buffer, 1, buffSize, inFile); if (readSize != (size_t)buffSize) { fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); - exit(4); + exit(5); } fclose(inFile); /* can't fail, read only */ *size = buffSize; @@ -65,11 +70,11 @@ static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSi size_t const wSize = fwrite(buff, 1, buffSize, oFile); if (wSize != (size_t)buffSize) { fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno)); - exit(5); + exit(6); } if (fclose(oFile)) { perror(fileName); - exit(6); + exit(7); } } @@ -84,7 +89,7 @@ static void compress_orDie(const char* fname, const char* oname) size_t const cSize = ZSTD_compress(cBuff, cBuffSize, fBuff, fSize, 1); if (ZSTD_isError(cSize)) { fprintf(stderr, "error compressing %s : %s \n", fname, ZSTD_getErrorName(cSize)); - exit(7); + exit(8); } saveFile_orDie(oname, cBuff, cSize); diff --git a/lib/Makefile b/lib/Makefile index 44c64b8ed..21a805d05 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -47,9 +47,9 @@ ifeq ($(shell uname), Darwin) SHARED_EXT = dylib SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT) SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) - SONAME_FLAGS = -install_name $(PREFIX)/lib/$@.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) + SONAME_FLAGS = -install_name $(PREFIX)/lib/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) else - SONAME_FLAGS = -Wl,-soname=$@.$(SHARED_EXT).$(LIBVER_MAJOR) + SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) SHARED_EXT = so SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR) SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) From 383b8088a33530500131a17b50b687fade2b199b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 8 Dec 2016 18:42:27 -0800 Subject: [PATCH 162/185] minor lib build refactoring --- NEWS | 1 - lib/Makefile | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index f6f1ad90b..7f30f2d52 100644 --- a/NEWS +++ b/NEWS @@ -6,7 +6,6 @@ cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat lib : changed : only public ZSTD_ symbols are now exposed -lib : fixed : soname API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame API : added experimental : dictID retrieval functions diff --git a/lib/Makefile b/lib/Makefile index 21a805d05..fcc0d099d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -47,7 +47,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 $(PREFIX)/lib/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) + SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) else SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) SHARED_EXT = so @@ -107,15 +107,15 @@ libzstd.pc: libzstd.pc.in install: libzstd.a libzstd libzstd.pc @install -d -m 755 $(DESTDIR)$(LIBDIR)/pkgconfig/ $(DESTDIR)$(INCLUDEDIR)/ - @install -m 755 libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_VER) + @install -m 755 libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR) @cp -a libzstd.$(SHARED_EXT_MAJOR) $(DESTDIR)$(LIBDIR) @cp -a libzstd.$(SHARED_EXT) $(DESTDIR)$(LIBDIR) @cp -a libzstd.pc $(DESTDIR)$(LIBDIR)/pkgconfig/ - @install -m 644 libzstd.a $(DESTDIR)$(LIBDIR)/libzstd.a - @install -m 644 zstd.h $(DESTDIR)$(INCLUDEDIR)/zstd.h - @install -m 644 common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h - @install -m 644 deprecated/zbuff.h $(DESTDIR)$(INCLUDEDIR)/zbuff.h # prototypes generate deprecation warnings - @install -m 644 dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)/zdict.h + @install -m 644 libzstd.a $(DESTDIR)$(LIBDIR) + @install -m 644 zstd.h $(DESTDIR)$(INCLUDEDIR) + @install -m 644 common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR) + @install -m 644 deprecated/zbuff.h $(DESTDIR)$(INCLUDEDIR) # prototypes generate deprecation warnings + @install -m 644 dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR) @echo zstd static and shared library installed uninstall: From 0012332ce0acf589da4831e9f9b2e79ce12eed9d Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 9 Dec 2016 17:15:33 -0800 Subject: [PATCH 163/185] Fix compression segfault When the overflow protection kicks in, it makes sure that ip - ctx->base isn't too large. However, it didn't ensure that saved offsets are still valid. This change ensures that any valid offsets (<= windowLog) are still representable after the update. The bug would shop up on line 1056, when `offset_1 > current + 1`, which causes an underflow. This in turn, would cause a segfault on line 1063. The input must necessarily be longer than 1 GB for this issue to occur. Even then, it only occurs if one of the last 3 matches is larger than the chain size and block size. --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 665d09c0f..a575534c3 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2277,7 +2277,7 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (cctx->lowLimit > (1<<30)) { U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; - U32 const supLog = MAX(cctx->params.cParams.chainLog, 17 /* blockSize */); + U32 const supLog = MAX(MAX(cctx->params.cParams.chainLog, 17 /* blockSize */), cctx->params.cParams.windowLog); U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */ U32 const correction = cctx->lowLimit - newLowLimit; ZSTD_reduceIndex(cctx, correction); From 3826207a70779477703fcfe11f652d5cea9cff8c Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 18:46:55 -0800 Subject: [PATCH 164/185] Simplify segfault fix Take advantage of the fact that `chainLog <= windowLog`. --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index a575534c3..aef769fc0 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2277,7 +2277,7 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (cctx->lowLimit > (1<<30)) { U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; - U32 const supLog = MAX(MAX(cctx->params.cParams.chainLog, 17 /* blockSize */), cctx->params.cParams.windowLog); + U32 const supLog = MAX(cctx->params.cParams.windowLog, 17 /* blockSize */); U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */ U32 const correction = cctx->lowLimit - newLowLimit; ZSTD_reduceIndex(cctx, correction); From 0acae734f17e43ccceb8bd6bd3f1eee0d179ca9f Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 19:12:13 -0800 Subject: [PATCH 165/185] Add exposing test case --- tests/.gitignore | 1 + tests/Makefile | 10 +++++-- tests/longmatch.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 tests/longmatch.c diff --git a/tests/.gitignore b/tests/.gitignore index c8f9ae79e..b558ac258 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -11,6 +11,7 @@ datagen paramgrill paramgrill32 roundTripCrash +longmatch # Tmp test directory zstdtest diff --git a/tests/Makefile b/tests/Makefile index fbee21448..6110465f6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -124,6 +124,9 @@ datagen : $(PRGDIR)/datagen.c datagencli.c roundTripCrash : $(ZSTD_FILES) roundTripCrash.c $(CC) $(FLAGS) $^ -o $@$(EXT) +longmatch : $(ZSTD_FILES) longmatch.c + $(CC) $(FLAGS) $^ -o $@$(EXT) + namespaceTest: if $(CC) namespaceTest.c ../lib/common/xxhash.c -o $@ ; then echo compilation should fail; exit 1 ; fi $(RM) $@ @@ -140,7 +143,7 @@ clean: fullbench-lib$(EXT) fullbench-dll$(EXT) \ fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \ zstreamtest$(EXT) zstreamtest32$(EXT) \ - datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) + datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) @echo Cleaning completed @@ -180,7 +183,7 @@ zstd-playTests: datagen file $(ZSTD) ZSTD="$(QEMU_SYS) $(ZSTD)" ./playTests.sh $(ZSTDRTTEST) -test: test-zstd test-fullbench test-fuzzer test-zstream +test: test-zstd test-fullbench test-fuzzer test-zstream test-longmatch test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zstream32 @@ -237,4 +240,7 @@ test-zstream: zstreamtest test-zstream32: zstreamtest32 $(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) +test-longmatch: longmatch + $(QEMU_SYS) ./longmatch + endif diff --git a/tests/longmatch.c b/tests/longmatch.c new file mode 100644 index 000000000..b99dccc6f --- /dev/null +++ b/tests/longmatch.c @@ -0,0 +1,72 @@ +#define ZSTD_STATIC_LINKING_ONLY +#include +#include +#include +#include + +void compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { + ZSTD_inBuffer in = { data, size, 0 }; + while (in.pos < in.size) { + ZSTD_outBuffer tmp = out; + const size_t rc = ZSTD_compressStream(ctx, &tmp, &in); + if (ZSTD_isError(rc)) { + exit(5); + } + } + ZSTD_outBuffer tmp = out; + const size_t rc = ZSTD_flushStream(ctx, &tmp); + if (rc != 0) { exit(6); } +} + +int main() { + ZSTD_CStream *ctx; + ZSTD_parameters params = {}; + size_t rc; + unsigned windowLog; + /* Create stream */ + ctx = ZSTD_createCStream(); + if (!ctx) { return 1; } + /* Set parameters */ + params.cParams.windowLog = 18; + params.cParams.chainLog = 13; + params.cParams.hashLog = 14; + params.cParams.searchLog = 1; + params.cParams.searchLength = 7; + params.cParams.targetLength = 16; + params.cParams.strategy = ZSTD_fast; + windowLog = params.cParams.windowLog; + /* Initialize stream */ + rc = ZSTD_initCStream_advanced(ctx, NULL, 0, params, 0); + if (ZSTD_isError(rc)) { return 2; } + { + uint64_t compressed = 0; + const uint64_t toCompress = ((uint64_t)1) << 33; + const size_t size = 1 << windowLog; + size_t pos = 0; + char *srcBuffer = (char*) malloc(1 << windowLog); + char *dstBuffer = (char*) malloc(ZSTD_compressBound(1 << windowLog)); + ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 }; + const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const size_t randomData = (1 << windowLog) - 2*sizeof(match); + for (size_t i = 0; i < sizeof(match); ++i) { + srcBuffer[i] = match[i]; + } + for (size_t i = 0; i < randomData; ++i) { + srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF); + } + for (size_t i = 0; i < sizeof(match); ++i) { + srcBuffer[sizeof(match) + randomData + i] = match[i]; + } + compress(ctx, out, srcBuffer, size); + compressed += size; + while (compressed < toCompress) { + const size_t block = rand() % (size - pos + 1); + if (pos == size) { pos = 0; } + compress(ctx, out, srcBuffer + pos, block); + pos += block; + compressed += block; + } + free(srcBuffer); + free(dstBuffer); + } +} From 5cc85cf18398cde78cef206a4f0ef381c0d91846 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 19:31:55 -0800 Subject: [PATCH 166/185] Switch uint64_t to U64 --- tests/longmatch.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/longmatch.c b/tests/longmatch.c index b99dccc6f..46dcbc77a 100644 --- a/tests/longmatch.c +++ b/tests/longmatch.c @@ -1,8 +1,10 @@ #define ZSTD_STATIC_LINKING_ONLY -#include +#include "zstd.h" +#include "mem.h" #include #include #include +#include void compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { ZSTD_inBuffer in = { data, size, 0 }; @@ -39,8 +41,8 @@ int main() { rc = ZSTD_initCStream_advanced(ctx, NULL, 0, params, 0); if (ZSTD_isError(rc)) { return 2; } { - uint64_t compressed = 0; - const uint64_t toCompress = ((uint64_t)1) << 33; + U64 compressed = 0; + const U64 toCompress = ((U64)1) << 33; const size_t size = 1 << windowLog; size_t pos = 0; char *srcBuffer = (char*) malloc(1 << windowLog); From b547d212a191c6cd7c2b0b4b942833ac8c360c33 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 23:17:36 -0800 Subject: [PATCH 167/185] Fix longmatch test build errors. --- tests/longmatch.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/tests/longmatch.c b/tests/longmatch.c index 46dcbc77a..c75c0d18e 100644 --- a/tests/longmatch.c +++ b/tests/longmatch.c @@ -6,29 +6,35 @@ #include #include -void compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { +int compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { ZSTD_inBuffer in = { data, size, 0 }; while (in.pos < in.size) { ZSTD_outBuffer tmp = out; const size_t rc = ZSTD_compressStream(ctx, &tmp, &in); if (ZSTD_isError(rc)) { - exit(5); + return 1; } } - ZSTD_outBuffer tmp = out; - const size_t rc = ZSTD_flushStream(ctx, &tmp); - if (rc != 0) { exit(6); } + { + ZSTD_outBuffer tmp = out; + const size_t rc = ZSTD_flushStream(ctx, &tmp); + if (rc != 0) { return 1; } + } + return 0; } -int main() { +int main(int argc, const char** argv) { ZSTD_CStream *ctx; - ZSTD_parameters params = {}; + ZSTD_parameters params; size_t rc; unsigned windowLog; + (void)argc; + (void)argv; /* Create stream */ ctx = ZSTD_createCStream(); if (!ctx) { return 1; } /* Set parameters */ + memset(¶ms, 0, sizeof(params)); params.cParams.windowLog = 18; params.cParams.chainLog = 13; params.cParams.hashLog = 14; @@ -50,25 +56,31 @@ int main() { ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 }; const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; const size_t randomData = (1 << windowLog) - 2*sizeof(match); - for (size_t i = 0; i < sizeof(match); ++i) { + size_t i; + for (i = 0; i < sizeof(match); ++i) { srcBuffer[i] = match[i]; } - for (size_t i = 0; i < randomData; ++i) { + for (i = 0; i < randomData; ++i) { srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF); } - for (size_t i = 0; i < sizeof(match); ++i) { + for (i = 0; i < sizeof(match); ++i) { srcBuffer[sizeof(match) + randomData + i] = match[i]; } - compress(ctx, out, srcBuffer, size); + if (compress(ctx, out, srcBuffer, size)) { + return 1; + } compressed += size; while (compressed < toCompress) { const size_t block = rand() % (size - pos + 1); if (pos == size) { pos = 0; } - compress(ctx, out, srcBuffer + pos, block); + if (compress(ctx, out, srcBuffer + pos, block)) { + return 1; + } pos += block; compressed += block; } free(srcBuffer); free(dstBuffer); } + return 0; } From c261f71f6a85dfcf66f612357782bd29acbb44c1 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 12 Dec 2016 00:25:07 +0100 Subject: [PATCH 168/185] minor variation of rescale fix --- NEWS | 9 +++++---- lib/compress/zstd_compress.c | 12 +++++++----- tests/longmatch.c | 10 +++++++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 7f30f2d52..dc6c93234 100644 --- a/NEWS +++ b/NEWS @@ -1,14 +1,15 @@ v1.1.2 -Improved : faster decompression speed at ultra compression settings and in 32-bits mode +Improved : faster decompression speed at ultra compression settings and 32-bits mode cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat +lib : fixed : bug in streaming compression, by Nick Terrell lib : changed : only public ZSTD_ symbols are now exposed -API : changed : zbuff prototypes now generate deprecation warnings -API : changed : streaming decompression implicit reset on starting new frame -API : added experimental : dictID retrieval functions +API : zbuff : changed : prototypes now generate deprecation warnings +API : streaming : decompression : changed : implicit reset on starting new frames without init +API : experimental : added : dictID retrieval functions zlib_wrapper : added support for gz* functions, by Przemyslaw Skibinski Changed : zbuff source files moved to lib/deprecated Changed : reduced stack memory use diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index aef769fc0..35201a3a2 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -33,6 +33,7 @@ typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZS /*-************************************* * Helper functions ***************************************/ +#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; } size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; } @@ -2274,16 +2275,17 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (remaining < blockSize) blockSize = remaining; /* preemptive overflow correction */ - if (cctx->lowLimit > (1<<30)) { + if (cctx->lowLimit > (2U<<30)) { U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; - U32 const supLog = MAX(cctx->params.cParams.windowLog, 17 /* blockSize */); - U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */ - U32 const correction = cctx->lowLimit - newLowLimit; + U32 const current = (U32)(ip - cctx->base); + U32 const newCurrent = (current & chainMask) + (1 << cctx->params.cParams.windowLog); + U32 const correction = current - newCurrent; + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30); ZSTD_reduceIndex(cctx, correction); cctx->base += correction; cctx->dictBase += correction; - cctx->lowLimit = newLowLimit; + cctx->lowLimit -= correction; cctx->dictLimit -= correction; if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0; else cctx->nextToUpdate -= correction; diff --git a/tests/longmatch.c b/tests/longmatch.c index c75c0d18e..61b81b359 100644 --- a/tests/longmatch.c +++ b/tests/longmatch.c @@ -1,10 +1,10 @@ -#define ZSTD_STATIC_LINKING_ONLY -#include "zstd.h" -#include "mem.h" #include #include #include #include +#include "mem.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" int compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { ZSTD_inBuffer in = { data, size, 0 }; @@ -57,6 +57,8 @@ int main(int argc, const char** argv) { const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; const size_t randomData = (1 << windowLog) - 2*sizeof(match); size_t i; + printf("\n === Long Match Test === \n"); + printf("Creating random data to produce long matches \n"); for (i = 0; i < sizeof(match); ++i) { srcBuffer[i] = match[i]; } @@ -66,6 +68,7 @@ int main(int argc, const char** argv) { for (i = 0; i < sizeof(match); ++i) { srcBuffer[sizeof(match) + randomData + i] = match[i]; } + printf("Compressing, trying to generate a segfault \n"); if (compress(ctx, out, srcBuffer, size)) { return 1; } @@ -79,6 +82,7 @@ int main(int argc, const char** argv) { pos += block; compressed += block; } + printf("Compression completed successfully (no error triggered)\n"); free(srcBuffer); free(dstBuffer); } From c3a5c4bef8e3ed2dac9407f08a381c3dfb431cd2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 12 Dec 2016 00:47:30 +0100 Subject: [PATCH 169/185] introduced cycleLog --- lib/compress/zstd_compress.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 35201a3a2..6e52ec8ec 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -149,6 +149,14 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) } +/** ZSTD_cycleLog() : + * condition for correct operation : hashLog > 1 */ +static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) +{ + U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2); + return hashLog - btScale; +} + /** ZSTD_adjustCParams() : optimize `cPar` for a given input (`srcSize` and `dictSize`). mostly downsizing to reduce memory consumption and initialization. @@ -167,9 +175,9 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; } } if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog; - { U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) | (cPar.strategy == ZSTD_btopt) | (cPar.strategy == ZSTD_btopt2); - U32 const maxChainLog = cPar.windowLog+btPlus; - if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */ + { U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); + if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog); + } if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ @@ -2276,10 +2284,9 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, /* preemptive overflow correction */ if (cctx->lowLimit > (2U<<30)) { - U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); - U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; + U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1; U32 const current = (U32)(ip - cctx->base); - U32 const newCurrent = (current & chainMask) + (1 << cctx->params.cParams.windowLog); + U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog); U32 const correction = current - newCurrent; ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30); ZSTD_reduceIndex(cctx, correction); From fda539f50b5f8e9c63df546ef952a75eba4505b6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 12 Dec 2016 01:03:23 +0100 Subject: [PATCH 170/185] minor coding style changes --- programs/util.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/programs/util.h b/programs/util.h index fd07c348a..012c20c49 100644 --- a/programs/util.h +++ b/programs/util.h @@ -25,7 +25,7 @@ extern "C" { # define _CRT_SECURE_NO_DEPRECATE /* VS2005 */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ #if _MSC_VER <= 1800 /* (1800 = Visual Studio 2013) */ - #define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */ +# define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */ #endif #endif @@ -49,11 +49,11 @@ extern "C" { #include /* stat, utime */ #include /* stat */ #if defined(_MSC_VER) - #include /* utime */ - #include /* _chmod */ +# include /* utime */ +# include /* _chmod */ #else - #include /* chown, stat */ - #include /* utime */ +# include /* chown, stat */ +# include /* utime */ #endif #include /* time */ #include @@ -406,16 +406,15 @@ UTIL_STATIC const char** UTIL_createFileList(const char **inputNames, unsigned i { size_t pos; unsigned i, nbFiles; - char *bufend, *buf; + char* buf = (char*)malloc(LIST_SIZE_INCREASE); + char* bufend = buf + LIST_SIZE_INCREASE; const char** fileTable; - buf = (char*)malloc(LIST_SIZE_INCREASE); if (!buf) return NULL; - bufend = buf + LIST_SIZE_INCREASE; for (i=0, pos=0, nbFiles=0; i= bufend) { ptrdiff_t newListSize = (bufend - buf) + LIST_SIZE_INCREASE; buf = (char*)UTIL_realloc(buf, newListSize); @@ -437,8 +436,7 @@ UTIL_STATIC const char** UTIL_createFileList(const char **inputNames, unsigned i fileTable = (const char**)malloc((nbFiles+1) * sizeof(const char*)); if (!fileTable) { free(buf); return NULL; } - for (i=0, pos=0; i Date: Mon, 12 Dec 2016 11:23:21 +0100 Subject: [PATCH 171/185] turn on the '-r' option for *BSD and Solaris --- programs/util.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/programs/util.h b/programs/util.h index fd07c348a..20fb493f4 100644 --- a/programs/util.h +++ b/programs/util.h @@ -325,7 +325,8 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_ return nbFiles; } -#elif (defined(__APPLE__) && defined(__MACH__)) || \ +#elif (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || \ + defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ ((defined(__unix__) || defined(__unix) || defined(__midipix__)) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) /* snprintf, opendir */ # define UTIL_HAS_CREATEFILELIST # include /* opendir, readdir */ From 242c03687588ab5e0d7cdc402ef7a9df9ad3d361 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 12 Dec 2016 11:59:17 +0100 Subject: [PATCH 172/185] turn on the '-r' option for HP-UX and AIX --- programs/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/util.h b/programs/util.h index 20fb493f4..7552250dd 100644 --- a/programs/util.h +++ b/programs/util.h @@ -325,7 +325,7 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_ return nbFiles; } -#elif (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || \ +#elif (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) || \ defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ ((defined(__unix__) || defined(__unix) || defined(__midipix__)) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) /* snprintf, opendir */ # define UTIL_HAS_CREATEFILELIST From c855da75330291a71d8d6e76f0424c75c544071f Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 12 Dec 2016 15:37:43 +0100 Subject: [PATCH 173/185] allow all operationg systems with _POSIX_C_SOURCE >= 200112L --- programs/util.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/programs/util.h b/programs/util.h index 7552250dd..e7c6b0569 100644 --- a/programs/util.h +++ b/programs/util.h @@ -325,9 +325,10 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_ return nbFiles; } -#elif (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) || \ +#elif (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) || \ + (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) || \ defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ - ((defined(__unix__) || defined(__unix) || defined(__midipix__)) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) /* snprintf, opendir */ + (defined(__linux__) && defined(_POSIX_C_SOURCE)) /* opendir */ # define UTIL_HAS_CREATEFILELIST # include /* opendir, readdir */ From 12df6da83b9837f30e1591cc15064a1d289ca554 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 12 Dec 2016 19:22:47 +0100 Subject: [PATCH 174/185] Fix running test suite on FreeBSD * Remove last bashism from tests/playTests.sh * Use gmd5sum from the sysutils/coreutils port --- tests/playTests.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 6179265e7..abde72c80 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -31,8 +31,10 @@ case "$OS" in ;; esac -case "$OSTYPE" in - darwin*) MD5SUM="md5 -r" ;; +UNAME=$(uname) +case "$UNAME" in + Darwin) MD5SUM="md5 -r" ;; + FreeBSD) MD5SUM="gmd5sum" ;; *) MD5SUM="md5sum" ;; esac @@ -228,8 +230,8 @@ cp ../programs/*.h dirTestDict $MD5SUM dirTestDict/* > tmph1 $ZSTD -f --rm dirTestDict/* -D tmpDictC $ZSTD -d --rm dirTestDict/*.zst -D tmpDictC # note : use internal checksum by default -case "$OSTYPE" in - darwin*) $ECHO "md5sum -c not supported on OS-X : test skipped" ;; # not compatible with OS-X's md5 +case "$UNAME" in + Darwin) $ECHO "md5sum -c not supported on OS-X : test skipped" ;; # not compatible with OS-X's md5 *) $MD5SUM -c tmph1 ;; esac rm -rf dirTestDict From 83cc2fb083c1f757a23d75173cdf1f104759f77c Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 12 Dec 2016 19:24:51 +0100 Subject: [PATCH 175/185] Enable using isatty() and nanosleep() on *BSD --- contrib/pzstd/Options.cpp | 10 ++-------- programs/util.h | 2 +- programs/zstdcli.c | 3 ++- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp index 18c069eae..0b1403354 100644 --- a/contrib/pzstd/Options.cpp +++ b/contrib/pzstd/Options.cpp @@ -22,19 +22,13 @@ defined(__CYGWIN__) #include /* _isatty */ #define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) -#else -#if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \ - defined(_POSIX_SOURCE) || \ - (defined(__APPLE__) && \ - defined( \ - __MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ \ - */ +#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) || \ + defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ #include /* isatty */ #define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #else #define IS_CONSOLE(stdStream) 0 #endif -#endif namespace pzstd { diff --git a/programs/util.h b/programs/util.h index 3d5c44642..0fa70577a 100644 --- a/programs/util.h +++ b/programs/util.h @@ -98,7 +98,7 @@ extern "C" { # define SET_HIGH_PRIORITY /* disabled */ # endif # define UTIL_sleep(s) sleep(s) -# if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L) +# if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)) # define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); } # else # define UTIL_sleepMilli(milli) /* disabled */ diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 7ffb0bb62..561730a5f 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -43,7 +43,8 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) # include /* _isatty */ # define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) -#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ +#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) || \ + defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ # include /* isatty */ # define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #else From e474aa55b4d6b52d5e7d97db163835f208415a12 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 12 Dec 2016 18:05:30 -0800 Subject: [PATCH 176/185] Fix decompression buffer overrun Allows an adversary to write up to 3 bytes beyond the end of the buffer. Occurs if the match overlaps the `extDict` and `currentPrefix`, and the match length in the `currentPrefix` is less than `MINMATCH`, and `op-(16-MINMATCH) >= oMatchEnd > op-16`. --- lib/decompress/zstd_decompress.c | 8 ++++---- lib/legacy/zstd_v01.c | 2 +- lib/legacy/zstd_v02.c | 2 +- lib/legacy/zstd_v03.c | 2 +- lib/legacy/zstd_v04.c | 4 ++-- lib/legacy/zstd_v05.c | 4 ++-- lib/legacy/zstd_v06.c | 2 +- lib/legacy/zstd_v07.c | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 70dd4ccaa..1422d2b3b 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -963,13 +963,13 @@ size_t ZSTD_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_w) { + if (op > oend_w || sequence.matchLength < MINMATCH) { U32 i; for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; return sequenceLength; } } } - /* Requirement: op <= oend_w */ + /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ /* match within prefix */ if (sequence.offset < 8) { @@ -1183,13 +1183,13 @@ size_t ZSTD_execSequenceLong(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_w) { + if (op > oend_w || sequence.matchLength < MINMATCH) { U32 i; for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; return sequenceLength; } } } - /* Requirement: op <= oend_w */ + /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ #endif /* match within prefix */ diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index 5c36c2108..7c8b0f1e6 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -1803,7 +1803,7 @@ static size_t ZSTD_execSequence(BYTE* op, } else { ZSTD_copy8(op, match); } op += 8; match += 8; - if (endMatch > oend-12) + if (endMatch > oend-(16-MINMATCH)) { if (op < oend-8) { diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index ed082aad7..135b5bc90 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -3206,7 +3206,7 @@ static size_t ZSTD_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index 321450670..8cb5928fb 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -2847,7 +2847,7 @@ static size_t ZSTD_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 11b5481a1..60cde97c5 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -3107,7 +3107,7 @@ static size_t ZSTD_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_8) { + if (op > oend_8 || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } @@ -3134,7 +3134,7 @@ static size_t ZSTD_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index bf1235a35..3dcf70399 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -3325,7 +3325,7 @@ static size_t ZSTDv05_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_8) { + if (op > oend_8 || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } @@ -3348,7 +3348,7 @@ static size_t ZSTDv05_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) { + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { ZSTDv05_wildcopy(op, match, oend_8 - op); match += oend_8 - op; diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 6584d4858..8aa6dc999 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -3470,7 +3470,7 @@ size_t ZSTDv06_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_8) { + if (op > oend_8 || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 2ae6c5ad2..7719ba089 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -3693,7 +3693,7 @@ size_t ZSTDv07_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_w) { + if (op > oend_w || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } From 064a143520ded4d8410c63220fa9b3630a40c503 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 12 Dec 2016 19:01:23 -0800 Subject: [PATCH 177/185] Fix execSequence wildcopy undefined behavior execSequence relied on pointer overflow to handle cases where `sequence.matchLength < 8`. Instead of passing an `size_t` to wildcopy, pass a `ptrdiff_t`. --- lib/common/zstd_internal.h | 2 +- lib/decompress/zstd_decompress.c | 4 ++-- lib/legacy/zstd_v01.c | 4 ++-- lib/legacy/zstd_v02.c | 4 ++-- lib/legacy/zstd_v03.c | 4 ++-- lib/legacy/zstd_v04.c | 4 ++-- lib/legacy/zstd_v05.c | 4 ++-- lib/legacy/zstd_v06.c | 4 ++-- lib/legacy/zstd_v07.c | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index a5002fb11..96e057758 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -147,7 +147,7 @@ static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); } /*! ZSTD_wildcopy() : * custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */ #define WILDCOPY_OVERLENGTH 8 -MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, size_t length) +MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length) { const BYTE* ip = (const BYTE*)src; BYTE* op = (BYTE*)dst; diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 70dd4ccaa..ce91c0aff 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -997,7 +997,7 @@ size_t ZSTD_execSequence(BYTE* op, } while (op < oMatchEnd) *op++ = *match++; } else { - ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ } return sequenceLength; } @@ -1218,7 +1218,7 @@ size_t ZSTD_execSequenceLong(BYTE* op, } while (op < oMatchEnd) *op++ = *match++; } else { - ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ } return sequenceLength; } diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index 5c36c2108..376aefe2d 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -1354,7 +1354,7 @@ static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); } #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } -static void ZSTD_wildcopy(void* dst, const void* src, size_t length) +static void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length) { const BYTE* ip = (const BYTE*)src; BYTE* op = (BYTE*)dst; @@ -1814,7 +1814,7 @@ static size_t ZSTD_execSequence(BYTE* op, while (op Date: Tue, 13 Dec 2016 11:45:19 +0100 Subject: [PATCH 178/185] updated NEWS --- NEWS | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index dc6c93234..35e0e5820 100644 --- a/NEWS +++ b/NEWS @@ -1,18 +1,19 @@ v1.1.2 -Improved : faster decompression speed at ultra compression settings and 32-bits mode +API : streaming : decompression : changed : implicit reset on starting new frames without init +API : experimental : added : dictID retrieval functions +API : zbuff : changed : prototypes now generate deprecation warnings +lib : improved : faster decompression speed at ultra compression settings and 32-bits mode +lib : changed : only public ZSTD_ symbols are now exposed +lib : changed : reduced usage of stack memory +lib : fixed : several corner case bugs, by Nick Terrell cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat -lib : fixed : bug in streaming compression, by Nick Terrell -lib : changed : only public ZSTD_ symbols are now exposed -API : zbuff : changed : prototypes now generate deprecation warnings -API : streaming : decompression : changed : implicit reset on starting new frames without init -API : experimental : added : dictID retrieval functions zlib_wrapper : added support for gz* functions, by Przemyslaw Skibinski -Changed : zbuff source files moved to lib/deprecated -Changed : reduced stack memory use +install : better compatibility with FreeBSD, by Dimitry Andric +source tree : changed : zbuff source files moved to lib/deprecated v1.1.1 New : command -M#, --memory=, --memlimit=, --memlimit-decompress= to limit allowed memory consumption From 5397a66b19400255623494acd2caa7847b775700 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 13 Dec 2016 15:21:06 +0100 Subject: [PATCH 179/185] minor BMI version check --- lib/common/bitstream.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index e96798fe4..3a45244f8 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -266,7 +266,7 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); bitD->bitContainer = MEM_readLEST(bitD->ptr); { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; - bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } } else { bitD->start = (const char*)srcBuffer; @@ -298,7 +298,7 @@ MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) { -#if defined(__BMI__) && defined(__GNUC__) /* experimental */ +#if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */ # if defined(__x86_64__) if (sizeof(bitContainer)==8) return _bextr_u64(bitContainer, start, nbBits); @@ -367,10 +367,10 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) } /*! BIT_reloadDStream() : -* Refill `BIT_DStream_t` from src buffer previously defined (see BIT_initDStream() ). +* Refill `bitD` from buffer previously set in BIT_initDStream() . * This function is safe, it guarantees it will not read beyond src buffer. * @return : status of `BIT_DStream_t` internal register. - if status == unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */ + if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) { if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */ From e795c8a5f6cf07e913bf0766e44e4b8a5fad9ef0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 13 Dec 2016 16:39:36 +0100 Subject: [PATCH 180/185] Added ZSTD_initCStream_srcSize(). Added relevant test cases in zstreamtest --- lib/compress/zstd_compress.c | 14 +++++++++++ lib/deprecated/zbuff.h | 4 +--- lib/zstd.h | 19 +++++++-------- tests/Makefile | 4 ++-- tests/zbufftest.c | 10 ++++---- tests/zstreamtest.c | 45 +++++++++++++++++++++++++++--------- 6 files changed, 66 insertions(+), 30 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 6e52ec8ec..3d10fbd96 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2852,6 +2852,8 @@ struct ZSTD_CStream_s { ZSTD_cStreamStage stage; U32 checksum; U32 frameEnded; + U64 pledgedSrcSize; + U64 inputProcessed; ZSTD_parameters params; ZSTD_customMem customMem; }; /* typedef'd to ZSTD_CStream within "zstd.h" */ @@ -2909,6 +2911,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize) zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; zcs->stage = zcss_load; zcs->frameEnded = 0; + zcs->pledgedSrcSize = pledgedSrcSize; + zcs->inputProcessed = 0; return 0; /* ready to go */ } @@ -2961,6 +2965,12 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t di return ZSTD_initCStream_advanced(zcs, dict, dictSize, params, 0); } +size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize) +{ + ZSTD_parameters const params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0); + return ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize); +} + size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) { return ZSTD_initCStream_usingDict(zcs, NULL, 0, compressionLevel); @@ -3057,6 +3067,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, *srcSizePtr = ip - istart; *dstCapacityPtr = op - ostart; + zcs->inputProcessed += *srcSizePtr; if (zcs->frameEnded) return 0; { size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos; if (hintInSize==0) hintInSize = zcs->blockSize; @@ -3101,6 +3112,9 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) BYTE* const oend = (BYTE*)(output->dst) + output->size; BYTE* op = ostart; + if ((zcs->pledgedSrcSize) && (zcs->inputProcessed != zcs->pledgedSrcSize)) + return ERROR(srcSize_wrong); /* pledgedSrcSize not respected */ + if (zcs->stage != zcss_final) { /* flush whatever remains */ size_t srcSize = 0; diff --git a/lib/deprecated/zbuff.h b/lib/deprecated/zbuff.h index 8296dc64a..85f973557 100644 --- a/lib/deprecated/zbuff.h +++ b/lib/deprecated/zbuff.h @@ -27,7 +27,7 @@ extern "C" { * Dependencies ***************************************/ #include /* size_t */ -#include /* ZSTD_CStream, ZSTD_DStream, ZSTDLIB_API */ +#include "zstd.h" /* ZSTD_CStream, ZSTD_DStream, ZSTDLIB_API */ /* *************************************************************** @@ -170,7 +170,6 @@ ZBUFF_DEPRECATED("use ZSTD_DStreamOutSize") size_t ZBUFF_recommendedDOutSize(voi #ifdef ZBUFF_STATIC_LINKING_ONLY - #ifndef ZBUFF_STATIC_H_30298098432 #define ZBUFF_STATIC_H_30298098432 @@ -203,7 +202,6 @@ ZBUFF_DEPRECATED("use ZSTD_initDStream_usingDict") size_t ZBUFF_compressInit_adv #endif /* ZBUFF_STATIC_H_30298098432 */ - #endif /* ZBUFF_STATIC_LINKING_ONLY */ diff --git a/lib/zstd.h b/lib/zstd.h index 44aa99566..a4766e335 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -237,20 +237,20 @@ typedef struct ZSTD_outBuffer_s { * * Start a new compression by initializing ZSTD_CStream. * Use ZSTD_initCStream() to start a new compression operation. -* Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary. +* Use ZSTD_initCStream_usingDict() or ZSTD_initCStream_usingCDict() for a compression which requires a dictionary (experimental section) * * Use ZSTD_compressStream() repetitively to consume input stream. * The function will automatically update both `pos` fields. * Note that it may not consume the entire input, in which case `pos < size`, * and it's up to the caller to present again remaining data. * @return : a size hint, preferred nb of bytes to use as input for next function call -* (it's just a hint, to help latency a little, any other value will work fine) -* (note : the size hint is guaranteed to be <= ZSTD_CStreamInSize() ) * or an error code, which can be tested using ZSTD_isError(). +* Note 1 : it's just a hint, to help latency a little, any other value will work fine. +* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() * -* At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream(). +* At any moment, it's possible to flush whatever data remains within internal buffer, using ZSTD_flushStream(). * `output->pos` will be updated. -* Note some content might still be left within internal buffer if `output->size` is too small. +* Note that some content might still be left within internal buffer if `output->size` is too small. * @return : nb of bytes still present within internal buffer (0 if it's empty) * or an error code, which can be tested using ZSTD_isError(). * @@ -259,15 +259,15 @@ typedef struct ZSTD_outBuffer_s { * The epilogue is required for decoders to consider a frame completed. * Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small. * In which case, call again ZSTD_endStream() to complete the flush. -* @return : nb of bytes still present within internal buffer (0 if it's empty) +* @return : nb of bytes still present within internal buffer (0 if it's empty, hence compression completed) * or an error code, which can be tested using ZSTD_isError(). * * *******************************************************************/ -/*===== Streaming compression functions ======*/ typedef struct ZSTD_CStream_s ZSTD_CStream; ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void); ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); + ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel); ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output); @@ -300,10 +300,10 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output * The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame. * *******************************************************************************/ -/*===== Streaming decompression functions =====*/ typedef struct ZSTD_DStream_s ZSTD_DStream; ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void); ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds); + ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds); ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); @@ -490,6 +490,7 @@ unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); /*===== Advanced Streaming compression functions =====*/ ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); +ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct */ ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be zero == unknown */ @@ -602,7 +603,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). This information is not required to properly decode a frame. - == Special case : skippable frames == + == Special case : skippable frames == Skippable frames allow integration of user-defined data into a flow of concatenated frames. Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows : diff --git a/tests/Makefile b/tests/Makefile index 6110465f6..d7d25026a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -100,9 +100,9 @@ fuzzer32 : $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c $(CC) -m32 $(FLAGS) $^ -o $@$(EXT) zbufftest : CPPFLAGS += -I$(ZSTDDIR)/deprecated -zbufftest : CFLAGS += -Wno-deprecated-declarations +zbufftest : CFLAGS += -Wno-deprecated-declarations # required to silence deprecation warnings zbufftest : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c - $(CC) $(FLAGS) $^ -o $@$(EXT) # flag required to silence deprecation warnings + $(CC) $(FLAGS) $^ -o $@$(EXT) zbufftest32 : CPPFLAGS += -I$(ZSTDDIR)/deprecated zbufftest32 : CFLAGS += -Wno-deprecated-declarations -m32 diff --git a/tests/zbufftest.c b/tests/zbufftest.c index 9dc164eaf..14b739233 100644 --- a/tests/zbufftest.c +++ b/tests/zbufftest.c @@ -28,8 +28,8 @@ #include "mem.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */ #include "zstd.h" /* ZSTD_compressBound */ -#define ZBUFF_STATIC_LINKING_ONLY -#include "zbuff.h" /* ZBUFF_createCCtx_advanced */ +#define ZBUFF_STATIC_LINKING_ONLY /* ZBUFF_createCCtx_advanced */ +#include "zbuff.h" /* ZBUFF_isError */ #include "datagen.h" /* RDG_genBuffer */ #define XXH_STATIC_LINKING_ONLY #include "xxhash.h" /* XXH64_* */ @@ -265,11 +265,11 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres static const U32 maxSrcLog = 24; static const U32 maxSampleLog = 19; BYTE* cNoiseBuffer[5]; - size_t srcBufferSize = (size_t)1<> 5; } -/* -static unsigned FUZ_highbit32(U32 v32) -{ - unsigned nbBits = 0; - if (v32==0) return 0; - for ( ; v32 ; v32>>=1) nbBits++; - return nbBits; -} -*/ - static void* allocFunction(void* opaque, size_t size) { void* address = malloc(size); @@ -254,6 +245,38 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo } } DISPLAYLEVEL(4, "OK \n"); + /* _srcSize compression test */ + DISPLAYLEVEL(4, "test%3i : compress_srcSize %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH); + ZSTD_initCStream_srcSize(zc, 1, CNBufferSize); + outBuff.dst = (char*)(compressedBuffer)+cSize; + outBuff.size = compressedBufferSize; + outBuff.pos = 0; + inBuff.src = CNBuffer; + inBuff.size = CNBufferSize; + inBuff.pos = 0; + { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff); + if (ZSTD_isError(r)) goto _output_error; } + if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + { size_t const r = ZSTD_endStream(zc, &outBuff); + if (r != 0) goto _output_error; } /* error, or some data not flushed */ + DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100); + + /* wrong _srcSize compression test */ + DISPLAYLEVEL(4, "test%3i : wrong srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); + ZSTD_initCStream_srcSize(zc, 1, CNBufferSize-1); + outBuff.dst = (char*)(compressedBuffer)+cSize; + outBuff.size = compressedBufferSize; + outBuff.pos = 0; + inBuff.src = CNBuffer; + inBuff.size = CNBufferSize; + inBuff.pos = 0; + { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff); + if (ZSTD_isError(r)) goto _output_error; } + if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + { size_t const r = ZSTD_endStream(zc, &outBuff); + if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; /* must fail : wrong srcSize */ + DISPLAYLEVEL(4, "OK (error detected : %s) \n", ZSTD_getErrorName(r)); } + /* Complex context re-use scenario */ DISPLAYLEVEL(4, "test%3i : context re-use : ", testNb++); ZSTD_freeCStream(zc); @@ -519,7 +542,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres { ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ; U32 n; for (n=0, cSize=0, totalTestSize=0 ; totalTestSize < maxTestSize ; n++) { - /* compress random chunk into random size dst buffer */ + /* compress random chunks into randomly sized dst buffers */ { size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog); size_t const srcSize = MIN (maxTestSize-totalTestSize, randomSrcSize); size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize); From 2b36b238d399078bbdbe31a721ef23b2668fc094 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 13 Dec 2016 17:59:55 +0100 Subject: [PATCH 181/185] changed variable name to estimatedSrcSize, to emphasize it does not need to be exact --- lib/zstd.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/zstd.h b/lib/zstd.h index a4766e335..b02e16b42 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -406,15 +406,15 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS * Gives the amount of memory used by a given ZSTD_sizeof_CDict */ ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict); -/*! ZSTD_getParams() : -* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`. -* All fields of `ZSTD_frameParameters` are set to default (0) */ -ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize); - /*! ZSTD_getCParams() : -* @return ZSTD_compressionParameters structure for a selected compression level and srcSize. -* `srcSize` value is optional, select 0 if not known */ -ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize); +* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. +* `estimatedSrcSize` value is optional, select 0 if not known */ +ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); + +/*! ZSTD_getParams() : +* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. +* All fields of `ZSTD_frameParameters` are set to default (0) */ +ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); /*! ZSTD_checkCParams() : * Ensure param values remain within authorized range */ From eee427ee250d7a2bbb02c54d98c92c06f70d0b2d Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 13 Dec 2016 19:14:04 +0100 Subject: [PATCH 182/185] fixed fitblk --- zlibWrapper/examples/fitblk.c | 8 +++----- zlibWrapper/zstd_zlibwrapper.c | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 760e338a2..f389c3a4f 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -90,7 +90,7 @@ local int partcompress(FILE *in, z_streamp def) flush = Z_FINISH; LOG_FITBLK("partcompress1 avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); ret = deflate(def, flush); - LOG_FITBLK("partcompress2 avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); + LOG_FITBLK("partcompress2 ret=%d avail_in=%d total_in=%d avail_out=%d total_out=%d\n", ret, (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); assert(ret != Z_STREAM_ERROR); } while (def->avail_out != 0 && flush == Z_SYNC_FLUSH); return ret; @@ -106,6 +106,7 @@ local int recompress(z_streamp inf, z_streamp def) unsigned char raw[RAWLEN]; flush = Z_NO_FLUSH; + LOG_FITBLK("recompress start\n"); do { /* decompress */ inf->avail_out = RAWLEN; @@ -125,7 +126,7 @@ local int recompress(z_streamp inf, z_streamp def) flush = Z_FINISH; LOG_FITBLK("recompress1deflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); ret = deflate(def, flush); - LOG_FITBLK("recompress2deflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); + LOG_FITBLK("recompress2deflate ret=%d avail_in=%d total_in=%d avail_out=%d total_out=%d\n", ret, (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); assert(ret != Z_STREAM_ERROR); } while (ret != Z_STREAM_END && def->avail_out != 0); return ret; @@ -165,9 +166,6 @@ int main(int argc, char **argv) ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); if (ret != Z_OK || blk == NULL) quit("out of memory"); - ret = ZWRAP_setPledgedSrcSize(&def, 1<<16); - if (ret != Z_OK) - quit("ZWRAP_setPledgedSrcSize"); /* compress from stdin until output full, or no more input */ def.avail_out = size + EXCESS; diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 3b23358f3..d26663142 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -301,7 +301,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) } } - LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (strm->avail_in > 0) { zwc->inBuffer.src = strm->next_in; zwc->inBuffer.size = strm->avail_in; @@ -355,7 +355,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; } - LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + LOG_WRAPPERC("- deflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); return Z_OK; } From 622d741a67fe9f41b9a40bff14a2eb45e3fdf35a Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 13 Dec 2016 19:44:07 +0100 Subject: [PATCH 183/185] updated zlib copyright notice --- zlibWrapper/examples/minigzip.c | 2 +- zlibWrapper/gzclose.c | 2 +- zlibWrapper/gzguts.h | 2 +- zlibWrapper/gzlib.c | 2 +- zlibWrapper/gzread.c | 2 +- zlibWrapper/gzwrite.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/zlibWrapper/examples/minigzip.c b/zlibWrapper/examples/minigzip.c index 0ddc93f25..521d04711 100644 --- a/zlibWrapper/examples/minigzip.c +++ b/zlibWrapper/examples/minigzip.c @@ -3,7 +3,7 @@ /* minigzip.c -- simulate gzip using the zlib compression library * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html */ /* diff --git a/zlibWrapper/gzclose.c b/zlibWrapper/gzclose.c index b5b7480c3..d4493d010 100644 --- a/zlibWrapper/gzclose.c +++ b/zlibWrapper/gzclose.c @@ -3,7 +3,7 @@ /* gzclose.c -- zlib gzclose() function * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html */ #include "gzguts.h" diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index e2538df15..40536de4f 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -4,7 +4,7 @@ /* gzguts.h -- zlib internal header definitions for gz* operations * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html */ #ifdef _LARGEFILE64_SOURCE diff --git a/zlibWrapper/gzlib.c b/zlibWrapper/gzlib.c index 172041df5..932319af6 100644 --- a/zlibWrapper/gzlib.c +++ b/zlibWrapper/gzlib.c @@ -3,7 +3,7 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html */ #include "gzguts.h" diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index 51ffef3e6..bf1a3cc6c 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -3,7 +3,7 @@ /* gzread.c -- zlib functions for reading gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html */ #include "gzguts.h" diff --git a/zlibWrapper/gzwrite.c b/zlibWrapper/gzwrite.c index d1478d3c1..13c8fb264 100644 --- a/zlibWrapper/gzwrite.c +++ b/zlibWrapper/gzwrite.c @@ -3,7 +3,7 @@ /* gzwrite.c -- zlib functions for writing gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h + * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html */ #include "gzguts.h" From b23420fa48a9b53eedc82d3ff2e8c5651e2f91b4 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 13 Dec 2016 19:47:17 +0100 Subject: [PATCH 184/185] updated NEWS --- NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 35e0e5820..9b0001636 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ v1.1.2 -API : streaming : decompression : changed : implicit reset on starting new frames without init -API : experimental : added : dictID retrieval functions +API : streaming : decompression : changed : automatic implicit reset when chain-decoding new frames without init +API : experimental : added : dictID retrieval functions, and ZSTD_initCStream_srcSize() API : zbuff : changed : prototypes now generate deprecation warnings lib : improved : faster decompression speed at ultra compression settings and 32-bits mode lib : changed : only public ZSTD_ symbols are now exposed From dc9931205a87fdf6b993b3e215139011d3ef9fee Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 14 Dec 2016 14:53:47 +0100 Subject: [PATCH 185/185] updated manual --- doc/zstd_manual.html | 81 ++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 51 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 81901ce9f..1badcbd79 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -88,29 +88,21 @@ note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more.


-

Helper functions

int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
+

Helper functions

int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
 size_t      ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
 unsigned    ZSTD_isError(size_t code);          /*!< tells if a `size_t` function result is an error code */
 const char* ZSTD_getErrorName(size_t code);     /*!< provides readable string from an error code */
-

+

Explicit memory management


 
-

Compression context

   When compressing many times,
-   it is recommended to allocate a context just once, and re-use it for each successive compression operation.
-   This will make workload friendlier for system's memory.
-   Use one context per thread for parallel execution in multi-threaded environments. 
-
typedef struct ZSTD_CCtx_s ZSTD_CCtx;
-ZSTD_CCtx* ZSTD_createCCtx(void);
-size_t     ZSTD_freeCCtx(ZSTD_CCtx* cctx);
-

size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
 

Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()).


-

Decompression context

typedef struct ZSTD_DCtx_s ZSTD_DCtx;
+

Decompression context

typedef struct ZSTD_DCtx_s ZSTD_DCtx;
 ZSTD_DCtx* ZSTD_createDCtx(void);
 size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
-

+

size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 

Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()).


@@ -200,20 +192,20 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); Start a new compression by initializing ZSTD_CStream. Use ZSTD_initCStream() to start a new compression operation. - Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary. + Use ZSTD_initCStream_usingDict() or ZSTD_initCStream_usingCDict() for a compression which requires a dictionary (experimental section) Use ZSTD_compressStream() repetitively to consume input stream. The function will automatically update both `pos` fields. Note that it may not consume the entire input, in which case `pos < size`, and it's up to the caller to present again remaining data. @return : a size hint, preferred nb of bytes to use as input for next function call - (it's just a hint, to help latency a little, any other value will work fine) - (note : the size hint is guaranteed to be <= ZSTD_CStreamInSize() ) or an error code, which can be tested using ZSTD_isError(). + Note 1 : it's just a hint, to help latency a little, any other value will work fine. + Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() - At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream(). + At any moment, it's possible to flush whatever data remains within internal buffer, using ZSTD_flushStream(). `output->pos` will be updated. - Note some content might still be left within internal buffer if `output->size` is too small. + Note that some content might still be left within internal buffer if `output->size` is too small. @return : nb of bytes still present within internal buffer (0 if it's empty) or an error code, which can be tested using ZSTD_isError(). @@ -222,20 +214,12 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); The epilogue is required for decoders to consider a frame completed. Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small. In which case, call again ZSTD_endStream() to complete the flush. - @return : nb of bytes still present within internal buffer (0 if it's empty) + @return : nb of bytes still present within internal buffer (0 if it's empty, hence compression completed) or an error code, which can be tested using ZSTD_isError().
-

Streaming compression functions

typedef struct ZSTD_CStream_s ZSTD_CStream;
-ZSTD_CStream* ZSTD_createCStream(void);
-size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
-size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
-size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-

size_t ZSTD_CStreamInSize(void);    /**< recommended size for input buffer */
 

size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
@@ -261,12 +245,6 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
  
 
-

Streaming decompression functions

typedef struct ZSTD_DStream_s ZSTD_DStream;
-ZSTD_DStream* ZSTD_createDStream(void);
-size_t ZSTD_freeDStream(ZSTD_DStream* zds);
-size_t ZSTD_initDStream(ZSTD_DStream* zds);
-size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-

size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */
 

size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
@@ -303,10 +281,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     ZSTD_frameParameters fParams;
 } ZSTD_parameters;
 

-

Custom memory allocation functions

typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
+

Custom memory allocation functions

typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
 typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
 typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
-

+

Advanced compression functions


 
 
size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
@@ -331,14 +309,14 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
 

Gives the amount of memory used by a given ZSTD_sizeof_CDict


-
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
-

same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`. - All fields of `ZSTD_frameParameters` are set to default (0) +

ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+

@return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. + `estimatedSrcSize` value is optional, select 0 if not known


-
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
-

@return ZSTD_compressionParameters structure for a selected compression level and srcSize. - `srcSize` value is optional, select 0 if not known +

ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+

same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. + All fields of `ZSTD_frameParameters` are set to default (0)


size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
@@ -409,22 +387,23 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
 
 

Advanced streaming functions


 
-

Advanced Streaming compression functions

ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
+

Advanced Streaming compression functions

ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
+size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct */
 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
 size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                              ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be zero == unknown */
 size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);  /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before */
 size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
-

-

Advanced Streaming decompression functions

typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
+

+

Advanced Streaming decompression functions

typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
 ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
 size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
 size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
 size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
 size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
 size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
-

+

Buffer-less and synchronous inner streaming functions

   This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
   But it's also a complex one, with many restrictions (documented below).
@@ -461,13 +440,13 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
   You can then reuse `ZSTD_CCtx` (ZSTD_compressBegin()) to compress some new frame.
 
-

Buffer-less streaming compression functions

size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+

Buffer-less streaming compression functions

size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
 size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
 size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize);
 size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-

+

Buffer-less streaming decompression (synchronous mode)

   A ZSTD_DCtx object is required to track streaming operations.
   Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
@@ -511,7 +490,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const vo
   Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
   This information is not required to properly decode a frame.
 
-  == Special case : skippable frames == 
+  == Special case : skippable frames ==
 
   Skippable frames allow integration of user-defined data into a flow of concatenated frames.
   Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
@@ -530,7 +509,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const vo
     unsigned checksumFlag;
 } ZSTD_frameParams;
 

-

Buffer-less streaming decompression functions

size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
+

Buffer-less streaming decompression functions

size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
 size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
 void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
@@ -538,7 +517,7 @@ size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
 size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
 ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
-

+

Block functions

     Block functions produce and decode raw zstd blocks, without frame metadata.
     Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
@@ -563,10 +542,10 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
         Use ZSTD_insertBlock() in such a case.
 
-

Raw zstd block functions

size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
+

Raw zstd block functions

size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
 size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
 size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
-

+