Compare commits
72
Commits
zstd-0.4.0
...
v0.4.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef774a68bb | ||
|
|
324a3e27c3 | ||
|
|
6a4583542a | ||
|
|
17d188fa38 | ||
|
|
31683c0b28 | ||
|
|
fdcad6d3e1 | ||
|
|
035c5429ba | ||
|
|
deb078b9b1 | ||
|
|
9d90922d49 | ||
|
|
24c98f2b4b | ||
|
|
4f13703b2f | ||
|
|
367060b874 | ||
|
|
f54f57023c | ||
|
|
ad84ac9375 | ||
|
|
880486ff05 | ||
|
|
a52c98d23a | ||
|
|
7061135d33 | ||
|
|
6c8b925ab9 | ||
|
|
ed699e692d | ||
|
|
7a3ab588c7 | ||
|
|
c95aa912e0 | ||
|
|
397f1ffd52 | ||
|
|
5d4fa0ed9b | ||
|
|
60348b91f3 | ||
|
|
f6f3d7526a | ||
|
|
0700585fb9 | ||
|
|
188b6ed6c7 | ||
|
|
3a061a4c9f | ||
|
|
6c3e2e7855 | ||
|
|
9f5ab1a4f5 | ||
|
|
7b7027f21e | ||
|
|
8329191c63 | ||
|
|
fa9df079a4 | ||
|
|
695a6cb463 | ||
|
|
3882fd016e | ||
|
|
2abb04d90d | ||
|
|
7b05324a71 | ||
|
|
844baf4fc5 | ||
|
|
d608088ca3 | ||
|
|
9ad743e74d | ||
|
|
2b465840a8 | ||
|
|
0b570b59d2 | ||
|
|
76be378513 | ||
|
|
d66db2ff04 | ||
|
|
0cde77bc5e | ||
|
|
d2199e7250 | ||
|
|
c6e845398a | ||
|
|
d89d578ce9 | ||
|
|
56005e7ac8 | ||
|
|
4bfe415fa7 | ||
|
|
e47c4e5f8e | ||
|
|
1c2ddba469 | ||
|
|
553cf6a926 | ||
|
|
417890cec2 | ||
|
|
28e7cefea9 | ||
|
|
a174fb1b41 | ||
|
|
6a2f03295c | ||
|
|
aaf6f20993 | ||
|
|
120230b895 | ||
|
|
a308259afa | ||
|
|
a9b34280a1 | ||
|
|
06ef07b469 | ||
|
|
f06e238d6f | ||
|
|
a2e5f7473d | ||
|
|
6adf3e2ec8 | ||
|
|
c620b48489 | ||
|
|
d062f1379c | ||
|
|
0338635e93 | ||
|
|
44287a3bf4 | ||
|
|
aead1bf86b | ||
|
|
daa1c65500 | ||
|
|
a85a8dd94a |
+18
@@ -20,3 +20,21 @@
|
|||||||
# Visual solution files
|
# Visual solution files
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
@@ -16,8 +16,10 @@ env:
|
|||||||
- ZSTD_TRAVIS_CI_ENV=armtest
|
- ZSTD_TRAVIS_CI_ENV=armtest
|
||||||
- ZSTD_TRAVIS_CI_ENV=test
|
- ZSTD_TRAVIS_CI_ENV=test
|
||||||
- ZSTD_TRAVIS_CI_ENV="-C programs test32"
|
- ZSTD_TRAVIS_CI_ENV="-C programs test32"
|
||||||
|
- ZSTD_TRAVIS_CI_ENV="-C programs test-zstd_nolegacy"
|
||||||
- ZSTD_TRAVIS_CI_ENV=usan
|
- ZSTD_TRAVIS_CI_ENV=usan
|
||||||
- ZSTD_TRAVIS_CI_ENV=asan
|
- ZSTD_TRAVIS_CI_ENV=asan
|
||||||
|
- ZSTD_TRAVIS_CI_ENV=asan32
|
||||||
- ZSTD_TRAVIS_CI_ENV="-C programs valgrindTest"
|
- ZSTD_TRAVIS_CI_ENV="-C programs valgrindTest"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
# ################################################################
|
# ################################################################
|
||||||
|
|
||||||
# Version number
|
# Version number
|
||||||
export VERSION := 0.4.0
|
export VERSION := 0.4.5
|
||||||
|
|
||||||
PRGDIR = programs
|
PRGDIR = programs
|
||||||
ZSTDDIR = lib
|
ZSTDDIR = lib
|
||||||
@@ -74,7 +74,7 @@ uninstall:
|
|||||||
$(MAKE) -C $(PRGDIR) $@
|
$(MAKE) -C $(PRGDIR) $@
|
||||||
|
|
||||||
travis-install:
|
travis-install:
|
||||||
sudo $(MAKE) install
|
$(MAKE) install PREFIX=~/install_test_dir
|
||||||
|
|
||||||
test:
|
test:
|
||||||
$(MAKE) -C $(PRGDIR) $@
|
$(MAKE) -C $(PRGDIR) $@
|
||||||
@@ -87,8 +87,8 @@ gpptest: clean
|
|||||||
$(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror"
|
$(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror"
|
||||||
|
|
||||||
armtest: clean
|
armtest: clean
|
||||||
$(MAKE) -C $(ZSTDDIR) -e all CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror"
|
$(MAKE) -C $(ZSTDDIR) all CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror"
|
||||||
$(MAKE) -C $(PRGDIR) -e CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror"
|
$(MAKE) -C $(PRGDIR) CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror -static"
|
||||||
|
|
||||||
usan: clean
|
usan: clean
|
||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
|
||||||
@@ -96,6 +96,9 @@ usan: clean
|
|||||||
asan: clean
|
asan: clean
|
||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address"
|
||||||
|
|
||||||
|
asan32: clean
|
||||||
|
$(MAKE) -C $(PRGDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
|
||||||
|
|
||||||
uasan: clean
|
uasan: clean
|
||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,25 @@
|
|||||||
|
v0.4.5
|
||||||
|
new : -m/--multiple : compress/decompress multiple files
|
||||||
|
|
||||||
|
v0.4.4
|
||||||
|
Fixed : high compression modes for Windows 32 bits
|
||||||
|
new : external dictionary API extended to buffered mode and accessible through command line
|
||||||
|
new : windows DLL project, thanks to Christophe Chevalier
|
||||||
|
|
||||||
|
v0.4.3 :
|
||||||
|
new : external dictionary API
|
||||||
|
new : zstd-frugal
|
||||||
|
|
||||||
|
v0.4.2 :
|
||||||
|
Generic minor improvements for small blocks
|
||||||
|
Fixed : big-endian compatibility, by Peter Harris (#85)
|
||||||
|
|
||||||
|
v0.4.1
|
||||||
|
Fixed : ZSTD_LEGACY_SUPPORT=0 build mode (reported by Luben)
|
||||||
|
removed `zstd.c`
|
||||||
|
|
||||||
v0.4.0
|
v0.4.0
|
||||||
Command line utility is now compatible with high compression levels
|
Command line utility compatible with high compression levels
|
||||||
Removed zstdhc => merged into zstd
|
Removed zstdhc => merged into zstd
|
||||||
Added : ZBUFF API (see zstd_buffered.h)
|
Added : ZBUFF API (see zstd_buffered.h)
|
||||||
Rolling buffer support
|
Rolling buffer support
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 35 KiB |
+16
-8
@@ -40,7 +40,7 @@ VERSION?= $(LIBVER)
|
|||||||
|
|
||||||
DESTDIR?=
|
DESTDIR?=
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
CPPFLAGS= -I. -I./legacy -DZSTD_LEGACY_SUPPORT=1
|
CPPFLAGS= -I.
|
||||||
CFLAGS ?= -O3
|
CFLAGS ?= -O3
|
||||||
CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes
|
CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes
|
||||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
||||||
@@ -48,6 +48,16 @@ FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
|||||||
LIBDIR ?= $(PREFIX)/lib
|
LIBDIR ?= $(PREFIX)/lib
|
||||||
INCLUDEDIR=$(PREFIX)/include
|
INCLUDEDIR=$(PREFIX)/include
|
||||||
|
|
||||||
|
ZSTD_FILES := zstd_compress.c zstd_decompress.c fse.c huff0.c
|
||||||
|
ZSTD_LEGACY:= legacy/zstd_v01.c legacy/zstd_v02.c legacy/zstd_v03.c
|
||||||
|
|
||||||
|
ifeq ($(ZSTD_LEGACY_SUPPORT), 0)
|
||||||
|
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
||||||
|
else
|
||||||
|
ZSTD_FILES+= $(ZSTD_LEGACY)
|
||||||
|
CPPFLAGS += -I./legacy -DZSTD_LEGACY_SUPPORT=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
# OS X linker doesn't support -soname, and use different extension
|
# 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
|
# see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
|
||||||
@@ -55,9 +65,9 @@ ifeq ($(shell uname), Darwin)
|
|||||||
SHARED_EXT = dylib
|
SHARED_EXT = dylib
|
||||||
SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT)
|
SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT)
|
||||||
SHARED_EXT_VER = $(LIBVER).$(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 $(PREFIX)/lib/$@.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER)
|
||||||
else
|
else
|
||||||
SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR)
|
SONAME_FLAGS = -Wl,-soname=$@.$(SHARED_EXT).$(LIBVER_MAJOR)
|
||||||
SHARED_EXT = so
|
SHARED_EXT = so
|
||||||
SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR)
|
SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR)
|
||||||
SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER)
|
SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER)
|
||||||
@@ -70,11 +80,10 @@ default: clean libzstd
|
|||||||
|
|
||||||
all: clean libzstd
|
all: clean libzstd
|
||||||
|
|
||||||
libzstd: zstd_compress.c zstd_decompress.c huff0.c fse.c \
|
libzstd: $(ZSTD_FILES)
|
||||||
legacy/zstd_v01.c legacy/zstd_v02.c legacy/zstd_v03.c
|
|
||||||
@echo compiling static library
|
@echo compiling static library
|
||||||
@$(CC) $(FLAGS) -c $^
|
@$(CC) $(FLAGS) -c $^
|
||||||
@$(AR) rcs libzstd.a *.o
|
@$(AR) rcs $@.a *.o
|
||||||
@echo compiling dynamic library $(LIBVER)
|
@echo compiling dynamic library $(LIBVER)
|
||||||
@$(CC) $(FLAGS) -shared $^ -fPIC $(SONAME_FLAGS) -o $@.$(SHARED_EXT_VER)
|
@$(CC) $(FLAGS) -shared $^ -fPIC $(SONAME_FLAGS) -o $@.$(SHARED_EXT_VER)
|
||||||
@echo creating versioned links
|
@echo creating versioned links
|
||||||
@@ -82,10 +91,9 @@ libzstd: zstd_compress.c zstd_decompress.c huff0.c fse.c \
|
|||||||
@ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT)
|
@ln -sf $@.$(SHARED_EXT_VER) $@.$(SHARED_EXT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f core *.o *.a *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc
|
@rm -f core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc
|
||||||
@echo Cleaning library completed
|
@echo Cleaning library completed
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#make install is validated only for Linux, OSX, kFreeBSD and Hurd targets
|
#make install is validated only for Linux, OSX, kFreeBSD and Hurd targets
|
||||||
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU))
|
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU))
|
||||||
|
|||||||
-1462
@@ -1,1462 +0,0 @@
|
|||||||
/*
|
|
||||||
zstd - standard compression library
|
|
||||||
Copyright (C) 2014-2015, Yann Collet.
|
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"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 COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS 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.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ***************************************************************
|
|
||||||
* Tuning parameters
|
|
||||||
*****************************************************************/
|
|
||||||
/*!
|
|
||||||
* MEMORY_USAGE :
|
|
||||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
|
||||||
* Increasing memory usage improves compression ratio
|
|
||||||
* Reduced memory usage can improve speed, due to cache effect
|
|
||||||
*/
|
|
||||||
#define ZSTD_MEMORY_USAGE 16
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* HEAPMODE :
|
|
||||||
* Select how default compression functions will allocate memory for their hash table,
|
|
||||||
* in memory stack (0, fastest), or in memory heap (1, requires malloc())
|
|
||||||
* Note that compression context is fairly large, as a consequence heap memory is recommended.
|
|
||||||
*/
|
|
||||||
#ifndef ZSTD_HEAPMODE
|
|
||||||
# define ZSTD_HEAPMODE 1
|
|
||||||
#endif /* ZSTD_HEAPMODE */
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* LEGACY_SUPPORT :
|
|
||||||
* decompressor can decode older formats (starting from Zstd 0.1+)
|
|
||||||
*/
|
|
||||||
#ifndef ZSTD_LEGACY_SUPPORT
|
|
||||||
# define ZSTD_LEGACY_SUPPORT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* *******************************************************
|
|
||||||
* Includes
|
|
||||||
*********************************************************/
|
|
||||||
#include <stdlib.h> /* calloc */
|
|
||||||
#include <string.h> /* memcpy, memmove */
|
|
||||||
#include <stdio.h> /* debug : printf */
|
|
||||||
#include "mem.h" /* low level memory routines */
|
|
||||||
#include "zstd_static.h"
|
|
||||||
#include "zstd_internal.h"
|
|
||||||
#include "fse_static.h"
|
|
||||||
#include "huff0.h"
|
|
||||||
|
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
|
||||||
# include "zstd_legacy.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* *******************************************************
|
|
||||||
* Compiler specifics
|
|
||||||
*********************************************************/
|
|
||||||
#ifdef __AVX2__
|
|
||||||
# include <immintrin.h> /* AVX2 intrinsics */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
|
||||||
#else
|
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* *******************************************************
|
|
||||||
* Constants
|
|
||||||
*********************************************************/
|
|
||||||
#define HASH_LOG (ZSTD_MEMORY_USAGE - 2)
|
|
||||||
#define HASH_TABLESIZE (1 << HASH_LOG)
|
|
||||||
#define HASH_MASK (HASH_TABLESIZE - 1)
|
|
||||||
|
|
||||||
#define KNUTH 2654435761
|
|
||||||
|
|
||||||
#define BIT7 128
|
|
||||||
#define BIT6 64
|
|
||||||
#define BIT5 32
|
|
||||||
#define BIT4 16
|
|
||||||
#define BIT1 2
|
|
||||||
#define BIT0 1
|
|
||||||
|
|
||||||
#define KB *(1 <<10)
|
|
||||||
#define MB *(1 <<20)
|
|
||||||
#define GB *(1U<<30)
|
|
||||||
|
|
||||||
#define BLOCKSIZE (128 KB) /* define, for static allocation */
|
|
||||||
#define IS_RAW BIT0
|
|
||||||
#define IS_RLE BIT1
|
|
||||||
|
|
||||||
static const U32 g_maxDistance = 4 * BLOCKSIZE;
|
|
||||||
static const U32 g_maxLimit = 1 GB;
|
|
||||||
|
|
||||||
#define WORKPLACESIZE (BLOCKSIZE*3)
|
|
||||||
#define MINMATCH 4
|
|
||||||
#define LitFSELog 11
|
|
||||||
#define MLFSELog 10
|
|
||||||
#define LLFSELog 10
|
|
||||||
#define OffFSELog 9
|
|
||||||
#define MAX(a,b) ((a)<(b)?(b):(a))
|
|
||||||
#define MaxSeq MAX(MaxLL, MaxML)
|
|
||||||
|
|
||||||
#define LITERAL_NOENTROPY 63
|
|
||||||
#define COMMAND_NOENTROPY 7 /* to remove */
|
|
||||||
|
|
||||||
static const size_t ZSTD_blockHeaderSize = 3;
|
|
||||||
static const size_t ZSTD_frameHeaderSize = 4;
|
|
||||||
|
|
||||||
|
|
||||||
/* *******************************************************
|
|
||||||
* Memory operations
|
|
||||||
**********************************************************/
|
|
||||||
static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************************
|
|
||||||
* Local structures
|
|
||||||
****************************************/
|
|
||||||
void ZSTD_resetSeqStore(seqStore_t* ssPtr)
|
|
||||||
{
|
|
||||||
ssPtr->offset = ssPtr->offsetStart;
|
|
||||||
ssPtr->lit = ssPtr->litStart;
|
|
||||||
ssPtr->litLength = ssPtr->litLengthStart;
|
|
||||||
ssPtr->matchLength = ssPtr->matchLengthStart;
|
|
||||||
ssPtr->dumps = ssPtr->dumpsStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ZSTD_CCtx_s
|
|
||||||
{
|
|
||||||
const BYTE* base;
|
|
||||||
U32 current;
|
|
||||||
U32 nextUpdate;
|
|
||||||
seqStore_t seqStore;
|
|
||||||
#ifdef __AVX2__
|
|
||||||
__m256i hashTable[HASH_TABLESIZE>>3];
|
|
||||||
#else
|
|
||||||
U32 hashTable[HASH_TABLESIZE];
|
|
||||||
#endif
|
|
||||||
BYTE buffer[WORKPLACESIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void ZSTD_resetCCtx(ZSTD_CCtx* ctx)
|
|
||||||
{
|
|
||||||
ctx->base = NULL;
|
|
||||||
ctx->seqStore.buffer = ctx->buffer;
|
|
||||||
ctx->seqStore.offsetStart = (U32*) (ctx->seqStore.buffer);
|
|
||||||
ctx->seqStore.offCodeStart = (BYTE*) (ctx->seqStore.offsetStart + (BLOCKSIZE>>2));
|
|
||||||
ctx->seqStore.litStart = ctx->seqStore.offCodeStart + (BLOCKSIZE>>2);
|
|
||||||
ctx->seqStore.litLengthStart = ctx->seqStore.litStart + BLOCKSIZE;
|
|
||||||
ctx->seqStore.matchLengthStart = ctx->seqStore.litLengthStart + (BLOCKSIZE>>2);
|
|
||||||
ctx->seqStore.dumpsStart = ctx->seqStore.matchLengthStart + (BLOCKSIZE>>2);
|
|
||||||
memset(ctx->hashTable, 0, sizeof(ctx->hashTable));
|
|
||||||
}
|
|
||||||
|
|
||||||
ZSTD_CCtx* ZSTD_createCCtx(void)
|
|
||||||
{
|
|
||||||
ZSTD_CCtx* ctx = (ZSTD_CCtx*) malloc( sizeof(ZSTD_CCtx) );
|
|
||||||
if (ctx==NULL) return NULL;
|
|
||||||
ZSTD_resetCCtx(ctx);
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ZSTD_freeCCtx(ZSTD_CCtx* ctx)
|
|
||||||
{
|
|
||||||
free(ctx);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Error Management
|
|
||||||
***************************************/
|
|
||||||
/*! ZSTD_isError
|
|
||||||
* tells if a return value is an error code */
|
|
||||||
unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
|
|
||||||
|
|
||||||
/*! ZSTD_getErrorName
|
|
||||||
* provides error code string (useful for debugging) */
|
|
||||||
const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Tool functions
|
|
||||||
***************************************/
|
|
||||||
unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
|
|
||||||
|
|
||||||
|
|
||||||
/* *******************************************************
|
|
||||||
* Compression
|
|
||||||
*********************************************************/
|
|
||||||
size_t ZSTD_compressBound(size_t srcSize) /* maximum compressed size */
|
|
||||||
{
|
|
||||||
return FSE_compressBound(srcSize) + 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_noCompressBlock (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
|
||||||
|
|
||||||
if (srcSize + ZSTD_blockHeaderSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
|
||||||
memcpy(ostart + ZSTD_blockHeaderSize, src, srcSize);
|
|
||||||
|
|
||||||
/* Build header */
|
|
||||||
ostart[0] = (BYTE)(srcSize>>16);
|
|
||||||
ostart[1] = (BYTE)(srcSize>>8);
|
|
||||||
ostart[2] = (BYTE) srcSize;
|
|
||||||
ostart[0] += (BYTE)(bt_raw<<6); /* is a raw (uncompressed) block */
|
|
||||||
|
|
||||||
return ZSTD_blockHeaderSize+srcSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_compressRawLiteralsBlock (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
|
||||||
|
|
||||||
if (srcSize + 3 > maxDstSize) return ERROR(dstSize_tooSmall);
|
|
||||||
|
|
||||||
MEM_writeLE32(dst, ((U32)srcSize << 2) | IS_RAW);
|
|
||||||
memcpy(ostart + 3, src, srcSize);
|
|
||||||
return srcSize + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
|
||||||
|
|
||||||
(void)maxDstSize;
|
|
||||||
MEM_writeLE32(dst, ((U32)srcSize << 2) | IS_RLE); /* note : maxDstSize > litHeaderSize > 4 */
|
|
||||||
ostart[3] = *(const BYTE*)src;
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 1; }
|
|
||||||
|
|
||||||
static size_t ZSTD_compressLiterals (void* dst, size_t maxDstSize,
|
|
||||||
const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
const size_t minGain = ZSTD_minGain(srcSize);
|
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
|
||||||
size_t hsize;
|
|
||||||
static const size_t litHeaderSize = 5;
|
|
||||||
|
|
||||||
if (maxDstSize < litHeaderSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
|
||||||
|
|
||||||
hsize = HUF_compress(ostart+litHeaderSize, maxDstSize-litHeaderSize, src, srcSize);
|
|
||||||
|
|
||||||
if ((hsize==0) || (hsize >= srcSize - minGain)) return ZSTD_compressRawLiteralsBlock(dst, maxDstSize, src, srcSize);
|
|
||||||
if (hsize==1) return ZSTD_compressRleLiteralsBlock(dst, maxDstSize, src, srcSize);
|
|
||||||
|
|
||||||
/* Build header */
|
|
||||||
{
|
|
||||||
ostart[0] = (BYTE)(srcSize << 2); /* is a block, is compressed */
|
|
||||||
ostart[1] = (BYTE)(srcSize >> 6);
|
|
||||||
ostart[2] = (BYTE)(srcSize >>14);
|
|
||||||
ostart[2] += (BYTE)(hsize << 5);
|
|
||||||
ostart[3] = (BYTE)(hsize >> 3);
|
|
||||||
ostart[4] = (BYTE)(hsize >>11);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hsize+litHeaderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressSequences(BYTE* dst, size_t maxDstSize,
|
|
||||||
const seqStore_t* seqStorePtr,
|
|
||||||
size_t srcSize)
|
|
||||||
{
|
|
||||||
U32 count[MaxSeq+1];
|
|
||||||
S16 norm[MaxSeq+1];
|
|
||||||
size_t mostFrequent;
|
|
||||||
U32 max = 255;
|
|
||||||
U32 tableLog = 11;
|
|
||||||
U32 CTable_LitLength [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL )];
|
|
||||||
U32 CTable_OffsetBits [FSE_CTABLE_SIZE_U32(OffFSELog,MaxOff)];
|
|
||||||
U32 CTable_MatchLength[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML )];
|
|
||||||
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
|
|
||||||
const BYTE* const op_lit_start = seqStorePtr->litStart;
|
|
||||||
const BYTE* const llTable = seqStorePtr->litLengthStart;
|
|
||||||
const BYTE* const llPtr = seqStorePtr->litLength;
|
|
||||||
const BYTE* const mlTable = seqStorePtr->matchLengthStart;
|
|
||||||
const U32* const offsetTable = seqStorePtr->offsetStart;
|
|
||||||
BYTE* const offCodeTable = seqStorePtr->offCodeStart;
|
|
||||||
BYTE* op = dst;
|
|
||||||
BYTE* const oend = dst + maxDstSize;
|
|
||||||
const size_t nbSeq = llPtr - llTable;
|
|
||||||
const size_t minGain = ZSTD_minGain(srcSize);
|
|
||||||
const size_t maxCSize = srcSize - minGain;
|
|
||||||
BYTE* seqHead;
|
|
||||||
|
|
||||||
|
|
||||||
/* Compress literals */
|
|
||||||
{
|
|
||||||
size_t cSize;
|
|
||||||
size_t litSize = seqStorePtr->lit - op_lit_start;
|
|
||||||
|
|
||||||
if (litSize <= LITERAL_NOENTROPY)
|
|
||||||
cSize = ZSTD_compressRawLiteralsBlock(op, maxDstSize, op_lit_start, litSize);
|
|
||||||
else
|
|
||||||
cSize = ZSTD_compressLiterals(op, maxDstSize, op_lit_start, litSize);
|
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
|
||||||
op += cSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sequences Header */
|
|
||||||
if ((oend-op) < MIN_SEQUENCES_SIZE)
|
|
||||||
return ERROR(dstSize_tooSmall);
|
|
||||||
MEM_writeLE16(op, (U16)nbSeq); op+=2;
|
|
||||||
seqHead = op;
|
|
||||||
|
|
||||||
/* dumps : contains too large lengths */
|
|
||||||
{
|
|
||||||
size_t dumpsLength = seqStorePtr->dumps - seqStorePtr->dumpsStart;
|
|
||||||
if (dumpsLength < 512)
|
|
||||||
{
|
|
||||||
op[0] = (BYTE)(dumpsLength >> 8);
|
|
||||||
op[1] = (BYTE)(dumpsLength);
|
|
||||||
op += 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
op[0] = 2;
|
|
||||||
op[1] = (BYTE)(dumpsLength>>8);
|
|
||||||
op[2] = (BYTE)(dumpsLength);
|
|
||||||
op += 3;
|
|
||||||
}
|
|
||||||
if ((size_t)(oend-op) < dumpsLength+6) return ERROR(dstSize_tooSmall);
|
|
||||||
memcpy(op, seqStorePtr->dumpsStart, dumpsLength);
|
|
||||||
op += dumpsLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CTable for Literal Lengths */
|
|
||||||
max = MaxLL;
|
|
||||||
mostFrequent = FSE_countFast(count, &max, seqStorePtr->litLengthStart, nbSeq);
|
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
|
||||||
{
|
|
||||||
*op++ = *(seqStorePtr->litLengthStart);
|
|
||||||
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
|
||||||
LLtype = bt_rle;
|
|
||||||
}
|
|
||||||
else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (LLbits-1))))
|
|
||||||
{
|
|
||||||
FSE_buildCTable_raw(CTable_LitLength, LLbits);
|
|
||||||
LLtype = bt_raw;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t NCountSize;
|
|
||||||
tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
|
|
||||||
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
|
||||||
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);
|
|
||||||
LLtype = bt_compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CTable for Offsets codes */
|
|
||||||
{
|
|
||||||
/* create Offset codes */
|
|
||||||
size_t i;
|
|
||||||
max = MaxOff;
|
|
||||||
for (i=0; i<nbSeq; i++)
|
|
||||||
{
|
|
||||||
offCodeTable[i] = (BYTE)ZSTD_highbit(offsetTable[i]) + 1;
|
|
||||||
if (offsetTable[i]==0) offCodeTable[i]=0;
|
|
||||||
}
|
|
||||||
mostFrequent = FSE_countFast(count, &max, offCodeTable, nbSeq);
|
|
||||||
}
|
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
|
||||||
{
|
|
||||||
*op++ = *offCodeTable;
|
|
||||||
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
|
||||||
Offtype = bt_rle;
|
|
||||||
}
|
|
||||||
else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (Offbits-1))))
|
|
||||||
{
|
|
||||||
FSE_buildCTable_raw(CTable_OffsetBits, Offbits);
|
|
||||||
Offtype = bt_raw;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t NCountSize;
|
|
||||||
tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
|
|
||||||
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
|
||||||
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);
|
|
||||||
Offtype = bt_compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CTable for MatchLengths */
|
|
||||||
max = MaxML;
|
|
||||||
mostFrequent = FSE_countFast(count, &max, seqStorePtr->matchLengthStart, nbSeq);
|
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
|
||||||
{
|
|
||||||
*op++ = *seqStorePtr->matchLengthStart;
|
|
||||||
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
|
||||||
MLtype = bt_rle;
|
|
||||||
}
|
|
||||||
else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (MLbits-1))))
|
|
||||||
{
|
|
||||||
FSE_buildCTable_raw(CTable_MatchLength, MLbits);
|
|
||||||
MLtype = bt_raw;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t NCountSize;
|
|
||||||
tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
|
|
||||||
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
|
||||||
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);
|
|
||||||
MLtype = bt_compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
seqHead[0] += (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
|
|
||||||
|
|
||||||
/* Encoding Sequences */
|
|
||||||
{
|
|
||||||
size_t streamSize, errorCode;
|
|
||||||
BIT_CStream_t blockStream;
|
|
||||||
FSE_CState_t stateMatchLength;
|
|
||||||
FSE_CState_t stateOffsetBits;
|
|
||||||
FSE_CState_t stateLitLength;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
errorCode = BIT_initCStream(&blockStream, op, oend-op);
|
|
||||||
if (ERR_isError(errorCode)) return ERROR(dstSize_tooSmall); /* not enough space remaining */
|
|
||||||
FSE_initCState(&stateMatchLength, CTable_MatchLength);
|
|
||||||
FSE_initCState(&stateOffsetBits, CTable_OffsetBits);
|
|
||||||
FSE_initCState(&stateLitLength, CTable_LitLength);
|
|
||||||
|
|
||||||
for (i=(int)nbSeq-1; i>=0; i--)
|
|
||||||
{
|
|
||||||
BYTE matchLength = mlTable[i];
|
|
||||||
U32 offset = offsetTable[i];
|
|
||||||
BYTE offCode = offCodeTable[i]; /* 32b*/ /* 64b*/
|
|
||||||
U32 nbBits = (offCode-1) * (!!offCode);
|
|
||||||
BYTE litLength = llTable[i]; /* (7)*/ /* (7)*/
|
|
||||||
FSE_encodeSymbol(&blockStream, &stateMatchLength, matchLength); /* 17 */ /* 17 */
|
|
||||||
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
|
||||||
BIT_addBits(&blockStream, offset, nbBits); /* 32 */ /* 42 */
|
|
||||||
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
|
||||||
FSE_encodeSymbol(&blockStream, &stateOffsetBits, offCode); /* 16 */ /* 51 */
|
|
||||||
FSE_encodeSymbol(&blockStream, &stateLitLength, litLength); /* 26 */ /* 61 */
|
|
||||||
BIT_flushBits(&blockStream); /* 7 */ /* 7 */
|
|
||||||
}
|
|
||||||
|
|
||||||
FSE_flushCState(&blockStream, &stateMatchLength);
|
|
||||||
FSE_flushCState(&blockStream, &stateOffsetBits);
|
|
||||||
FSE_flushCState(&blockStream, &stateLitLength);
|
|
||||||
|
|
||||||
streamSize = BIT_closeCStream(&blockStream);
|
|
||||||
if (streamSize==0) return ERROR(dstSize_tooSmall); /* not enough space */
|
|
||||||
op += streamSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check compressibility */
|
|
||||||
if ((size_t)(op-dst) >= maxCSize) return 0;
|
|
||||||
|
|
||||||
return op - dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//static const U32 hashMask = (1<<HASH_LOG)-1;
|
|
||||||
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return (U32) _bextr_u64(*(U64*)p * prime7bytes, (56-HASH_LOG), HASH_LOG); }
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U64*)p * prime7bytes) << 8 >> (64-HASH_LOG)); }
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U64*)p * prime7bytes) >> (56-HASH_LOG)) & ((1<<HASH_LOG)-1); }
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return ( ((*(U64*)p & 0xFFFFFFFFFFFFFF) * prime7bytes) >> (64-HASH_LOG)); }
|
|
||||||
|
|
||||||
//static const U64 prime8bytes = 14923729446516375013ULL;
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U64*)p * prime8bytes) >> (64-HASH_LOG)); }
|
|
||||||
|
|
||||||
static const U64 prime7bytes = 58295818150454627ULL;
|
|
||||||
static U32 ZSTD_hashPtr(const void* p) { return ( (MEM_read64(p) * prime7bytes) >> (56-HASH_LOG)) & HASH_MASK; }
|
|
||||||
|
|
||||||
//static const U64 prime6bytes = 227718039650203ULL;
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return ( (MEM_read64(p) * prime6bytes) >> (48-HASH_LOG)) & HASH_MASK; }
|
|
||||||
|
|
||||||
//static const U64 prime5bytes = 889523592379ULL;
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U64*)p * prime5bytes) >> (40-HASH_LOG)) & HASH_MASK; }
|
|
||||||
|
|
||||||
//static U32 ZSTD_hashPtr(const void* p) { return ( (*(U32*)p * KNUTH) >> (32-HASH_LOG)); }
|
|
||||||
|
|
||||||
static const BYTE* ZSTD_updateMatch(U32* table, const BYTE* p, const BYTE* start)
|
|
||||||
{
|
|
||||||
U32 h = ZSTD_hashPtr(p);
|
|
||||||
const BYTE* r;
|
|
||||||
r = table[h] + start;
|
|
||||||
table[h] = (U32)(p-start);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ZSTD_checkMatch(const BYTE* match, const BYTE* ip)
|
|
||||||
{
|
|
||||||
return MEM_read32(match) == MEM_read32(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ZSTD_addPtr(U32* table, const BYTE* p, const BYTE* start) { table[ZSTD_hashPtr(p)] = (U32)(p-start); }
|
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_compressBlock(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
U32* HashTable = (U32*)(ctx->hashTable);
|
|
||||||
seqStore_t* seqStorePtr = &(ctx->seqStore);
|
|
||||||
const BYTE* const base = ctx->base;
|
|
||||||
|
|
||||||
const BYTE* const istart = (const BYTE*)src;
|
|
||||||
const BYTE* ip = istart + 1;
|
|
||||||
const BYTE* anchor = istart;
|
|
||||||
const BYTE* const iend = istart + srcSize;
|
|
||||||
const BYTE* const ilimit = iend - 8;
|
|
||||||
|
|
||||||
size_t offset_2=4, offset_1=4;
|
|
||||||
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
if (ip-base < 4)
|
|
||||||
{
|
|
||||||
ZSTD_addPtr(HashTable, ip+0, base);
|
|
||||||
ZSTD_addPtr(HashTable, ip+1, base);
|
|
||||||
ZSTD_addPtr(HashTable, ip+2, base);
|
|
||||||
ZSTD_addPtr(HashTable, ip+3, base);
|
|
||||||
ip += 4;
|
|
||||||
}
|
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
|
||||||
|
|
||||||
/* Main Search Loop */
|
|
||||||
while (ip < ilimit) /* < instead of <=, because unconditionnal ZSTD_addPtr(ip+1) */
|
|
||||||
{
|
|
||||||
const BYTE* match = ZSTD_updateMatch(HashTable, ip, base);
|
|
||||||
|
|
||||||
if (ZSTD_checkMatch(ip-offset_2,ip)) match = ip-offset_2;
|
|
||||||
if (!ZSTD_checkMatch(match,ip)) { ip += ((ip-anchor) >> g_searchStrength) + 1; offset_2 = offset_1; continue; }
|
|
||||||
while ((ip>anchor) && (match>base) && (ip[-1] == match[-1])) { ip--; match--; } /* catch up */
|
|
||||||
|
|
||||||
{
|
|
||||||
size_t litLength = ip-anchor;
|
|
||||||
size_t matchLength = ZSTD_count(ip+MINMATCH, match+MINMATCH, iend);
|
|
||||||
size_t offsetCode = ip-match;
|
|
||||||
if (offsetCode == offset_2) offsetCode = 0;
|
|
||||||
offset_2 = offset_1;
|
|
||||||
offset_1 = ip-match;
|
|
||||||
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offsetCode, matchLength);
|
|
||||||
|
|
||||||
/* Fill Table */
|
|
||||||
ZSTD_addPtr(HashTable, ip+1, base);
|
|
||||||
ip += matchLength + MINMATCH;
|
|
||||||
anchor = ip;
|
|
||||||
if (ip < ilimit) /* same test as loop, for speed */
|
|
||||||
ZSTD_addPtr(HashTable, ip-2, base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last Literals */
|
|
||||||
{
|
|
||||||
size_t lastLLSize = iend - anchor;
|
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
|
||||||
seqStorePtr->lit += lastLLSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finale compression stage */
|
|
||||||
return ZSTD_compressSequences((BYTE*)dst, maxDstSize,
|
|
||||||
seqStorePtr, srcSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressBegin(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize)
|
|
||||||
{
|
|
||||||
/* Sanity check */
|
|
||||||
if (maxDstSize < ZSTD_frameHeaderSize) return ERROR(dstSize_tooSmall);
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
ZSTD_resetCCtx(ctx);
|
|
||||||
|
|
||||||
/* Write Header */
|
|
||||||
MEM_writeLE32(dst, ZSTD_magicNumber);
|
|
||||||
|
|
||||||
return ZSTD_frameHeaderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ZSTD_scaleDownCtx(ZSTD_CCtx* ctx, const U32 limit)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
#if defined(__AVX2__)
|
|
||||||
/* AVX2 version */
|
|
||||||
__m256i* h = ctx->hashTable;
|
|
||||||
const __m256i limit8 = _mm256_set1_epi32(limit);
|
|
||||||
for (i=0; i<(HASH_TABLESIZE>>3); i++)
|
|
||||||
{
|
|
||||||
__m256i src =_mm256_loadu_si256((const __m256i*)(h+i));
|
|
||||||
const __m256i dec = _mm256_min_epu32(src, limit8);
|
|
||||||
src = _mm256_sub_epi32(src, dec);
|
|
||||||
_mm256_storeu_si256((__m256i*)(h+i), src);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* this should be auto-vectorized by compiler */
|
|
||||||
U32* h = ctx->hashTable;
|
|
||||||
for (i=0; i<HASH_TABLESIZE; ++i)
|
|
||||||
{
|
|
||||||
U32 dec;
|
|
||||||
if (h[i] > limit) dec = limit; else dec = h[i];
|
|
||||||
h[i] -= dec;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ZSTD_limitCtx(ZSTD_CCtx* ctx, const U32 limit)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (limit > g_maxLimit)
|
|
||||||
{
|
|
||||||
ZSTD_scaleDownCtx(ctx, limit);
|
|
||||||
ctx->base += limit;
|
|
||||||
ctx->current -= limit;
|
|
||||||
ctx->nextUpdate -= limit;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__AVX2__)
|
|
||||||
/* AVX2 version */
|
|
||||||
{
|
|
||||||
__m256i* h = ctx->hashTable;
|
|
||||||
const __m256i limit8 = _mm256_set1_epi32(limit);
|
|
||||||
//printf("Address h : %0X\n", (U32)h); // address test
|
|
||||||
for (i=0; i<(HASH_TABLESIZE>>3); i++)
|
|
||||||
{
|
|
||||||
__m256i src =_mm256_loadu_si256((const __m256i*)(h+i)); // Unfortunately, clang doesn't guarantee 32-bytes alignment
|
|
||||||
src = _mm256_max_epu32(src, limit8);
|
|
||||||
_mm256_storeu_si256((__m256i*)(h+i), src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* this should be auto-vectorized by compiler */
|
|
||||||
{
|
|
||||||
U32* h = (U32*)(ctx->hashTable);
|
|
||||||
for (i=0; i<HASH_TABLESIZE; ++i)
|
|
||||||
{
|
|
||||||
if (h[i] < limit) h[i] = limit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressContinue(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
const BYTE* const istart = (const BYTE* const)src;
|
|
||||||
const BYTE* ip = istart;
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
|
||||||
BYTE* op = ostart;
|
|
||||||
const U32 updateRate = 2 * BLOCKSIZE;
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
if (ctx->base==NULL)
|
|
||||||
ctx->base = (const BYTE*)src, ctx->current=0, ctx->nextUpdate = g_maxDistance;
|
|
||||||
if (src != ctx->base + ctx->current) /* not contiguous */
|
|
||||||
{
|
|
||||||
ZSTD_resetCCtx(ctx);
|
|
||||||
ctx->base = (const BYTE*)src;
|
|
||||||
ctx->current = 0;
|
|
||||||
}
|
|
||||||
ctx->current += (U32)srcSize;
|
|
||||||
|
|
||||||
while (srcSize)
|
|
||||||
{
|
|
||||||
size_t cSize;
|
|
||||||
size_t blockSize = BLOCKSIZE;
|
|
||||||
if (blockSize > srcSize) blockSize = srcSize;
|
|
||||||
|
|
||||||
if (maxDstSize < 2*ZSTD_blockHeaderSize+1) /* one RLE block + endMark */
|
|
||||||
return ERROR(dstSize_tooSmall);
|
|
||||||
|
|
||||||
/* update hash table */
|
|
||||||
if (g_maxDistance <= BLOCKSIZE) /* static test ; yes == blocks are independent */
|
|
||||||
{
|
|
||||||
ZSTD_resetCCtx(ctx);
|
|
||||||
ctx->base = ip;
|
|
||||||
ctx->current=0;
|
|
||||||
}
|
|
||||||
else if (ip >= ctx->base + ctx->nextUpdate)
|
|
||||||
{
|
|
||||||
ctx->nextUpdate += updateRate;
|
|
||||||
ZSTD_limitCtx(ctx, ctx->nextUpdate - g_maxDistance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compress */
|
|
||||||
cSize = ZSTD_compressBlock(ctx, op+ZSTD_blockHeaderSize, maxDstSize-ZSTD_blockHeaderSize, ip, blockSize);
|
|
||||||
if (cSize == 0)
|
|
||||||
{
|
|
||||||
cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, blockSize); /* block is not compressible */
|
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
|
||||||
op[0] = (BYTE)(cSize>>16);
|
|
||||||
op[1] = (BYTE)(cSize>>8);
|
|
||||||
op[2] = (BYTE)cSize;
|
|
||||||
op[0] += (BYTE)(bt_compressed << 6); /* is a compressed block */
|
|
||||||
cSize += 3;
|
|
||||||
}
|
|
||||||
op += cSize;
|
|
||||||
maxDstSize -= cSize;
|
|
||||||
ip += blockSize;
|
|
||||||
srcSize -= blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return op-ostart;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressEnd(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize)
|
|
||||||
{
|
|
||||||
BYTE* op = (BYTE*)dst;
|
|
||||||
|
|
||||||
/* Sanity check */
|
|
||||||
(void)ctx;
|
|
||||||
if (maxDstSize < ZSTD_blockHeaderSize) return ERROR(dstSize_tooSmall);
|
|
||||||
|
|
||||||
/* End of frame */
|
|
||||||
op[0] = (BYTE)(bt_end << 6);
|
|
||||||
op[1] = 0;
|
|
||||||
op[2] = 0;
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
|
||||||
BYTE* op = ostart;
|
|
||||||
size_t oSize;
|
|
||||||
|
|
||||||
/* Header */
|
|
||||||
oSize = ZSTD_compressBegin(ctx, dst, maxDstSize);
|
|
||||||
if(ZSTD_isError(oSize)) return oSize;
|
|
||||||
op += oSize;
|
|
||||||
maxDstSize -= oSize;
|
|
||||||
|
|
||||||
/* Compression */
|
|
||||||
oSize = ZSTD_compressContinue(ctx, op, maxDstSize, src, srcSize);
|
|
||||||
if (ZSTD_isError(oSize)) return oSize;
|
|
||||||
op += oSize;
|
|
||||||
maxDstSize -= oSize;
|
|
||||||
|
|
||||||
/* Close frame */
|
|
||||||
oSize = ZSTD_compressEnd(ctx, op, maxDstSize);
|
|
||||||
if(ZSTD_isError(oSize)) return oSize;
|
|
||||||
op += oSize;
|
|
||||||
|
|
||||||
return (op - ostart);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
size_t r;
|
|
||||||
#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
|
|
||||||
ZSTD_CCtx* ctx;
|
|
||||||
ctx = ZSTD_createCCtx();
|
|
||||||
if (ctx==NULL) return ERROR(GENERIC);
|
|
||||||
# else
|
|
||||||
ZSTD_CCtx ctxBody;
|
|
||||||
ZSTD_CCtx* const ctx = &ctxBody;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
r = ZSTD_compressCCtx(ctx, dst, maxDstSize, src, srcSize);
|
|
||||||
|
|
||||||
#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
|
|
||||||
ZSTD_freeCCtx(ctx);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************************************
|
|
||||||
* Decompression section
|
|
||||||
***************************************************************/
|
|
||||||
struct ZSTD_DCtx_s
|
|
||||||
{
|
|
||||||
U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
|
||||||
U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
|
||||||
U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
|
||||||
void* previousDstEnd;
|
|
||||||
void* base;
|
|
||||||
size_t expected;
|
|
||||||
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" */
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
|
||||||
{
|
|
||||||
const BYTE* const in = (const BYTE* const)src;
|
|
||||||
BYTE headerFlags;
|
|
||||||
U32 cSize;
|
|
||||||
|
|
||||||
if (srcSize < 3) return ERROR(srcSize_wrong);
|
|
||||||
|
|
||||||
headerFlags = *in;
|
|
||||||
cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
|
|
||||||
|
|
||||||
bpPtr->blockType = (blockType_t)(headerFlags >> 6);
|
|
||||||
bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
|
|
||||||
|
|
||||||
if (bpPtr->blockType == bt_end) return 0;
|
|
||||||
if (bpPtr->blockType == bt_rle) return 1;
|
|
||||||
return cSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
|
||||||
memcpy(dst, src, srcSize);
|
|
||||||
return srcSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_decompressLiterals
|
|
||||||
@return : nb of bytes read from src, or an error code*/
|
|
||||||
static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr,
|
|
||||||
const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
const BYTE* ip = (const BYTE*)src;
|
|
||||||
|
|
||||||
const size_t litSize = (MEM_readLE32(src) & 0x1FFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
|
|
||||||
const size_t litCSize = (MEM_readLE32(ip+2) & 0xFFFFFF) >> 5; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
|
|
||||||
|
|
||||||
if (litSize > *maxDstSizePtr) return ERROR(corruption_detected);
|
|
||||||
if (litCSize + 5 > srcSize) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
if (HUF_isError(HUF_decompress(dst, litSize, ip+5, litCSize))) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
*maxDstSizePtr = litSize;
|
|
||||||
return litCSize + 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_decodeLiteralsBlock
|
|
||||||
@return : nb of bytes read from src (< srcSize )*/
|
|
||||||
size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
|
||||||
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
|
||||||
{
|
|
||||||
ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx;
|
|
||||||
const BYTE* const istart = (const BYTE*) src;
|
|
||||||
|
|
||||||
/* any compressed block with literals segment must be at least this size */
|
|
||||||
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
switch(*istart & 3)
|
|
||||||
{
|
|
||||||
/* compressed */
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
return readSize; /* works if it's an error too */
|
|
||||||
}
|
|
||||||
case IS_RAW:
|
|
||||||
{
|
|
||||||
const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
|
|
||||||
if (litSize > srcSize-11) /* risk of reading too far with wildcopy */
|
|
||||||
{
|
|
||||||
if (litSize > srcSize-3) return ERROR(corruption_detected);
|
|
||||||
memcpy(dctx->litBuffer, istart, litSize);
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
|
||||||
dctx->litBufSize = BLOCKSIZE+8;
|
|
||||||
dctx->litSize = litSize;
|
|
||||||
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:
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
|
||||||
dctx->litBufSize = BLOCKSIZE+8;
|
|
||||||
dctx->litSize = litSize;
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return ERROR(corruption_detected); /* forbidden nominal case */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
|
|
||||||
FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
|
|
||||||
const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
const BYTE* const istart = (const BYTE* const)src;
|
|
||||||
const BYTE* ip = istart;
|
|
||||||
const BYTE* const iend = istart + srcSize;
|
|
||||||
U32 LLtype, Offtype, MLtype;
|
|
||||||
U32 LLlog, Offlog, MLlog;
|
|
||||||
size_t dumpsLength;
|
|
||||||
|
|
||||||
/* check */
|
|
||||||
if (srcSize < 5) return ERROR(srcSize_wrong);
|
|
||||||
|
|
||||||
/* SeqHead */
|
|
||||||
*nbSeq = MEM_readLE16(ip); ip+=2;
|
|
||||||
LLtype = *ip >> 6;
|
|
||||||
Offtype = (*ip >> 4) & 3;
|
|
||||||
MLtype = (*ip >> 2) & 3;
|
|
||||||
if (*ip & 2)
|
|
||||||
{
|
|
||||||
dumpsLength = ip[2];
|
|
||||||
dumpsLength += ip[1] << 8;
|
|
||||||
ip += 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dumpsLength = ip[1];
|
|
||||||
dumpsLength += (ip[0] & 1) << 8;
|
|
||||||
ip += 2;
|
|
||||||
}
|
|
||||||
*dumpsPtr = ip;
|
|
||||||
ip += dumpsLength;
|
|
||||||
*dumpsLengthPtr = dumpsLength;
|
|
||||||
|
|
||||||
/* check */
|
|
||||||
if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
|
|
||||||
|
|
||||||
/* sequences */
|
|
||||||
{
|
|
||||||
S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL and MaxOff */
|
|
||||||
size_t headerSize;
|
|
||||||
|
|
||||||
/* Build DTables */
|
|
||||||
switch(LLtype)
|
|
||||||
{
|
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
|
||||||
LLlog = 0;
|
|
||||||
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
|
||||||
case bt_raw :
|
|
||||||
LLlog = LLbits;
|
|
||||||
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
|
||||||
default :
|
|
||||||
max = MaxLL;
|
|
||||||
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
|
||||||
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
|
||||||
ip += headerSize;
|
|
||||||
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(Offtype)
|
|
||||||
{
|
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
|
||||||
Offlog = 0;
|
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
|
||||||
FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
|
|
||||||
break;
|
|
||||||
case bt_raw :
|
|
||||||
Offlog = Offbits;
|
|
||||||
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
|
||||||
default :
|
|
||||||
max = MaxOff;
|
|
||||||
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
|
||||||
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
|
||||||
ip += headerSize;
|
|
||||||
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(MLtype)
|
|
||||||
{
|
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
|
||||||
MLlog = 0;
|
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
|
||||||
FSE_buildDTable_rle(DTableML, *ip++); break;
|
|
||||||
case bt_raw :
|
|
||||||
MLlog = MLbits;
|
|
||||||
FSE_buildDTable_raw(DTableML, MLbits); break;
|
|
||||||
default :
|
|
||||||
max = MaxML;
|
|
||||||
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
|
||||||
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
|
||||||
ip += headerSize;
|
|
||||||
FSE_buildDTable(DTableML, norm, max, MLlog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip-istart;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t litLength;
|
|
||||||
size_t offset;
|
|
||||||
size_t matchLength;
|
|
||||||
} seq_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
BIT_DStream_t DStream;
|
|
||||||
FSE_DState_t stateLL;
|
|
||||||
FSE_DState_t stateOffb;
|
|
||||||
FSE_DState_t stateML;
|
|
||||||
size_t prevOffset;
|
|
||||||
const BYTE* dumps;
|
|
||||||
const BYTE* dumpsEnd;
|
|
||||||
} seqState_t;
|
|
||||||
|
|
||||||
|
|
||||||
static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|
||||||
{
|
|
||||||
size_t litLength;
|
|
||||||
size_t prevOffset;
|
|
||||||
size_t offset;
|
|
||||||
size_t matchLength;
|
|
||||||
const BYTE* dumps = seqState->dumps;
|
|
||||||
const BYTE* const de = seqState->dumpsEnd;
|
|
||||||
|
|
||||||
/* Literal length */
|
|
||||||
litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
|
|
||||||
prevOffset = litLength ? seq->offset : seqState->prevOffset;
|
|
||||||
seqState->prevOffset = seq->offset;
|
|
||||||
if (litLength == MaxLL)
|
|
||||||
{
|
|
||||||
U32 add = *dumps++;
|
|
||||||
if (add < 255) litLength += add;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
|
|
||||||
dumps += 3;
|
|
||||||
}
|
|
||||||
if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Offset */
|
|
||||||
{
|
|
||||||
static const U32 offsetPrefix[MaxOff+1] = {
|
|
||||||
1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256,
|
|
||||||
512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144,
|
|
||||||
524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 };
|
|
||||||
U32 offsetCode, nbBits;
|
|
||||||
offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* <= maxOff, by table construction */
|
|
||||||
if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
|
|
||||||
nbBits = offsetCode - 1;
|
|
||||||
if (offsetCode==0) nbBits = 0; /* cmove */
|
|
||||||
offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits);
|
|
||||||
if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
|
|
||||||
if (offsetCode==0) offset = prevOffset; /* cmove */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MatchLength */
|
|
||||||
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
|
|
||||||
if (matchLength == MaxML)
|
|
||||||
{
|
|
||||||
U32 add = *dumps++;
|
|
||||||
if (add < 255) matchLength += add;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
|
|
||||||
dumps += 3;
|
|
||||||
}
|
|
||||||
if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */
|
|
||||||
}
|
|
||||||
matchLength += MINMATCH;
|
|
||||||
|
|
||||||
/* save result */
|
|
||||||
seq->litLength = litLength;
|
|
||||||
seq->offset = offset;
|
|
||||||
seq->matchLength = matchLength;
|
|
||||||
seqState->dumps = dumps;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_execSequence(BYTE* op,
|
|
||||||
seq_t sequence,
|
|
||||||
const BYTE** litPtr, const BYTE* const litLimit_8,
|
|
||||||
BYTE* const base, BYTE* const oend)
|
|
||||||
{
|
|
||||||
static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
|
|
||||||
static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* substracted */
|
|
||||||
const BYTE* const ostart = op;
|
|
||||||
BYTE* const oLitEnd = op + sequence.litLength;
|
|
||||||
BYTE* const oMatchEnd = op + sequence.litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */
|
|
||||||
BYTE* const oend_8 = oend-8;
|
|
||||||
const BYTE* const litEnd = *litPtr + sequence.litLength;
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
|
|
||||||
/* copy Literals */
|
|
||||||
ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
|
||||||
op = oLitEnd;
|
|
||||||
*litPtr = litEnd; /* update for next sequence */
|
|
||||||
|
|
||||||
/* copy Match */
|
|
||||||
{
|
|
||||||
const BYTE* match = op - sequence.offset;
|
|
||||||
|
|
||||||
/* check */
|
|
||||||
//if (match > op) return ERROR(corruption_detected); /* address space overflow test (is clang optimizer removing this test ?) */
|
|
||||||
if (sequence.offset > (size_t)op) return ERROR(corruption_detected); /* address space overflow test (this test seems kept by clang optimizer) */
|
|
||||||
if (match < base) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
/* close range match, overlap */
|
|
||||||
if (sequence.offset < 8)
|
|
||||||
{
|
|
||||||
const int dec64 = 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 -= dec64;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ZSTD_copy8(op, match);
|
|
||||||
}
|
|
||||||
op += 8; match += 8;
|
|
||||||
|
|
||||||
if (oMatchEnd > oend-12)
|
|
||||||
{
|
|
||||||
if (op < oend_8)
|
|
||||||
{
|
|
||||||
ZSTD_wildcopy(op, match, oend_8 - op);
|
|
||||||
match += oend_8 - op;
|
|
||||||
op = oend_8;
|
|
||||||
}
|
|
||||||
while (op < oMatchEnd) *op++ = *match++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return oMatchEnd - ostart;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t ZSTD_decompressSequences(
|
|
||||||
void* ctx,
|
|
||||||
void* dst, size_t maxDstSize,
|
|
||||||
const void* seqStart, size_t seqSize)
|
|
||||||
{
|
|
||||||
ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx;
|
|
||||||
const BYTE* ip = (const BYTE*)seqStart;
|
|
||||||
const BYTE* const iend = ip + seqSize;
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
|
||||||
BYTE* op = ostart;
|
|
||||||
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;
|
|
||||||
U32* DTableLL = dctx->LLTable;
|
|
||||||
U32* DTableML = dctx->MLTable;
|
|
||||||
U32* DTableOffb = dctx->OffTable;
|
|
||||||
BYTE* const base = (BYTE*) (dctx->base);
|
|
||||||
|
|
||||||
/* Build Decoding Tables */
|
|
||||||
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
|
|
||||||
DTableLL, DTableML, DTableOffb,
|
|
||||||
ip, iend-ip);
|
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
|
||||||
ip += errorCode;
|
|
||||||
|
|
||||||
/* Regen sequences */
|
|
||||||
{
|
|
||||||
seq_t sequence;
|
|
||||||
seqState_t seqState;
|
|
||||||
|
|
||||||
memset(&sequence, 0, sizeof(sequence));
|
|
||||||
sequence.offset = 4;
|
|
||||||
seqState.dumps = dumps;
|
|
||||||
seqState.dumpsEnd = dumps + dumpsLength;
|
|
||||||
seqState.prevOffset = 4;
|
|
||||||
errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
|
|
||||||
if (ERR_isError(errorCode)) return ERROR(corruption_detected);
|
|
||||||
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
|
||||||
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
|
||||||
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
|
||||||
|
|
||||||
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (nbSeq>0) ; )
|
|
||||||
{
|
|
||||||
size_t oneSeqSize;
|
|
||||||
nbSeq--;
|
|
||||||
ZSTD_decodeSequence(&sequence, &seqState);
|
|
||||||
oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litLimit_8, base, oend);
|
|
||||||
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
|
||||||
op += oneSeqSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if reached exact end */
|
|
||||||
if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* requested too much : data is corrupted */
|
|
||||||
if (nbSeq<0) return ERROR(corruption_detected); /* requested too many sequences : data is corrupted */
|
|
||||||
|
|
||||||
/* last literal segment */
|
|
||||||
{
|
|
||||||
size_t lastLLSize = litEnd - litPtr;
|
|
||||||
if (litPtr > litEnd) return ERROR(corruption_detected);
|
|
||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
|
||||||
if (op != litPtr) memcpy(op, litPtr, lastLLSize);
|
|
||||||
op += lastLLSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return op-ostart;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_decompressBlock(
|
|
||||||
void* ctx,
|
|
||||||
void* dst, size_t maxDstSize,
|
|
||||||
const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
/* blockType == blockCompressed */
|
|
||||||
const BYTE* ip = (const BYTE*)src;
|
|
||||||
|
|
||||||
/* Decode literals sub-block */
|
|
||||||
size_t litCSize = ZSTD_decodeLiteralsBlock(ctx, src, srcSize);
|
|
||||||
if (ZSTD_isError(litCSize)) return litCSize;
|
|
||||||
ip += litCSize;
|
|
||||||
srcSize -= litCSize;
|
|
||||||
|
|
||||||
return ZSTD_decompressSequences(ctx, dst, maxDstSize, ip, srcSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
const BYTE* ip = (const BYTE*)src;
|
|
||||||
const BYTE* iend = ip + srcSize;
|
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
|
||||||
BYTE* op = ostart;
|
|
||||||
BYTE* const oend = ostart + maxDstSize;
|
|
||||||
size_t remainingSize = srcSize;
|
|
||||||
U32 magicNumber;
|
|
||||||
blockProperties_t blockProperties;
|
|
||||||
|
|
||||||
/* Frame Header */
|
|
||||||
if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
|
||||||
magicNumber = MEM_readLE32(src);
|
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
|
||||||
if (ZSTD_isLegacy(magicNumber))
|
|
||||||
return ZSTD_decompressLegacy(dst, maxDstSize, src, srcSize, magicNumber);
|
|
||||||
#endif
|
|
||||||
if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);
|
|
||||||
ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize;
|
|
||||||
|
|
||||||
/* Loop on each block */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
size_t decodedSize=0;
|
|
||||||
size_t cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
|
|
||||||
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
|
||||||
|
|
||||||
ip += ZSTD_blockHeaderSize;
|
|
||||||
remainingSize -= ZSTD_blockHeaderSize;
|
|
||||||
if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
|
|
||||||
|
|
||||||
switch(blockProperties.blockType)
|
|
||||||
{
|
|
||||||
case bt_compressed:
|
|
||||||
decodedSize = ZSTD_decompressBlock(ctx, op, oend-op, ip, cBlockSize);
|
|
||||||
break;
|
|
||||||
case bt_raw :
|
|
||||||
decodedSize = ZSTD_copyUncompressedBlock(op, oend-op, ip, cBlockSize);
|
|
||||||
break;
|
|
||||||
case bt_rle :
|
|
||||||
return ERROR(GENERIC); /* not yet supported */
|
|
||||||
break;
|
|
||||||
case bt_end :
|
|
||||||
/* end of frame */
|
|
||||||
if (remainingSize) return ERROR(srcSize_wrong);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ERROR(GENERIC); /* impossible */
|
|
||||||
}
|
|
||||||
if (cBlockSize == 0) break; /* bt_end */
|
|
||||||
|
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
|
||||||
op += decodedSize;
|
|
||||||
ip += cBlockSize;
|
|
||||||
remainingSize -= cBlockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return op-ostart;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
ZSTD_DCtx ctx;
|
|
||||||
ctx.base = dst;
|
|
||||||
return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ******************************
|
|
||||||
* Streaming Decompression API
|
|
||||||
********************************/
|
|
||||||
|
|
||||||
size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)
|
|
||||||
{
|
|
||||||
dctx->expected = ZSTD_frameHeaderSize;
|
|
||||||
dctx->phase = 0;
|
|
||||||
dctx->previousDstEnd = NULL;
|
|
||||||
dctx->base = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZSTD_DCtx* ZSTD_createDCtx(void)
|
|
||||||
{
|
|
||||||
ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
|
|
||||||
if (dctx==NULL) return NULL;
|
|
||||||
ZSTD_resetDCtx(dctx);
|
|
||||||
return dctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
|
||||||
{
|
|
||||||
free(dctx);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
|
|
||||||
{
|
|
||||||
return dctx->expected;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
/* Sanity check */
|
|
||||||
if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
|
|
||||||
if (dst != ctx->previousDstEnd) /* not contiguous */
|
|
||||||
ctx->base = dst;
|
|
||||||
|
|
||||||
/* Decompress : frame header */
|
|
||||||
if (ctx->phase == 0)
|
|
||||||
{
|
|
||||||
/* Check frame magic header */
|
|
||||||
U32 magicNumber = MEM_readLE32(src);
|
|
||||||
if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);
|
|
||||||
ctx->phase = 1;
|
|
||||||
ctx->expected = ZSTD_blockHeaderSize;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decompress : block header */
|
|
||||||
if (ctx->phase == 1)
|
|
||||||
{
|
|
||||||
blockProperties_t bp;
|
|
||||||
size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
|
||||||
if (ZSTD_isError(blockSize)) return blockSize;
|
|
||||||
if (bp.blockType == bt_end)
|
|
||||||
{
|
|
||||||
ctx->expected = 0;
|
|
||||||
ctx->phase = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctx->expected = blockSize;
|
|
||||||
ctx->bType = bp.blockType;
|
|
||||||
ctx->phase = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decompress : block content */
|
|
||||||
{
|
|
||||||
size_t rSize;
|
|
||||||
switch(ctx->bType)
|
|
||||||
{
|
|
||||||
case bt_compressed:
|
|
||||||
rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src, srcSize);
|
|
||||||
break;
|
|
||||||
case bt_raw :
|
|
||||||
rSize = ZSTD_copyUncompressedBlock(dst, maxDstSize, src, srcSize);
|
|
||||||
break;
|
|
||||||
case bt_rle :
|
|
||||||
return ERROR(GENERIC); /* not yet handled */
|
|
||||||
break;
|
|
||||||
case bt_end : /* should never happen (filtered at phase 1) */
|
|
||||||
rSize = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ERROR(GENERIC);
|
|
||||||
}
|
|
||||||
ctx->phase = 1;
|
|
||||||
ctx->expected = ZSTD_blockHeaderSize;
|
|
||||||
ctx->previousDstEnd = (void*)( ((char*)dst) + rSize);
|
|
||||||
return rSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+27
-13
@@ -43,25 +43,39 @@ extern "C" {
|
|||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
|
/* ***************************************************************
|
||||||
|
* Tuning parameters
|
||||||
|
*****************************************************************/
|
||||||
|
/*!
|
||||||
|
* 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
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Version
|
* Version
|
||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */
|
#define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */
|
||||||
#define ZSTD_VERSION_MINOR 4 /* for new (non-breaking) interface capabilities */
|
#define ZSTD_VERSION_MINOR 4 /* for new (non-breaking) interface capabilities */
|
||||||
#define ZSTD_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */
|
#define ZSTD_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */
|
||||||
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
|
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
|
||||||
unsigned ZSTD_versionNumber (void);
|
ZSTDLIB_API unsigned ZSTD_versionNumber (void);
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Simple functions
|
* Simple functions
|
||||||
***************************************/
|
***************************************/
|
||||||
size_t ZSTD_compress( void* dst, size_t maxDstSize,
|
ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t maxDstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
int compressionLevel);
|
int compressionLevel);
|
||||||
|
|
||||||
size_t ZSTD_decompress( void* dst, size_t maxOriginalSize,
|
ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t maxOriginalSize,
|
||||||
const void* src, size_t compressedSize);
|
const void* src, size_t compressedSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
ZSTD_compress() :
|
ZSTD_compress() :
|
||||||
@@ -83,25 +97,25 @@ ZSTD_decompress() :
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Tool functions
|
* Tool functions
|
||||||
***************************************/
|
***************************************/
|
||||||
size_t ZSTD_compressBound(size_t srcSize); /** maximum compressed size (worst case scenario) */
|
ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /** maximum compressed size (worst case scenario) */
|
||||||
|
|
||||||
/* Error Management */
|
/* Error Management */
|
||||||
unsigned ZSTD_isError(size_t code); /** tells if a return value is an error code */
|
ZSTDLIB_API unsigned ZSTD_isError(size_t code); /** tells if a return value is an error code */
|
||||||
const char* ZSTD_getErrorName(size_t code); /** provides error code string */
|
ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /** provides error code string */
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Advanced functions
|
* Advanced functions
|
||||||
***************************************/
|
***************************************/
|
||||||
typedef struct ZSTD_CCtx_s ZSTD_CCtx; /* incomplete type */
|
typedef struct ZSTD_CCtx_s ZSTD_CCtx; /* incomplete type */
|
||||||
ZSTD_CCtx* ZSTD_createCCtx(void);
|
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
||||||
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
ZSTD_compressCCtx() :
|
ZSTD_compressCCtx() :
|
||||||
Same as ZSTD_compress(), but requires a ZSTD_CCtx working space already allocated
|
Same as ZSTD_compress(), but requires a ZSTD_CCtx working space already allocated
|
||||||
*/
|
*/
|
||||||
size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel);
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
|
|||||||
+18
-2
@@ -160,6 +160,12 @@ size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZBUFF_compressWithDictionary(ZBUFF_CCtx* zbc, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
ZSTD_compress_insertDictionary(zbc->zc, src, srcSize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Compression *** */
|
/* *** Compression *** */
|
||||||
|
|
||||||
@@ -327,6 +333,8 @@ struct ZBUFF_DCtx_s {
|
|||||||
size_t outStart;
|
size_t outStart;
|
||||||
size_t outEnd;
|
size_t outEnd;
|
||||||
size_t hPos;
|
size_t hPos;
|
||||||
|
const char* dict;
|
||||||
|
size_t dictSize;
|
||||||
ZBUFF_dStage stage;
|
ZBUFF_dStage stage;
|
||||||
unsigned char headerBuffer[ZSTD_frameHeaderSize_max];
|
unsigned char headerBuffer[ZSTD_frameHeaderSize_max];
|
||||||
}; /* typedef'd to ZBUFF_DCtx within "zstd_buffered.h" */
|
}; /* typedef'd to ZBUFF_DCtx within "zstd_buffered.h" */
|
||||||
@@ -353,17 +361,23 @@ size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Initialization *** */
|
/* *** Initialization *** */
|
||||||
|
|
||||||
size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbc)
|
size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbc)
|
||||||
{
|
{
|
||||||
zbc->stage = ZBUFFds_readHeader;
|
zbc->stage = ZBUFFds_readHeader;
|
||||||
zbc->hPos = zbc->inPos = zbc->outStart = zbc->outEnd = 0;
|
zbc->hPos = zbc->inPos = zbc->outStart = zbc->outEnd = zbc->dictSize = 0;
|
||||||
return ZSTD_resetDCtx(zbc->zc);
|
return ZSTD_resetDCtx(zbc->zc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZBUFF_decompressWithDictionary(ZBUFF_DCtx* zbc, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
zbc->dict = (const char*)src;
|
||||||
|
zbc->dictSize = srcSize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Decompression *** */
|
/* *** Decompression *** */
|
||||||
|
|
||||||
@@ -442,6 +456,8 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc, void* dst, size_t* maxDstSizePt
|
|||||||
if (zbc->outBuff == NULL) return ERROR(memory_allocation);
|
if (zbc->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (zbc->dictSize)
|
||||||
|
ZSTD_decompress_insertDictionary(zbc->zc, zbc->dict, zbc->dictSize);
|
||||||
if (zbc->hPos)
|
if (zbc->hPos)
|
||||||
{
|
{
|
||||||
/* some data already loaded into headerBuffer : transfer into inBuff */
|
/* some data already loaded into headerBuffer : transfer into inBuff */
|
||||||
|
|||||||
+40
-16
@@ -47,17 +47,32 @@ extern "C" {
|
|||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
|
/* ***************************************************************
|
||||||
|
* Tuning parameters
|
||||||
|
*****************************************************************/
|
||||||
|
/*!
|
||||||
|
* 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
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Streaming functions
|
* Streaming functions
|
||||||
***************************************/
|
***************************************/
|
||||||
typedef struct ZBUFF_CCtx_s ZBUFF_CCtx;
|
typedef struct ZBUFF_CCtx_s ZBUFF_CCtx;
|
||||||
ZBUFF_CCtx* ZBUFF_createCCtx(void);
|
ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx(void);
|
||||||
size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx);
|
ZSTDLIB_API size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx);
|
||||||
|
|
||||||
size_t ZBUFF_compressInit(ZBUFF_CCtx* cctx, int compressionLevel);
|
ZSTDLIB_API size_t ZBUFF_compressInit(ZBUFF_CCtx* cctx, int compressionLevel);
|
||||||
size_t ZBUFF_compressContinue(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr);
|
ZSTDLIB_API size_t ZBUFF_compressWithDictionary(ZBUFF_CCtx* cctx, const void* src, size_t srcSize);
|
||||||
size_t ZBUFF_compressFlush(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr);
|
ZSTDLIB_API size_t ZBUFF_compressContinue(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr);
|
||||||
size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr);
|
ZSTDLIB_API size_t ZBUFF_compressFlush(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr);
|
||||||
|
ZSTDLIB_API size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr);
|
||||||
|
|
||||||
/** ************************************************
|
/** ************************************************
|
||||||
* Streaming compression
|
* Streaming compression
|
||||||
@@ -67,6 +82,9 @@ size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr);
|
|||||||
* Use ZBUFF_compressInit() to start a new compression operation.
|
* Use ZBUFF_compressInit() to start a new compression operation.
|
||||||
* ZBUFF_CCtx objects can be reused multiple times.
|
* ZBUFF_CCtx objects can be reused multiple times.
|
||||||
*
|
*
|
||||||
|
* Optionally, a reference to a static dictionary can be created with ZBUFF_compressWithDictionary()
|
||||||
|
* Note that the dictionary content must remain accessible during the compression process.
|
||||||
|
*
|
||||||
* Use ZBUFF_compressContinue() repetitively to consume input stream.
|
* Use ZBUFF_compressContinue() repetitively to consume input stream.
|
||||||
* *srcSizePtr and *maxDstSizePtr can be any size.
|
* *srcSizePtr and *maxDstSizePtr can be any size.
|
||||||
* The function will report how many bytes were read or written within *srcSizePtr and *maxDstSizePtr.
|
* The function will report how many bytes were read or written within *srcSizePtr and *maxDstSizePtr.
|
||||||
@@ -97,11 +115,13 @@ size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* maxDstSizePtr);
|
|||||||
|
|
||||||
|
|
||||||
typedef struct ZBUFF_DCtx_s ZBUFF_DCtx;
|
typedef struct ZBUFF_DCtx_s ZBUFF_DCtx;
|
||||||
ZBUFF_DCtx* ZBUFF_createDCtx(void);
|
ZSTDLIB_API ZBUFF_DCtx* ZBUFF_createDCtx(void);
|
||||||
size_t ZBUFF_freeDCtx(ZBUFF_DCtx* dctx);
|
ZSTDLIB_API size_t ZBUFF_freeDCtx(ZBUFF_DCtx* dctx);
|
||||||
|
|
||||||
size_t ZBUFF_decompressInit(ZBUFF_DCtx* dctx);
|
ZSTDLIB_API size_t ZBUFF_decompressInit(ZBUFF_DCtx* dctx);
|
||||||
size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr);
|
ZSTDLIB_API size_t ZBUFF_decompressWithDictionary(ZBUFF_DCtx* dctx, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr);
|
||||||
|
|
||||||
/** ************************************************
|
/** ************************************************
|
||||||
* Streaming decompression
|
* Streaming decompression
|
||||||
@@ -111,6 +131,10 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, void* dst, size_t* maxDstSizeP
|
|||||||
* Use ZBUFF_decompressInit() to start a new decompression operation.
|
* Use ZBUFF_decompressInit() to start a new decompression operation.
|
||||||
* ZBUFF_DCtx objects can be reused multiple times.
|
* ZBUFF_DCtx objects can be reused multiple times.
|
||||||
*
|
*
|
||||||
|
* Optionally, a reference to a static dictionary can be set, using ZBUFF_decompressWithDictionary()
|
||||||
|
* It must be the same content as the one set during compression phase.
|
||||||
|
* Dictionary content must remain accessible during the decompression process.
|
||||||
|
*
|
||||||
* Use ZBUFF_decompressContinue() repetitively to consume your input.
|
* Use ZBUFF_decompressContinue() repetitively to consume your input.
|
||||||
* *srcSizePtr and *maxDstSizePtr can be any size.
|
* *srcSizePtr and *maxDstSizePtr can be any size.
|
||||||
* The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr.
|
* The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr.
|
||||||
@@ -129,15 +153,15 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, void* dst, size_t* maxDstSizeP
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Tool functions
|
* Tool functions
|
||||||
***************************************/
|
***************************************/
|
||||||
unsigned ZBUFF_isError(size_t errorCode);
|
ZSTDLIB_API unsigned ZBUFF_isError(size_t errorCode);
|
||||||
const char* ZBUFF_getErrorName(size_t errorCode);
|
ZSTDLIB_API const char* ZBUFF_getErrorName(size_t errorCode);
|
||||||
|
|
||||||
/** The below functions provide recommended buffer sizes for Compression or Decompression operations.
|
/** The below functions provide recommended buffer sizes for Compression or Decompression operations.
|
||||||
* These sizes are not compulsory, they just tend to offer better latency */
|
* These sizes are not compulsory, they just tend to offer better latency */
|
||||||
size_t ZBUFF_recommendedCInSize(void);
|
ZSTDLIB_API size_t ZBUFF_recommendedCInSize(void);
|
||||||
size_t ZBUFF_recommendedCOutSize(void);
|
ZSTDLIB_API size_t ZBUFF_recommendedCOutSize(void);
|
||||||
size_t ZBUFF_recommendedDInSize(void);
|
ZSTDLIB_API size_t ZBUFF_recommendedDInSize(void);
|
||||||
size_t ZBUFF_recommendedDOutSize(void);
|
ZSTDLIB_API size_t ZBUFF_recommendedDOutSize(void);
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ extern "C" {
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Advanced Streaming functions
|
* Advanced Streaming functions
|
||||||
***************************************/
|
***************************************/
|
||||||
size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* cctx, ZSTD_parameters params);
|
ZSTDLIB_API size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* cctx, ZSTD_parameters params);
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
|
|||||||
+128
-49
@@ -65,6 +65,7 @@
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Constants
|
* Constants
|
||||||
***************************************/
|
***************************************/
|
||||||
|
unsigned ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
||||||
static const U32 g_searchStrength = 8;
|
static const U32 g_searchStrength = 8;
|
||||||
|
|
||||||
|
|
||||||
@@ -100,8 +101,6 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Context memory management
|
* Context memory management
|
||||||
***************************************/
|
***************************************/
|
||||||
#define WORKPLACESIZE (BLOCKSIZE*3)
|
|
||||||
|
|
||||||
struct ZSTD_CCtx_s
|
struct ZSTD_CCtx_s
|
||||||
{
|
{
|
||||||
const BYTE* nextSrc; /* next block here to continue on current prefix */
|
const BYTE* nextSrc; /* next block here to continue on current prefix */
|
||||||
@@ -113,6 +112,7 @@ struct ZSTD_CCtx_s
|
|||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
void* workSpace;
|
void* workSpace;
|
||||||
size_t workSpaceSize;
|
size_t workSpaceSize;
|
||||||
|
size_t blockSize;
|
||||||
|
|
||||||
seqStore_t seqStore; /* sequences storage ptrs */
|
seqStore_t seqStore; /* sequences storage ptrs */
|
||||||
U32* hashTable;
|
U32* hashTable;
|
||||||
@@ -170,11 +170,14 @@ void ZSTD_validateParams(ZSTD_parameters* params)
|
|||||||
static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
||||||
ZSTD_parameters params)
|
ZSTD_parameters params)
|
||||||
{
|
{
|
||||||
|
/* note : params considered validated here */
|
||||||
|
const size_t blockSize = MIN(BLOCKSIZE, (size_t)1 << params.windowLog);
|
||||||
|
|
||||||
/* reserve table memory */
|
/* reserve table memory */
|
||||||
{
|
{
|
||||||
const U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog;
|
const U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog;
|
||||||
const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog)) * sizeof(U32);
|
const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog)) * sizeof(U32);
|
||||||
const size_t neededSpace = tableSpace + WORKPLACESIZE;
|
const size_t neededSpace = tableSpace + (3*blockSize);
|
||||||
if (zc->workSpaceSize < neededSpace)
|
if (zc->workSpaceSize < neededSpace)
|
||||||
{
|
{
|
||||||
free(zc->workSpace);
|
free(zc->workSpace);
|
||||||
@@ -195,12 +198,13 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|||||||
zc->dictLimit = 0;
|
zc->dictLimit = 0;
|
||||||
zc->lowLimit = 0;
|
zc->lowLimit = 0;
|
||||||
zc->params = params;
|
zc->params = params;
|
||||||
|
zc->blockSize = blockSize;
|
||||||
zc->seqStore.offsetStart = (U32*) (zc->seqStore.buffer);
|
zc->seqStore.offsetStart = (U32*) (zc->seqStore.buffer);
|
||||||
zc->seqStore.offCodeStart = (BYTE*) (zc->seqStore.offsetStart + (BLOCKSIZE>>2));
|
zc->seqStore.offCodeStart = (BYTE*) (zc->seqStore.offsetStart + (blockSize>>2));
|
||||||
zc->seqStore.litStart = zc->seqStore.offCodeStart + (BLOCKSIZE>>2);
|
zc->seqStore.litStart = zc->seqStore.offCodeStart + (blockSize>>2);
|
||||||
zc->seqStore.litLengthStart = zc->seqStore.litStart + BLOCKSIZE;
|
zc->seqStore.litLengthStart = zc->seqStore.litStart + blockSize;
|
||||||
zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + (BLOCKSIZE>>2);
|
zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + (blockSize>>2);
|
||||||
zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + (BLOCKSIZE>>2);
|
zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + (blockSize>>2);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -485,7 +489,7 @@ size_t ZSTD_compressSequences(void* dst, size_t maxDstSize,
|
|||||||
BYTE litLength = llTable[i]; /* (7)*/ /* (7)*/
|
BYTE litLength = llTable[i]; /* (7)*/ /* (7)*/
|
||||||
FSE_encodeSymbol(&blockStream, &stateMatchLength, matchLength); /* 17 */ /* 17 */
|
FSE_encodeSymbol(&blockStream, &stateMatchLength, matchLength); /* 17 */ /* 17 */
|
||||||
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
||||||
BIT_addBits(&blockStream, offset, nbBits); /* 32 */ /* 42 */
|
BIT_addBits(&blockStream, offset, nbBits); /* 31 */ /* 42 */ /* 24 bits max in 32-bits mode */
|
||||||
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
||||||
FSE_encodeSymbol(&blockStream, &stateOffsetBits, offCode); /* 16 */ /* 51 */
|
FSE_encodeSymbol(&blockStream, &stateOffsetBits, offCode); /* 16 */ /* 51 */
|
||||||
FSE_encodeSymbol(&blockStream, &stateLitLength, litLength); /* 26 */ /* 61 */
|
FSE_encodeSymbol(&blockStream, &stateLitLength, litLength); /* 26 */ /* 61 */
|
||||||
@@ -596,7 +600,7 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
|
|||||||
# if defined(_MSC_VER) && defined(_WIN64)
|
# if defined(_MSC_VER) && defined(_WIN64)
|
||||||
unsigned long r = 0;
|
unsigned long r = 0;
|
||||||
_BitScanForward64( &r, (U64)val );
|
_BitScanForward64( &r, (U64)val );
|
||||||
return (int)(r>>3);
|
return (unsigned)(r>>3);
|
||||||
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
||||||
return (__builtin_ctzll((U64)val) >> 3);
|
return (__builtin_ctzll((U64)val) >> 3);
|
||||||
# else
|
# else
|
||||||
@@ -609,7 +613,7 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
|
|||||||
# if defined(_MSC_VER)
|
# if defined(_MSC_VER)
|
||||||
unsigned long r=0;
|
unsigned long r=0;
|
||||||
_BitScanForward( &r, (U32)val );
|
_BitScanForward( &r, (U32)val );
|
||||||
return (int)(r>>3);
|
return (unsigned)(r>>3);
|
||||||
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
||||||
return (__builtin_ctz((U32)val) >> 3);
|
return (__builtin_ctz((U32)val) >> 3);
|
||||||
# else
|
# else
|
||||||
@@ -620,7 +624,7 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
|
|||||||
}
|
}
|
||||||
else /* Big Endian CPU */
|
else /* Big Endian CPU */
|
||||||
{
|
{
|
||||||
if (MEM_32bits())
|
if (MEM_64bits())
|
||||||
{
|
{
|
||||||
# if defined(_MSC_VER) && defined(_WIN64)
|
# if defined(_MSC_VER) && defined(_WIN64)
|
||||||
unsigned long r = 0;
|
unsigned long r = 0;
|
||||||
@@ -727,13 +731,30 @@ static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
|
|||||||
* Fast Scan
|
* Fast Scan
|
||||||
***************************************/
|
***************************************/
|
||||||
|
|
||||||
|
#define FILLHASHSTEP 3
|
||||||
|
static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
|
||||||
|
{
|
||||||
|
U32* const hashTable = zc->hashTable;
|
||||||
|
const U32 hBits = zc->params.hashLog;
|
||||||
|
const BYTE* const base = zc->base;
|
||||||
|
const BYTE* ip = base + zc->nextToUpdate;
|
||||||
|
const BYTE* const iend = (const BYTE*) end;
|
||||||
|
|
||||||
|
while(ip <= iend)
|
||||||
|
{
|
||||||
|
hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
|
||||||
|
ip += FILLHASHSTEP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const U32 mls)
|
const U32 mls)
|
||||||
{
|
{
|
||||||
U32* hashTable = zc->hashTable;
|
U32* const hashTable = zc->hashTable;
|
||||||
const U32 hBits = zc->params.hashLog;
|
const U32 hBits = zc->params.hashLog;
|
||||||
seqStore_t* seqStorePtr = &(zc->seqStore);
|
seqStore_t* seqStorePtr = &(zc->seqStore);
|
||||||
const BYTE* const base = zc->base;
|
const BYTE* const base = zc->base;
|
||||||
@@ -749,12 +770,12 @@ size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
if (ip < base+4)
|
if (ip < lowest+4)
|
||||||
{
|
{
|
||||||
hashTable[ZSTD_hashPtr(base+1, hBits, mls)] = 1;
|
hashTable[ZSTD_hashPtr(lowest+1, hBits, mls)] = zc->dictLimit+1;
|
||||||
hashTable[ZSTD_hashPtr(base+2, hBits, mls)] = 2;
|
hashTable[ZSTD_hashPtr(lowest+2, hBits, mls)] = zc->dictLimit+2;
|
||||||
hashTable[ZSTD_hashPtr(base+3, hBits, mls)] = 3;
|
hashTable[ZSTD_hashPtr(lowest+3, hBits, mls)] = zc->dictLimit+3;
|
||||||
ip = base+4;
|
ip = lowest+4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main Search Loop */
|
/* Main Search Loop */
|
||||||
@@ -1005,7 +1026,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|||||||
size_t commonLengthSmaller=0, commonLengthLarger=0;
|
size_t commonLengthSmaller=0, commonLengthLarger=0;
|
||||||
const BYTE* const base = zc->base;
|
const BYTE* const base = zc->base;
|
||||||
const BYTE* match = base + matchIndex;
|
const BYTE* match = base + matchIndex;
|
||||||
U32 current = (U32)(ip-base);
|
const U32 current = (U32)(ip-base);
|
||||||
const U32 btLow = btMask >= current ? 0 : current - btMask;
|
const U32 btLow = btMask >= current ? 0 : current - btMask;
|
||||||
U32* smallerPtr = bt + 2*(current&btMask);
|
U32* smallerPtr = bt + 2*(current&btMask);
|
||||||
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
||||||
@@ -1013,13 +1034,14 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|||||||
const U32 windowLow = zc->lowLimit;
|
const U32 windowLow = zc->lowLimit;
|
||||||
|
|
||||||
if ( (current-matchIndex == 1) /* RLE */
|
if ( (current-matchIndex == 1) /* RLE */
|
||||||
|
&& (matchIndex > windowLow)
|
||||||
&& (MEM_read64(match) == MEM_read64(ip)) )
|
&& (MEM_read64(match) == MEM_read64(ip)) )
|
||||||
{
|
{
|
||||||
size_t rleLength = ZSTD_count(ip+8, match+8, iend) + 8;
|
size_t rleLength = ZSTD_count(ip+8, match+8, iend) + 8;
|
||||||
return (U32)(rleLength - mls);
|
return (U32)(rleLength - mls);
|
||||||
}
|
}
|
||||||
|
|
||||||
hashTable[h] = (U32)(ip - base); /* Update Hash Table */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow))
|
while (nbCompares-- && (matchIndex > windowLow))
|
||||||
{
|
{
|
||||||
@@ -1082,7 +1104,7 @@ size_t ZSTD_insertBtAndFindBestMatch (
|
|||||||
size_t bestLength = 0;
|
size_t bestLength = 0;
|
||||||
U32 dummy32; /* to be nullified at the end */
|
U32 dummy32; /* to be nullified at the end */
|
||||||
|
|
||||||
hashTable[h] = (U32)(ip-base); /* Update Hash Table */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow))
|
while (nbCompares-- && (matchIndex > windowLow))
|
||||||
{
|
{
|
||||||
@@ -1192,7 +1214,7 @@ static U32 ZSTD_insertBt1_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const U32
|
|||||||
const BYTE* const dictEnd = dictBase + dictLimit;
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
||||||
const BYTE* const prefixStart = base + dictLimit;
|
const BYTE* const prefixStart = base + dictLimit;
|
||||||
const BYTE* match = base + matchIndex;
|
const BYTE* match = base + matchIndex;
|
||||||
U32 current = (U32)(ip-base);
|
const U32 current = (U32)(ip-base);
|
||||||
const U32 btLow = btMask >= current ? 0 : current - btMask;
|
const U32 btLow = btMask >= current ? 0 : current - btMask;
|
||||||
U32* smallerPtr = bt + 2*(current&btMask);
|
U32* smallerPtr = bt + 2*(current&btMask);
|
||||||
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
||||||
@@ -1206,7 +1228,7 @@ static U32 ZSTD_insertBt1_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const U32
|
|||||||
return (U32)(rleLength - mls);
|
return (U32)(rleLength - mls);
|
||||||
}
|
}
|
||||||
|
|
||||||
hashTable[h] = (U32)(ip - base); /* Update Hash Table */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow))
|
while (nbCompares-- && (matchIndex > windowLow))
|
||||||
{
|
{
|
||||||
@@ -1297,7 +1319,7 @@ size_t ZSTD_insertBtAndFindBestMatch_extDict (
|
|||||||
size_t bestLength = 0;
|
size_t bestLength = 0;
|
||||||
U32 dummy32; /* to be nullified at the end */
|
U32 dummy32; /* to be nullified at the end */
|
||||||
|
|
||||||
hashTable[h] = (U32)(ip-base); /* Update Hash Table */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow))
|
while (nbCompares-- && (matchIndex > windowLow))
|
||||||
{
|
{
|
||||||
@@ -1515,6 +1537,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
const BYTE* anchor = istart;
|
const BYTE* anchor = istart;
|
||||||
const BYTE* const iend = istart + srcSize;
|
const BYTE* const iend = istart + srcSize;
|
||||||
const BYTE* const ilimit = iend - 8;
|
const BYTE* const ilimit = iend - 8;
|
||||||
|
const BYTE* const base = ctx->base + ctx->dictLimit;
|
||||||
|
|
||||||
size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE;
|
size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE;
|
||||||
const U32 maxSearches = 1 << ctx->params.searchLog;
|
const U32 maxSearches = 1 << ctx->params.searchLog;
|
||||||
@@ -1527,7 +1550,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
if (((ip-ctx->base) - ctx->dictLimit) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
|
if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE;
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit)
|
while (ip < ilimit)
|
||||||
@@ -1552,7 +1575,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
matchLength = ml2, start = ip, offset=offsetFound;
|
matchLength = ml2, start = ip, offset=offsetFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchLength < MINMATCH)
|
if (matchLength < MINMATCH)
|
||||||
{
|
{
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
||||||
continue;
|
continue;
|
||||||
@@ -1613,7 +1636,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
/* catch up */
|
/* catch up */
|
||||||
if (offset)
|
if (offset)
|
||||||
{
|
{
|
||||||
while ((start>anchor) && (start>ctx->base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */
|
while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */
|
||||||
{ start--; matchLength++; }
|
{ start--; matchLength++; }
|
||||||
offset_2 = offset_1; offset_1 = offset;
|
offset_2 = offset_1; offset_1 = offset;
|
||||||
}
|
}
|
||||||
@@ -1704,7 +1727,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
if (((ip-base) - dictLimit) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
|
if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit)
|
while (ip < ilimit)
|
||||||
@@ -1919,7 +1942,7 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* ctxPtr,
|
|||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
size_t blockSize = BLOCKSIZE;
|
size_t blockSize = ctxPtr->blockSize;
|
||||||
size_t remaining = srcSize;
|
size_t remaining = srcSize;
|
||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
@@ -1972,28 +1995,33 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
|
|||||||
{
|
{
|
||||||
const BYTE* const ip = (const BYTE*) src;
|
const BYTE* const ip = (const BYTE*) src;
|
||||||
|
|
||||||
/* preemptive overflow correction */
|
|
||||||
if ((zc->base > (const BYTE*)src) || (zc->lowLimit > (1<<30) ))
|
|
||||||
{
|
|
||||||
U32 correction = zc->lowLimit-1;
|
|
||||||
ZSTD_reduceIndex(zc, correction);
|
|
||||||
zc->base += correction;
|
|
||||||
zc->dictBase += correction;
|
|
||||||
zc->lowLimit -= correction;
|
|
||||||
zc->dictLimit -= correction;
|
|
||||||
if (zc->nextToUpdate < correction) zc->nextToUpdate = 0;
|
|
||||||
else zc->nextToUpdate -= correction;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if blocks follow each other */
|
/* Check if blocks follow each other */
|
||||||
if (src != zc->nextSrc)
|
if (src != zc->nextSrc)
|
||||||
{
|
{
|
||||||
/* not contiguous */
|
/* not contiguous */
|
||||||
|
size_t delta = zc->nextSrc - ip;
|
||||||
zc->lowLimit = zc->dictLimit;
|
zc->lowLimit = zc->dictLimit;
|
||||||
zc->dictLimit = (U32)(zc->nextSrc - zc->base);
|
zc->dictLimit = (U32)(zc->nextSrc - zc->base);
|
||||||
zc->dictBase = zc->base;
|
zc->dictBase = zc->base;
|
||||||
zc->base += ip - zc->nextSrc;
|
zc->base -= delta;
|
||||||
zc->nextToUpdate = zc->dictLimit;
|
zc->nextToUpdate = zc->dictLimit;
|
||||||
|
if (zc->dictLimit - zc->lowLimit < 8) zc->lowLimit = zc->dictLimit; /* too small extDict */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* preemptive overflow correction */
|
||||||
|
if (zc->lowLimit > (1<<30))
|
||||||
|
{
|
||||||
|
U32 btplus = (zc->params.strategy == ZSTD_btlazy2);
|
||||||
|
U32 contentMask = (1 << (zc->params.contentLog - btplus)) - 1;
|
||||||
|
U32 newLowLimit = zc->lowLimit & contentMask; /* preserve position % contentSize */
|
||||||
|
U32 correction = zc->lowLimit - newLowLimit;
|
||||||
|
ZSTD_reduceIndex(zc, correction);
|
||||||
|
zc->base += correction;
|
||||||
|
zc->dictBase += correction;
|
||||||
|
zc->lowLimit = newLowLimit;
|
||||||
|
zc->dictLimit -= correction;
|
||||||
|
if (zc->nextToUpdate < correction) zc->nextToUpdate = 0;
|
||||||
|
else zc->nextToUpdate -= correction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* input-dictionary overlap */
|
/* input-dictionary overlap */
|
||||||
@@ -2008,8 +2036,46 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
|
|||||||
return ZSTD_compress_generic (zc, dst, dstSize, src, srcSize);
|
return ZSTD_compress_generic (zc, dst, dstSize, src, srcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
const BYTE* const ip = (const BYTE*) src;
|
||||||
|
const BYTE* const iend = ip + srcSize;
|
||||||
|
|
||||||
/** ZSTD_compressBegin_advanced
|
/* input becomes current prefix */
|
||||||
|
zc->lowLimit = zc->dictLimit;
|
||||||
|
zc->dictLimit = (U32)(zc->nextSrc - zc->base);
|
||||||
|
zc->dictBase = zc->base;
|
||||||
|
zc->base += ip - zc->nextSrc;
|
||||||
|
zc->nextToUpdate = zc->dictLimit;
|
||||||
|
|
||||||
|
zc->nextSrc = iend;
|
||||||
|
if (srcSize <= 8) return 0;
|
||||||
|
|
||||||
|
switch(zc->params.strategy)
|
||||||
|
{
|
||||||
|
case ZSTD_fast:
|
||||||
|
ZSTD_fillHashTable (zc, iend-8, zc->params.searchLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZSTD_greedy:
|
||||||
|
case ZSTD_lazy:
|
||||||
|
case ZSTD_lazy2:
|
||||||
|
ZSTD_insertAndFindFirstIndex (zc, iend-8, zc->params.searchLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZSTD_btlazy2:
|
||||||
|
ZSTD_updateTree(zc, iend-8, iend, 1 << zc->params.searchLog, zc->params.searchLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ERROR(GENERIC); /* strategy doesn't exist; impossible */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! ZSTD_compressBegin_advanced
|
||||||
* Write frame header, according to params
|
* Write frame header, according to params
|
||||||
* @return : nb of bytes written */
|
* @return : nb of bytes written */
|
||||||
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx,
|
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx,
|
||||||
@@ -2036,7 +2102,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx,
|
|||||||
ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint)
|
ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint)
|
||||||
{
|
{
|
||||||
ZSTD_parameters result;
|
ZSTD_parameters result;
|
||||||
int tableID = ((srcSizeHint-1) <= 128 KB); /* intentional underflow for srcSizeHint == 0 */
|
int tableID = ((srcSizeHint-1) <= 256 KB) + ((srcSizeHint-1) <= 128 KB) + ((srcSizeHint-1) <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
|
||||||
if (compressionLevel<=0) compressionLevel = 1;
|
if (compressionLevel<=0) compressionLevel = 1;
|
||||||
if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
|
if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
|
||||||
result = ZSTD_defaultParameters[tableID][compressionLevel];
|
result = ZSTD_defaultParameters[tableID][compressionLevel];
|
||||||
@@ -2051,7 +2117,7 @@ size_t ZSTD_compressBegin(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, int comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_compressEnd
|
/*! ZSTD_compressEnd
|
||||||
* Write frame epilogue
|
* Write frame epilogue
|
||||||
* @return : nb of bytes written into dst (or an error code) */
|
* @return : nb of bytes written into dst (or an error code) */
|
||||||
size_t ZSTD_compressEnd(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize)
|
size_t ZSTD_compressEnd(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize)
|
||||||
@@ -2073,6 +2139,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize)
|
|||||||
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict,size_t dictSize,
|
||||||
ZSTD_parameters params)
|
ZSTD_parameters params)
|
||||||
{
|
{
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
@@ -2085,9 +2152,15 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|||||||
op += oSize;
|
op += oSize;
|
||||||
maxDstSize -= oSize;
|
maxDstSize -= oSize;
|
||||||
|
|
||||||
|
/* dictionary */
|
||||||
|
if (dict)
|
||||||
|
{
|
||||||
|
oSize = ZSTD_compress_insertDictionary(ctx, dict, dictSize);
|
||||||
|
if (ZSTD_isError(oSize)) return oSize;
|
||||||
|
}
|
||||||
|
|
||||||
/* body (compression) */
|
/* body (compression) */
|
||||||
ctx->base = (const BYTE*)src;
|
oSize = ZSTD_compressContinue (ctx, op, maxDstSize, src, srcSize);
|
||||||
oSize = ZSTD_compress_generic (ctx, op, maxDstSize, src, srcSize);
|
|
||||||
if(ZSTD_isError(oSize)) return oSize;
|
if(ZSTD_isError(oSize)) return oSize;
|
||||||
op += oSize;
|
op += oSize;
|
||||||
maxDstSize -= oSize;
|
maxDstSize -= oSize;
|
||||||
@@ -2100,9 +2173,14 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|||||||
return (op - ostart);
|
return (op - ostart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel)
|
||||||
|
{
|
||||||
|
return ZSTD_compress_advanced(ctx, dst, maxDstSize, src, srcSize, dict, dictSize, ZSTD_getParams(compressionLevel, srcSize+dictSize));
|
||||||
|
}
|
||||||
|
|
||||||
size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel)
|
size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel)
|
||||||
{
|
{
|
||||||
return ZSTD_compress_advanced(ctx, dst, maxDstSize, src, srcSize, ZSTD_getParams(compressionLevel, srcSize));
|
return ZSTD_compress_advanced(ctx, dst, maxDstSize, src, srcSize, NULL, 0, ZSTD_getParams(compressionLevel, srcSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_compress(void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel)
|
size_t ZSTD_compress(void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel)
|
||||||
@@ -2114,3 +2192,4 @@ size_t ZSTD_compress(void* dst, size_t maxDstSize, const void* src, size_t srcSi
|
|||||||
free(ctxBody.workSpace); /* can't free ctxBody, since it's on stack; free heap content */
|
free(ctxBody.workSpace); /* can't free ctxBody, since it's on stack; free heap content */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+97
-90
@@ -127,10 +127,10 @@ struct ZSTD_DCtx_s
|
|||||||
U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
||||||
U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
||||||
U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
||||||
void* previousDstEnd;
|
const void* previousDstEnd;
|
||||||
void* base;
|
const void* base;
|
||||||
void* vBase;
|
const void* vBase;
|
||||||
void* dictEnd;
|
const void* dictEnd;
|
||||||
size_t expected;
|
size_t expected;
|
||||||
size_t headerSize;
|
size_t headerSize;
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
@@ -141,7 +141,7 @@ struct ZSTD_DCtx_s
|
|||||||
size_t litSize;
|
size_t litSize;
|
||||||
BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */];
|
BYTE litBuffer[BLOCKSIZE + 8 /* margin for wildcopy */];
|
||||||
BYTE headerBuffer[ZSTD_frameHeaderSize_max];
|
BYTE headerBuffer[ZSTD_frameHeaderSize_max];
|
||||||
}; /* typedef'd to ZSTD_Dctx within "zstd_static.h" */
|
}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
|
||||||
|
|
||||||
size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)
|
size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx)
|
||||||
{
|
{
|
||||||
@@ -505,7 +505,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|||||||
FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
|
FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
|
||||||
BYTE* const oend, seq_t sequence,
|
BYTE* const oend, seq_t sequence,
|
||||||
const BYTE** litPtr, const BYTE* const litLimit_8,
|
const BYTE** litPtr, const BYTE* const litLimit_8,
|
||||||
BYTE* const base, BYTE* const vBase, BYTE* const dictEnd)
|
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 */
|
static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
|
||||||
static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
|
static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
|
||||||
@@ -527,64 +527,61 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
|
|||||||
*litPtr = litEnd; /* update for next sequence */
|
*litPtr = litEnd; /* update for next sequence */
|
||||||
|
|
||||||
/* copy Match */
|
/* copy Match */
|
||||||
/* check */
|
if (sequence.offset > (size_t)(oLitEnd - base))
|
||||||
//if (match > oLitEnd) return ERROR(corruption_detected); /* address space overflow test (is clang optimizer wrongly removing this test ?) */
|
{
|
||||||
if (sequence.offset > (size_t)oLitEnd) return ERROR(corruption_detected); /* address space overflow test (this test seems preserved by clang optimizer) */
|
/* 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 length1 = dictEnd - match;
|
||||||
|
memmove(oLitEnd, match, length1);
|
||||||
|
op = oLitEnd + length1;
|
||||||
|
sequence.matchLength -= length1;
|
||||||
|
match = base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (match < base)
|
/* match within prefix */
|
||||||
{
|
if (sequence.offset < 8)
|
||||||
/* offset beyond prefix */
|
{
|
||||||
if (match < vBase) return ERROR(corruption_detected);
|
/* close range match, overlap */
|
||||||
match = dictEnd - (base-match);
|
const int sub2 = dec64table[sequence.offset];
|
||||||
if (match + sequence.matchLength <= dictEnd)
|
op[0] = match[0];
|
||||||
{
|
op[1] = match[1];
|
||||||
memcpy(oLitEnd, match, sequence.matchLength);
|
op[2] = match[2];
|
||||||
return sequenceLength;
|
op[3] = match[3];
|
||||||
}
|
match += dec32table[sequence.offset];
|
||||||
/* span extDict & currentPrefixSegment */
|
ZSTD_copy4(op+4, match);
|
||||||
{
|
match -= sub2;
|
||||||
size_t length1 = dictEnd - match;
|
}
|
||||||
memcpy(oLitEnd, match, length1);
|
else
|
||||||
op = oLitEnd + length1;
|
{
|
||||||
sequence.matchLength -= length1;
|
ZSTD_copy8(op, match);
|
||||||
match = base;
|
}
|
||||||
}
|
op += 8; match += 8;
|
||||||
}
|
|
||||||
|
|
||||||
/* match within prefix */
|
if (oMatchEnd > oend-12)
|
||||||
if (sequence.offset < 8)
|
{
|
||||||
{
|
if (op < oend_8)
|
||||||
/* close range match, overlap */
|
{
|
||||||
const int sub2 = dec64table[sequence.offset];
|
ZSTD_wildcopy(op, match, oend_8 - op);
|
||||||
op[0] = match[0];
|
match += oend_8 - op;
|
||||||
op[1] = match[1];
|
op = oend_8;
|
||||||
op[2] = match[2];
|
}
|
||||||
op[3] = match[3];
|
while (op < oMatchEnd) *op++ = *match++;
|
||||||
match += dec32table[sequence.offset];
|
}
|
||||||
ZSTD_copy4(op+4, match);
|
else
|
||||||
match -= sub2;
|
{
|
||||||
}
|
ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
||||||
else
|
}
|
||||||
{
|
return sequenceLength;
|
||||||
ZSTD_copy8(op, match);
|
|
||||||
}
|
|
||||||
op += 8; match += 8;
|
|
||||||
|
|
||||||
if (oMatchEnd > oend-12)
|
|
||||||
{
|
|
||||||
if (op < oend_8)
|
|
||||||
{
|
|
||||||
ZSTD_wildcopy(op, match, oend_8 - op);
|
|
||||||
match += oend_8 - op;
|
|
||||||
op = oend_8;
|
|
||||||
}
|
|
||||||
while (op < oMatchEnd) *op++ = *match++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
|
||||||
}
|
|
||||||
return sequenceLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -607,9 +604,9 @@ static size_t ZSTD_decompressSequences(
|
|||||||
U32* DTableLL = dctx->LLTable;
|
U32* DTableLL = dctx->LLTable;
|
||||||
U32* DTableML = dctx->MLTable;
|
U32* DTableML = dctx->MLTable;
|
||||||
U32* DTableOffb = dctx->OffTable;
|
U32* DTableOffb = dctx->OffTable;
|
||||||
BYTE* const base = (BYTE*) (dctx->base);
|
const BYTE* const base = (const BYTE*) (dctx->base);
|
||||||
BYTE* const vBase = (BYTE*) (dctx->vBase);
|
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
|
||||||
BYTE* const dictEnd = (BYTE*) (dctx->dictEnd);
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
||||||
|
|
||||||
/* Build Decoding Tables */
|
/* Build Decoding Tables */
|
||||||
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
|
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
|
||||||
@@ -634,20 +631,7 @@ static size_t ZSTD_decompressSequences(
|
|||||||
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
||||||
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
||||||
|
|
||||||
for ( ; (BIT_reloadDStream(&(seqState.DStream)) < BIT_DStream_completed) ; )
|
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; )
|
||||||
{
|
|
||||||
size_t oneSeqSize;
|
|
||||||
nbSeq--;
|
|
||||||
ZSTD_decodeSequence(&sequence, &seqState);
|
|
||||||
oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
|
|
||||||
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
|
||||||
op += oneSeqSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nbSeq<0) return ERROR(corruption_detected); /* requested too many sequences : data is corrupted */
|
|
||||||
|
|
||||||
/* now BIT_reloadDStream(&(seqState.DStream)) >= BIT_DStream_completed) */
|
|
||||||
for ( ; (BIT_reloadDStream(&(seqState.DStream)) == BIT_DStream_completed) && nbSeq ; )
|
|
||||||
{
|
{
|
||||||
size_t oneSeqSize;
|
size_t oneSeqSize;
|
||||||
nbSeq--;
|
nbSeq--;
|
||||||
@@ -658,7 +642,7 @@ static size_t ZSTD_decompressSequences(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if reached exact end */
|
/* check if reached exact end */
|
||||||
if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* DStream should be entirely and precisely consumed; otherwise data is corrupted */
|
if ( !BIT_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* DStream should be entirely and exactly consumed; otherwise data is corrupted */
|
||||||
|
|
||||||
/* last literal segment */
|
/* last literal segment */
|
||||||
{
|
{
|
||||||
@@ -692,7 +676,10 @@ static size_t ZSTD_decompressBlock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,
|
||||||
|
void* dst, size_t maxDstSize,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
const BYTE* iend = ip + srcSize;
|
const BYTE* iend = ip + srcSize;
|
||||||
@@ -702,9 +689,19 @@ size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const v
|
|||||||
size_t remainingSize = srcSize;
|
size_t remainingSize = srcSize;
|
||||||
blockProperties_t blockProperties;
|
blockProperties_t blockProperties;
|
||||||
|
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ctx->base = ctx->vBase = ctx->dictEnd = dst;
|
ZSTD_resetDCtx(ctx);
|
||||||
|
if (dict)
|
||||||
|
{
|
||||||
|
ZSTD_decompress_insertDictionary(ctx, dict, dictSize);
|
||||||
|
ctx->dictEnd = ctx->previousDstEnd;
|
||||||
|
ctx->vBase = (const char*)dst - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
|
||||||
|
ctx->base = dst;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ctx->vBase = ctx->base = ctx->dictEnd = dst;
|
||||||
|
}
|
||||||
|
|
||||||
/* Frame Header */
|
/* Frame Header */
|
||||||
{
|
{
|
||||||
@@ -765,10 +762,16 @@ size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const v
|
|||||||
return op-ostart;
|
return op-ostart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
return ZSTD_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
ZSTD_DCtx ctx;
|
ZSTD_DCtx dctx;
|
||||||
return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize);
|
return ZSTD_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -786,10 +789,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, con
|
|||||||
if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
|
if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
|
||||||
if (dst != ctx->previousDstEnd) /* not contiguous */
|
if (dst != ctx->previousDstEnd) /* not contiguous */
|
||||||
{
|
{
|
||||||
if ((dst > ctx->base) && (dst < ctx->previousDstEnd)) /* rolling buffer : new segment into dictionary */
|
|
||||||
ctx->base = (char*)dst; /* temporary affectation, for vBase calculation */
|
|
||||||
ctx->dictEnd = ctx->previousDstEnd;
|
ctx->dictEnd = ctx->previousDstEnd;
|
||||||
ctx->vBase = (char*)dst - ((char*)(ctx->previousDstEnd) - (char*)(ctx->base));
|
ctx->vBase = (const char*)dst - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
|
||||||
ctx->base = dst;
|
ctx->base = dst;
|
||||||
ctx->previousDstEnd = dst;
|
ctx->previousDstEnd = dst;
|
||||||
}
|
}
|
||||||
@@ -840,10 +841,9 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, con
|
|||||||
ctx->bType = bp.blockType;
|
ctx->bType = bp.blockType;
|
||||||
ctx->stage = ZSTDds_decompressBlock;
|
ctx->stage = ZSTDds_decompressBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case 3:
|
case ZSTDds_decompressBlock:
|
||||||
{
|
{
|
||||||
/* Decompress : block content */
|
/* Decompress : block content */
|
||||||
size_t rSize;
|
size_t rSize;
|
||||||
@@ -875,3 +875,10 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
ctx->dictEnd = ctx->previousDstEnd;
|
||||||
|
ctx->vBase = (const char*)src - ((const char*)(ctx->previousDstEnd) - (const char*)(ctx->base));
|
||||||
|
ctx->base = src;
|
||||||
|
ctx->previousDstEnd = (const char*)src + srcSize;
|
||||||
|
}
|
||||||
|
|||||||
+112
-27
@@ -80,35 +80,64 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Advanced function
|
* Advanced functions
|
||||||
***************************************/
|
***************************************/
|
||||||
/** ZSTD_getParams
|
/** ZSTD_getParams
|
||||||
* return ZSTD_parameters structure for a selected compression level and srcSize.
|
* return ZSTD_parameters structure for a selected compression level and srcSize.
|
||||||
* srcSizeHint value is optional, select 0 if not known */
|
* srcSizeHint value is optional, select 0 if not known */
|
||||||
ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint);
|
ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint);
|
||||||
|
|
||||||
/** ZSTD_validateParams
|
/** ZSTD_validateParams
|
||||||
* correct params value to remain within authorized range */
|
* correct params value to remain within authorized range */
|
||||||
void ZSTD_validateParams(ZSTD_parameters* params);
|
ZSTDLIB_API void ZSTD_validateParams(ZSTD_parameters* params);
|
||||||
|
|
||||||
|
/** ZSTD_compress_usingDict
|
||||||
|
* Same as ZSTD_compressCCtx(), using a Dictionary content as prefix
|
||||||
|
* Note : dict can be NULL, in which case, it's equivalent to ZSTD_compressCCtx() */
|
||||||
|
ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
|
||||||
|
void* dst, size_t maxDstSize,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict,size_t dictSize,
|
||||||
|
int compressionLevel);
|
||||||
|
|
||||||
/** ZSTD_compress_advanced
|
/** ZSTD_compress_advanced
|
||||||
* Same as ZSTD_compressCCtx(), with fine-tune control of each compression parameter */
|
* Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter */
|
||||||
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
ZSTD_parameters params);
|
const void* dict,size_t dictSize,
|
||||||
|
ZSTD_parameters params);
|
||||||
|
|
||||||
|
/** Decompression context management */
|
||||||
|
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
||||||
|
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
||||||
|
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
|
/** ZSTD_decompressDCtx
|
||||||
|
* Same as ZSTD_decompress, with pre-allocated DCtx structure */
|
||||||
|
size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
/** ZSTD_decompress_usingDict
|
||||||
|
* Same as ZSTD_decompressDCtx, using a Dictionary content as prefix
|
||||||
|
* Note : dict can be NULL, in which case, it's equivalent to ZSTD_decompressDCtx() */
|
||||||
|
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,
|
||||||
|
void* dst, size_t maxDstSize,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict, size_t dictSize);
|
||||||
|
|
||||||
|
|
||||||
/* **************************************
|
/* **************************************
|
||||||
* Streaming functions (bufferless mode)
|
* Streaming functions (direct mode)
|
||||||
****************************************/
|
****************************************/
|
||||||
size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize, int compressionLevel);
|
||||||
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, ZSTD_parameters params);
|
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, ZSTD_parameters params);
|
||||||
size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
|
||||||
size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize);
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Streaming compression, bufferless mode
|
Streaming compression, direct mode (bufferless)
|
||||||
|
|
||||||
A ZSTD_CCtx object is required to track streaming operations.
|
A ZSTD_CCtx object is required to track streaming operations.
|
||||||
Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage it.
|
Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage it.
|
||||||
@@ -118,6 +147,10 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize);
|
|||||||
Use ZSTD_compressBegin().
|
Use ZSTD_compressBegin().
|
||||||
You may also prefer the advanced derivative ZSTD_compressBegin_advanced(), for finer parameter control.
|
You may also prefer the advanced derivative ZSTD_compressBegin_advanced(), for finer parameter control.
|
||||||
|
|
||||||
|
It's then possible to add a dictionary with ZSTD_compress_insertDictionary()
|
||||||
|
Note that dictionary presence is a "hidden" information,
|
||||||
|
the decoder needs to be aware that it is required for proper decoding, or decoding will fail.
|
||||||
|
|
||||||
Then, consume your input using ZSTD_compressContinue().
|
Then, consume your input using ZSTD_compressContinue().
|
||||||
The interface is synchronous, so all input will be consumed.
|
The interface is synchronous, so all input will be consumed.
|
||||||
You must ensure there is enough space in destination buffer to store compressed data under worst case scenario.
|
You must ensure there is enough space in destination buffer to store compressed data under worst case scenario.
|
||||||
@@ -125,18 +158,18 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize);
|
|||||||
|
|
||||||
Finish a frame with ZSTD_compressEnd(), which will write the epilogue.
|
Finish a frame with ZSTD_compressEnd(), which will write the epilogue.
|
||||||
Without it, the frame will be considered incomplete by decoders.
|
Without it, the frame will be considered incomplete by decoders.
|
||||||
You can then re-use ZSTD_CCtx to compress new frames.
|
|
||||||
|
You can then reuse ZSTD_CCtx to compress new frames.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
ZSTDLIB_API size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx);
|
||||||
ZSTD_DCtx* ZSTD_createDCtx(void);
|
ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize);
|
||||||
size_t ZSTD_resetDCtx(ZSTD_DCtx* dctx);
|
ZSTDLIB_API void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* src, size_t srcSize);
|
||||||
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
||||||
|
|
||||||
size_t ZSTD_getFrameParams(ZSTD_parameters* params, const void* src, size_t srcSize);
|
|
||||||
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
|
|
||||||
size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
|
||||||
/**
|
/**
|
||||||
Streaming decompression, bufferless mode
|
Streaming decompression, bufferless mode
|
||||||
|
|
||||||
@@ -146,15 +179,18 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, co
|
|||||||
|
|
||||||
First operation is to retrieve frame parameters, using ZSTD_getFrameParams().
|
First operation is to retrieve frame parameters, using ZSTD_getFrameParams().
|
||||||
This function doesn't consume its input. It needs enough input data to properly decode the frame header.
|
This function doesn't consume its input. It needs enough input data to properly decode the frame header.
|
||||||
The objective is to retrieve *params.windowlog, to know minimum amount of memory required during decoding.
|
Objective is to retrieve *params.windowlog, to know minimum amount of memory required during decoding.
|
||||||
Result : 0 when successful, it means the ZSTD_parameters structure has been filled.
|
Result : 0 when successful, it means the ZSTD_parameters structure has been filled.
|
||||||
>0 : means there is not enough data into src. Provides the expected size to successfully decode header.
|
>0 : means there is not enough data into src. Provides the expected size to successfully decode header.
|
||||||
errorCode, which can be tested using ZSTD_isError() (For example, if it's not a ZSTD header)
|
errorCode, which can be tested using ZSTD_isError() (For example, if it's not a ZSTD header)
|
||||||
|
|
||||||
|
Then, you can optionally insert a dictionary.
|
||||||
|
This operation must mimic the compressor behavior, otherwise decompression will fail or be corrupted.
|
||||||
|
|
||||||
Then it's possible to start decompression.
|
Then it's possible to start decompression.
|
||||||
Use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
|
Use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
|
||||||
ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().
|
ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().
|
||||||
ZSTD_decompressContinue() requires this exact amount of bytes, or just fails.
|
ZSTD_decompressContinue() requires this exact amount of bytes, or it will fail.
|
||||||
ZSTD_decompressContinue() needs previous data blocks during decompression, up to (1 << windowlog).
|
ZSTD_decompressContinue() needs previous data blocks during decompression, up to (1 << windowlog).
|
||||||
They should preferably be located contiguously, prior to current block. Alternatively, a round buffer is also possible.
|
They should preferably be located contiguously, prior to current block. Alternatively, a round buffer is also possible.
|
||||||
|
|
||||||
@@ -169,9 +205,10 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, co
|
|||||||
* Pre-defined compression levels
|
* Pre-defined compression levels
|
||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTD_MAX_CLEVEL 20
|
#define ZSTD_MAX_CLEVEL 20
|
||||||
static const ZSTD_parameters ZSTD_defaultParameters[2][ZSTD_MAX_CLEVEL+1] = {
|
ZSTDLIB_API unsigned ZSTD_maxCLevel (void);
|
||||||
|
static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = {
|
||||||
{ /* "default" */
|
{ /* "default" */
|
||||||
/* W, C, H, S, L, strat */
|
/* W, C, H, S, L, strat */
|
||||||
{ 0, 18, 12, 12, 1, 4, ZSTD_fast }, /* level 0 - never used */
|
{ 0, 18, 12, 12, 1, 4, ZSTD_fast }, /* level 0 - never used */
|
||||||
{ 0, 19, 13, 14, 1, 7, ZSTD_fast }, /* level 1 */
|
{ 0, 19, 13, 14, 1, 7, ZSTD_fast }, /* level 1 */
|
||||||
{ 0, 19, 15, 16, 1, 6, ZSTD_fast }, /* level 2 */
|
{ 0, 19, 15, 16, 1, 6, ZSTD_fast }, /* level 2 */
|
||||||
@@ -194,8 +231,32 @@ static const ZSTD_parameters ZSTD_defaultParameters[2][ZSTD_MAX_CLEVEL+1] = {
|
|||||||
{ 0, 25, 26, 23, 5, 5, ZSTD_btlazy2 }, /* level 19 */
|
{ 0, 25, 26, 23, 5, 5, ZSTD_btlazy2 }, /* level 19 */
|
||||||
{ 0, 26, 27, 25, 9, 5, ZSTD_btlazy2 }, /* level 20 */
|
{ 0, 26, 27, 25, 9, 5, ZSTD_btlazy2 }, /* level 20 */
|
||||||
},
|
},
|
||||||
|
{ /* for srcSize <= 256 KB */
|
||||||
|
/* W, C, H, S, L, strat */
|
||||||
|
{ 0, 18, 13, 14, 1, 7, ZSTD_fast }, /* level 0 - never used */
|
||||||
|
{ 0, 18, 14, 15, 1, 6, ZSTD_fast }, /* level 1 */
|
||||||
|
{ 0, 18, 14, 15, 1, 5, ZSTD_fast }, /* level 2 */
|
||||||
|
{ 0, 18, 12, 15, 3, 7, ZSTD_greedy }, /* level 3 */
|
||||||
|
{ 0, 18, 13, 15, 4, 7, ZSTD_greedy }, /* level 4 */
|
||||||
|
{ 0, 18, 14, 15, 5, 7, ZSTD_greedy }, /* level 5 */
|
||||||
|
{ 0, 18, 13, 15, 4, 7, ZSTD_lazy }, /* level 6 */
|
||||||
|
{ 0, 18, 14, 16, 5, 7, ZSTD_lazy }, /* level 7 */
|
||||||
|
{ 0, 18, 15, 16, 6, 7, ZSTD_lazy }, /* level 8 */
|
||||||
|
{ 0, 18, 15, 15, 7, 7, ZSTD_lazy }, /* level 9 */
|
||||||
|
{ 0, 18, 16, 16, 7, 7, ZSTD_lazy }, /* level 10 */
|
||||||
|
{ 0, 18, 16, 16, 8, 4, ZSTD_lazy }, /* level 11 */
|
||||||
|
{ 0, 18, 17, 16, 8, 4, ZSTD_lazy }, /* level 12 */
|
||||||
|
{ 0, 18, 17, 16, 9, 4, ZSTD_lazy }, /* level 13 */
|
||||||
|
{ 0, 18, 18, 16, 9, 4, ZSTD_lazy }, /* level 14 */
|
||||||
|
{ 0, 18, 17, 17, 9, 4, ZSTD_lazy2 }, /* level 15 */
|
||||||
|
{ 0, 18, 18, 18, 9, 4, ZSTD_lazy2 }, /* level 16 */
|
||||||
|
{ 0, 18, 18, 18, 10, 4, ZSTD_lazy2 }, /* level 17 */
|
||||||
|
{ 0, 18, 18, 18, 11, 4, ZSTD_lazy2 }, /* level 18 */
|
||||||
|
{ 0, 18, 18, 18, 12, 4, ZSTD_lazy2 }, /* level 19 */
|
||||||
|
{ 0, 18, 18, 18, 13, 4, ZSTD_lazy2 }, /* level 20 */
|
||||||
|
},
|
||||||
{ /* for srcSize <= 128 KB */
|
{ /* for srcSize <= 128 KB */
|
||||||
/* W, C, H, S, L, strat */
|
/* W, C, H, S, L, strat */
|
||||||
{ 0, 17, 12, 12, 1, 4, ZSTD_fast }, /* level 0 - never used */
|
{ 0, 17, 12, 12, 1, 4, ZSTD_fast }, /* level 0 - never used */
|
||||||
{ 0, 17, 12, 13, 1, 6, ZSTD_fast }, /* level 1 */
|
{ 0, 17, 12, 13, 1, 6, ZSTD_fast }, /* level 1 */
|
||||||
{ 0, 17, 15, 16, 1, 5, ZSTD_fast }, /* level 2 */
|
{ 0, 17, 15, 16, 1, 5, ZSTD_fast }, /* level 2 */
|
||||||
@@ -218,6 +279,30 @@ static const ZSTD_parameters ZSTD_defaultParameters[2][ZSTD_MAX_CLEVEL+1] = {
|
|||||||
{ 0, 17, 18, 16, 10, 4, ZSTD_btlazy2 }, /* level 19 */
|
{ 0, 17, 18, 16, 10, 4, ZSTD_btlazy2 }, /* level 19 */
|
||||||
{ 0, 17, 18, 18, 12, 4, ZSTD_btlazy2 }, /* level 20 */
|
{ 0, 17, 18, 18, 12, 4, ZSTD_btlazy2 }, /* level 20 */
|
||||||
},
|
},
|
||||||
|
{ /* for srcSize <= 16 KB */
|
||||||
|
/* W, C, H, S, L, strat */
|
||||||
|
{ 0, 0, 0, 0, 0, 0, ZSTD_fast }, /* level 0 - never used */
|
||||||
|
{ 0, 14, 14, 14, 1, 4, ZSTD_fast }, /* level 1 */
|
||||||
|
{ 0, 14, 14, 16, 1, 4, ZSTD_fast }, /* level 1 */
|
||||||
|
{ 0, 14, 14, 14, 5, 4, ZSTD_greedy }, /* level 3 */
|
||||||
|
{ 0, 14, 14, 14, 8, 4, ZSTD_greedy }, /* level 4 */
|
||||||
|
{ 0, 14, 11, 14, 6, 4, ZSTD_lazy }, /* level 5 */
|
||||||
|
{ 0, 14, 14, 13, 6, 5, ZSTD_lazy }, /* level 6 */
|
||||||
|
{ 0, 14, 14, 14, 7, 6, ZSTD_lazy }, /* level 7 */
|
||||||
|
{ 0, 14, 14, 14, 8, 4, ZSTD_lazy }, /* level 8 */
|
||||||
|
{ 0, 14, 14, 15, 9, 4, ZSTD_lazy }, /* level 9 */
|
||||||
|
{ 0, 14, 14, 15, 10, 4, ZSTD_lazy }, /* level 10 */
|
||||||
|
{ 0, 14, 15, 15, 6, 4, ZSTD_btlazy2 }, /* level 11 */
|
||||||
|
{ 0, 14, 15, 15, 7, 4, ZSTD_btlazy2 }, /* level 12 */
|
||||||
|
{ 0, 14, 15, 15, 8, 4, ZSTD_btlazy2 }, /* level 13 */
|
||||||
|
{ 0, 14, 15, 15, 9, 4, ZSTD_btlazy2 }, /* level 14 */
|
||||||
|
{ 0, 14, 15, 15, 10, 4, ZSTD_btlazy2 }, /* level 15 */
|
||||||
|
{ 0, 14, 15, 15, 11, 4, ZSTD_btlazy2 }, /* level 16 */
|
||||||
|
{ 0, 14, 15, 15, 12, 4, ZSTD_btlazy2 }, /* level 17 */
|
||||||
|
{ 0, 14, 15, 15, 13, 4, ZSTD_btlazy2 }, /* level 18 */
|
||||||
|
{ 0, 14, 15, 15, 14, 4, ZSTD_btlazy2 }, /* level 19 */
|
||||||
|
{ 0, 14, 15, 15, 15, 4, ZSTD_btlazy2 }, /* level 20 */
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+29
-79
@@ -30,7 +30,7 @@
|
|||||||
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode
|
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
|
|
||||||
VERSION?= 0.4.0
|
VERSION?= 0.4.5
|
||||||
|
|
||||||
DESTDIR?=
|
DESTDIR?=
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
@@ -46,7 +46,7 @@ ZSTDDIR = ../lib
|
|||||||
ZSTD_FILES := $(ZSTDDIR)/zstd_compress.c $(ZSTDDIR)/zstd_decompress.c $(ZSTDDIR)/fse.c $(ZSTDDIR)/huff0.c
|
ZSTD_FILES := $(ZSTDDIR)/zstd_compress.c $(ZSTDDIR)/zstd_decompress.c $(ZSTDDIR)/fse.c $(ZSTDDIR)/huff0.c
|
||||||
ZSTD_LEGACY:= $(ZSTDDIR)/legacy/zstd_v01.c $(ZSTDDIR)/legacy/zstd_v02.c $(ZSTDDIR)/legacy/zstd_v03.c
|
ZSTD_LEGACY:= $(ZSTDDIR)/legacy/zstd_v01.c $(ZSTDDIR)/legacy/zstd_v02.c $(ZSTDDIR)/legacy/zstd_v03.c
|
||||||
|
|
||||||
ifeq ($(ZSTD_LEGACY),disable)
|
ifeq ($(ZSTD_LEGACY_SUPPORT), 0)
|
||||||
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
||||||
else
|
else
|
||||||
ZSTD_FILES+= $(ZSTD_LEGACY)
|
ZSTD_FILES+= $(ZSTD_LEGACY)
|
||||||
@@ -65,6 +65,7 @@ VOID = /dev/null
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ZBUFFTEST = -T2mn
|
ZBUFFTEST = -T2mn
|
||||||
|
FUZZERTEST= -T5mn
|
||||||
|
|
||||||
.PHONY: default all clean install uninstall test test32 test-all
|
.PHONY: default all clean install uninstall test test32 test-all
|
||||||
|
|
||||||
@@ -73,13 +74,29 @@ default: zstd
|
|||||||
all: zstd zstd32 fullbench fullbench32 fuzzer fuzzer32 zbufftest zbufftest32 paramgrill datagen
|
all: zstd zstd32 fullbench fullbench32 fuzzer fuzzer32 zbufftest zbufftest32 paramgrill datagen
|
||||||
|
|
||||||
zstd : $(ZSTD_FILES) $(ZSTDDIR)/zstd_buffered.c \
|
zstd : $(ZSTD_FILES) $(ZSTDDIR)/zstd_buffered.c \
|
||||||
xxhash.c bench.c fileio.c zstdcli.c $(ZSTD_FILEIO_LEGACY)
|
zstdcli.c fileio.c $(ZSTD_FILEIO_LEGACY) bench.c xxhash.c datagen.c
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
zstd32: $(ZSTD_FILES) $(ZSTDDIR)/zstd_buffered.c \
|
zstd32: $(ZSTD_FILES) $(ZSTDDIR)/zstd_buffered.c \
|
||||||
xxhash.c bench.c fileio.c zstdcli.c $(ZSTD_FILEIO_LEGACY)
|
zstdcli.c fileio.c $(ZSTD_FILEIO_LEGACY) bench.c xxhash.c datagen.c
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
zstd_nolegacy :
|
||||||
|
$(MAKE) zstd ZSTD_LEGACY_SUPPORT=0
|
||||||
|
|
||||||
|
zstd-pgo : MOREFLAGS = -fprofile-generate
|
||||||
|
zstd-pgo : clean zstd
|
||||||
|
./zstd -b $(PROFILE_WITH)
|
||||||
|
rm zstd
|
||||||
|
$(MAKE) zstd MOREFLAGS=-fprofile-use
|
||||||
|
|
||||||
|
zstd-noBench: $(ZSTD_FILES) $(ZSTDDIR)/zstd_buffered.c \
|
||||||
|
zstdcli.c fileio.c $(ZSTD_FILEIO_LEGACY)
|
||||||
|
$(CC) $(FLAGS) -DZSTD_NOBENCH $^ -o zstd$(EXT)
|
||||||
|
|
||||||
|
zstd-frugal: clean
|
||||||
|
$(MAKE) zstd-noBench ZSTD_LEGACY_SUPPORT=0
|
||||||
|
|
||||||
fullbench : $(ZSTD_FILES) \
|
fullbench : $(ZSTD_FILES) \
|
||||||
datagen.c fullbench.c
|
datagen.c fullbench.c
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
@@ -112,7 +129,7 @@ datagen : datagen.c datagencli.c
|
|||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f core *.o tmp* \
|
@rm -f core *.o tmp* result* *.gcda \
|
||||||
zstd$(EXT) zstd32$(EXT) \
|
zstd$(EXT) zstd32$(EXT) \
|
||||||
fullbench$(EXT) fullbench32$(EXT) \
|
fullbench$(EXT) fullbench32$(EXT) \
|
||||||
fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \
|
fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \
|
||||||
@@ -152,77 +169,7 @@ test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zbuff32
|
|||||||
test-all: test test32 valgrindTest
|
test-all: test test32 valgrindTest
|
||||||
|
|
||||||
zstd-playTests: datagen
|
zstd-playTests: datagen
|
||||||
@echo "\n**** frame concatenation **** "
|
ZSTD=$(ZSTD) ./playTests.sh --test-large-data
|
||||||
@echo "hello " > hello.tmp
|
|
||||||
@echo "world!" > world.tmp
|
|
||||||
@cat hello.tmp world.tmp > helloworld.tmp
|
|
||||||
$(ZSTD) hello.tmp > hello.zstd
|
|
||||||
$(ZSTD) world.tmp > world.zstd
|
|
||||||
@cat hello.zstd world.zstd > helloworld.zstd
|
|
||||||
$(ZSTD) -df helloworld.zstd > result.tmp
|
|
||||||
cat result.tmp
|
|
||||||
sdiff helloworld.tmp result.tmp
|
|
||||||
@rm *.tmp *.zstd
|
|
||||||
@echo frame concatenation test completed
|
|
||||||
@echo "**** flush write error test **** "
|
|
||||||
echo foo | $(ZSTD) > /dev/full; if [ $$? -eq 0 ] ; then echo "write error not detected!"; false; fi
|
|
||||||
echo foo | $(ZSTD) | $(ZSTD) -d > /dev/full; if [ $$? -eq 0 ] ; then echo "write error not detected!"; false; fi
|
|
||||||
@echo "**** zstd round-trip tests **** "
|
|
||||||
@./datagen | md5sum > tmp1
|
|
||||||
./datagen | $(ZSTD) -v | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen | $(ZSTD) -6 -v | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
@./datagen -g270000000 | md5sum > tmp1
|
|
||||||
./datagen -g270000000 | $(ZSTD) -v | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g270000000 | $(ZSTD) -v2 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g270000000 | $(ZSTD) -v3 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
@./datagen -g140000000 -P60| md5sum > tmp1
|
|
||||||
./datagen -g140000000 -P60 | $(ZSTD) -v4 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g140000000 -P60 | $(ZSTD) -v5 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g140000000 -P60 | $(ZSTD) -v6 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
@./datagen -g70000000 -P70 | md5sum > tmp1
|
|
||||||
./datagen -g70000000 -P70 | $(ZSTD) -v7 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g70000000 -P70 | $(ZSTD) -v8 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g70000000 -P70 | $(ZSTD) -v9 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
@./datagen -g35000000 -P75 | md5sum > tmp1
|
|
||||||
./datagen -g35000000 -P75 | $(ZSTD) -v10 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g35000000 -P75 | $(ZSTD) -v11 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g35000000 -P75 | $(ZSTD) -v12 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
@./datagen -g18000000 -P80 | md5sum > tmp1
|
|
||||||
./datagen -g18000000 -P80 | $(ZSTD) -v13 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g18000000 -P80 | $(ZSTD) -v14 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g18000000 -P80 | $(ZSTD) -v15 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g18000000 -P80 | $(ZSTD) -v16 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g18000000 -P80 | $(ZSTD) -v17 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
@./datagen -g50000000 -P94 | md5sum > tmp1
|
|
||||||
./datagen -g50000000 -P94 | $(ZSTD) -v18 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g50000000 -P94 | $(ZSTD) -v19 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
@./datagen -g99000000 -P99 | md5sum > tmp1
|
|
||||||
./datagen -g99000000 -P99 | $(ZSTD) -v20 | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
./datagen -g6000000000 -P99| md5sum > tmp1
|
|
||||||
./datagen -g6000000000 -P99| $(ZSTD) -vq | $(ZSTD) -d | md5sum > tmp2
|
|
||||||
@diff tmp1 tmp2
|
|
||||||
|
|
||||||
test-zstd: ZSTD = ./zstd
|
test-zstd: ZSTD = ./zstd
|
||||||
test-zstd: zstd zstd-playTests
|
test-zstd: zstd zstd-playTests
|
||||||
@@ -230,6 +177,9 @@ test-zstd: zstd zstd-playTests
|
|||||||
test-zstd32: ZSTD = ./zstd32
|
test-zstd32: ZSTD = ./zstd32
|
||||||
test-zstd32: zstd32 zstd-playTests
|
test-zstd32: zstd32 zstd-playTests
|
||||||
|
|
||||||
|
test-zstd_nolegacy: ZSTD = ./zstd
|
||||||
|
test-zstd_nolegacy: zstd_nolegacy zstd-playTests
|
||||||
|
|
||||||
test-fullbench: fullbench datagen
|
test-fullbench: fullbench datagen
|
||||||
./fullbench -i1
|
./fullbench -i1
|
||||||
./fullbench -i1 -P0
|
./fullbench -i1 -P0
|
||||||
@@ -239,10 +189,10 @@ test-fullbench32: fullbench32 datagen
|
|||||||
./fullbench32 -i1 -P0
|
./fullbench32 -i1 -P0
|
||||||
|
|
||||||
test-fuzzer: fuzzer
|
test-fuzzer: fuzzer
|
||||||
./fuzzer
|
./fuzzer $(FUZZERTEST)
|
||||||
|
|
||||||
test-fuzzer32: fuzzer32
|
test-fuzzer32: fuzzer32
|
||||||
./fuzzer32
|
./fuzzer32 $(FUZZERTEST)
|
||||||
|
|
||||||
test-zbuff: zbufftest
|
test-zbuff: zbufftest
|
||||||
./zbufftest $(ZBUFFTEST)
|
./zbufftest $(ZBUFFTEST)
|
||||||
@@ -261,7 +211,7 @@ valgrindTest: zstd datagen fuzzer fullbench zbufftest
|
|||||||
./datagen -g64MB > tmp
|
./datagen -g64MB > tmp
|
||||||
valgrind --leak-check=yes --error-exitcode=1 ./zstd -vf tmp $(VOID)
|
valgrind --leak-check=yes --error-exitcode=1 ./zstd -vf tmp $(VOID)
|
||||||
@rm tmp
|
@rm tmp
|
||||||
valgrind --leak-check=yes --error-exitcode=1 ./fuzzer -i1000 -t1
|
valgrind --leak-check=yes --error-exitcode=1 ./fuzzer -T1mn -t1
|
||||||
valgrind --leak-check=yes --error-exitcode=1 ./fullbench -i1
|
valgrind --leak-check=yes --error-exitcode=1 ./fullbench -i1
|
||||||
valgrind --leak-check=yes --error-exitcode=1 ./zbufftest -T1mn
|
valgrind --leak-check=yes --error-exitcode=1 ./zbufftest -T1mn
|
||||||
|
|
||||||
|
|||||||
+202
-206
@@ -27,7 +27,10 @@
|
|||||||
* Compiler Options
|
* Compiler Options
|
||||||
****************************************/
|
****************************************/
|
||||||
/* Disable some Visual warning messages */
|
/* Disable some Visual warning messages */
|
||||||
#define _CRT_SECURE_NO_WARNINGS /* fopen */
|
#ifdef _MSC_VER
|
||||||
|
# define _CRT_SECURE_NO_WARNINGS /* fopen */
|
||||||
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Unix Large Files support (>4GB) */
|
/* Unix Large Files support (>4GB) */
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
@@ -54,14 +57,15 @@
|
|||||||
|
|
||||||
/* Use ftime() if gettimeofday() is not available */
|
/* Use ftime() if gettimeofday() is not available */
|
||||||
#if defined(BMK_LEGACY_TIMER)
|
#if defined(BMK_LEGACY_TIMER)
|
||||||
# include <sys/timeb.h> /* timeb, ftime */
|
# include <sys/timeb.h> /* timeb, ftime */
|
||||||
#else
|
#else
|
||||||
# include <sys/time.h> /* gettimeofday */
|
# include <sys/time.h> /* gettimeofday */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "zstd.h"
|
#include "zstd_static.h"
|
||||||
#include "xxhash.h"
|
#include "xxhash.h"
|
||||||
|
#include "datagen.h" /* RDG_genBuffer */
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -71,6 +75,10 @@
|
|||||||
# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
|
# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define snprintf sprintf_s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Constants
|
* Constants
|
||||||
@@ -82,18 +90,35 @@
|
|||||||
#define MB *(1 <<20)
|
#define MB *(1 <<20)
|
||||||
#define GB *(1U<<30)
|
#define GB *(1U<<30)
|
||||||
|
|
||||||
static const size_t maxMemory = sizeof(size_t)==4 ? (2 GB - 64 MB) : (size_t)(1ULL << ((sizeof(size_t)*8)-31));
|
static const size_t maxMemory = (sizeof(size_t)==4) ? (2 GB - 64 MB) : (size_t)(1ULL << ((sizeof(size_t)*8)-31));
|
||||||
#define DEFAULT_CHUNKSIZE (4 MB)
|
#define DEFAULT_CHUNKSIZE (4 MB)
|
||||||
|
|
||||||
static U32 g_compressibilityDefault = 50;
|
static U32 g_compressibilityDefault = 50;
|
||||||
static U32 prime1 = 2654435761U;
|
|
||||||
static U32 prime2 = 2246822519U;
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Macros
|
* console display
|
||||||
***************************************/
|
***************************************/
|
||||||
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
||||||
|
#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
|
||||||
|
static U32 g_displayLevel = 2; /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Exceptions
|
||||||
|
***************************************/
|
||||||
|
#ifndef DEBUG
|
||||||
|
# define DEBUG 0
|
||||||
|
#endif
|
||||||
|
#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
|
||||||
|
#define EXM_THROW(error, ...) \
|
||||||
|
{ \
|
||||||
|
DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
|
||||||
|
DISPLAYLEVEL(1, "Error %i : ", error); \
|
||||||
|
DISPLAYLEVEL(1, __VA_ARGS__); \
|
||||||
|
DISPLAYLEVEL(1, "\n"); \
|
||||||
|
exit(error); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -157,60 +182,18 @@ static int BMK_GetMilliSpan( int nTimeStart )
|
|||||||
return nSpan;
|
return nSpan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static U64 BMK_getFileSize(const char* infilename)
|
||||||
/* ********************************************************
|
|
||||||
* Data generator
|
|
||||||
**********************************************************/
|
|
||||||
/* will hopefully be converted into ROL instruction by compiler */
|
|
||||||
static U32 BMK_rotl32(unsigned val32, unsigned nbBits) { return((val32 << nbBits) | (val32 >> (32 - nbBits))); }
|
|
||||||
|
|
||||||
static U32 BMK_rand(U32* src)
|
|
||||||
{
|
{
|
||||||
U32 rand32 = *src;
|
int r;
|
||||||
rand32 *= prime1;
|
#if defined(_MSC_VER)
|
||||||
rand32 += prime2;
|
struct _stat64 statbuf;
|
||||||
rand32 = BMK_rotl32(rand32, 13);
|
r = _stat64(infilename, &statbuf);
|
||||||
*src = rand32;
|
#else
|
||||||
return rand32 >> 9;
|
struct stat statbuf;
|
||||||
}
|
r = stat(infilename, &statbuf);
|
||||||
|
#endif
|
||||||
#define BMK_RAND15BITS ( BMK_rand(&seed) & 0x7FFF)
|
if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */
|
||||||
#define BMK_RANDLENGTH ((BMK_rand(&seed) & 3) ? (BMK_rand(&seed) % 15) : (BMK_rand(&seed) % 510) + 15)
|
return (U64)statbuf.st_size;
|
||||||
#define BMK_RANDCHAR (BYTE)((BMK_rand(&seed) & 63) + '0')
|
|
||||||
static void BMK_datagen(void* buffer, size_t bufferSize, double proba, U32 seed)
|
|
||||||
{
|
|
||||||
BYTE* BBuffer = (BYTE*)buffer;
|
|
||||||
unsigned pos = 0;
|
|
||||||
U32 P32 = (U32)(32768 * proba);
|
|
||||||
|
|
||||||
/* First Byte */
|
|
||||||
BBuffer[pos++] = BMK_RANDCHAR;
|
|
||||||
|
|
||||||
while (pos < bufferSize)
|
|
||||||
{
|
|
||||||
/* Select : Literal (noise) or copy (within 64K) */
|
|
||||||
if (BMK_RAND15BITS < P32)
|
|
||||||
{
|
|
||||||
/* Match */
|
|
||||||
size_t match, end;
|
|
||||||
unsigned length = BMK_RANDLENGTH + 4;
|
|
||||||
unsigned offset = BMK_RAND15BITS + 1;
|
|
||||||
if (offset > pos) offset = pos;
|
|
||||||
match = pos - offset;
|
|
||||||
end = pos + length;
|
|
||||||
if (end > bufferSize) end = bufferSize;
|
|
||||||
while (pos < end) BBuffer[pos++] = BBuffer[match++];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Literal */
|
|
||||||
size_t end;
|
|
||||||
unsigned length = BMK_RANDLENGTH;
|
|
||||||
end = pos + length;
|
|
||||||
if (end > bufferSize) end = bufferSize;
|
|
||||||
while (pos < end) BBuffer[pos++] = BMK_RANDCHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -219,7 +202,7 @@ static void BMK_datagen(void* buffer, size_t bufferSize, double proba, U32 seed)
|
|||||||
**********************************************************/
|
**********************************************************/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char* srcPtr;
|
const char* srcPtr;
|
||||||
size_t srcSize;
|
size_t srcSize;
|
||||||
char* cPtr;
|
char* cPtr;
|
||||||
size_t cRoom;
|
size_t cRoom;
|
||||||
@@ -228,62 +211,60 @@ typedef struct
|
|||||||
size_t resSize;
|
size_t resSize;
|
||||||
} blockParam_t;
|
} blockParam_t;
|
||||||
|
|
||||||
typedef size_t (*compressor_t) (void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel);
|
|
||||||
|
|
||||||
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||||
|
|
||||||
static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, int cLevel)
|
static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
||||||
|
const char* displayName, int cLevel,
|
||||||
|
const size_t* fileSizes, U32 nbFiles,
|
||||||
|
const void* dictBuffer, size_t dictBufferSize)
|
||||||
{
|
{
|
||||||
const size_t blockSize = (g_blockSize ? g_blockSize : srcSize) + (!srcSize); /* avoid div by 0 */
|
const size_t blockSize = (g_blockSize ? g_blockSize : srcSize) + (!srcSize); /* avoid div by 0 */
|
||||||
const U32 nbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize);
|
const U32 maxNbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize) + nbFiles;
|
||||||
blockParam_t* const blockTable = (blockParam_t*) malloc(nbBlocks * sizeof(blockParam_t));
|
blockParam_t* const blockTable = (blockParam_t*) malloc(maxNbBlocks * sizeof(blockParam_t));
|
||||||
const size_t maxCompressedSize = (size_t)nbBlocks * ZSTD_compressBound(blockSize);
|
const size_t maxCompressedSize = ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024); /* add some room for safety */
|
||||||
void* const compressedBuffer = malloc(maxCompressedSize);
|
void* const compressedBuffer = malloc(maxCompressedSize);
|
||||||
void* const resultBuffer = malloc(srcSize);
|
void* const resultBuffer = malloc(srcSize);
|
||||||
const compressor_t compressor = ZSTD_compress;
|
ZSTD_CCtx* ctx = ZSTD_createCCtx();
|
||||||
U64 crcOrig;
|
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
||||||
|
U64 crcOrig = XXH64(srcBuffer, srcSize, 0);
|
||||||
|
U32 nbBlocks = 0;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
if (strlen(fileName)>16)
|
if (strlen(displayName)>17) displayName += strlen(displayName)-17; /* can only display 17 characters */
|
||||||
fileName += strlen(fileName)-16;
|
|
||||||
|
|
||||||
/* Memory allocation & restrictions */
|
/* Memory allocation & restrictions */
|
||||||
if (!compressedBuffer || !resultBuffer || !blockTable)
|
if (!compressedBuffer || !resultBuffer || !blockTable || !ctx || !dctx)
|
||||||
{
|
EXM_THROW(31, "not enough memory");
|
||||||
DISPLAY("\nError: not enough memory!\n");
|
|
||||||
free(compressedBuffer);
|
|
||||||
free(resultBuffer);
|
|
||||||
free(blockTable);
|
|
||||||
return 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculating input Checksum */
|
|
||||||
crcOrig = XXH64(srcBuffer, srcSize, 0);
|
|
||||||
|
|
||||||
/* Init blockTable data */
|
/* Init blockTable data */
|
||||||
{
|
{
|
||||||
U32 i;
|
U32 fileNb;
|
||||||
size_t remaining = srcSize;
|
const char* srcPtr = (const char*)srcBuffer;
|
||||||
char* srcPtr = (char*)srcBuffer;
|
|
||||||
char* cPtr = (char*)compressedBuffer;
|
char* cPtr = (char*)compressedBuffer;
|
||||||
char* resPtr = (char*)resultBuffer;
|
char* resPtr = (char*)resultBuffer;
|
||||||
for (i=0; i<nbBlocks; i++)
|
for (fileNb=0; fileNb<nbFiles; fileNb++)
|
||||||
{
|
{
|
||||||
size_t thisBlockSize = MIN(remaining, blockSize);
|
size_t remaining = fileSizes[fileNb];
|
||||||
blockTable[i].srcPtr = srcPtr;
|
U32 nbBlocksforThisFile = (U32)((remaining + (blockSize-1)) / blockSize);
|
||||||
blockTable[i].cPtr = cPtr;
|
U32 blockEnd = nbBlocks + nbBlocksforThisFile;
|
||||||
blockTable[i].resPtr = resPtr;
|
for ( ; nbBlocks<blockEnd; nbBlocks++)
|
||||||
blockTable[i].srcSize = thisBlockSize;
|
{
|
||||||
blockTable[i].cRoom = ZSTD_compressBound(thisBlockSize);
|
size_t thisBlockSize = MIN(remaining, blockSize);
|
||||||
srcPtr += thisBlockSize;
|
blockTable[nbBlocks].srcPtr = srcPtr;
|
||||||
cPtr += blockTable[i].cRoom;
|
blockTable[nbBlocks].cPtr = cPtr;
|
||||||
resPtr += thisBlockSize;
|
blockTable[nbBlocks].resPtr = resPtr;
|
||||||
remaining -= thisBlockSize;
|
blockTable[nbBlocks].srcSize = thisBlockSize;
|
||||||
|
blockTable[nbBlocks].cRoom = ZSTD_compressBound(thisBlockSize);
|
||||||
|
srcPtr += thisBlockSize;
|
||||||
|
cPtr += blockTable[nbBlocks].cRoom;
|
||||||
|
resPtr += thisBlockSize;
|
||||||
|
remaining -= thisBlockSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warmimg up memory */
|
/* warmimg up memory */
|
||||||
BMK_datagen(compressedBuffer, maxCompressedSize, 0.10, 1);
|
RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1);
|
||||||
|
|
||||||
/* Bench */
|
/* Bench */
|
||||||
{
|
{
|
||||||
@@ -301,7 +282,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, i
|
|||||||
U32 blockNb;
|
U32 blockNb;
|
||||||
|
|
||||||
/* Compression */
|
/* Compression */
|
||||||
DISPLAY("%2i-%-17.17s :%10u ->\r", loopNb, fileName, (U32)srcSize);
|
DISPLAY("%2i-%-17.17s :%10u ->\r", loopNb, displayName, (U32)srcSize);
|
||||||
memset(compressedBuffer, 0xE5, maxCompressedSize);
|
memset(compressedBuffer, 0xE5, maxCompressedSize);
|
||||||
|
|
||||||
nbLoops = 0;
|
nbLoops = 0;
|
||||||
@@ -311,7 +292,11 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, i
|
|||||||
while (BMK_GetMilliSpan(milliTime) < TIMELOOP)
|
while (BMK_GetMilliSpan(milliTime) < TIMELOOP)
|
||||||
{
|
{
|
||||||
for (blockNb=0; blockNb<nbBlocks; blockNb++)
|
for (blockNb=0; blockNb<nbBlocks; blockNb++)
|
||||||
blockTable[blockNb].cSize = compressor(blockTable[blockNb].cPtr, blockTable[blockNb].cRoom, blockTable[blockNb].srcPtr,blockTable[blockNb].srcSize, cLevel);
|
blockTable[blockNb].cSize = ZSTD_compress_usingDict(ctx,
|
||||||
|
blockTable[blockNb].cPtr, blockTable[blockNb].cRoom,
|
||||||
|
blockTable[blockNb].srcPtr,blockTable[blockNb].srcSize,
|
||||||
|
dictBuffer, dictBufferSize,
|
||||||
|
cLevel);
|
||||||
nbLoops++;
|
nbLoops++;
|
||||||
}
|
}
|
||||||
milliTime = BMK_GetMilliSpan(milliTime);
|
milliTime = BMK_GetMilliSpan(milliTime);
|
||||||
@@ -321,7 +306,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, i
|
|||||||
cSize += blockTable[blockNb].cSize;
|
cSize += blockTable[blockNb].cSize;
|
||||||
if ((double)milliTime < fastestC*nbLoops) fastestC = (double)milliTime / nbLoops;
|
if ((double)milliTime < fastestC*nbLoops) fastestC = (double)milliTime / nbLoops;
|
||||||
ratio = (double)srcSize / (double)cSize;
|
ratio = (double)srcSize / (double)cSize;
|
||||||
DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s\r", loopNb, fileName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000.);
|
DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s\r", loopNb, displayName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000.);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
/* Decompression */
|
/* Decompression */
|
||||||
@@ -334,13 +319,15 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, i
|
|||||||
for ( ; BMK_GetMilliSpan(milliTime) < TIMELOOP; nbLoops++)
|
for ( ; BMK_GetMilliSpan(milliTime) < TIMELOOP; nbLoops++)
|
||||||
{
|
{
|
||||||
for (blockNb=0; blockNb<nbBlocks; blockNb++)
|
for (blockNb=0; blockNb<nbBlocks; blockNb++)
|
||||||
blockTable[blockNb].resSize = ZSTD_decompress(blockTable[blockNb].resPtr, blockTable[blockNb].srcSize,
|
blockTable[blockNb].resSize = ZSTD_decompress_usingDict(dctx,
|
||||||
blockTable[blockNb].cPtr, blockTable[blockNb].cSize);
|
blockTable[blockNb].resPtr, blockTable[blockNb].srcSize,
|
||||||
|
blockTable[blockNb].cPtr, blockTable[blockNb].cSize,
|
||||||
|
dictBuffer, dictBufferSize);
|
||||||
}
|
}
|
||||||
milliTime = BMK_GetMilliSpan(milliTime);
|
milliTime = BMK_GetMilliSpan(milliTime);
|
||||||
|
|
||||||
if ((double)milliTime < fastestD*nbLoops) fastestD = (double)milliTime / nbLoops;
|
if ((double)milliTime < fastestD*nbLoops) fastestD = (double)milliTime / nbLoops;
|
||||||
DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s\r", loopNb, fileName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.);
|
DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s\r", loopNb, displayName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.);
|
||||||
|
|
||||||
/* CRC Checking */
|
/* CRC Checking */
|
||||||
crcCheck = XXH64(resultBuffer, srcSize, 0);
|
crcCheck = XXH64(resultBuffer, srcSize, 0);
|
||||||
@@ -348,10 +335,10 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, i
|
|||||||
{
|
{
|
||||||
unsigned u;
|
unsigned u;
|
||||||
unsigned eBlockSize = (unsigned)(MIN(65536*2, blockSize));
|
unsigned eBlockSize = (unsigned)(MIN(65536*2, blockSize));
|
||||||
DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", fileName, (unsigned)crcOrig, (unsigned)crcCheck);
|
DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", displayName, (unsigned)crcOrig, (unsigned)crcCheck);
|
||||||
for (u=0; u<srcSize; u++)
|
for (u=0; u<srcSize; u++)
|
||||||
{
|
{
|
||||||
if (((BYTE*)srcBuffer)[u] != ((BYTE*)resultBuffer)[u])
|
if (((const BYTE*)srcBuffer)[u] != ((const BYTE*)resultBuffer)[u])
|
||||||
{
|
{
|
||||||
printf("Decoding error at pos %u (block %u, pos %u) \n", u, u / eBlockSize, u % eBlockSize);
|
printf("Decoding error at pos %u (block %u, pos %u) \n", u, u / eBlockSize, u % eBlockSize);
|
||||||
break;
|
break;
|
||||||
@@ -363,30 +350,20 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (crcOrig == crcCheck)
|
if (crcOrig == crcCheck)
|
||||||
DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s \n", cLevel, fileName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.);
|
DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s \n", cLevel, displayName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.);
|
||||||
|
else
|
||||||
|
DISPLAY("X \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End cleaning */
|
/* clean up */
|
||||||
free(compressedBuffer);
|
free(compressedBuffer);
|
||||||
free(resultBuffer);
|
free(resultBuffer);
|
||||||
|
ZSTD_freeCCtx(ctx);
|
||||||
|
ZSTD_freeDCtx(dctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static U64 BMK_GetFileSize(const char* infilename)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
struct _stat64 statbuf;
|
|
||||||
r = _stat64(infilename, &statbuf);
|
|
||||||
#else
|
|
||||||
struct stat statbuf;
|
|
||||||
r = stat(infilename, &statbuf);
|
|
||||||
#endif
|
|
||||||
if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */
|
|
||||||
return (U64)statbuf.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t BMK_findMaxMem(U64 requiredMem)
|
static size_t BMK_findMaxMem(U64 requiredMem)
|
||||||
{
|
{
|
||||||
size_t step = 64 MB;
|
size_t step = 64 MB;
|
||||||
@@ -406,124 +383,143 @@ static size_t BMK_findMaxMem(U64 requiredMem)
|
|||||||
return (size_t)(requiredMem - step);
|
return (size_t)(requiredMem - step);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int BMK_benchOneFile(const char* inFileName, int cLevel)
|
static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize,
|
||||||
|
const char* displayName, int cLevel,
|
||||||
|
const size_t* fileSizes, unsigned nbFiles,
|
||||||
|
const void* dictBuffer, size_t dictBufferSize)
|
||||||
{
|
{
|
||||||
FILE* inFile;
|
if (cLevel < 0)
|
||||||
U64 inFileSize;
|
|
||||||
size_t benchedSize, readSize;
|
|
||||||
void* srcBuffer;
|
|
||||||
int result=0;
|
|
||||||
|
|
||||||
/* Check file existence */
|
|
||||||
inFile = fopen(inFileName, "rb");
|
|
||||||
if (inFile == NULL)
|
|
||||||
{
|
{
|
||||||
DISPLAY("Pb opening %s\n", inFileName);
|
int l;
|
||||||
return 11;
|
for (l=1; l <= -cLevel; l++)
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, cLevel,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static U64 BMK_getTotalFileSize(const char** fileNamesTable, unsigned nbFiles)
|
||||||
|
{
|
||||||
|
U64 total = 0;
|
||||||
|
unsigned n;
|
||||||
|
for (n=0; n<nbFiles; n++)
|
||||||
|
total += BMK_getFileSize(fileNamesTable[n]);
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMK_loadFiles(void* buffer, size_t bufferSize,
|
||||||
|
size_t* fileSizes,
|
||||||
|
const char** fileNamesTable, unsigned nbFiles)
|
||||||
|
{
|
||||||
|
BYTE* buff = (BYTE*)buffer;
|
||||||
|
size_t pos = 0;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
|
for (n=0; n<nbFiles; n++)
|
||||||
|
{
|
||||||
|
size_t readSize;
|
||||||
|
U64 fileSize = BMK_getFileSize(fileNamesTable[n]);
|
||||||
|
FILE* f = fopen(fileNamesTable[n], "rb");
|
||||||
|
if (f==NULL) EXM_THROW(10, "impossible to open file %s", fileNamesTable[n]);
|
||||||
|
DISPLAYLEVEL(2, "Loading %s... \r", fileNamesTable[n]);
|
||||||
|
if (fileSize > bufferSize-pos) fileSize = bufferSize-pos;
|
||||||
|
readSize = fread(buff+pos, 1, (size_t)fileSize, f);
|
||||||
|
if (readSize != (size_t)fileSize) EXM_THROW(11, "could not read %s", fileNamesTable[n]);
|
||||||
|
pos += readSize;
|
||||||
|
fileSizes[n] = (size_t)fileSize;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles,
|
||||||
|
const char* dictFileName, int cLevel)
|
||||||
|
{
|
||||||
|
void* srcBuffer;
|
||||||
|
size_t benchedSize;
|
||||||
|
void* dictBuffer = NULL;
|
||||||
|
size_t dictBufferSize = 0;
|
||||||
|
size_t* fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t));
|
||||||
|
U64 totalSizeToLoad = BMK_getTotalFileSize(fileNamesTable, nbFiles);
|
||||||
|
char mfName[20] = {0};
|
||||||
|
const char* displayName = NULL;
|
||||||
|
|
||||||
|
if (!fileSizes) EXM_THROW(12, "not enough memory for fileSizes");
|
||||||
|
|
||||||
|
/* Load dictionary */
|
||||||
|
if (dictFileName != NULL)
|
||||||
|
{
|
||||||
|
U64 dictFileSize = BMK_getFileSize(dictFileName);
|
||||||
|
if (dictFileSize > 64 MB) EXM_THROW(10, "dictionary file %s too large", dictFileName);
|
||||||
|
dictBufferSize = (size_t)dictFileSize;
|
||||||
|
dictBuffer = malloc(dictBufferSize);
|
||||||
|
if (dictBuffer==NULL) EXM_THROW(11, "not enough memory for dictionary (%u bytes)", (U32)dictBufferSize);
|
||||||
|
BMK_loadFiles(dictBuffer, dictBufferSize, fileSizes, &dictFileName, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Memory allocation & restrictions */
|
/* Memory allocation & restrictions */
|
||||||
inFileSize = BMK_GetFileSize(inFileName);
|
benchedSize = BMK_findMaxMem(totalSizeToLoad * 3) / 3;
|
||||||
benchedSize = BMK_findMaxMem(inFileSize * 3) / 3;
|
if ((U64)benchedSize > totalSizeToLoad) benchedSize = (size_t)totalSizeToLoad;
|
||||||
if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
|
if (benchedSize < totalSizeToLoad)
|
||||||
if (benchedSize < inFileSize)
|
DISPLAY("Not enough memory; testing %u MB only...\n", (U32)(benchedSize >> 20));
|
||||||
DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", inFileName, (int)(benchedSize >> 20));
|
|
||||||
srcBuffer = malloc(benchedSize);
|
srcBuffer = malloc(benchedSize);
|
||||||
if (!srcBuffer)
|
if (!srcBuffer) EXM_THROW(12, "not enough memory");
|
||||||
{
|
|
||||||
DISPLAY("\nError: not enough memory!\n");
|
|
||||||
fclose(inFile);
|
|
||||||
return 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill input buffer */
|
/* Load input buffer */
|
||||||
DISPLAY("Loading %s... \r", inFileName);
|
BMK_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles);
|
||||||
readSize = fread(srcBuffer, 1, benchedSize, inFile);
|
|
||||||
fclose(inFile);
|
|
||||||
|
|
||||||
if (readSize != benchedSize)
|
|
||||||
{
|
|
||||||
DISPLAY("\nError: problem reading file '%s' !! \n", inFileName);
|
|
||||||
free(srcBuffer);
|
|
||||||
return 13;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bench */
|
/* Bench */
|
||||||
if (cLevel<0)
|
snprintf (mfName, sizeof(mfName), " %u files", nbFiles);
|
||||||
{
|
if (nbFiles > 1) displayName = mfName;
|
||||||
int l;
|
else displayName = fileNamesTable[0];
|
||||||
for (l=1; l <= -cLevel; l++)
|
|
||||||
result = BMK_benchMem(srcBuffer, benchedSize, inFileName, l);
|
BMK_benchCLevel(srcBuffer, benchedSize,
|
||||||
}
|
displayName, cLevel,
|
||||||
else
|
fileSizes, nbFiles,
|
||||||
result = BMK_benchMem(srcBuffer, benchedSize, inFileName, cLevel);
|
dictBuffer, dictBufferSize);
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
free(srcBuffer);
|
free(srcBuffer);
|
||||||
DISPLAY("\n");
|
free(dictBuffer);
|
||||||
return result;
|
free(fileSizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int BMK_syntheticTest(int cLevel, double compressibility)
|
static void BMK_syntheticTest(int cLevel, double compressibility)
|
||||||
{
|
{
|
||||||
|
char name[20] = {0};
|
||||||
size_t benchedSize = 10000000;
|
size_t benchedSize = 10000000;
|
||||||
void* srcBuffer = malloc(benchedSize);
|
void* srcBuffer = malloc(benchedSize);
|
||||||
int result=0;
|
|
||||||
char name[20] = {0};
|
|
||||||
|
|
||||||
/* Memory allocation */
|
/* Memory allocation */
|
||||||
if (!srcBuffer)
|
if (!srcBuffer) EXM_THROW(21, "not enough memory");
|
||||||
{
|
|
||||||
DISPLAY("\nError: not enough memory!\n");
|
|
||||||
free(srcBuffer);
|
|
||||||
return 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill input buffer */
|
/* Fill input buffer */
|
||||||
BMK_datagen(srcBuffer, benchedSize, compressibility, 0);
|
RDG_genBuffer(srcBuffer, benchedSize, compressibility, 0.0, 0);
|
||||||
|
|
||||||
/* Bench */
|
/* Bench */
|
||||||
#ifdef _MSC_VER
|
snprintf (name, sizeof(name), "Synthetic %2u%%", (unsigned)(compressibility*100));
|
||||||
sprintf_s(name, 20, "Synthetic %2u%%", (unsigned)(compressibility*100));
|
BMK_benchCLevel(srcBuffer, benchedSize, name, cLevel, &benchedSize, 1, NULL, 0);
|
||||||
#else
|
|
||||||
snprintf (name, 20, "Synthetic %2u%%", (unsigned)(compressibility*100));
|
|
||||||
#endif
|
|
||||||
/* Bench */
|
|
||||||
if (cLevel<0)
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
for (l=1; l <= -cLevel; l++)
|
|
||||||
result = BMK_benchMem(srcBuffer, benchedSize, name, l);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = BMK_benchMem(srcBuffer, benchedSize, name, cLevel);
|
|
||||||
|
|
||||||
/* End */
|
/* clean up */
|
||||||
free(srcBuffer);
|
free(srcBuffer);
|
||||||
DISPLAY("\n");
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, unsigned cLevel)
|
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
|
||||||
|
const char* dictFileName, int cLevel)
|
||||||
{
|
{
|
||||||
double compressibility = (double)g_compressibilityDefault / 100;
|
double compressibility = (double)g_compressibilityDefault / 100;
|
||||||
|
|
||||||
if (nbFiles == 0)
|
if (nbFiles == 0)
|
||||||
{
|
|
||||||
BMK_syntheticTest(cLevel, compressibility);
|
BMK_syntheticTest(cLevel, compressibility);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel);
|
||||||
/* Loop for each file */
|
|
||||||
unsigned fileIdx = 0;
|
|
||||||
while (fileIdx<nbFiles)
|
|
||||||
{
|
|
||||||
BMK_benchOneFile(fileNamesTable[fileIdx], cLevel);
|
|
||||||
fileIdx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -26,7 +26,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Main function */
|
/* Main function */
|
||||||
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, unsigned cLevel);
|
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
|
||||||
|
const char* dictFileName, int cLevel);
|
||||||
|
|
||||||
/* Set Parameters */
|
/* Set Parameters */
|
||||||
void BMK_SetNbIterations(int nbLoops);
|
void BMK_SetNbIterations(int nbLoops);
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ void RDG_genBlock(void* buffer, size_t buffSize, size_t prefixSize, double match
|
|||||||
U32 repeatOffset = (RDG_rand(seed) & 15) == 2;
|
U32 repeatOffset = (RDG_rand(seed) & 15) == 2;
|
||||||
if (repeatOffset) offset = prevOffset;
|
if (repeatOffset) offset = prevOffset;
|
||||||
if (offset > pos) offset = (U32)pos;
|
if (offset > pos) offset = (U32)pos;
|
||||||
|
prevOffset = offset;
|
||||||
match = pos - offset;
|
match = pos - offset;
|
||||||
d = pos + length;
|
d = pos + length;
|
||||||
if (d > buffSize) d = buffSize;
|
if (d > buffSize) d = buffSize;
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
void RDG_genStdout(unsigned long long size, double matchProba, double litProba, unsigned seed);
|
void RDG_genStdout(unsigned long long size, double matchProba, double litProba, unsigned seed);
|
||||||
void RDG_genBuffer(void* buffer, size_t size, double matchProba, double litProba, unsigned seed);
|
void RDG_genBuffer(void* buffer, size_t size, double matchProba, double litProba, unsigned seed);
|
||||||
/* RDG_genBuffer
|
/*!RDG_genBuffer
|
||||||
Generate 'size' bytes of compressible data into 'buffer'.
|
Generate 'size' bytes of compressible data into 'buffer'.
|
||||||
Compressibility can be controlled using 'matchProba', which is floating point value between 0 and 1.
|
Compressibility can be controlled using 'matchProba', which is floating point value between 0 and 1.
|
||||||
'LitProba' is optional, it affect variability of individual bytes. If litProba==0.0, default value will be used.
|
'LitProba' is optional, it affect variability of individual bytes. If litProba==0.0, default value will be used.
|
||||||
|
|||||||
+364
-131
@@ -121,6 +121,7 @@
|
|||||||
|
|
||||||
#define CACHELINE 64
|
#define CACHELINE 64
|
||||||
|
|
||||||
|
#define MAX_DICT_SIZE (512 KB)
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Macros
|
* Macros
|
||||||
@@ -174,52 +175,6 @@ static unsigned FIO_GetMilliSpan(clock_t nPrevious)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void FIO_getFileHandles(FILE** pfinput, FILE** pfoutput, const char* input_filename, const char* output_filename)
|
|
||||||
{
|
|
||||||
if (!strcmp (input_filename, stdinmark))
|
|
||||||
{
|
|
||||||
DISPLAYLEVEL(4,"Using stdin for input\n");
|
|
||||||
*pfinput = stdin;
|
|
||||||
SET_BINARY_MODE(stdin);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*pfinput = fopen(input_filename, "rb");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp (output_filename, stdoutmark))
|
|
||||||
{
|
|
||||||
DISPLAYLEVEL(4,"Using stdout for output\n");
|
|
||||||
*pfoutput = stdout;
|
|
||||||
SET_BINARY_MODE(stdout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Check if destination file already exists */
|
|
||||||
*pfoutput=0;
|
|
||||||
if (strcmp(output_filename,nulmark)) *pfoutput = fopen( output_filename, "rb" );
|
|
||||||
if (*pfoutput!=0)
|
|
||||||
{
|
|
||||||
fclose(*pfoutput);
|
|
||||||
if (!g_overwrite)
|
|
||||||
{
|
|
||||||
char ch;
|
|
||||||
if (g_displayLevel <= 1) /* No interaction possible */
|
|
||||||
EXM_THROW(11, "Operation aborted : %s already exists", output_filename);
|
|
||||||
DISPLAYLEVEL(2, "Warning : %s already exists\n", output_filename);
|
|
||||||
DISPLAYLEVEL(2, "Overwrite ? (Y/N) : ");
|
|
||||||
ch = (char)getchar();
|
|
||||||
if ((ch!='Y') && (ch!='y')) EXM_THROW(11, "Operation aborted : %s already exists", output_filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*pfoutput = fopen( output_filename, "wb" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( *pfinput==0 ) EXM_THROW(12, "Pb opening src : %s", input_filename);
|
|
||||||
if ( *pfoutput==0) EXM_THROW(13, "Pb opening dst : %s", output_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static U64 FIO_getFileSize(const char* infilename)
|
static U64 FIO_getFileSize(const char* infilename)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@@ -235,39 +190,182 @@ static U64 FIO_getFileSize(const char* infilename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIO_compressFilename(const char* output_filename, const char* input_filename, int cLevel)
|
static int FIO_getFiles(FILE** fileOutPtr, FILE** fileInPtr,
|
||||||
|
const char* dstFileName, const char* srcFileName)
|
||||||
{
|
{
|
||||||
U64 filesize = 0;
|
if (!strcmp (srcFileName, stdinmark))
|
||||||
U64 compressedfilesize = 0;
|
{
|
||||||
BYTE* inBuff;
|
DISPLAYLEVEL(4,"Using stdin for input\n");
|
||||||
BYTE* outBuff;
|
*fileInPtr = stdin;
|
||||||
size_t inBuffSize = ZBUFF_recommendedCInSize();
|
SET_BINARY_MODE(stdin);
|
||||||
size_t outBuffSize = ZBUFF_recommendedCOutSize();
|
}
|
||||||
FILE* finput;
|
else
|
||||||
FILE* foutput;
|
{
|
||||||
size_t sizeCheck, errorCode;
|
*fileInPtr = fopen(srcFileName, "rb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( *fileInPtr==0 )
|
||||||
|
{
|
||||||
|
DISPLAYLEVEL(1, "Unable to access file for processing: %s\n", srcFileName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp (dstFileName, stdoutmark))
|
||||||
|
{
|
||||||
|
DISPLAYLEVEL(4,"Using stdout for output\n");
|
||||||
|
*fileOutPtr = stdout;
|
||||||
|
SET_BINARY_MODE(stdout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if destination file already exists */
|
||||||
|
if (!g_overwrite)
|
||||||
|
{
|
||||||
|
*fileOutPtr = fopen( dstFileName, "rb" );
|
||||||
|
if (*fileOutPtr != 0)
|
||||||
|
{
|
||||||
|
/* prompt for overwrite authorization */
|
||||||
|
int ch = 'N';
|
||||||
|
fclose(*fileOutPtr);
|
||||||
|
DISPLAY("Warning : %s already exists \n", dstFileName);
|
||||||
|
if ((g_displayLevel <= 1) || (*fileInPtr == stdin))
|
||||||
|
{
|
||||||
|
/* No interaction possible */
|
||||||
|
DISPLAY("Operation aborted : %s already exists \n", dstFileName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
DISPLAY("Overwrite ? (y/N) : ");
|
||||||
|
while((ch = getchar()) != '\n' && ch != EOF); /* flush integrated */
|
||||||
|
if ((ch!='Y') && (ch!='y'))
|
||||||
|
{
|
||||||
|
DISPLAY("No. Operation aborted : %s already exists \n", dstFileName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fileOutPtr = fopen( dstFileName, "wb" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*fileOutPtr==0) EXM_THROW(13, "Pb opening %s", dstFileName);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!FIO_loadFile
|
||||||
|
* creates a buffer, pointed by *bufferPtr,
|
||||||
|
* loads "filename" content into it
|
||||||
|
* up to MAX_DICT_SIZE bytes
|
||||||
|
*/
|
||||||
|
static size_t FIO_loadFile(void** bufferPtr, const char* fileName)
|
||||||
|
{
|
||||||
|
FILE* fileHandle;
|
||||||
|
size_t readSize;
|
||||||
|
U64 fileSize;
|
||||||
|
|
||||||
|
*bufferPtr = NULL;
|
||||||
|
if (fileName == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4,"Loading %s as dictionary \n", fileName);
|
||||||
|
fileHandle = fopen(fileName, "rb");
|
||||||
|
if (fileHandle==0) EXM_THROW(31, "Error opening file %s", fileName);
|
||||||
|
fileSize = FIO_getFileSize(fileName);
|
||||||
|
if (fileSize > MAX_DICT_SIZE)
|
||||||
|
{
|
||||||
|
int seekResult;
|
||||||
|
if (fileSize > 1 GB) EXM_THROW(32, "Dictionary file %s is too large", fileName); /* avoid extreme cases */
|
||||||
|
DISPLAYLEVEL(2,"Dictionary %s is too large : using last %u bytes only \n", fileName, MAX_DICT_SIZE);
|
||||||
|
seekResult = fseek(fileHandle, (long int)(fileSize-MAX_DICT_SIZE), SEEK_SET); /* use end of file */
|
||||||
|
if (seekResult != 0) EXM_THROW(33, "Error seeking into file %s", fileName);
|
||||||
|
fileSize = MAX_DICT_SIZE;
|
||||||
|
}
|
||||||
|
*bufferPtr = (BYTE*)malloc((size_t)fileSize);
|
||||||
|
if (*bufferPtr==NULL) EXM_THROW(34, "Allocation error : not enough memory for dictBuffer");
|
||||||
|
readSize = fread(*bufferPtr, 1, (size_t)fileSize, fileHandle);
|
||||||
|
if (readSize!=fileSize) EXM_THROW(35, "Error reading dictionary file %s", fileName);
|
||||||
|
fclose(fileHandle);
|
||||||
|
return (size_t)fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* **********************************************************************
|
||||||
|
* Compression
|
||||||
|
************************************************************************/
|
||||||
|
typedef struct {
|
||||||
|
void* srcBuffer;
|
||||||
|
size_t srcBufferSize;
|
||||||
|
void* dstBuffer;
|
||||||
|
size_t dstBufferSize;
|
||||||
|
void* dictBuffer;
|
||||||
|
size_t dictBufferSize;
|
||||||
ZBUFF_CCtx* ctx;
|
ZBUFF_CCtx* ctx;
|
||||||
|
} cRess_t;
|
||||||
|
|
||||||
|
static cRess_t FIO_createCResources(const char* dictFileName)
|
||||||
|
{
|
||||||
|
cRess_t ress;
|
||||||
|
|
||||||
|
ress.ctx = ZBUFF_createCCtx();
|
||||||
|
if (ress.ctx == NULL) EXM_THROW(30, "Allocation error : can't create ZBUFF context");
|
||||||
|
|
||||||
/* Allocate Memory */
|
/* Allocate Memory */
|
||||||
ctx = ZBUFF_createCCtx();
|
ress.srcBufferSize = ZBUFF_recommendedCInSize();
|
||||||
inBuff = (BYTE*)malloc(inBuffSize);
|
ress.srcBuffer = malloc(ress.srcBufferSize);
|
||||||
outBuff = (BYTE*)malloc(outBuffSize);
|
ress.dstBufferSize = ZBUFF_recommendedCOutSize();
|
||||||
if (!inBuff || !outBuff || !ctx) EXM_THROW(21, "Allocation error : not enough memory");
|
ress.dstBuffer = malloc(ress.dstBufferSize);
|
||||||
|
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(31, "Allocation error : not enough memory");
|
||||||
|
|
||||||
|
/* dictionary */
|
||||||
|
ress.dictBufferSize = FIO_loadFile(&(ress.dictBuffer), dictFileName);
|
||||||
|
|
||||||
|
return ress;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_freeCResources(cRess_t ress)
|
||||||
|
{
|
||||||
|
size_t errorCode;
|
||||||
|
free(ress.srcBuffer);
|
||||||
|
free(ress.dstBuffer);
|
||||||
|
free(ress.dictBuffer);
|
||||||
|
errorCode = ZBUFF_freeCCtx(ress.ctx);
|
||||||
|
if (ZBUFF_isError(errorCode)) EXM_THROW(38, "Error : can't release ZBUFF context resource : %s", ZBUFF_getErrorName(errorCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIO_compressFilename_extRess()
|
||||||
|
* result : 0 : compression completed correctly
|
||||||
|
* 1 : missing or pb opening srcFileName
|
||||||
|
*/
|
||||||
|
static int FIO_compressFilename_extRess(cRess_t ress,
|
||||||
|
const char* dstFileName, const char* srcFileName,
|
||||||
|
int cLevel)
|
||||||
|
{
|
||||||
|
FILE* srcFile;
|
||||||
|
FILE* dstFile;
|
||||||
|
U64 filesize = 0;
|
||||||
|
U64 compressedfilesize = 0;
|
||||||
|
size_t dictSize = ress.dictBufferSize;
|
||||||
|
size_t sizeCheck, errorCode;
|
||||||
|
|
||||||
|
/* File check */
|
||||||
|
if (FIO_getFiles(&dstFile, &srcFile, dstFileName, srcFileName)) return 1;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
FIO_getFileHandles(&finput, &foutput, input_filename, output_filename);
|
filesize = FIO_getFileSize(srcFileName) + dictSize;
|
||||||
filesize = FIO_getFileSize(input_filename);
|
errorCode = ZBUFF_compressInit_advanced(ress.ctx, ZSTD_getParams(cLevel, filesize));
|
||||||
errorCode = ZBUFF_compressInit_advanced(ctx, ZSTD_getParams(cLevel, filesize));
|
if (ZBUFF_isError(errorCode)) EXM_THROW(21, "Error initializing compression");
|
||||||
if (ZBUFF_isError(errorCode)) EXM_THROW(22, "Error initializing compression");
|
errorCode = ZBUFF_compressWithDictionary(ress.ctx, ress.dictBuffer, ress.dictBufferSize);
|
||||||
filesize = 0;
|
if (ZBUFF_isError(errorCode)) EXM_THROW(22, "Error initializing dictionary");
|
||||||
|
|
||||||
/* Main compression loop */
|
/* Main compression loop */
|
||||||
|
filesize = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
size_t inSize;
|
size_t inSize;
|
||||||
|
|
||||||
/* Fill input Buffer */
|
/* Fill input Buffer */
|
||||||
inSize = fread(inBuff, (size_t)1, inBuffSize, finput);
|
inSize = fread(ress.srcBuffer, (size_t)1, ress.srcBufferSize, srcFile);
|
||||||
if (inSize==0) break;
|
if (inSize==0) break;
|
||||||
filesize += inSize;
|
filesize += inSize;
|
||||||
DISPLAYUPDATE(2, "\rRead : %u MB ", (U32)(filesize>>20));
|
DISPLAYUPDATE(2, "\rRead : %u MB ", (U32)(filesize>>20));
|
||||||
@@ -275,8 +373,8 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
|
|||||||
{
|
{
|
||||||
/* Compress (buffered streaming ensures appropriate formatting) */
|
/* Compress (buffered streaming ensures appropriate formatting) */
|
||||||
size_t usedInSize = inSize;
|
size_t usedInSize = inSize;
|
||||||
size_t cSize = outBuffSize;
|
size_t cSize = ress.dstBufferSize;
|
||||||
size_t result = ZBUFF_compressContinue(ctx, outBuff, &cSize, inBuff, &usedInSize);
|
size_t result = ZBUFF_compressContinue(ress.ctx, ress.dstBuffer, &cSize, ress.srcBuffer, &usedInSize);
|
||||||
if (ZBUFF_isError(result))
|
if (ZBUFF_isError(result))
|
||||||
EXM_THROW(23, "Compression error : %s ", ZBUFF_getErrorName(result));
|
EXM_THROW(23, "Compression error : %s ", ZBUFF_getErrorName(result));
|
||||||
if (inSize != usedInSize)
|
if (inSize != usedInSize)
|
||||||
@@ -284,8 +382,8 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
|
|||||||
EXM_THROW(24, "Compression error : input block not fully consumed");
|
EXM_THROW(24, "Compression error : input block not fully consumed");
|
||||||
|
|
||||||
/* Write cBlock */
|
/* Write cBlock */
|
||||||
sizeCheck = fwrite(outBuff, 1, cSize, foutput);
|
sizeCheck = fwrite(ress.dstBuffer, 1, cSize, dstFile);
|
||||||
if (sizeCheck!=cSize) EXM_THROW(25, "Write error : cannot write compressed block into %s", output_filename);
|
if (sizeCheck!=cSize) EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName);
|
||||||
compressedfilesize += cSize;
|
compressedfilesize += cSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,12 +392,12 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
|
|||||||
|
|
||||||
/* End of Frame */
|
/* End of Frame */
|
||||||
{
|
{
|
||||||
size_t cSize = outBuffSize;
|
size_t cSize = ress.dstBufferSize;
|
||||||
size_t result = ZBUFF_compressEnd(ctx, outBuff, &cSize);
|
size_t result = ZBUFF_compressEnd(ress.ctx, ress.dstBuffer, &cSize);
|
||||||
if (result!=0) EXM_THROW(26, "Compression error : cannot create frame end");
|
if (result!=0) EXM_THROW(26, "Compression error : cannot create frame end");
|
||||||
|
|
||||||
sizeCheck = fwrite(outBuff, 1, cSize, foutput);
|
sizeCheck = fwrite(ress.dstBuffer, 1, cSize, dstFile);
|
||||||
if (sizeCheck!=cSize) EXM_THROW(27, "Write error : cannot write frame end into %s", output_filename);
|
if (sizeCheck!=cSize) EXM_THROW(27, "Write error : cannot write frame end into %s", dstFileName);
|
||||||
compressedfilesize += cSize;
|
compressedfilesize += cSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,49 +407,149 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
|
|||||||
(unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100);
|
(unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100);
|
||||||
|
|
||||||
/* clean */
|
/* clean */
|
||||||
free(inBuff);
|
fclose(srcFile);
|
||||||
free(outBuff);
|
if (fclose(dstFile)) EXM_THROW(28, "Write error : cannot properly close %s", dstFileName);
|
||||||
ZBUFF_freeCCtx(ctx);
|
|
||||||
fclose(finput);
|
|
||||||
if (fclose(foutput)) EXM_THROW(28, "Write error : cannot properly close %s", output_filename);
|
|
||||||
|
|
||||||
return compressedfilesize;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIO_decompressFrame(FILE* foutput, FILE* finput,
|
int FIO_compressFilename(const char* dstFileName, const char* srcFileName,
|
||||||
BYTE* inBuff, size_t inBuffSize, size_t alreadyLoaded,
|
const char* dictFileName, int compressionLevel)
|
||||||
BYTE* outBuff, size_t outBuffSize,
|
{
|
||||||
ZBUFF_DCtx* dctx)
|
clock_t start, end;
|
||||||
|
cRess_t ress;
|
||||||
|
int issueWithSrcFile = 0;
|
||||||
|
|
||||||
|
/* Init */
|
||||||
|
start = clock();
|
||||||
|
ress = FIO_createCResources(dictFileName);
|
||||||
|
|
||||||
|
/* Compress File */
|
||||||
|
issueWithSrcFile += FIO_compressFilename_extRess(ress, dstFileName, srcFileName, compressionLevel);
|
||||||
|
|
||||||
|
/* Free resources */
|
||||||
|
FIO_freeCResources(ress);
|
||||||
|
|
||||||
|
/* Final Status */
|
||||||
|
end = clock();
|
||||||
|
{
|
||||||
|
double seconds = (double)(end - start) / CLOCKS_PER_SEC;
|
||||||
|
DISPLAYLEVEL(4, "Completed in %.2f sec \n", seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
return issueWithSrcFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define FNSPACE 30
|
||||||
|
int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFiles,
|
||||||
|
const char* suffix,
|
||||||
|
const char* dictFileName, int compressionLevel)
|
||||||
|
{
|
||||||
|
unsigned u;
|
||||||
|
int missed_files = 0;
|
||||||
|
char* dstFileName = (char*)malloc(FNSPACE);
|
||||||
|
size_t dfnSize = FNSPACE;
|
||||||
|
const size_t suffixSize = strlen(suffix);
|
||||||
|
cRess_t ress;
|
||||||
|
|
||||||
|
/* init */
|
||||||
|
ress = FIO_createCResources(dictFileName);
|
||||||
|
|
||||||
|
/* loop on each file */
|
||||||
|
for (u=0; u<nbFiles; u++)
|
||||||
|
{
|
||||||
|
size_t ifnSize = strlen(inFileNamesTable[u]);
|
||||||
|
if (dfnSize <= ifnSize+suffixSize+1) { free(dstFileName); dfnSize = ifnSize + 20; dstFileName = (char*)malloc(dfnSize); }
|
||||||
|
strcpy(dstFileName, inFileNamesTable[u]);
|
||||||
|
strcat(dstFileName, suffix);
|
||||||
|
|
||||||
|
missed_files += FIO_compressFilename_extRess(ress, dstFileName, inFileNamesTable[u], compressionLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close & Free */
|
||||||
|
FIO_freeCResources(ress);
|
||||||
|
free(dstFileName);
|
||||||
|
|
||||||
|
return missed_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************************
|
||||||
|
* Decompression
|
||||||
|
****************************************************************************/
|
||||||
|
typedef struct {
|
||||||
|
void* srcBuffer;
|
||||||
|
size_t srcBufferSize;
|
||||||
|
void* dstBuffer;
|
||||||
|
size_t dstBufferSize;
|
||||||
|
void* dictBuffer;
|
||||||
|
size_t dictBufferSize;
|
||||||
|
ZBUFF_DCtx* dctx;
|
||||||
|
} dRess_t;
|
||||||
|
|
||||||
|
static dRess_t FIO_createDResources(const char* dictFileName)
|
||||||
|
{
|
||||||
|
dRess_t ress;
|
||||||
|
|
||||||
|
/* init */
|
||||||
|
ress.dctx = ZBUFF_createDCtx();
|
||||||
|
if (ress.dctx==NULL) EXM_THROW(60, "Can't create ZBUFF decompression context");
|
||||||
|
|
||||||
|
/* Allocate Memory */
|
||||||
|
ress.srcBufferSize = ZBUFF_recommendedDInSize();
|
||||||
|
ress.srcBuffer = malloc(ress.srcBufferSize);
|
||||||
|
ress.dstBufferSize = ZBUFF_recommendedDOutSize();
|
||||||
|
ress.dstBuffer = malloc(ress.dstBufferSize);
|
||||||
|
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory");
|
||||||
|
|
||||||
|
/* dictionary */
|
||||||
|
ress.dictBufferSize = FIO_loadFile(&(ress.dictBuffer), dictFileName);
|
||||||
|
|
||||||
|
return ress;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_freeDResources(dRess_t ress)
|
||||||
|
{
|
||||||
|
size_t errorCode = ZBUFF_freeDCtx(ress.dctx);
|
||||||
|
if (ZBUFF_isError(errorCode)) EXM_THROW(69, "Error : can't free ZBUFF context resource : %s", ZBUFF_getErrorName(errorCode));
|
||||||
|
free(ress.srcBuffer);
|
||||||
|
free(ress.dstBuffer);
|
||||||
|
free(ress.dictBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long long FIO_decompressFrame(dRess_t ress,
|
||||||
|
FILE* foutput, FILE* finput, size_t alreadyLoaded)
|
||||||
{
|
{
|
||||||
U64 frameSize = 0;
|
U64 frameSize = 0;
|
||||||
size_t readSize=alreadyLoaded;
|
size_t readSize=alreadyLoaded;
|
||||||
|
|
||||||
/* Main decompression Loop */
|
/* Main decompression Loop */
|
||||||
ZBUFF_decompressInit(dctx);
|
ZBUFF_decompressInit(ress.dctx);
|
||||||
|
ZBUFF_decompressWithDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* Decode */
|
/* Decode */
|
||||||
size_t sizeCheck;
|
size_t sizeCheck;
|
||||||
size_t inSize=readSize, decodedSize=outBuffSize;
|
size_t inSize=readSize, decodedSize=ress.dstBufferSize;
|
||||||
size_t inStart=0;
|
size_t toRead = ZBUFF_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize);
|
||||||
size_t toRead = ZBUFF_decompressContinue(dctx, outBuff, &decodedSize, inBuff+inStart, &inSize);
|
|
||||||
if (ZBUFF_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFF_getErrorName(toRead));
|
if (ZBUFF_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFF_getErrorName(toRead));
|
||||||
readSize -= inSize;
|
readSize -= inSize;
|
||||||
inStart += inSize;
|
|
||||||
|
|
||||||
/* Write block */
|
/* Write block */
|
||||||
sizeCheck = fwrite(outBuff, 1, decodedSize, foutput);
|
sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput);
|
||||||
if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block to destination file");
|
if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block to destination file");
|
||||||
frameSize += decodedSize;
|
frameSize += decodedSize;
|
||||||
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
|
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
|
||||||
|
|
||||||
if (toRead == 0) break;
|
if (toRead == 0) break;
|
||||||
if (readSize) continue; /* still some data left within inBuff */
|
if (readSize) EXM_THROW(38, "Decoding error : should consume entire input");
|
||||||
|
|
||||||
/* Fill input buffer */
|
/* Fill input buffer */
|
||||||
if (toRead > inBuffSize) EXM_THROW(34, "too large block");
|
if (toRead > ress.srcBufferSize) EXM_THROW(34, "too large block");
|
||||||
readSize = fread(inBuff, 1, toRead, finput);
|
readSize = fread(ress.srcBuffer, 1, toRead, finput);
|
||||||
if (readSize != toRead) EXM_THROW(35, "Read error");
|
if (readSize != toRead) EXM_THROW(35, "Read error");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,61 +557,96 @@ unsigned long long FIO_decompressFrame(FILE* foutput, FILE* finput,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIO_decompressFilename(const char* output_filename, const char* input_filename)
|
static int FIO_decompressFile_extRess(dRess_t ress,
|
||||||
|
const char* dstFileName, const char* srcFileName)
|
||||||
{
|
{
|
||||||
FILE* finput, *foutput;
|
unsigned long long filesize = 0;
|
||||||
BYTE* inBuff=NULL;
|
FILE* srcFile;
|
||||||
size_t inBuffSize = ZBUFF_recommendedDInSize();
|
FILE* dstFile;
|
||||||
BYTE* outBuff=NULL;
|
|
||||||
size_t outBuffSize = ZBUFF_recommendedDOutSize();
|
|
||||||
U64 filesize = 0;
|
|
||||||
size_t toRead;
|
|
||||||
|
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
ZBUFF_DCtx* dctx = ZBUFF_createDCtx();
|
if (FIO_getFiles(&dstFile, &srcFile, dstFileName, srcFileName)) return 1;
|
||||||
FIO_getFileHandles(&finput, &foutput, input_filename, output_filename);
|
|
||||||
|
|
||||||
/* Allocate Memory (if needed) */
|
|
||||||
inBuff = (BYTE*)malloc(inBuffSize);
|
|
||||||
outBuff = (BYTE*)malloc(outBuffSize);
|
|
||||||
if (!inBuff || !outBuff) EXM_THROW(33, "Allocation error : not enough memory");
|
|
||||||
|
|
||||||
/* for each frame */
|
/* for each frame */
|
||||||
for ( ; ; )
|
for ( ; ; )
|
||||||
{
|
{
|
||||||
toRead = 0;
|
size_t sizeCheck;
|
||||||
|
/* check magic number -> version */
|
||||||
|
size_t toRead = 4;
|
||||||
|
sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile);
|
||||||
|
if (sizeCheck==0) break; /* no more input */
|
||||||
|
if (sizeCheck != toRead) EXM_THROW(31, "Read error : cannot read header");
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
||||||
|
if (ZSTD_isLegacy(MEM_readLE32(ress.srcBuffer)))
|
||||||
{
|
{
|
||||||
size_t sizeCheck;
|
filesize += FIO_decompressLegacyFrame(dstFile, srcFile, MEM_readLE32(ress.srcBuffer));
|
||||||
/* check magic number -> version */
|
continue;
|
||||||
toRead = 4;
|
|
||||||
sizeCheck = fread(inBuff, (size_t)1, toRead, finput);
|
|
||||||
if (sizeCheck==0) break; /* no more input */
|
|
||||||
if (sizeCheck != toRead) EXM_THROW(31, "Read error : cannot read header");
|
|
||||||
if (ZSTD_isLegacy(MEM_readLE32(inBuff)))
|
|
||||||
{
|
|
||||||
filesize += FIO_decompressLegacyFrame(foutput, finput, MEM_readLE32(inBuff));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* ZSTD_LEGACY_SUPPORT */
|
#endif /* ZSTD_LEGACY_SUPPORT */
|
||||||
|
|
||||||
filesize += FIO_decompressFrame(foutput, finput, inBuff, inBuffSize, toRead, outBuff, outBuffSize, dctx);
|
filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Final Status */
|
||||||
DISPLAYLEVEL(2, "\r%79s\r", "");
|
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||||
DISPLAYLEVEL(2, "Decoded %llu bytes \n", (long long unsigned)filesize);
|
DISPLAYLEVEL(2, "Successfully decoded %llu bytes \n", filesize);
|
||||||
|
|
||||||
/* clean */
|
/* Close */
|
||||||
free(inBuff);
|
fclose(srcFile);
|
||||||
free(outBuff);
|
if (fclose(dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);
|
||||||
ZBUFF_freeDCtx(dctx);
|
|
||||||
fclose(finput);
|
|
||||||
if (fclose(foutput)) EXM_THROW(38, "Write error : cannot properly close %s", output_filename);
|
|
||||||
|
|
||||||
return filesize;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FIO_decompressFilename(const char* dstFileName, const char* srcFileName,
|
||||||
|
const char* dictFileName)
|
||||||
|
{
|
||||||
|
int missingFiles = 0;
|
||||||
|
dRess_t ress = FIO_createDResources(dictFileName);
|
||||||
|
|
||||||
|
missingFiles += FIO_decompressFile_extRess(ress, dstFileName, srcFileName);
|
||||||
|
|
||||||
|
FIO_freeDResources(ress);
|
||||||
|
return missingFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXSUFFIXSIZE 8
|
||||||
|
int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles,
|
||||||
|
const char* suffix,
|
||||||
|
const char* dictFileName)
|
||||||
|
{
|
||||||
|
unsigned u;
|
||||||
|
int skippedFiles = 0;
|
||||||
|
int missingFiles = 0;
|
||||||
|
char* dstFileName = (char*)malloc(FNSPACE);
|
||||||
|
size_t dfnSize = FNSPACE;
|
||||||
|
const size_t suffixSize = strlen(suffix);
|
||||||
|
dRess_t ress;
|
||||||
|
|
||||||
|
if (dstFileName==NULL) EXM_THROW(70, "not enough memory for dstFileName");
|
||||||
|
ress = FIO_createDResources(dictFileName);
|
||||||
|
|
||||||
|
for (u=0; u<nbFiles; u++)
|
||||||
|
{
|
||||||
|
const char* srcFileName = srcNamesTable[u];
|
||||||
|
size_t sfnSize = strlen(srcFileName);
|
||||||
|
const char* suffixPtr = srcFileName + sfnSize - suffixSize;
|
||||||
|
if (dfnSize <= sfnSize-suffixSize+1) { free(dstFileName); dfnSize = sfnSize + 20; dstFileName = (char*)malloc(dfnSize); if (dstFileName==NULL) EXM_THROW(71, "not enough memory for dstFileName"); }
|
||||||
|
if (sfnSize <= suffixSize || strcmp(suffixPtr, suffix) != 0)
|
||||||
|
{
|
||||||
|
DISPLAYLEVEL(1, "File extension doesn't match expected extension (%4s); will not process file: %s\n", suffix, srcFileName);
|
||||||
|
skippedFiles++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memcpy(dstFileName, srcFileName, sfnSize - suffixSize);
|
||||||
|
dstFileName[sfnSize-suffixSize] = '\0';
|
||||||
|
|
||||||
|
missingFiles += FIO_decompressFile_extRess(ress, dstFileName, srcFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
FIO_freeDResources(ress);
|
||||||
|
free(dstFileName);
|
||||||
|
return missingFiles + skippedFiles;
|
||||||
|
}
|
||||||
|
|||||||
+21
-5
@@ -50,19 +50,35 @@ void FIO_setNotificationLevel(unsigned level);
|
|||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Stream/File functions
|
* Single File functions
|
||||||
***************************************/
|
***************************************/
|
||||||
unsigned long long FIO_compressFilename (const char* outfilename, const char* infilename, int compressionLevel);
|
int FIO_compressFilename (const char* outfilename, const char* infilename, const char* dictFileName, int compressionLevel);
|
||||||
unsigned long long FIO_decompressFilename (const char* outfilename, const char* infilename);
|
int FIO_decompressFilename (const char* outfilename, const char* infilename, const char* dictFileName);
|
||||||
/**
|
/**
|
||||||
FIO_compressFilename :
|
FIO_compressFilename :
|
||||||
@result : size of compressed file
|
@result : 0 == ok; 1 == pb with src file.
|
||||||
|
|
||||||
FIO_decompressFilename :
|
FIO_decompressFilename :
|
||||||
@result : size of regenerated file
|
@result : 0 == ok; 1 == pb with src file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Multiple File functions
|
||||||
|
***************************************/
|
||||||
|
int FIO_compressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles,
|
||||||
|
const char* suffix,
|
||||||
|
const char* dictFileName, int compressionLevel);
|
||||||
|
int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles,
|
||||||
|
const char* suffix,
|
||||||
|
const char* dictFileName);
|
||||||
|
/**
|
||||||
|
FIO_compressMultipleFilenames :
|
||||||
|
@result : nb of missing files
|
||||||
|
FIO_decompressMultipleFilenames :
|
||||||
|
@result : nb of missing or skipped files
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ size_t local_ZSTD_decodeLiteralsBlock(void* dst, size_t dstSize, void* buff2, co
|
|||||||
|
|
||||||
size_t local_ZSTD_decodeSeqHeaders(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize)
|
size_t local_ZSTD_decodeSeqHeaders(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
U32 DTableML[1<<11], DTableLL[1<<10], DTableOffb[1<<9];
|
U32 DTableML[FSE_DTABLE_SIZE_U32(10)], DTableLL[FSE_DTABLE_SIZE_U32(10)], DTableOffb[FSE_DTABLE_SIZE_U32(9)]; /* MLFSELog, LLFSELog and OffFSELog are not public values */
|
||||||
const BYTE* dumps;
|
const BYTE* dumps;
|
||||||
size_t length;
|
size_t length;
|
||||||
int nbSeq;
|
int nbSeq;
|
||||||
@@ -245,7 +245,6 @@ size_t local_ZSTD_decodeSeqHeaders(void* dst, size_t dstSize, void* buff2, const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
* Bench functions
|
* Bench functions
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
@@ -429,7 +428,7 @@ int benchFiles(char** fileNamesTable, int nbFiles, U32 benchNb)
|
|||||||
return 11;
|
return 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory allocation & restrictions
|
/* Memory allocation & restrictions */
|
||||||
inFileSize = BMK_GetFileSize(inFileName);
|
inFileSize = BMK_GetFileSize(inFileName);
|
||||||
benchedSize = (size_t) BMK_findMaxMem(inFileSize*3) / 3;
|
benchedSize = (size_t) BMK_findMaxMem(inFileSize*3) / 3;
|
||||||
if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
|
if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
|
||||||
|
|||||||
+109
-17
@@ -79,11 +79,13 @@ static const U32 prime2 = 2246822519U;
|
|||||||
static U32 g_displayLevel = 2;
|
static U32 g_displayLevel = 2;
|
||||||
|
|
||||||
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
||||||
if ((FUZ_GetMilliSpan(g_time) > g_refreshRate) || (g_displayLevel>=4)) \
|
if ((FUZ_GetMilliSpan(g_displayTime) > g_refreshRate) || (g_displayLevel>=4)) \
|
||||||
{ g_time = FUZ_GetMilliStart(); DISPLAY(__VA_ARGS__); \
|
{ g_displayTime = FUZ_GetMilliStart(); DISPLAY(__VA_ARGS__); \
|
||||||
if (g_displayLevel>=4) fflush(stdout); } }
|
if (g_displayLevel>=4) fflush(stdout); } }
|
||||||
static const U32 g_refreshRate = 150;
|
static const U32 g_refreshRate = 150;
|
||||||
static U32 g_time = 0;
|
static U32 g_displayTime = 0;
|
||||||
|
|
||||||
|
static U32 g_testTime = 0;
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
@@ -259,6 +261,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
BYTE* srcBuffer;
|
BYTE* srcBuffer;
|
||||||
BYTE* cBuffer;
|
BYTE* cBuffer;
|
||||||
BYTE* dstBuffer;
|
BYTE* dstBuffer;
|
||||||
|
BYTE* mirrorBuffer;
|
||||||
size_t srcBufferSize = (size_t)1<<maxSrcLog;
|
size_t srcBufferSize = (size_t)1<<maxSrcLog;
|
||||||
size_t dstBufferSize = (size_t)1<<maxSampleLog;
|
size_t dstBufferSize = (size_t)1<<maxSampleLog;
|
||||||
size_t cBufferSize = ZSTD_compressBound(dstBufferSize);
|
size_t cBufferSize = ZSTD_compressBound(dstBufferSize);
|
||||||
@@ -266,17 +269,22 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
U32 testNb = 0;
|
U32 testNb = 0;
|
||||||
U32 coreSeed = seed, lseed = 0;
|
U32 coreSeed = seed, lseed = 0;
|
||||||
ZSTD_CCtx* ctx;
|
ZSTD_CCtx* ctx;
|
||||||
|
ZSTD_DCtx* dctx;
|
||||||
|
U32 startTime = FUZ_GetMilliStart();
|
||||||
|
|
||||||
/* allocation */
|
/* allocation */
|
||||||
ctx = ZSTD_createCCtx();
|
ctx = ZSTD_createCCtx();
|
||||||
|
dctx= ZSTD_createDCtx();
|
||||||
cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
|
cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
|
||||||
cNoiseBuffer[1] = (BYTE*)malloc (srcBufferSize);
|
cNoiseBuffer[1] = (BYTE*)malloc (srcBufferSize);
|
||||||
cNoiseBuffer[2] = (BYTE*)malloc (srcBufferSize);
|
cNoiseBuffer[2] = (BYTE*)malloc (srcBufferSize);
|
||||||
cNoiseBuffer[3] = (BYTE*)malloc (srcBufferSize);
|
cNoiseBuffer[3] = (BYTE*)malloc (srcBufferSize);
|
||||||
cNoiseBuffer[4] = (BYTE*)malloc (srcBufferSize);
|
cNoiseBuffer[4] = (BYTE*)malloc (srcBufferSize);
|
||||||
dstBuffer = (BYTE*)malloc (dstBufferSize);
|
dstBuffer = (BYTE*)malloc (dstBufferSize);
|
||||||
|
mirrorBuffer = (BYTE*)malloc (dstBufferSize);
|
||||||
cBuffer = (BYTE*)malloc (cBufferSize);
|
cBuffer = (BYTE*)malloc (cBufferSize);
|
||||||
CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !dstBuffer || !cBuffer || !ctx,
|
CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4]
|
||||||
|
|| !dstBuffer || !mirrorBuffer || !cBuffer || !ctx || !dctx,
|
||||||
"Not enough memory, fuzzer tests cancelled");
|
"Not enough memory, fuzzer tests cancelled");
|
||||||
|
|
||||||
/* Create initial samples */
|
/* Create initial samples */
|
||||||
@@ -292,17 +300,23 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
FUZ_rand(&coreSeed);
|
FUZ_rand(&coreSeed);
|
||||||
|
|
||||||
/* test loop */
|
/* test loop */
|
||||||
for ( ; testNb <= nbTests; testNb++ )
|
for ( ; (testNb <= nbTests) || (FUZ_GetMilliSpan(startTime) < g_testTime); testNb++ )
|
||||||
{
|
{
|
||||||
size_t sampleSize, sampleStart;
|
size_t sampleSize, sampleStart, maxTestSize, totalTestSize;
|
||||||
size_t cSize, dSize, dSupSize;
|
size_t cSize, dSize, dSupSize, errorCode, totalCSize, totalGenSize;
|
||||||
U32 sampleSizeLog, buffNb, cLevelMod;
|
U32 sampleSizeLog, buffNb, cLevelMod, nbChunks, n;
|
||||||
|
XXH64_state_t crc64;
|
||||||
U64 crcOrig, crcDest;
|
U64 crcOrig, crcDest;
|
||||||
int cLevel;
|
int cLevel;
|
||||||
BYTE* sampleBuffer;
|
BYTE* sampleBuffer;
|
||||||
|
const BYTE* dict;
|
||||||
|
size_t dictSize;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests);
|
if (nbTests >= testNb)
|
||||||
|
{ DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); }
|
||||||
|
else { DISPLAYUPDATE(2, "\r%6u ", testNb); }
|
||||||
|
|
||||||
FUZ_rand(&coreSeed);
|
FUZ_rand(&coreSeed);
|
||||||
lseed = coreSeed ^ prime1;
|
lseed = coreSeed ^ prime1;
|
||||||
buffNb = FUZ_rand(&lseed) & 127;
|
buffNb = FUZ_rand(&lseed) & 127;
|
||||||
@@ -342,7 +356,6 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
/* compression failure test : too small dest buffer */
|
/* compression failure test : too small dest buffer */
|
||||||
if (cSize > 3)
|
if (cSize > 3)
|
||||||
{
|
{
|
||||||
size_t errorCode;
|
|
||||||
const size_t missing = (FUZ_rand(&lseed) % (cSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
const size_t missing = (FUZ_rand(&lseed) % (cSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
||||||
const size_t tooSmallSize = cSize - missing;
|
const size_t tooSmallSize = cSize - missing;
|
||||||
static const U32 endMark = 0x4DC2B1A9;
|
static const U32 endMark = 0x4DC2B1A9;
|
||||||
@@ -365,7 +378,6 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
|
|
||||||
/* truncated src decompression test */
|
/* truncated src decompression test */
|
||||||
{
|
{
|
||||||
size_t errorCode;
|
|
||||||
const size_t missing = (FUZ_rand(&lseed) % (cSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
const size_t missing = (FUZ_rand(&lseed) % (cSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
||||||
const size_t tooSmallSize = cSize - missing;
|
const size_t tooSmallSize = cSize - missing;
|
||||||
void* cBufferTooSmall = malloc(tooSmallSize); /* valgrind will catch overflows */
|
void* cBufferTooSmall = malloc(tooSmallSize); /* valgrind will catch overflows */
|
||||||
@@ -379,7 +391,6 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
/* too small dst decompression test */
|
/* too small dst decompression test */
|
||||||
if (sampleSize > 3)
|
if (sampleSize > 3)
|
||||||
{
|
{
|
||||||
size_t errorCode;
|
|
||||||
const size_t missing = (FUZ_rand(&lseed) % (sampleSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
const size_t missing = (FUZ_rand(&lseed) % (sampleSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
||||||
const size_t tooSmallSize = sampleSize - missing;
|
const size_t tooSmallSize = sampleSize - missing;
|
||||||
static const BYTE token = 0xA9;
|
static const BYTE token = 0xA9;
|
||||||
@@ -424,7 +435,6 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
U32 noiseSrc = FUZ_rand(&lseed) % 5;
|
U32 noiseSrc = FUZ_rand(&lseed) % 5;
|
||||||
const U32 endMark = 0xA9B1C3D6;
|
const U32 endMark = 0xA9B1C3D6;
|
||||||
U32 endCheck;
|
U32 endCheck;
|
||||||
size_t errorCode;
|
|
||||||
srcBuffer = cNoiseBuffer[noiseSrc];
|
srcBuffer = cNoiseBuffer[noiseSrc];
|
||||||
memcpy(dstBuffer+sampleSize, &endMark, 4);
|
memcpy(dstBuffer+sampleSize, &endMark, 4);
|
||||||
errorCode = ZSTD_decompress(dstBuffer, sampleSize, cBuffer, cSize);
|
errorCode = ZSTD_decompress(dstBuffer, sampleSize, cBuffer, cSize);
|
||||||
@@ -435,11 +445,80 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
CHECK(endMark!=endCheck, "ZSTD_decompress on noisy src : dst buffer overflow");
|
CHECK(endMark!=endCheck, "ZSTD_decompress on noisy src : dst buffer overflow");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Streaming compression of scattered segments test */
|
||||||
|
XXH64_reset(&crc64, 0);
|
||||||
|
nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
||||||
|
sampleSizeLog = FUZ_rand(&lseed) % maxSrcLog;
|
||||||
|
maxTestSize = (size_t)1 << sampleSizeLog;
|
||||||
|
maxTestSize += FUZ_rand(&lseed) & (maxTestSize-1);
|
||||||
|
if (maxTestSize >= dstBufferSize) maxTestSize = dstBufferSize-1;
|
||||||
|
|
||||||
|
sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
|
||||||
|
sampleSize = (size_t)1 << sampleSizeLog;
|
||||||
|
sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
|
||||||
|
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
||||||
|
dict = srcBuffer + sampleStart;
|
||||||
|
dictSize = sampleSize;
|
||||||
|
|
||||||
|
cSize = ZSTD_compressBegin(ctx, cBuffer, cBufferSize, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1);
|
||||||
|
errorCode = ZSTD_compress_insertDictionary(ctx, dict, dictSize);
|
||||||
|
CHECK (ZSTD_isError(errorCode), "dictionary insertion error : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
totalTestSize = 0;
|
||||||
|
for (n=0; n<nbChunks; n++)
|
||||||
|
{
|
||||||
|
sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
|
||||||
|
sampleSize = (size_t)1 << sampleSizeLog;
|
||||||
|
sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
|
||||||
|
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
||||||
|
|
||||||
|
if (cBufferSize-cSize < ZSTD_compressBound(sampleSize))
|
||||||
|
/* avoid invalid dstBufferTooSmall */
|
||||||
|
break;
|
||||||
|
if (totalTestSize+sampleSize > maxTestSize) break;
|
||||||
|
|
||||||
|
errorCode = ZSTD_compressContinue(ctx, cBuffer+cSize, cBufferSize-cSize, srcBuffer+sampleStart, sampleSize);
|
||||||
|
CHECK (ZSTD_isError(errorCode), "multi-segments compression error : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
cSize += errorCode;
|
||||||
|
|
||||||
|
XXH64_update(&crc64, srcBuffer+sampleStart, sampleSize);
|
||||||
|
memcpy(mirrorBuffer + totalTestSize, srcBuffer+sampleStart, sampleSize);
|
||||||
|
totalTestSize += sampleSize;
|
||||||
|
}
|
||||||
|
errorCode = ZSTD_compressEnd(ctx, cBuffer+cSize, cBufferSize-cSize);
|
||||||
|
CHECK (ZSTD_isError(errorCode), "multi-segments epilogue error : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
cSize += errorCode;
|
||||||
|
crcOrig = XXH64_digest(&crc64);
|
||||||
|
|
||||||
|
/* streaming decompression test */
|
||||||
|
errorCode = ZSTD_resetDCtx(dctx);
|
||||||
|
CHECK (ZSTD_isError(errorCode), "cannot init DCtx : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
|
||||||
|
totalCSize = 0;
|
||||||
|
totalGenSize = 0;
|
||||||
|
while (totalCSize < cSize)
|
||||||
|
{
|
||||||
|
size_t inSize = ZSTD_nextSrcSizeToDecompress(dctx);
|
||||||
|
size_t genSize = ZSTD_decompressContinue(dctx, dstBuffer+totalGenSize, dstBufferSize-totalGenSize, cBuffer+totalCSize, inSize);
|
||||||
|
CHECK (ZSTD_isError(genSize), "streaming decompression error : %s", ZSTD_getErrorName(genSize));
|
||||||
|
totalGenSize += genSize;
|
||||||
|
totalCSize += inSize;
|
||||||
|
}
|
||||||
|
CHECK (ZSTD_nextSrcSizeToDecompress(dctx) != 0, "frame not fully decoded");
|
||||||
|
CHECK (totalGenSize != totalTestSize, "decompressed data : wrong size")
|
||||||
|
CHECK (totalCSize != cSize, "compressed data should be fully read")
|
||||||
|
crcDest = XXH64(dstBuffer, totalTestSize, 0);
|
||||||
|
if (crcDest!=crcOrig)
|
||||||
|
errorCode = findDiff(mirrorBuffer, dstBuffer, totalTestSize);
|
||||||
|
CHECK (crcDest!=crcOrig, "streaming decompressed data corrupted : byte %u / %u (%02X!=%02X)",
|
||||||
|
(U32)errorCode, (U32)totalTestSize, dstBuffer[errorCode], mirrorBuffer[errorCode]);
|
||||||
|
|
||||||
}
|
}
|
||||||
DISPLAY("\rAll fuzzer tests completed \n");
|
DISPLAY("\r%u fuzzer tests completed \n", testNb-1);
|
||||||
|
|
||||||
_cleanup:
|
_cleanup:
|
||||||
ZSTD_freeCCtx(ctx);
|
ZSTD_freeCCtx(ctx);
|
||||||
|
ZSTD_freeDCtx(dctx);
|
||||||
free(cNoiseBuffer[0]);
|
free(cNoiseBuffer[0]);
|
||||||
free(cNoiseBuffer[1]);
|
free(cNoiseBuffer[1]);
|
||||||
free(cNoiseBuffer[2]);
|
free(cNoiseBuffer[2]);
|
||||||
@@ -447,6 +526,7 @@ _cleanup:
|
|||||||
free(cNoiseBuffer[4]);
|
free(cNoiseBuffer[4]);
|
||||||
free(cBuffer);
|
free(cBuffer);
|
||||||
free(dstBuffer);
|
free(dstBuffer);
|
||||||
|
free(mirrorBuffer);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
_output_error:
|
_output_error:
|
||||||
@@ -520,7 +600,7 @@ int main(int argc, char** argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
argument++;
|
argument++; g_testTime=0;
|
||||||
nbTests=0;
|
nbTests=0;
|
||||||
while ((*argument>='0') && (*argument<='9'))
|
while ((*argument>='0') && (*argument<='9'))
|
||||||
{
|
{
|
||||||
@@ -530,6 +610,20 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
argument++;
|
||||||
|
nbTests=0; g_testTime=0;
|
||||||
|
while ((*argument>='0') && (*argument<='9'))
|
||||||
|
{
|
||||||
|
g_testTime *= 10;
|
||||||
|
g_testTime += *argument - '0';
|
||||||
|
argument++;
|
||||||
|
}
|
||||||
|
if (*argument=='m') g_testTime *=60, argument++;
|
||||||
|
if (*argument=='n') argument++;
|
||||||
|
g_testTime *= 1000;
|
||||||
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
argument++;
|
argument++;
|
||||||
seed=0;
|
seed=0;
|
||||||
@@ -580,8 +674,6 @@ int main(int argc, char** argv)
|
|||||||
DISPLAY("Seed = %u\n", seed);
|
DISPLAY("Seed = %u\n", seed);
|
||||||
if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
|
if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
|
||||||
|
|
||||||
if (nbTests<=0) nbTests=1;
|
|
||||||
|
|
||||||
if (testNb==0) result = basicUnitTests(0, ((double)proba) / 100); /* constant seed for predictability */
|
if (testNb==0) result = basicUnitTests(0, ((double)proba) / 100); /* constant seed for predictability */
|
||||||
if (!result)
|
if (!result)
|
||||||
result = fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100);
|
result = fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100);
|
||||||
|
|||||||
@@ -342,6 +342,7 @@ static size_t BMK_benchParam(BMK_result_t* resultPtr,
|
|||||||
blockTable[blockNb].cSize = ZSTD_compress_advanced(ctx,
|
blockTable[blockNb].cSize = ZSTD_compress_advanced(ctx,
|
||||||
blockTable[blockNb].cPtr, blockTable[blockNb].cRoom,
|
blockTable[blockNb].cPtr, blockTable[blockNb].cRoom,
|
||||||
blockTable[blockNb].srcPtr, blockTable[blockNb].srcSize,
|
blockTable[blockNb].srcPtr, blockTable[blockNb].srcSize,
|
||||||
|
NULL, 0,
|
||||||
params);
|
params);
|
||||||
nbLoops++;
|
nbLoops++;
|
||||||
}
|
}
|
||||||
@@ -681,6 +682,8 @@ static void BMK_selectRandomStart(
|
|||||||
/* totally random entry */
|
/* totally random entry */
|
||||||
ZSTD_parameters p;
|
ZSTD_parameters p;
|
||||||
potentialRandomParams(&p, 1);
|
potentialRandomParams(&p, 1);
|
||||||
|
p.srcSize = srcSize;
|
||||||
|
ZSTD_validateParams(&p);
|
||||||
playAround(f, winners, p, srcBuffer, srcSize, ctx);
|
playAround(f, winners, p, srcBuffer, srcSize, ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -734,6 +737,7 @@ static void BMK_benchMem(void* srcBuffer, size_t srcSize)
|
|||||||
for (i=1; i<=maxSeeds; i++)
|
for (i=1; i<=maxSeeds; i++)
|
||||||
{
|
{
|
||||||
params = ZSTD_getParams(i, blockSize);
|
params = ZSTD_getParams(i, blockSize);
|
||||||
|
ZSTD_validateParams(¶ms);
|
||||||
BMK_seed(winners, params, srcBuffer, srcSize, ctx);
|
BMK_seed(winners, params, srcBuffer, srcSize, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+104
@@ -0,0 +1,104 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
die() {
|
||||||
|
echo "$@" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
roundTripTest() {
|
||||||
|
if [ -n "$3" ]; then
|
||||||
|
local c="$3"
|
||||||
|
local p="$2"
|
||||||
|
else
|
||||||
|
local c="$2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
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
|
||||||
|
diff -q tmp1 tmp2
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "$ZSTD" ] || die "ZSTD variable must be defined!"
|
||||||
|
|
||||||
|
printf "\n**** frame concatenation **** "
|
||||||
|
|
||||||
|
echo "hello " > hello.tmp
|
||||||
|
echo "world!" > world.tmp
|
||||||
|
cat hello.tmp world.tmp > helloworld.tmp
|
||||||
|
$ZSTD hello.tmp > hello.zstd
|
||||||
|
$ZSTD world.tmp > world.zstd
|
||||||
|
cat hello.zstd world.zstd > helloworld.zstd
|
||||||
|
$ZSTD -df helloworld.zstd > result.tmp
|
||||||
|
cat result.tmp
|
||||||
|
sdiff helloworld.tmp result.tmp
|
||||||
|
rm ./*.tmp ./*.zstd
|
||||||
|
|
||||||
|
echo frame concatenation test completed
|
||||||
|
|
||||||
|
echo "**** flush write error test **** "
|
||||||
|
|
||||||
|
echo "echo foo | $ZSTD > /dev/full"
|
||||||
|
echo foo | $ZSTD > /dev/full && die "write error not detected!"
|
||||||
|
echo "echo foo | $ZSTD | $ZSTD -d > /dev/full"
|
||||||
|
echo foo | $ZSTD | $ZSTD -d > /dev/full && die "write error not detected!"
|
||||||
|
|
||||||
|
|
||||||
|
echo "*** dictionary tests *** "
|
||||||
|
|
||||||
|
./datagen > tmpDict
|
||||||
|
./datagen -g1M | md5sum > tmp1
|
||||||
|
./datagen -g1M | $ZSTD -D tmpDict | $ZSTD -D tmpDict -dv | md5sum > tmp2
|
||||||
|
diff -q tmp1 tmp2
|
||||||
|
|
||||||
|
echo "*** multiple files tests *** "
|
||||||
|
|
||||||
|
./datagen -s1 > tmp1 2> /dev/null
|
||||||
|
./datagen -s2 -g100K > tmp2 2> /dev/null
|
||||||
|
./datagen -s3 -g1M > tmp3 2> /dev/null
|
||||||
|
$ZSTD -f -m tmp*
|
||||||
|
ls -ls tmp*
|
||||||
|
rm tmp1 tmp2 tmp3
|
||||||
|
$ZSTD -df -m *.zst
|
||||||
|
ls -ls tmp*
|
||||||
|
$ZSTD -f -m tmp1 notHere tmp2 && die "missing file not detected!"
|
||||||
|
rm tmp*
|
||||||
|
|
||||||
|
echo "**** zstd round-trip tests **** "
|
||||||
|
|
||||||
|
roundTripTest
|
||||||
|
roundTripTest '' 6
|
||||||
|
|
||||||
|
if [ "$1" != "--test-large-data" ]; then
|
||||||
|
echo "Skipping large data tests"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
roundTripTest -g270000000 1
|
||||||
|
roundTripTest -g270000000 2
|
||||||
|
roundTripTest -g270000000 3
|
||||||
|
|
||||||
|
roundTripTest -g140000000 -P60 4
|
||||||
|
roundTripTest -g140000000 -P60 5
|
||||||
|
roundTripTest -g140000000 -P60 6
|
||||||
|
|
||||||
|
roundTripTest -g70000000 -P70 7
|
||||||
|
roundTripTest -g70000000 -P70 8
|
||||||
|
roundTripTest -g70000000 -P70 9
|
||||||
|
|
||||||
|
roundTripTest -g35000000 -P75 10
|
||||||
|
roundTripTest -g35000000 -P75 11
|
||||||
|
roundTripTest -g35000000 -P75 12
|
||||||
|
|
||||||
|
roundTripTest -g18000000 -P80 13
|
||||||
|
roundTripTest -g18000000 -P80 14
|
||||||
|
roundTripTest -g18000000 -P80 15
|
||||||
|
roundTripTest -g18000000 -P80 16
|
||||||
|
roundTripTest -g18000000 -P80 17
|
||||||
|
|
||||||
|
roundTripTest -g50000000 -P94 18
|
||||||
|
roundTripTest -g50000000 -P94 19
|
||||||
|
|
||||||
|
roundTripTest -g99000000 -P99 20
|
||||||
|
roundTripTest -g6000000000 -P99 q
|
||||||
+15
-2
@@ -161,6 +161,7 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
ZBUFF_compressInit(zc, 1);
|
ZBUFF_compressInit(zc, 1);
|
||||||
readSize = CNBufferSize;
|
readSize = CNBufferSize;
|
||||||
genSize = compressedBufferSize;
|
genSize = compressedBufferSize;
|
||||||
|
ZBUFF_compressWithDictionary(zc, CNBuffer, 128 KB);
|
||||||
result = ZBUFF_compressContinue(zc, compressedBuffer, &genSize, CNBuffer, &readSize);
|
result = ZBUFF_compressContinue(zc, compressedBuffer, &genSize, CNBuffer, &readSize);
|
||||||
if (ZBUFF_isError(result)) goto _output_error;
|
if (ZBUFF_isError(result)) goto _output_error;
|
||||||
if (readSize != CNBufferSize) goto _output_error; /* entire input should be consumed */
|
if (readSize != CNBufferSize) goto _output_error; /* entire input should be consumed */
|
||||||
@@ -174,6 +175,7 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
/* Basic decompression test */
|
/* Basic decompression test */
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
|
DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
|
||||||
ZBUFF_decompressInit(zd);
|
ZBUFF_decompressInit(zd);
|
||||||
|
ZBUFF_decompressWithDictionary(zd, CNBuffer, 128 KB);
|
||||||
readSize = cSize;
|
readSize = cSize;
|
||||||
genSize = CNBufferSize;
|
genSize = CNBufferSize;
|
||||||
result = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, compressedBuffer, &readSize);
|
result = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, compressedBuffer, &readSize);
|
||||||
@@ -244,7 +246,6 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
U32 coreSeed = seed, lseed = 0;
|
U32 coreSeed = seed, lseed = 0;
|
||||||
ZBUFF_CCtx* zc;
|
ZBUFF_CCtx* zc;
|
||||||
ZBUFF_DCtx* zd;
|
ZBUFF_DCtx* zd;
|
||||||
XXH64_state_t crc64;
|
|
||||||
U32 startTime = FUZ_GetMilliStart();
|
U32 startTime = FUZ_GetMilliStart();
|
||||||
|
|
||||||
/* allocation */
|
/* allocation */
|
||||||
@@ -280,10 +281,12 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
for ( ; (testNb <= nbTests) || (FUZ_GetMilliSpan(startTime) < g_testTime); testNb++ )
|
for ( ; (testNb <= nbTests) || (FUZ_GetMilliSpan(startTime) < g_testTime); testNb++ )
|
||||||
{
|
{
|
||||||
size_t sampleSize, sampleStart;
|
size_t sampleSize, sampleStart;
|
||||||
size_t cSize;
|
const BYTE* dict;
|
||||||
|
size_t cSize, dictSize;
|
||||||
size_t maxTestSize, totalTestSize, readSize, totalCSize, genSize, totalGenSize;
|
size_t maxTestSize, totalTestSize, readSize, totalCSize, genSize, totalGenSize;
|
||||||
size_t errorCode;
|
size_t errorCode;
|
||||||
U32 sampleSizeLog, buffNb, n, nbChunks;
|
U32 sampleSizeLog, buffNb, n, nbChunks;
|
||||||
|
XXH64_state_t crc64;
|
||||||
U64 crcOrig, crcDest;
|
U64 crcOrig, crcDest;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
@@ -316,6 +319,15 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
maxTestSize = (size_t)1 << sampleSizeLog;
|
maxTestSize = (size_t)1 << sampleSizeLog;
|
||||||
maxTestSize += FUZ_rand(&lseed) & (maxTestSize-1);
|
maxTestSize += FUZ_rand(&lseed) & (maxTestSize-1);
|
||||||
ZBUFF_compressInit(zc, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1);
|
ZBUFF_compressInit(zc, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1);
|
||||||
|
|
||||||
|
sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
|
||||||
|
sampleSize = (size_t)1 << sampleSizeLog;
|
||||||
|
sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
|
||||||
|
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
||||||
|
dict = srcBuffer + sampleStart;
|
||||||
|
dictSize = sampleSize;
|
||||||
|
ZBUFF_compressWithDictionary(zc, dict, dictSize);
|
||||||
|
|
||||||
totalTestSize = 0;
|
totalTestSize = 0;
|
||||||
cSize = 0;
|
cSize = 0;
|
||||||
for (n=0; n<nbChunks; n++)
|
for (n=0; n<nbChunks; n++)
|
||||||
@@ -363,6 +375,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
|
|
||||||
/* multi - fragments decompression test */
|
/* multi - fragments decompression test */
|
||||||
ZBUFF_decompressInit(zd);
|
ZBUFF_decompressInit(zd);
|
||||||
|
ZBUFF_decompressWithDictionary(zd, dict, dictSize);
|
||||||
totalCSize = 0;
|
totalCSize = 0;
|
||||||
totalGenSize = 0;
|
totalGenSize = 0;
|
||||||
while (totalCSize < cSize)
|
while (totalCSize < cSize)
|
||||||
|
|||||||
+23
-9
@@ -31,12 +31,21 @@ is equivalent to
|
|||||||
It is based on the \fBLZ77\fR family, with FSE & huff0 entropy stage.
|
It is based on the \fBLZ77\fR family, with FSE & huff0 entropy stage.
|
||||||
zstd offers compression speed > 200 MB/s per core.
|
zstd offers compression speed > 200 MB/s per core.
|
||||||
It also features a fast decoder, with speed > 500 MB/s per core.
|
It also features a fast decoder, with speed > 500 MB/s per core.
|
||||||
|
|
||||||
|
\fBzstd\fR command line is generally similar to gzip, but features the following differences :
|
||||||
|
- Original files are preserved
|
||||||
|
- By default, \fBzstd file1 file2\fR means : compress file1 \fBinto\fR file2.
|
||||||
|
Use \fB-m\fR command if you want : compress file1 into file1.zstd and file2 into file2.zst
|
||||||
|
- By default, when compressing files, \fBzstd\fR displays advancement notification and result summary.
|
||||||
|
Use \fB-q\fR to turn them off
|
||||||
|
|
||||||
|
|
||||||
\fBzstd\fR supports the following options :
|
\fBzstd\fR supports the following options :
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-1
|
.B \-#
|
||||||
fast compression (default)
|
# compression level [1-19](default:1)
|
||||||
.TP
|
.TP
|
||||||
.B \-d
|
.B \-d
|
||||||
decompression
|
decompression
|
||||||
@@ -44,6 +53,14 @@ It also features a fast decoder, with speed > 500 MB/s per core.
|
|||||||
.B \-f
|
.B \-f
|
||||||
overwrite output without prompting
|
overwrite output without prompting
|
||||||
.TP
|
.TP
|
||||||
|
.BR \-m ", " --multiple
|
||||||
|
multiple files mode
|
||||||
|
In this mode, multiple files on the command line means compression or decompression of each named file
|
||||||
|
Notifications are also turned off by default
|
||||||
|
.TP
|
||||||
|
.B \-D
|
||||||
|
Use next file as dictionary content for compress / decompression
|
||||||
|
.TP
|
||||||
.BR \-h/\-H ", " --help
|
.BR \-h/\-H ", " --help
|
||||||
display help/long help and exit
|
display help/long help and exit
|
||||||
.TP
|
.TP
|
||||||
@@ -53,20 +70,17 @@ It also features a fast decoder, with speed > 500 MB/s per core.
|
|||||||
.BR \-v ", " --verbose
|
.BR \-v ", " --verbose
|
||||||
verbose mode
|
verbose mode
|
||||||
.TP
|
.TP
|
||||||
.B \-q
|
.BR \-q ", " --quiet
|
||||||
suppress warnings; specify twice to suppress errors too
|
suppress warnings and notifications; specify twice to suppress errors too
|
||||||
.TP
|
.TP
|
||||||
.B \-c
|
.B \-c
|
||||||
force write to standard output, even if it is the console
|
force write to standard output, even if it is the console
|
||||||
.TP
|
.TP
|
||||||
.B \-t
|
|
||||||
test compressed file integrity
|
|
||||||
.TP
|
|
||||||
.B \-z
|
.B \-z
|
||||||
force compression
|
force compression
|
||||||
.TP
|
.TP
|
||||||
.B \-b
|
.B \-b#
|
||||||
benchmark file(s)
|
benchmark file(s) using compression level #
|
||||||
.TP
|
.TP
|
||||||
.B \-i#
|
.B \-i#
|
||||||
iteration loops [1-9](default : 3), benchmark mode only
|
iteration loops [1-9](default : 3), benchmark mode only
|
||||||
|
|||||||
+92
-51
@@ -43,23 +43,26 @@
|
|||||||
#include <stdio.h> /* fprintf, getchar */
|
#include <stdio.h> /* fprintf, getchar */
|
||||||
#include <stdlib.h> /* exit, calloc, free */
|
#include <stdlib.h> /* exit, calloc, free */
|
||||||
#include <string.h> /* strcmp, strlen */
|
#include <string.h> /* strcmp, strlen */
|
||||||
#include "bench.h" /* BMK_benchFiles, BMK_SetNbIterations */
|
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
#ifndef ZSTD_NOBENCH
|
||||||
|
# include "bench.h" /* BMK_benchFiles, BMK_SetNbIterations */
|
||||||
|
#endif
|
||||||
|
#include "zstd.h" /* ZSTD version numbers */
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
/**************************************
|
||||||
* OS-specific Includes
|
* OS-specific Includes
|
||||||
**************************************/
|
**************************************/
|
||||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
||||||
# include <fcntl.h> // _O_BINARY
|
# include <fcntl.h> /* _O_BINARY */
|
||||||
# include <io.h> // _setmode, _isatty
|
# include <io.h> /* _setmode, _isatty */
|
||||||
# ifdef __MINGW32__
|
# ifdef __MINGW32__
|
||||||
/* int _fileno(FILE *stream); // seems no longer useful // MINGW somehow forgets to include this windows declaration into <stdio.h> */
|
/* int _fileno(FILE *stream); // seems no longer useful // MINGW somehow forgets to include this windows declaration into <stdio.h> */
|
||||||
# endif
|
# endif
|
||||||
# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY)
|
# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY)
|
||||||
# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
|
# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
|
||||||
#else
|
#else
|
||||||
# include <unistd.h> // isatty
|
# include <unistd.h> /* isatty */
|
||||||
# define SET_BINARY_MODE(file)
|
# define SET_BINARY_MODE(file)
|
||||||
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
||||||
#endif
|
#endif
|
||||||
@@ -70,7 +73,9 @@
|
|||||||
**************************************/
|
**************************************/
|
||||||
#define COMPRESSOR_NAME "zstd command line interface"
|
#define COMPRESSOR_NAME "zstd command line interface"
|
||||||
#ifndef ZSTD_VERSION
|
#ifndef ZSTD_VERSION
|
||||||
# define ZSTD_VERSION "v0.4.0"
|
# define QUOTE(str) #str
|
||||||
|
# define EXPAND_AND_QUOTE(str) QUOTE(str)
|
||||||
|
# define ZSTD_VERSION "v" EXPAND_AND_QUOTE(ZSTD_VERSION_MAJOR) "." EXPAND_AND_QUOTE(ZSTD_VERSION_MINOR) "." EXPAND_AND_QUOTE(ZSTD_VERSION_RELEASE)
|
||||||
#endif
|
#endif
|
||||||
#define AUTHOR "Yann Collet"
|
#define AUTHOR "Yann Collet"
|
||||||
#define WELCOME_MESSAGE "*** %s %i-bits %s, by %s (%s) ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), ZSTD_VERSION, AUTHOR, __DATE__
|
#define WELCOME_MESSAGE "*** %s %i-bits %s, by %s (%s) ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), ZSTD_VERSION, AUTHOR, __DATE__
|
||||||
@@ -118,8 +123,7 @@ static int usage(const char* programName)
|
|||||||
DISPLAY( "input : a filename\n");
|
DISPLAY( "input : a filename\n");
|
||||||
DISPLAY( " with no FILE, or when FILE is - , read standard input\n");
|
DISPLAY( " with no FILE, or when FILE is - , read standard input\n");
|
||||||
DISPLAY( "Arguments :\n");
|
DISPLAY( "Arguments :\n");
|
||||||
DISPLAY( " -1 : Fast compression (default) \n");
|
DISPLAY( " -# : # compression level (1-19, default:1) \n");
|
||||||
DISPLAY( " -9 : High compression \n");
|
|
||||||
DISPLAY( " -d : decompression (default for %s extension)\n", ZSTD_EXTENSION);
|
DISPLAY( " -d : decompression (default for %s extension)\n", ZSTD_EXTENSION);
|
||||||
//DISPLAY( " -z : force compression\n");
|
//DISPLAY( " -z : force compression\n");
|
||||||
DISPLAY( " -f : overwrite output without prompting \n");
|
DISPLAY( " -f : overwrite output without prompting \n");
|
||||||
@@ -136,13 +140,16 @@ static int usage_advanced(const char* programName)
|
|||||||
DISPLAY( " -V : display Version number and exit\n");
|
DISPLAY( " -V : display Version number and exit\n");
|
||||||
DISPLAY( " -v : verbose mode\n");
|
DISPLAY( " -v : verbose mode\n");
|
||||||
DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n");
|
DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n");
|
||||||
|
DISPLAY( " -m : multiple input filenames mode \n");
|
||||||
DISPLAY( " -c : force write to standard output, even if it is the console\n");
|
DISPLAY( " -c : force write to standard output, even if it is the console\n");
|
||||||
//DISPLAY( " -t : test compressed file integrity\n");
|
DISPLAY( " -D file: use file content as Dictionary \n");
|
||||||
|
#ifndef ZSTD_NOBENCH
|
||||||
DISPLAY( "Benchmark arguments :\n");
|
DISPLAY( "Benchmark arguments :\n");
|
||||||
DISPLAY( " -b# : benchmark file(s), using # compression level (default : 1) \n");
|
DISPLAY( " -b# : benchmark file(s), using # compression level (default : 1) \n");
|
||||||
DISPLAY( " -B# : cut file into independent blocks of size # (default : no block)\n");
|
DISPLAY( " -B# : cut file into independent blocks of size # (default : no block)\n");
|
||||||
DISPLAY( " -i# : iteration loops [1-9](default : 3)\n");
|
DISPLAY( " -i# : iteration loops [1-9](default : 3)\n");
|
||||||
DISPLAY( " -r# : test all compression levels from 1 to # (default : disabled)\n");
|
DISPLAY( " -r# : test all compression levels from 1 to # (default : disabled)\n");
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,31 +177,31 @@ int main(int argCount, const char** argv)
|
|||||||
decode=0,
|
decode=0,
|
||||||
forceStdout=0,
|
forceStdout=0,
|
||||||
main_pause=0,
|
main_pause=0,
|
||||||
rangeBench = 1;
|
nextEntryIsDictionary=0,
|
||||||
unsigned fileNameStart = 0;
|
multiple=0,
|
||||||
unsigned nbFiles = 0;
|
operationResult=0;
|
||||||
unsigned cLevel = 1;
|
unsigned cLevel = 1;
|
||||||
|
const char** filenameTable = (const char**)malloc(argCount * sizeof(const char*)); /* argCount >= 1 */
|
||||||
|
unsigned filenameIdx = 0;
|
||||||
const char* programName = argv[0];
|
const char* programName = argv[0];
|
||||||
const char* inFileName = NULL;
|
|
||||||
const char* outFileName = NULL;
|
const char* outFileName = NULL;
|
||||||
|
const char* dictFileName = NULL;
|
||||||
char* dynNameSpace = NULL;
|
char* dynNameSpace = NULL;
|
||||||
const char extension[] = ZSTD_EXTENSION;
|
const char extension[] = ZSTD_EXTENSION;
|
||||||
|
int rangeBench = 1;
|
||||||
|
|
||||||
|
/* init */
|
||||||
|
(void)rangeBench; /* not used when ZSTD_NOBENCH set */
|
||||||
|
if (filenameTable==NULL) { DISPLAY("not enough memory\n"); exit(1); }
|
||||||
displayOut = stderr;
|
displayOut = stderr;
|
||||||
/* Pick out basename component. Don't rely on stdlib because of conflicting behavior. */
|
/* Pick out program name from path. Don't rely on stdlib because of conflicting behavior */
|
||||||
for (i = (int)strlen(programName); i > 0; i--)
|
for (i = (int)strlen(programName); i > 0; i--) { if (programName[i] == '/') { i++; break; } }
|
||||||
{
|
|
||||||
if (programName[i] == '/') { i++; break; }
|
|
||||||
}
|
|
||||||
programName += i;
|
programName += i;
|
||||||
|
|
||||||
/* zstdcat preset behavior */
|
/* preset behaviors */
|
||||||
|
if (!strcmp(programName, ZSTD_UNZSTD)) decode=1;
|
||||||
if (!strcmp(programName, ZSTD_CAT)) { decode=1; forceStdout=1; displayLevel=1; outFileName=stdoutmark; }
|
if (!strcmp(programName, ZSTD_CAT)) { decode=1; forceStdout=1; displayLevel=1; outFileName=stdoutmark; }
|
||||||
|
|
||||||
/* unzstd preset behavior */
|
|
||||||
if (!strcmp(programName, ZSTD_UNZSTD))
|
|
||||||
decode=1;
|
|
||||||
|
|
||||||
/* command switches */
|
/* command switches */
|
||||||
for(i=1; i<argCount; i++)
|
for(i=1; i<argCount; i++)
|
||||||
{
|
{
|
||||||
@@ -205,7 +212,9 @@ int main(int argCount, const char** argv)
|
|||||||
/* long commands (--long-word) */
|
/* long commands (--long-word) */
|
||||||
if (!strcmp(argument, "--version")) { displayOut=stdout; DISPLAY(WELCOME_MESSAGE); return 0; }
|
if (!strcmp(argument, "--version")) { displayOut=stdout; DISPLAY(WELCOME_MESSAGE); return 0; }
|
||||||
if (!strcmp(argument, "--help")) { displayOut=stdout; return usage_advanced(programName); }
|
if (!strcmp(argument, "--help")) { displayOut=stdout; return usage_advanced(programName); }
|
||||||
|
if (!strcmp(argument, "--multiple")) { multiple=1; continue; }
|
||||||
if (!strcmp(argument, "--verbose")) { displayLevel=4; continue; }
|
if (!strcmp(argument, "--verbose")) { displayLevel=4; continue; }
|
||||||
|
if (!strcmp(argument, "--quiet")) { displayLevel--; continue; }
|
||||||
|
|
||||||
/* Decode commands (note : aggregated commands are allowed) */
|
/* Decode commands (note : aggregated commands are allowed) */
|
||||||
if (argument[0]=='-')
|
if (argument[0]=='-')
|
||||||
@@ -213,9 +222,8 @@ int main(int argCount, const char** argv)
|
|||||||
/* '-' means stdin/stdout */
|
/* '-' means stdin/stdout */
|
||||||
if (argument[1]==0)
|
if (argument[1]==0)
|
||||||
{
|
{
|
||||||
if (!inFileName) inFileName=stdinmark;
|
if (!filenameIdx) { filenameIdx=1, filenameTable[0]=stdinmark; continue; }
|
||||||
else outFileName=stdoutmark;
|
outFileName=stdoutmark; continue;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
argument++;
|
argument++;
|
||||||
@@ -248,11 +256,17 @@ int main(int argCount, const char** argv)
|
|||||||
/* Decoding */
|
/* Decoding */
|
||||||
case 'd': decode=1; argument++; break;
|
case 'd': decode=1; argument++; break;
|
||||||
|
|
||||||
|
/* Multiple input files */
|
||||||
|
case 'm': multiple=1; argument++; break;
|
||||||
|
|
||||||
/* Force stdout, even if stdout==console */
|
/* Force stdout, even if stdout==console */
|
||||||
case 'c': forceStdout=1; outFileName=stdoutmark; displayLevel=1; argument++; break;
|
case 'c': forceStdout=1; outFileName=stdoutmark; displayLevel=1; argument++; break;
|
||||||
|
|
||||||
// Test
|
/* Use file content as dictionary */
|
||||||
//case 't': decode=1; LZ4IO_setOverwrite(1); output_filename=nulmark; break;
|
case 'D': nextEntryIsDictionary = 1; argument++; break;
|
||||||
|
|
||||||
|
/* Test -- not implemented */
|
||||||
|
/* case 't': decode=1; LZ4IO_setOverwrite(1); output_filename=nulmark; break; */
|
||||||
|
|
||||||
/* Overwrite */
|
/* Overwrite */
|
||||||
case 'f': FIO_overwriteMode(); argument++; break;
|
case 'f': FIO_overwriteMode(); argument++; break;
|
||||||
@@ -263,9 +277,10 @@ int main(int argCount, const char** argv)
|
|||||||
/* Quiet mode */
|
/* Quiet mode */
|
||||||
case 'q': displayLevel--; argument++; break;
|
case 'q': displayLevel--; argument++; break;
|
||||||
|
|
||||||
/* keep source file (default anyway, so useless; only for xz/lzma compatibility) */
|
/* keep source file (default anyway, so useless; for gzip/xz compatibility) */
|
||||||
case 'k': argument++; break;
|
case 'k': argument++; break;
|
||||||
|
|
||||||
|
#ifndef ZSTD_NOBENCH
|
||||||
/* Benchmark */
|
/* Benchmark */
|
||||||
case 'b': bench=1; argument++; break;
|
case 'b': bench=1; argument++; break;
|
||||||
|
|
||||||
@@ -299,6 +314,7 @@ int main(int argCount, const char** argv)
|
|||||||
rangeBench = -1;
|
rangeBench = -1;
|
||||||
argument++;
|
argument++;
|
||||||
break;
|
break;
|
||||||
|
#endif /* ZSTD_NOBENCH */
|
||||||
|
|
||||||
/* Pause at the end (hidden option) */
|
/* Pause at the end (hidden option) */
|
||||||
case 'p': main_pause=1; argument++; break;
|
case 'p': main_pause=1; argument++; break;
|
||||||
@@ -310,40 +326,47 @@ int main(int argCount, const char** argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first provided filename is input */
|
/* dictionary */
|
||||||
if (!inFileName) { inFileName = argument; fileNameStart = i; nbFiles = argCount-i; continue; }
|
if (nextEntryIsDictionary)
|
||||||
|
|
||||||
/* second provided filename is output */
|
|
||||||
if (!outFileName)
|
|
||||||
{
|
{
|
||||||
outFileName = argument;
|
nextEntryIsDictionary = 0;
|
||||||
if (!strcmp (outFileName, nullString)) outFileName = nulmark;
|
dictFileName = argument;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add filename to list */
|
||||||
|
filenameTable[filenameIdx++] = argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Welcome message (if verbose) */
|
/* Welcome message (if verbose) */
|
||||||
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
||||||
|
|
||||||
|
/* Check if benchmark is selected */
|
||||||
|
if (bench)
|
||||||
|
{
|
||||||
|
#ifndef ZSTD_NOBENCH
|
||||||
|
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel*rangeBench);
|
||||||
|
#endif
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
|
||||||
/* No input filename ==> use stdin */
|
/* No input filename ==> use stdin */
|
||||||
if(!inFileName) { inFileName=stdinmark; }
|
if(!filenameIdx) filenameIdx=1, filenameTable[0]=stdinmark;
|
||||||
|
|
||||||
/* Check if input defined as console; trigger an error in this case */
|
/* Check if input defined as console; trigger an error in this case */
|
||||||
if (!strcmp(inFileName, stdinmark) && IS_CONSOLE(stdin) ) return badusage(programName);
|
if (!strcmp(filenameTable[0], stdinmark) && IS_CONSOLE(stdin) ) return badusage(programName);
|
||||||
|
|
||||||
/* Check if benchmark is selected */
|
|
||||||
if (bench) { BMK_benchFiles(argv+fileNameStart, nbFiles, cLevel*rangeBench); goto _end; }
|
|
||||||
|
|
||||||
/* No output filename ==> try to select one automatically (when possible) */
|
/* No output filename ==> try to select one automatically (when possible) */
|
||||||
while (!outFileName)
|
if (filenameIdx>=2) outFileName = filenameTable[1];
|
||||||
|
while (!outFileName) /* while : just to allow break statement */
|
||||||
{
|
{
|
||||||
if (!IS_CONSOLE(stdout)) { outFileName=stdoutmark; break; } /* Default to stdout whenever possible (i.e. not a console) */
|
if (!IS_CONSOLE(stdout)) { outFileName=stdoutmark; break; } /* Default to stdout whenever possible (i.e. not a console) */
|
||||||
if (!decode) /* compression to file */
|
if (!decode) /* compression to file */
|
||||||
{
|
{
|
||||||
size_t l = strlen(inFileName);
|
size_t l = strlen(filenameTable[0]);
|
||||||
dynNameSpace = (char*)calloc(1,l+5);
|
dynNameSpace = (char*)calloc(1,l+5);
|
||||||
if (dynNameSpace==NULL) { DISPLAY("not enough memory\n"); exit(1); }
|
if (dynNameSpace==NULL) { DISPLAY("not enough memory\n"); exit(1); }
|
||||||
strcpy(dynNameSpace, inFileName);
|
strcpy(dynNameSpace, filenameTable[0]);
|
||||||
strcpy(dynNameSpace+l, ZSTD_EXTENSION);
|
strcpy(dynNameSpace+l, ZSTD_EXTENSION);
|
||||||
outFileName = dynNameSpace;
|
outFileName = dynNameSpace;
|
||||||
DISPLAYLEVEL(2, "Compressed filename will be : %s \n", outFileName);
|
DISPLAYLEVEL(2, "Compressed filename will be : %s \n", outFileName);
|
||||||
@@ -351,8 +374,8 @@ int main(int argCount, const char** argv)
|
|||||||
}
|
}
|
||||||
/* decompression to file (automatic name will work only if input filename has correct format extension) */
|
/* decompression to file (automatic name will work only if input filename has correct format extension) */
|
||||||
{
|
{
|
||||||
size_t filenameSize = strlen(inFileName);
|
size_t filenameSize = strlen(filenameTable[0]);
|
||||||
if (strcmp(inFileName + (filenameSize-4), extension))
|
if (strcmp(filenameTable[0] + (filenameSize-4), extension))
|
||||||
{
|
{
|
||||||
DISPLAYLEVEL(1, "unknown suffix - cannot determine destination filename\n");
|
DISPLAYLEVEL(1, "unknown suffix - cannot determine destination filename\n");
|
||||||
return badusage(programName);
|
return badusage(programName);
|
||||||
@@ -360,7 +383,7 @@ int main(int argCount, const char** argv)
|
|||||||
dynNameSpace = (char*)calloc(1,filenameSize+1);
|
dynNameSpace = (char*)calloc(1,filenameSize+1);
|
||||||
if (dynNameSpace==NULL) { DISPLAY("not enough memory\n"); exit(1); }
|
if (dynNameSpace==NULL) { DISPLAY("not enough memory\n"); exit(1); }
|
||||||
outFileName = dynNameSpace;
|
outFileName = dynNameSpace;
|
||||||
strcpy(dynNameSpace, inFileName);
|
strcpy(dynNameSpace, filenameTable[0]);
|
||||||
dynNameSpace[filenameSize-4]=0;
|
dynNameSpace[filenameSize-4]=0;
|
||||||
DISPLAYLEVEL(2, "Decoding file %s \n", outFileName);
|
DISPLAYLEVEL(2, "Decoding file %s \n", outFileName);
|
||||||
}
|
}
|
||||||
@@ -369,18 +392,36 @@ int main(int argCount, const char** argv)
|
|||||||
/* Check if output is defined as console; trigger an error in this case */
|
/* Check if output is defined as console; trigger an error in this case */
|
||||||
if (!strcmp(outFileName,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) return badusage(programName);
|
if (!strcmp(outFileName,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) return badusage(programName);
|
||||||
|
|
||||||
/* No warning message in pure pipe mode (stdin + stdout) */
|
/* No warning message in pure pipe mode (stdin + stdout) or multiple mode */
|
||||||
if (!strcmp(inFileName, stdinmark) && !strcmp(outFileName,stdoutmark) && (displayLevel==2)) displayLevel=1;
|
if (!strcmp(filenameTable[0], stdinmark) && !strcmp(outFileName,stdoutmark) && (displayLevel==2)) displayLevel=1;
|
||||||
|
if (multiple && (displayLevel==2)) displayLevel=1;
|
||||||
|
|
||||||
|
if ((!multiple) && (filenameIdx>2))
|
||||||
|
{
|
||||||
|
DISPLAY("Too many files on the command line (%u > 2). Do you mean -m ? \n", filenameIdx);
|
||||||
|
return filenameIdx;
|
||||||
|
}
|
||||||
|
|
||||||
/* IO Stream/File */
|
/* IO Stream/File */
|
||||||
FIO_setNotificationLevel(displayLevel);
|
FIO_setNotificationLevel(displayLevel);
|
||||||
if (decode)
|
if (decode)
|
||||||
FIO_decompressFilename(outFileName, inFileName);
|
{
|
||||||
|
if (multiple)
|
||||||
|
operationResult = FIO_decompressMultipleFilenames(filenameTable, filenameIdx, ZSTD_EXTENSION, dictFileName);
|
||||||
|
else
|
||||||
|
operationResult = FIO_decompressFilename(outFileName, filenameTable[0], dictFileName);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
FIO_compressFilename(outFileName, inFileName, cLevel);
|
{
|
||||||
|
if (multiple)
|
||||||
|
operationResult = FIO_compressMultipleFilenames(filenameTable, filenameIdx, ZSTD_EXTENSION, dictFileName, cLevel);
|
||||||
|
else
|
||||||
|
operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel);
|
||||||
|
}
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
if (main_pause) waitEnter();
|
if (main_pause) waitEnter();
|
||||||
free(dynNameSpace);
|
free(dynNameSpace);
|
||||||
return 0;
|
free((void*)filenameTable);
|
||||||
|
return operationResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,26 +27,26 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>true</EnablePREfast>
|
<EnablePREfast>true</EnablePREfast>
|
||||||
<AdditionalOptions>/analyze:stacksize19000 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>true</EnablePREfast>
|
<EnablePREfast>true</EnablePREfast>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<AdditionalOptions>/analyze:stacksize19000 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>true</EnablePREfast>
|
<EnablePREfast>true</EnablePREfast>
|
||||||
<AdditionalOptions>/analyze:stacksize19000 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -27,26 +27,26 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>true</EnablePREfast>
|
<EnablePREfast>true</EnablePREfast>
|
||||||
<AdditionalOptions>/analyze:stacksize19000 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>true</EnablePREfast>
|
<EnablePREfast>true</EnablePREfast>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<AdditionalOptions>/analyze:stacksize19000 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>true</EnablePREfast>
|
<EnablePREfast>true</EnablePREfast>
|
||||||
<AdditionalOptions>/analyze:stacksize19000 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Express 2012 for Windows Desktop
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.24720.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstd", "zstd\zstd.vcxproj", "{4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstd", "zstd\zstd.vcxproj", "{4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcxproj", "{6FD4352B-346C-4703-96EA-D4A8B9A6976E}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcxproj", "{6FD4352B-346C-4703-96EA-D4A8B9A6976E}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstdlib", "zstdlib\zstdlib.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
@@ -39,6 +43,14 @@ Global
|
|||||||
{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.Build.0 = Release|Win32
|
{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.ActiveCfg = Release|x64
|
||||||
{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.Build.0 = 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
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
<ClCompile Include="..\..\..\lib\zstd_compress.c" />
|
<ClCompile Include="..\..\..\lib\zstd_compress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\zstd_decompress.c" />
|
<ClCompile Include="..\..\..\lib\zstd_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\programs\bench.c" />
|
<ClCompile Include="..\..\..\programs\bench.c" />
|
||||||
|
<ClCompile Include="..\..\..\programs\datagen.c" />
|
||||||
<ClCompile Include="..\..\..\programs\fileio.c" />
|
<ClCompile Include="..\..\..\programs\fileio.c" />
|
||||||
<ClCompile Include="..\..\..\programs\legacy\fileio_legacy.c" />
|
<ClCompile Include="..\..\..\programs\legacy\fileio_legacy.c" />
|
||||||
<ClCompile Include="..\..\..\programs\xxhash.c" />
|
<ClCompile Include="..\..\..\programs\xxhash.c" />
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
<ClInclude Include="..\..\..\lib\zstd_internal.h" />
|
<ClInclude Include="..\..\..\lib\zstd_internal.h" />
|
||||||
<ClInclude Include="..\..\..\lib\zstd_static.h" />
|
<ClInclude Include="..\..\..\lib\zstd_static.h" />
|
||||||
<ClInclude Include="..\..\..\programs\bench.h" />
|
<ClInclude Include="..\..\..\programs\bench.h" />
|
||||||
|
<ClInclude Include="..\..\..\programs\datagen.h" />
|
||||||
<ClInclude Include="..\..\..\programs\fileio.h" />
|
<ClInclude Include="..\..\..\programs\fileio.h" />
|
||||||
<ClInclude Include="..\..\..\programs\legacy\fileio_legacy.h" />
|
<ClInclude Include="..\..\..\programs\legacy\fileio_legacy.h" />
|
||||||
<ClInclude Include="..\..\..\programs\xxhash.h" />
|
<ClInclude Include="..\..\..\programs\xxhash.h" />
|
||||||
@@ -61,27 +63,27 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
@@ -102,7 +104,7 @@
|
|||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -54,6 +54,9 @@
|
|||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v03.c">
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v03.c">
|
||||||
<Filter>Fichiers sources</Filter>
|
<Filter>Fichiers sources</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\programs\datagen.c">
|
||||||
|
<Filter>Fichiers sources</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\lib\fse.h">
|
<ClInclude Include="..\..\..\lib\fse.h">
|
||||||
@@ -107,5 +110,8 @@
|
|||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v03.h">
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v03.h">
|
||||||
<Filter>Fichiers d%27en-tête</Filter>
|
<Filter>Fichiers d%27en-tête</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\programs\datagen.h">
|
||||||
|
<Filter>Fichiers d%27en-tête</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,216 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\lib\fse.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\huff0.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\zstd_buffered.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\zstd_compress.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\zstd_decompress.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\lib\bitstream.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\error.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\fse.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\fse_static.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\huff0.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\huff0_static.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\mem.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_buffered.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_buffered_static.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_internal.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_static.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="zstdlib.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>zstdlib</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<TargetName>zstdlib_x86</TargetName>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IncludePath>$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
||||||
|
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<TargetName>zstdlib_x64</TargetName>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IncludePath>$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
||||||
|
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<TargetName>zstdlib_x86</TargetName>
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
<IncludePath>$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
||||||
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<TargetName>zstdlib_x64</TargetName>
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
<IncludePath>$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
||||||
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<EnablePREfast>true</EnablePREfast>
|
||||||
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<EnablePREfast>true</EnablePREfast>
|
||||||
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<EnablePREfast>true</EnablePREfast>
|
||||||
|
<AdditionalOptions>/analyze:stacksize25000 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<AssemblerOutput>All</AssemblerOutput>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
|
<EnablePREfast>false</EnablePREfast>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<AssemblerOutput>All</AssemblerOutput>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\lib\fse.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\huff0.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\zstd_buffered.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\zstd_compress.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\zstd_decompress.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\lib\fse.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\fse_static.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_static.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\huff0.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\huff0_static.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\error.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\bitstream.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_internal.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_buffered.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\zstd_buffered_static.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\mem.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="zstdlib.rc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user